<commit_before>/*
 * Copyright (C) 2013 salesforce.com, inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/**
 * @description Creates an Event with name, source component, event definition, event dispatcher, parameters, and sets the fired flag to false.
 * @constructor
 * @param {Object} config
 * @platform
 * @export
 */
Aura.Event.Event = function(config) {
    // source is only used to calculate the path, not determine access
    this.source = config["component"] || $A.getContext().getCurrentAccess() || $A.getRoot();
    this.eventDef = config["eventDef"];
    this.eventDispatcher = config["eventDispatcher"];
    this.eventName = config["name"];
    this.params = {};
    this.fired = false;
    this.eventStopPropagation = false;
    this.defaultPrevented = false;
    this.paused = false;
    this.componentEvent = false;
    this.phase = undefined;
    this.eventHandlerIterator = null;

    // propagating locker key when possible
    $A.lockerService.trust(this.source, this);
};

/**
 * Gets the source component that fired this event.
 *
 * @returns {Object} The source component
 * @platform
 * @export
 */
Aura.Event.Event.prototype.getSource = function() {
    return this.source;
};

/**
 * Gets the Event Definition.
 * Returns an EventDef object.
 * @export
 */
Aura.Event.Event.prototype.getDef = function(){
    return this.eventDef;
};

/**
 * Gets the current phase of this event.
 * Returns undefined if the event has not yet been fired.
 * Possible return values for APPLICATION and COMPONENT events
 * are "capture", "bubble", and "default" once fired.
 * VALUE events return "default" once fired.
 *
 * @platform
 * @export
 */
Aura.Event.Event.prototype.getPhase = function(){
    return this.phase;
};

/**
 * Sets whether the event can bubble or not. This will throw
 * an error if called in the "default" phase.
 * The default is false.
 * @platform
 * @export
 */
Aura.Event.Event.prototype.stopPropagation = function() {
    var eventExecutionType = this.getEventExecutionType();

    // stopPropagation was introduced before this assertion and may be used
    // in non-bubbling component events
    $A.assert(eventExecutionType !== "COMPONENT" ||
        eventExecutionType !== "APPLICATION" ||
        this.getPhase() !== "default", "stopPropagation() is not supported in the 'default' phase");
    this.eventStopPropagation = true;
};

/**
 * Prevents the default phase execution for this event. This will throw
 * an error if called in the "default" phase.
 * The default is true.
 * @platform
 * @export
 */
Aura.Event.Event.prototype.preventDefault = function() {
    $A.assert(this.getPhase() !== "default", "preventDefault() is not supported in the 'default' phase");
    this.defaultPrevented = true;
};

/**
 * Pauses this event such that event handlers will not be processed until
 * Event.resume() is called. The handling process will pause in the current
 * position of the event handler processing sequence. If the event is already
 * paused, calling this does nothing. This will throw an error
 * if called in the "default" phase.
 * @platform
 * @export
 */
Aura.Event.Event.prototype.pause = function() {
    $A.assert(this.getPhase() !== "default", "pause() is not supported in the 'default' phase");
    if(!this.paused) {
        this.paused = true;
    }
    return this;
};

/**
 * Resumes event handling for this event from the same position in the event
 * handler processing sequence from which it was previously paused.
 * If the event is not paused, calling this does nothing. This will throw an error
 * if called in the "default" phase.
 * This API does not define whether or not any remaining event handlers will
 * execute in the current call stack or be deferred and executed in a new call stack,
 * therefore the exact timing behavior is not dependable.
 * @platform
 * @export
 */
Aura.Event.Event.prototype.resume = function() {
    $A.assert(this.getPhase() !== "default", "resume() is not supported in the 'default' phase");
    if(this.paused) {
        this.paused = false;
        // JBA: should this queue a microtask/task or start from this activation frame?
        this.executeHandlers();
    }
};

/**
 * Sets the event as a "componentEvent" (won't bubble)
 * This type of event was used historically as a construct to call an action of a child
 * Since the advent of "methods", this type of event communication is discouraged and a "method" is preferred.
 * NOTE: Calling events on a child is discouraged and will be deprecated
 * @export
 */
Aura.Event.Event.prototype.setComponentEvent = function(){
    this.componentEvent = true;
    return this;
};

/**
 * Gets the name of the Event.
 * @returns {String} The event name
 * @platform
 * @export
 */
Aura.Event.Event.prototype.getName = function(){
    return this.eventName;
};

/**
 * Sets parameters for the Event. Does not modify an event that has already been fired.
 * Maps key in config to attributeDefs.
 * @param {Object} config - The parameters for the Event.
 * @platform
 * @export
 */
Aura.Event.Event.prototype.setParams = function(config) {
    if (this.fired) {
        $A.assert(false, "Event.setParams(): cannot modify all params in an event that has already been fired.");
    }

    if (config) {
        var attributeDefs = this.eventDef.getAttributeDefs();
        for (var key in config){
            if (config.hasOwnProperty(key)) {
                if (attributeDefs[key]) {
                    this.params[key] = config[key];
                } else {
                    $A.warning("Event.setParams(): '" + key +"'('" + config[key] + "') is not a valid parameter. Valid parameters are '"+ Object.keys(this.eventDef.getAttributeDefs()).join("', '") + "'");
                }
            }
        }
    }
    return this;
};

/**
 * Sets a parameter for the Event. Does not modify an event that has already been fired.
 * @param {String} key - The name of the parameter.
 * @param {Object} value - The value of the parameter.
 * @platform
 * @export
 */
Aura.Event.Event.prototype.setParam = function(key, value) {
    if (this.fired && this.componentEvent) {
        $A.assert(false, "Event.setParam(): cannot modify a component event that has already been fired.");
    }
    if (this.eventDef.getAttributeDefs()[key]) {
        this.params[key] = value;
    } else {
        $A.warning("Event.setParam(): '"+key+"' is not a valid parameter. Valid parameters are '" + Object.keys(this.eventDef.getAttributeDefs()).join("', '") + "'");
    }
};

/**
 * Gets an Event parameter.
 * @param {String} name The name of the Event. For example, event.getParam("button") returns the value of the pressed mouse button (0, 1, or 2).
 * @returns {String} The parameter value
 * @platform
 * @export
 */
Aura.Event.Event.prototype.getParam = function(name){
    return this.params[name];
};

/**
 * Gets all the Event parameters.
 * @returns {Object} The collection of parameters
 * @platform
 * @export
 */
Aura.Event.Event.prototype.getParams = function(){
    return this.params;
};

/**
 * Convenience function to determine which kind of event execution should be used
 * for this event. This is NOT PUBLIC! It's NOT an API and can change at any point.
 * @return {String} One of: "VALUE", "COMPONENT", "LEGACY_COMPONENT", "APPLICATION"
 * @private
 */
Aura.Event.Event.prototype.getEventExecutionType = function () {
    if(this.eventDef.getDescriptor().getQualifiedName() === "markup://aura:methodCall") {
        return "VALUE";
    }
    else if(this.eventName) {
        return this.componentEvent ?
            "LEGACY_COMPONENT" :
            "COMPONENT";
    }
    else {
        var def = this.eventDef;
        while (def) {
            var qname = def.getDescriptor().getQualifiedName();
            var handlers = this.eventDispatcher[qname];

            if (handlers) {
                return def.getEventType() === "VALUE" ?
                    "VALUE" :
                    "APPLICATION";
            }
            def = def.getSuperDef();
        }

        // we didn't find any handlers to begin with; just assume "APPLICATION"
        return "APPLICATION";
    }
};

/**
 * Executes the event handlers for this event.
 * @private
 */
Aura.Event.Event.prototype.executeHandlers = function() {
    if(!this.eventHandlerIterator) {
        this.eventHandlerIterator = this.getHandlerIterator();
    }
    this.executeHandlerIterator(this.eventHandlerIterator);
};

/**
 * Executes the handlers returned by handlerIterator.
 * @param {Iterator} handlerIterator
 * @private
 */
Aura.Event.Event.prototype.executeHandlerIterator = function(handlerIterator) {
    var res = {};
    var value;

    var isSystemError = this.eventDef.getDescriptor().toString() === "markup://aura:systemError";
    var isComponentEventType = this.getEventExecutionType() === "COMPONENT";

    while(!this.paused && !res.done) {
        res = handlerIterator.next();
        value = res.value;
        if(value && value.handler) {

            // LEGACY BEHAVIOR
            // COMPONENT events automatically stopPropagation if something is destroyed during BUBBLING
            // or CAPTURING
            if(isComponentEventType && !value.cmp.isValid() && this.phase !== "default") {
                this.stopPropagation();
            }

            // update our phase
            this.phase = value.phase;

            if(isSystemError) {
                // Special case... only wrap in try-catch for this type of event
                try {
                    value.handler(this);
                } catch (e) {
                    // if a systemError event handler failed, we don't want it to repeatedly fail
                    // because the event is fired in error handling framework.

                    // TODO: unregister this particular event handler here!
                    // cmpHandlers[j] = null;
                    $A.warning("aura:systemError event handler failed", e);
                    $A.logger.reportError(e);
                }
            }
            else {
                value.handler(this);
            }
        }
    }
};

/**
 * Returns an iterator over the handlers for this event.
 * @private
 */
Aura.Event.Event.prototype.getHandlerIterator = function() {
    var eventExecutionType = this.getEventExecutionType();

    switch(eventExecutionType) {
        case "VALUE":
            return $A.eventService.getValueHandlerIterator(this);
        case "LEGACY_COMPONENT":
            return $A.eventService.getNonBubblingComponentEventHandlerIterator(this);
        case "COMPONENT":
            return $A.eventService.getComponentEventHandlerIterator(this);
        case "APPLICATION":
            return $A.eventService.getAppEventHandlerIterator(this);
        default:
            throw new Aura.Errors.AuraError("Invalid event type");
    }
};

/**
 * Fires the Event. Checks if the Event has already been fired before firing.
 * Maps the component handlers to the event dispatcher.
 * @param {Object} params - Optional. A set of parameters for the Event. Any previous parameters of the same name will be overwritten.
 * @platform
 * @export
 */
Aura.Event.Event.prototype.fire = function(params) {
    var self = this;

    if (this.fired) {
        aura.assert(false, "Event.fire(): Unable to fire event. Event has already been fired.");
    }

    if (params) {
        this.setParams(params);
    }

    $A.run(function() {
        self.fired = true;
        self.executeHandlers();
    }, this.eventDef.getDescriptor().getQualifiedName()/*name for the stack*/);
};
<commit_msg>Updated getParam JSDoc return value.<commit_after>/*
 * Copyright (C) 2013 salesforce.com, inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/**
 * @description Creates an Event with name, source component, event definition, event dispatcher, parameters, and sets the fired flag to false.
 * @constructor
 * @param {Object} config
 * @platform
 * @export
 */
Aura.Event.Event = function(config) {
    // source is only used to calculate the path, not determine access
    this.source = config["component"] || $A.getContext().getCurrentAccess() || $A.getRoot();
    this.eventDef = config["eventDef"];
    this.eventDispatcher = config["eventDispatcher"];
    this.eventName = config["name"];
    this.params = {};
    this.fired = false;
    this.eventStopPropagation = false;
    this.defaultPrevented = false;
    this.paused = false;
    this.componentEvent = false;
    this.phase = undefined;
    this.eventHandlerIterator = null;

    // propagating locker key when possible
    $A.lockerService.trust(this.source, this);
};

/**
 * Gets the source component that fired this event.
 *
 * @returns {Object} The source component
 * @platform
 * @export
 */
Aura.Event.Event.prototype.getSource = function() {
    return this.source;
};

/**
 * Gets the Event Definition.
 * Returns an EventDef object.
 * @export
 */
Aura.Event.Event.prototype.getDef = function(){
    return this.eventDef;
};

/**
 * Gets the current phase of this event.
 * Returns undefined if the event has not yet been fired.
 * Possible return values for APPLICATION and COMPONENT events
 * are "capture", "bubble", and "default" once fired.
 * VALUE events return "default" once fired.
 *
 * @platform
 * @export
 */
Aura.Event.Event.prototype.getPhase = function(){
    return this.phase;
};

/**
 * Sets whether the event can bubble or not. This will throw
 * an error if called in the "default" phase.
 * The default is false.
 * @platform
 * @export
 */
Aura.Event.Event.prototype.stopPropagation = function() {
    var eventExecutionType = this.getEventExecutionType();

    // stopPropagation was introduced before this assertion and may be used
    // in non-bubbling component events
    $A.assert(eventExecutionType !== "COMPONENT" ||
        eventExecutionType !== "APPLICATION" ||
        this.getPhase() !== "default", "stopPropagation() is not supported in the 'default' phase");
    this.eventStopPropagation = true;
};

/**
 * Prevents the default phase execution for this event. This will throw
 * an error if called in the "default" phase.
 * The default is true.
 * @platform
 * @export
 */
Aura.Event.Event.prototype.preventDefault = function() {
    $A.assert(this.getPhase() !== "default", "preventDefault() is not supported in the 'default' phase");
    this.defaultPrevented = true;
};

/**
 * Pauses this event such that event handlers will not be processed until
 * Event.resume() is called. The handling process will pause in the current
 * position of the event handler processing sequence. If the event is already
 * paused, calling this does nothing. This will throw an error
 * if called in the "default" phase.
 * @platform
 * @export
 */
Aura.Event.Event.prototype.pause = function() {
    $A.assert(this.getPhase() !== "default", "pause() is not supported in the 'default' phase");
    if(!this.paused) {
        this.paused = true;
    }
    return this;
};

/**
 * Resumes event handling for this event from the same position in the event
 * handler processing sequence from which it was previously paused.
 * If the event is not paused, calling this does nothing. This will throw an error
 * if called in the "default" phase.
 * This API does not define whether or not any remaining event handlers will
 * execute in the current call stack or be deferred and executed in a new call stack,
 * therefore the exact timing behavior is not dependable.
 * @platform
 * @export
 */
Aura.Event.Event.prototype.resume = function() {
    $A.assert(this.getPhase() !== "default", "resume() is not supported in the 'default' phase");
    if(this.paused) {
        this.paused = false;
        // JBA: should this queue a microtask/task or start from this activation frame?
        this.executeHandlers();
    }
};

/**
 * Sets the event as a "componentEvent" (won't bubble)
 * This type of event was used historically as a construct to call an action of a child
 * Since the advent of "methods", this type of event communication is discouraged and a "method" is preferred.
 * NOTE: Calling events on a child is discouraged and will be deprecated
 * @export
 */
Aura.Event.Event.prototype.setComponentEvent = function(){
    this.componentEvent = true;
    return this;
};

/**
 * Gets the name of the Event.
 * @returns {String} The event name
 * @platform
 * @export
 */
Aura.Event.Event.prototype.getName = function(){
    return this.eventName;
};

/**
 * Sets parameters for the Event. Does not modify an event that has already been fired.
 * Maps key in config to attributeDefs.
 * @param {Object} config - The parameters for the Event.
 * @platform
 * @export
 */
Aura.Event.Event.prototype.setParams = function(config) {
    if (this.fired) {
        $A.assert(false, "Event.setParams(): cannot modify all params in an event that has already been fired.");
    }

    if (config) {
        var attributeDefs = this.eventDef.getAttributeDefs();
        for (var key in config){
            if (config.hasOwnProperty(key)) {
                if (attributeDefs[key]) {
                    this.params[key] = config[key];
                } else {
                    $A.warning("Event.setParams(): '" + key +"'('" + config[key] + "') is not a valid parameter. Valid parameters are '"+ Object.keys(this.eventDef.getAttributeDefs()).join("', '") + "'");
                }
            }
        }
    }
    return this;
};

/**
 * Sets a parameter for the Event. Does not modify an event that has already been fired.
 * @param {String} key - The name of the parameter.
 * @param {Object} value - The value of the parameter.
 * @platform
 * @export
 */
Aura.Event.Event.prototype.setParam = function(key, value) {
    if (this.fired && this.componentEvent) {
        $A.assert(false, "Event.setParam(): cannot modify a component event that has already been fired.");
    }
    if (this.eventDef.getAttributeDefs()[key]) {
        this.params[key] = value;
    } else {
        $A.warning("Event.setParam(): '"+key+"' is not a valid parameter. Valid parameters are '" + Object.keys(this.eventDef.getAttributeDefs()).join("', '") + "'");
    }
};

/**
 * Gets an Event parameter.
 * @param {String} name The name of the Event. For example, event.getParam("button") returns the value of the pressed mouse button (0, 1, or 2).
 * @returns {Object} The parameter value
 * @platform
 * @export
 */
Aura.Event.Event.prototype.getParam = function(name){
    return this.params[name];
};

/**
 * Gets all the Event parameters.
 * @returns {Object} The collection of parameters
 * @platform
 * @export
 */
Aura.Event.Event.prototype.getParams = function(){
    return this.params;
};

/**
 * Convenience function to determine which kind of event execution should be used
 * for this event. This is NOT PUBLIC! It's NOT an API and can change at any point.
 * @return {String} One of: "VALUE", "COMPONENT", "LEGACY_COMPONENT", "APPLICATION"
 * @private
 */
Aura.Event.Event.prototype.getEventExecutionType = function () {
    if(this.eventDef.getDescriptor().getQualifiedName() === "markup://aura:methodCall") {
        return "VALUE";
    }
    else if(this.eventName) {
        return this.componentEvent ?
            "LEGACY_COMPONENT" :
            "COMPONENT";
    }
    else {
        var def = this.eventDef;
        while (def) {
            var qname = def.getDescriptor().getQualifiedName();
            var handlers = this.eventDispatcher[qname];

            if (handlers) {
                return def.getEventType() === "VALUE" ?
                    "VALUE" :
                    "APPLICATION";
            }
            def = def.getSuperDef();
        }

        // we didn't find any handlers to begin with; just assume "APPLICATION"
        return "APPLICATION";
    }
};

/**
 * Executes the event handlers for this event.
 * @private
 */
Aura.Event.Event.prototype.executeHandlers = function() {
    if(!this.eventHandlerIterator) {
        this.eventHandlerIterator = this.getHandlerIterator();
    }
    this.executeHandlerIterator(this.eventHandlerIterator);
};

/**
 * Executes the handlers returned by handlerIterator.
 * @param {Iterator} handlerIterator
 * @private
 */
Aura.Event.Event.prototype.executeHandlerIterator = function(handlerIterator) {
    var res = {};
    var value;

    var isSystemError = this.eventDef.getDescriptor().toString() === "markup://aura:systemError";
    var isComponentEventType = this.getEventExecutionType() === "COMPONENT";

    while(!this.paused && !res.done) {
        res = handlerIterator.next();
        value = res.value;
        if(value && value.handler) {

            // LEGACY BEHAVIOR
            // COMPONENT events automatically stopPropagation if something is destroyed during BUBBLING
            // or CAPTURING
            if(isComponentEventType && !value.cmp.isValid() && this.phase !== "default") {
                this.stopPropagation();
            }

            // update our phase
            this.phase = value.phase;

            if(isSystemError) {
                // Special case... only wrap in try-catch for this type of event
                try {
                    value.handler(this);
                } catch (e) {
                    // if a systemError event handler failed, we don't want it to repeatedly fail
                    // because the event is fired in error handling framework.

                    // TODO: unregister this particular event handler here!
                    // cmpHandlers[j] = null;
                    $A.warning("aura:systemError event handler failed", e);
                    $A.logger.reportError(e);
                }
            }
            else {
                value.handler(this);
            }
        }
    }
};

/**
 * Returns an iterator over the handlers for this event.
 * @private
 */
Aura.Event.Event.prototype.getHandlerIterator = function() {
    var eventExecutionType = this.getEventExecutionType();

    switch(eventExecutionType) {
        case "VALUE":
            return $A.eventService.getValueHandlerIterator(this);
        case "LEGACY_COMPONENT":
            return $A.eventService.getNonBubblingComponentEventHandlerIterator(this);
        case "COMPONENT":
            return $A.eventService.getComponentEventHandlerIterator(this);
        case "APPLICATION":
            return $A.eventService.getAppEventHandlerIterator(this);
        default:
            throw new Aura.Errors.AuraError("Invalid event type");
    }
};

/**
 * Fires the Event. Checks if the Event has already been fired before firing.
 * Maps the component handlers to the event dispatcher.
 * @param {Object} params - Optional. A set of parameters for the Event. Any previous parameters of the same name will be overwritten.
 * @platform
 * @export
 */
Aura.Event.Event.prototype.fire = function(params) {
    var self = this;

    if (this.fired) {
        aura.assert(false, "Event.fire(): Unable to fire event. Event has already been fired.");
    }

    if (params) {
        this.setParams(params);
    }

    $A.run(function() {
        self.fired = true;
        self.executeHandlers();
    }, this.eventDef.getDescriptor().getQualifiedName()/*name for the stack*/);
};
<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2015 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

CLASS({
  package: 'foam.graphics',
  name:  'Label',
  extends: 'foam.graphics.CView',

  traits: [
    'foam.patterns.layout.LayoutItemHorizontalTrait',
    'foam.patterns.layout.LayoutItemVerticalTrait'
  ],

  imports: [
    'document'
  ],

  properties: [
    {
      name:  'textAlign',
      label: 'Text Alignment',
      type:  'String',
      defaultValue: 'left',
      help: 'Text alignment can be left, right, center, or the locale aware start and end.',
      preSet: function(old,nu) {
        // TODO(jacksonic): account for locale
        if ( nu == 'start' ) {
          console.warn("Right-to-left support in foam.graphics.Label not available.");
          return 'left';
        }
        if ( nu == 'end' ) {
          console.warn("Right-to-left support in foam.graphics.Label not available.");
          return 'right';
        }
        return nu;
      }
    },
    {
      name: 'text',
      aliases: 'data',
      type: 'String',
      defaultValue: ''
    },
    {
      name: 'font',
      type: 'String',
      defaultValue: "",
      help: "CSS-style font description string"
    },
    {
      name: 'background',
      defaultValue: 'rgba(0,0,0,0)'
    },
    {
      model_: 'IntProperty',
      name: 'padding',
      defaultValue: 5
    },
    {
      model_: 'BooleanProperty',
      name: 'isShrinkable',
      defaultValue: false,
      documentation: function() {/* Indicates if the minimum size constraint should
        be the same as the preferred size, preventing font shrinking. */}
    },
    {
      name: 'clipped',
      defaultValue: true
    }
  ],

  methods: {
    init: function() {
      this.SUPER();

      Events.dynamic(
        function() { this.text; this.font; this.padding; }.bind(this),
        this.updatePreferred );

      this.updatePreferred();
    },

    paintSelf: function(c) {
      this.SUPER(c);

      c.save();

      c.textBaseline = 'top';
      c.textAlign = this.textAlign;
      c.fillStyle = this.color;
      if (this.font) c.font = this.font;
      if ( this.textAlign === 'center' ) {
        c.fillText(this.text, this.width/2, this.padding, this.width-(this.padding*2));
      } else if ( this.textAlign === 'right' ) {
        c.fillText(this.text, this.padding + this.width-(this.padding*2), this.padding, this.width-(this.padding*2));
      } else {
        c.fillText(this.text, this.padding, this.padding, this.width-(this.padding*2));
      }
      c.restore();
    }
  },

  listeners: [
    {
      name: 'updatePreferred',
      isFramed: false, // preferred size updates propagate up immediately
      code: function() {
        var e = this.document.createElement('canvas');
        var c = e.getContext('2d');

        // width of text
        c.save();
        if (this.font) c.font = this.font;
        this.horizontalConstraints.preferred =
          c.measureText(this.text).width + this.padding*2;
        c.restore();

        // if no shrink, lock minimum to preferred
        if ( ! this.isShrinkable )
          this.horizontalConstraints.min = this.horizontalConstraints.preferred;

        // height (this is not directly accessible... options include putting
        // a span into the DOM and getting font metrics from that, or just going
        // by raw font height setting (which is always pixels in a canvas)
        if ( ! this.font ) this.font = c.font;

        var height = parseInt(/[0-9]+(?=pt|px)/.exec(this.font) || 0);
        this.verticalConstraints.preferred = height + this.padding*2;

        // if no shrink, lock minimum to preferred
        if ( ! this.isShrinkable )
          this.verticalConstraints.min = this.verticalConstraints.preferred;
      },

      documentation: function() {/* Calculates the preferred size of this
        $$DOC{ref:'foam.graphics.Label'} based on the actual text and font.
      */},
    }
  ]
});
<commit_msg>TODO added for graphics.Label layout<commit_after>/**
 * @license
 * Copyright 2015 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

CLASS({
  package: 'foam.graphics',
  name:  'Label',
  extends: 'foam.graphics.CView',

  traits: [
    'foam.patterns.layout.LayoutItemHorizontalTrait',
    'foam.patterns.layout.LayoutItemVerticalTrait'
  ],

  imports: [
    'document'
  ],

  properties: [
    {
      name:  'textAlign',
      label: 'Text Alignment',
      type:  'String',
      defaultValue: 'left',
      help: 'Text alignment can be left, right, center, or the locale aware start and end.',
      preSet: function(old,nu) {
        // TODO(jacksonic): account for locale
        if ( nu == 'start' ) {
          console.warn("Right-to-left support in foam.graphics.Label not available.");
          return 'left';
        }
        if ( nu == 'end' ) {
          console.warn("Right-to-left support in foam.graphics.Label not available.");
          return 'right';
        }
        return nu;
      }
    },
    {
      name: 'text',
      aliases: 'data',
      type: 'String',
      defaultValue: ''
    },
    {
      name: 'font',
      type: 'String',
      defaultValue: "",
      help: "CSS-style font description string"
    },
    {
      name: 'background',
      defaultValue: 'rgba(0,0,0,0)'
    },
    {
      model_: 'IntProperty',
      name: 'padding',
      defaultValue: 5
    },
    {
      model_: 'BooleanProperty',
      name: 'isShrinkable',
      defaultValue: false,
      documentation: function() {/* Indicates if the minimum size constraint should
        be the same as the preferred size, preventing font shrinking. */}
    },
    {
      name: 'clipped',
      defaultValue: true
    }
  ],

  methods: {
    init: function() {
      this.SUPER();

      Events.dynamic(
        function() { this.text; this.font; this.padding; }.bind(this),
        this.updatePreferred );

      this.updatePreferred();
    },

    paintSelf: function(c) {
      this.SUPER(c);

      c.save();

      c.textBaseline = 'top';
      c.textAlign = this.textAlign;
      c.fillStyle = this.color;
      if (this.font) c.font = this.font;
      if ( this.textAlign === 'center' ) {
        c.fillText(this.text, this.width/2, this.padding, this.width-(this.padding*2));
      } else if ( this.textAlign === 'right' ) {
        c.fillText(this.text, this.padding + this.width-(this.padding*2), this.padding, this.width-(this.padding*2));
      } else {
        c.fillText(this.text, this.padding, this.padding, this.width-(this.padding*2));
      }
      c.restore();
    }
  },

  listeners: [
    {
      name: 'updatePreferred',
      isFramed: false, // preferred size updates propagate up immediately
      code: function() {
        // TODO(jacksonic): Mark dirty and calculate the preferred size on next paint if possible.

        var e = this.document.createElement('canvas');
        var c = e.getContext('2d');

        // width of text
        c.save();
        if (this.font) c.font = this.font;
        this.horizontalConstraints.preferred =
          c.measureText(this.text).width + this.padding*2;
        c.restore();

        // if no shrink, lock minimum to preferred
        if ( ! this.isShrinkable )
          this.horizontalConstraints.min = this.horizontalConstraints.preferred;

        // height (this is not directly accessible... options include putting
        // a span into the DOM and getting font metrics from that, or just going
        // by raw font height setting (which is always pixels in a canvas)
        if ( ! this.font ) this.font = c.font;

        var height = parseInt(/[0-9]+(?=pt|px)/.exec(this.font) || 0);
        this.verticalConstraints.preferred = height + this.padding*2;

        // if no shrink, lock minimum to preferred
        if ( ! this.isShrinkable )
          this.verticalConstraints.min = this.verticalConstraints.preferred;
      },

      documentation: function() {/* Calculates the preferred size of this
        $$DOC{ref:'foam.graphics.Label'} based on the actual text and font.
      */},
    }
  ]
});
<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2015 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the License);
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 */

CLASS({
  package: 'foam.ui',
  name: 'FoamTagView',
  extendsModel: 'View',

  requires: [ 'foam.html.Element' ],

  imports: [ 'document' ],

  properties: [
    {
      name: 'element'
    },
    {
      name: 'className',
      defaultValue: 'foam-tag'
    }
  ],

  methods: {
    init: function() {
      this.SUPER();

      if ( ! this.Element.isInstance(this.element) ) this.install();
    },
    install: function() {
      var e = this.element;
      var models = [];
      var modelName = e.getAttribute('model' /*_*/);
      var viewName  = e.getAttribute('view' /*_*/);
      var onInit    = e.getAttribute('oninit' /*_*/);

      if ( modelName ) models.push(arequire(modelName));
      if ( viewName  ) models.push(arequire(viewName));

      aseq(apar.apply(null, models), function(ret) {
        var model = FOAM.lookup(modelName, this.X);

        if ( ! model ) {
          this.error('Unknown Model: ', modelName);
          return;
        }

        model.getPrototype();

        var obj = model.create(null, X);
        obj.fromElement(e);

        var view;

        if ( viewName ) {
          var viewModel = FOAM.lookup(viewName, X);
          view = viewModel.create({ model: model, data: obj });
        } else if ( View.isInstance(obj) || ( 'CView' in GLOBAL && CView.isInstance(obj) ) ) {
        view = obj;
      } else if ( obj.toView_ ) {
          view = obj.toView_();
        } else {
          var a = this.element.getAttribute('showActions');
          var showActions = ! a || (
            a.equalsIC('y')    ||
              a.equalsIC('yes')  ||
              a.equalsIC('true') ||
              a.equalsIC('t') );

          view = DetailView.create({
            model: model,
            data: obj,
            showActions: showActions
          });
        }

        if ( e.id ) this.document.FOAM_OBJECTS[e.id] = obj;
        obj.view_ = view;
        this.holder().outerHTML = view.toHTML();
        view.initHTML();

        if ( onInit )
          aeval('function() { ' + onInit + ' }')(function(f) { f.call(obj); });

      }.bind(this))();
    },
    holder: function() {
      // TODO(kgr): Add an outerHTML setter to foam.html.Element instead
      return this.Element.isInstance(this.element) ? this.$ : this.element;
    },
    error: function(msg) {
      console.error(msg);
      this.holder.innerHTML = msg;
    },
    initHTML: function() {
      this.install();
    }
  },

  templates: [
    function CSS() {/*
       .foam-tag {
         background: pink;
       }
    */}
  ]
});<commit_msg>Added 'style' attribute support to Foam tags.<commit_after>/**
 * @license
 * Copyright 2015 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the License);
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 */

CLASS({
  package: 'foam.ui',
  name: 'FoamTagView',
  extendsModel: 'View',

  requires: [ 'foam.html.Element' ],

  imports: [ 'document' ],

  properties: [
    {
      name: 'element'
    },
    {
      name: 'className',
      defaultValue: 'foam-tag'
    }
  ],

  methods: {
    init: function() {
      this.SUPER();

      if ( ! this.Element.isInstance(this.element) ) this.install();
    },
    install: function() {
      var e = this.element;
      var models = [];
      var style     = e.getAttribute('style' /*_*/);
      var modelName = e.getAttribute('model' /*_*/);
      var viewName  = e.getAttribute('view' /*_*/);
      var onInit    = e.getAttribute('oninit' /*_*/);

      if ( modelName ) models.push(arequire(modelName));
      if ( viewName  ) models.push(arequire(viewName));

      aseq(apar.apply(null, models), function(ret) {
        var model = FOAM.lookup(modelName, this.X);

        if ( ! model ) {
          this.error('Unknown Model: ', modelName);
          return;
        }

        model.getPrototype();

        var obj = model.create(null, X);
        obj.fromElement(e);

        var view;

        if ( viewName ) {
          var viewModel = FOAM.lookup(viewName, X);
          view = viewModel.create({ model: model, data: obj });
        } else if ( View.isInstance(obj) || ( 'CView' in GLOBAL && CView.isInstance(obj) ) ) {
        view = obj;
      } else if ( obj.toView_ ) {
          view = obj.toView_();
        } else {
          var a = this.element.getAttribute('showActions');
          var showActions = ! a || (
            a.equalsIC('y')    ||
              a.equalsIC('yes')  ||
              a.equalsIC('true') ||
              a.equalsIC('t') );

          view = DetailView.create({
            model: model,
            data: obj,
            showActions: showActions
          });
        }

        if ( e.id ) this.document.FOAM_OBJECTS[e.id] = obj;
        obj.view_ = view;
        this.holder().outerHTML = view.toHTML();
        if ( style ) {
          view.$.setAttribute('style', style);
        }
        view.initHTML();

        if ( onInit )
          aeval('function() { ' + onInit + ' }')(function(f) { f.call(obj); });

      }.bind(this))();
    },
    holder: function() {
      // TODO(kgr): Add an outerHTML setter to foam.html.Element instead
      return this.Element.isInstance(this.element) ? this.$ : this.element;
    },
    error: function(msg) {
      console.error(msg);
      this.holder.innerHTML = msg;
    },
    initHTML: function() {
      this.install();
    }
  },

  templates: [
    function CSS() {/*
       .foam-tag {
         background: pink;
       }
    */}
  ]
});
<|endoftext|>


<commit_before>import React from 'react';
import PropTypes from 'prop-types';
import { NavLink } from 'react-router-dom';

import Icon from '../icon/Icon';
import NavMenu from './NavMenu';
import { classnames } from '../../helpers/component';

const NavItem = ({
    type = 'link',
    ariaHiddenList,
    ariaCurrent,
    link,
    isActive,
    text,
    aside,
    onClick,
    icon,
    list = [],
    color,
    className = '',
    itemClassName = 'navigation__item',
    linkClassName = 'navigation__link'
}) => {
    const content = (

            {icon && (
                <Icon
                    name={icon}
                    color={color}
                    className="flex-item-noshrink navigation__icon mr0-5 flex-item-centered-vert"
                />
            )}
            {text}
            {aside && {aside}}

    );

    if (type === 'link') {
        return (

                <NavLink
                    className={classnames([linkClassName, className])}
                    isActive={isActive}
                    to={link}
                    aria-current={ariaCurrent}
                    onClick={onClick}
                >
                    {content}
                </NavLink>
                {list.length ? (
                    <NavMenu ariaHidden={ariaHiddenList} list={list} listClassName="nomobile navigation__sublist" />
                ) : null}

        );
    }

    if (type === 'text') {
        return (

                    {content}
                    {list.length ? (
                        <NavMenu ariaHidden={ariaHiddenList} list={list} listClassName="nomobile navigation__sublist" />
                    ) : null}

        );
    }

    if (type === 'button') {
        return (

                <button type="button" className={classnames(['w100', linkClassName, className])} onClick={onClick}>
                    {content}
                </button>
                {list.length ? (
                    <NavMenu ariaHidden={ariaHiddenList} list={list} listClassName="nomobile navigation__sublist" />
                ) : null}

        );
    }

    return null;
};

NavItem.propTypes = {
    ariaCurrent: PropTypes.string,
    ariaHiddenList: PropTypes.bool,
    linkClassName: PropTypes.string,
    itemClassName: PropTypes.string,
    isActive: PropTypes.func,
    icon: PropTypes.string,
    color: PropTypes.string,
    onClick: PropTypes.func,
    type: PropTypes.oneOf(['link', 'button', 'text']),
    link: PropTypes.string,
    text: PropTypes.node,
    aside: PropTypes.node,
    list: PropTypes.arrayOf(PropTypes.object),
    className: PropTypes.string
};

export default NavItem;
<commit_msg>allow disabled prop for button in sidebar<commit_after>import React from 'react';
import PropTypes from 'prop-types';
import { NavLink } from 'react-router-dom';

import Icon from '../icon/Icon';
import NavMenu from './NavMenu';
import { classnames } from '../../helpers/component';

const NavItem = ({
    type = 'link',
    ariaHiddenList,
    ariaCurrent,
    link,
    isActive,
    text,
    aside,
    disabled,
    onClick,
    icon,
    list = [],
    color,
    className = '',
    itemClassName = 'navigation__item',
    linkClassName = 'navigation__link'
}) => {
    const content = (

            {icon && (
                <Icon
                    name={icon}
                    color={color}
                    className="flex-item-noshrink navigation__icon mr0-5 flex-item-centered-vert"
                />
            )}
            {text}
            {aside && {aside}}

    );

    if (type === 'link') {
        return (

                <NavLink
                    className={classnames([linkClassName, className])}
                    isActive={isActive}
                    to={link}
                    aria-current={ariaCurrent}
                    onClick={onClick}
                >
                    {content}
                </NavLink>
                {list.length ? (
                    <NavMenu ariaHidden={ariaHiddenList} list={list} listClassName="nomobile navigation__sublist" />
                ) : null}

        );
    }

    if (type === 'text') {
        return (

                    {content}
                    {list.length ? (
                        <NavMenu ariaHidden={ariaHiddenList} list={list} listClassName="nomobile navigation__sublist" />
                    ) : null}

        );
    }

    if (type === 'button') {
        return (

                <button
                    type="button"
                    className={classnames(['w100', linkClassName, className])}
                    disabled={disabled}
                    onClick={onClick}
                >
                    {content}
                </button>
                {list.length ? (
                    <NavMenu ariaHidden={ariaHiddenList} list={list} listClassName="nomobile navigation__sublist" />
                ) : null}

        );
    }

    return null;
};

NavItem.propTypes = {
    ariaCurrent: PropTypes.string,
    ariaHiddenList: PropTypes.bool,
    linkClassName: PropTypes.string,
    itemClassName: PropTypes.string,
    isActive: PropTypes.func,
    icon: PropTypes.string,
    color: PropTypes.string,
    disabled: PropTypes.bool,
    onClick: PropTypes.func,
    type: PropTypes.oneOf(['link', 'button', 'text']),
    link: PropTypes.string,
    text: PropTypes.node,
    aside: PropTypes.node,
    list: PropTypes.arrayOf(PropTypes.object),
    className: PropTypes.string
};

export default NavItem;
<|endoftext|>


<commit_before>//Author: bachvtuan@gmail.com

//Format string
if (!String.prototype.formatString) {
  String.prototype.formatString = function() {
    var args = arguments;
    return this.replace(/{(\d+)}/g, function(match, number) {
      return typeof args[number] != 'undefined'
        ? args[number]
        : match
      ;
    });
  };
}

(function ( $ ) {

    $.fn.github_graph = function( options ) {

        //If the number less than 10, add Zero before it
        var prettyNumber = function( number ){
          return  number < 10 ? '0' + number.toString() : number = number.toString();
        };

        /*
        Count the number on each day and store the object
        */
        var processListTimeStamp = function(list_timestamp){

          //The result will store into this varriable
          obj_timestamp = {};
          for (var i=0; i < list_timestamp.length; i++){
            var _d = new Date( list_timestamp[i] );
            var display_date = getDisplayDate( _d );
            if ( !obj_timestamp[ display_date ] ){
              obj_timestamp[ display_date ] = 1;
            }
            else{
              obj_timestamp[ display_date ]++;
            }
          }
        }

        var getDisplayDate = function( date_obj ){
          var pretty_month = prettyNumber( date_obj.getMonth() + 1);
          var pretty_date = prettyNumber(date_obj.getDate());
          return "{0}-{1}-{2}".formatString( date_obj.getFullYear(), pretty_month , pretty_date  );
        }

        var getCount = function( display_date ){
          if ( obj_timestamp[ display_date ] ){
            return obj_timestamp[ display_date];
          }
          return 0;
        }

        var getColor = function(count){
          if ( count >= settings.colors.length ){
            return settings.colors[  settings.colors.length - 1 ];
          }
          return settings.colors[ count ];
        }

        var start = function(){
          processListTimeStamp( settings.data );
          var wrap_chart = _this;

          settings.colors_length = settings.colors.length;

          var start_date = new Date();
          start_date.setMonth( start_date.getMonth() - 12  );

          for ( var i=0; i < 7; i++ ){
            var day = start_date.getDay();
            if (day == 0){
              //sunday
              break;
            }
            else{
              //Loop until get Sunday
              start_date.setDate( start_date.getDate() + 1 );
            }
          }

          var loop_html = "";

          //One year has 52 weeks
          var step = 13;

          var month_position = [];
          var current_date = new Date();
          month_position.push({month_index: start_date.getMonth(), x: 0 });
          var using_month = start_date.getMonth();
          for ( var i =0; i < 52; i++ ){
            var g_x =i * step;
            var item_html = '<g transform="translate(' + g_x.toString() + ',0)">';

            for ( var j = 0; j < 7; j++ ){

              if ( start_date > current_date ){
                //Break the loop
                break;
              }
              var y = j * step;

              var month_in_day = start_date.getMonth();
              var data_date = getDisplayDate( start_date );
              //Check first day in week
              if ( j == 0 && month_in_day != using_month ){
                  using_month = month_in_day;
                  month_position.push({month_index: using_month, x: g_x });
              }
              //move on to next day
              start_date.setDate( start_date.getDate() + 1 );
              var count = getCount( data_date );
              var color = getColor( count );

              item_html += '<rect class="day" width="11" height="11" y="'+ y +'" fill="'+ color + '" data-count="'+ count +'" data-date="'+ data_date +'"/>';
            }

            item_html += "</g>";

            loop_html += item_html;

          }

          //trick
          if ( month_position[1].x - month_position[0].x < 40 ){
            //Fix ugly graph by remove first item
            month_position.shift(0);
          }

          for (  var i =0; i < month_position.length; i++){
            var item = month_position[i];
            var month_name =  settings.month_names[ item.month_index ];
            loop_html += '<text x="'+ item.x +'" y="-5" class="month">'+ month_name +'</text>';
          }

          //Add Monday, Wenesday, Friday label
          loop_html +=  '<text text-anchor="middle" class="wday" dx="-10" dy="22">{0}</text>'.formatString( settings.h_days[0] )+
                        '<text text-anchor="middle" class="wday" dx="-10" dy="48">{0}</text>'.formatString( settings.h_days[1] )+
                        '<text text-anchor="middle" class="wday" dx="-10" dy="74">{0}</text>'.formatString( settings.h_days[2] );

          //Fixed size for now with width= 721 and height = 110
          var wire_html =
            '<svg width="721" height="110" class="js-calendar-graph-svg">'+
              '<g transform="translate(20, 20)">'+
                loop_html +
              '</g>'+
            '</svg>';

          wrap_chart.html(wire_html);

          //Mare sure off previous event
          /*$(document).off('mouseenter', _this.find('rect'), mouseEnter );
          $(document).off('mouseleave', _this.find('rect'), mouseLeave );
          $(document).on('mouseenter', _this.find('rect'), mouseEnter );
          $(document).on('mouseleave', _this.find('rect'), mouseLeave );
*/
          _this.find('rect').mouseenter( mouseEnter );
          _this.find('rect').mouseleave( mouseLeave );
          appendTooltip();

        }

        var mouseLeave =function(evt){
          $('.svg-tip').hide();
        }

        //handle event mouseenter when enter into rect element
        var mouseEnter = function(evt){

          var target_offset = $(evt.target).offset();
          var count = $(evt.target).attr('data-count');
          var date = $(evt.target).attr('data-date');

          var count_text = ( count > 1 ) ? settings.texts[1]: settings.texts[0];
          var text = "{0} {1} on {2}".formatString( count, count_text , date );

          var svg_tip = $('.svg-tip').show();
          svg_tip.html( text );
          var svg_width = Math.round( svg_tip.width()/2 + 5 )  ;
          var svg_height =  svg_tip.height() *2 + 10 ;

          svg_tip.css({top:target_offset.top - svg_height});
          svg_tip.css({left:target_offset.left -svg_width});
        }
        //Append tooltip to display when mouse enter the rect element
        //Default is display:none
        var appendTooltip = function(){
          if ( $('.svg-tip').length == 0 ){
            $('body').append('

');
          }
        }

        var settings = $.extend({
          //Default init settings.colors, user can override
          colors: ['#eeeeee','#d6e685','#8cc665','#44a340','#44a340'],
          //List of name months
          month_names: ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'],
          h_days : ['M','W','F'],
          //Default is empty, it can be overrided
          data:[],
        }, options );

        var _this = $(this);

        start();

    };

}( jQuery ));

<commit_msg>Closed #1 The tip is always flashing<commit_after>//Author: bachvtuan@gmail.com

//Format string
if (!String.prototype.formatString) {
  String.prototype.formatString = function() {
    var args = arguments;
    return this.replace(/{(\d+)}/g, function(match, number) {
      return typeof args[number] != 'undefined'
        ? args[number]
        : match
      ;
    });
  };
}

(function ( $ ) {

    $.fn.github_graph = function( options ) {

        //If the number less than 10, add Zero before it
        var prettyNumber = function( number ){
          return  number < 10 ? '0' + number.toString() : number = number.toString();
        };

        /*
        Count the number on each day and store the object
        */
        var processListTimeStamp = function(list_timestamp){

          //The result will store into this varriable
          obj_timestamp = {};
          for (var i=0; i < list_timestamp.length; i++){
            var _d = new Date( list_timestamp[i] );
            var display_date = getDisplayDate( _d );
            if ( !obj_timestamp[ display_date ] ){
              obj_timestamp[ display_date ] = 1;
            }
            else{
              obj_timestamp[ display_date ]++;
            }
          }
        }

        var getDisplayDate = function( date_obj ){
          var pretty_month = prettyNumber( date_obj.getMonth() + 1);
          var pretty_date = prettyNumber(date_obj.getDate());
          return "{0}-{1}-{2}".formatString( date_obj.getFullYear(), pretty_month , pretty_date  );
        }

        var getCount = function( display_date ){
          if ( obj_timestamp[ display_date ] ){
            return obj_timestamp[ display_date];
          }
          return 0;
        }

        var getColor = function(count){
          if ( count >= settings.colors.length ){
            return settings.colors[  settings.colors.length - 1 ];
          }
          return settings.colors[ count ];
        }

        var start = function(){
          processListTimeStamp( settings.data );
          var wrap_chart = _this;

          settings.colors_length = settings.colors.length;

          var start_date = new Date();
          start_date.setMonth( start_date.getMonth() - 12  );

          for ( var i=0; i < 7; i++ ){
            var day = start_date.getDay();
            if (day == 0){
              //sunday
              break;
            }
            else{
              //Loop until get Sunday
              start_date.setDate( start_date.getDate() + 1 );
            }
          }

          var loop_html = "";

          //One year has 52 weeks
          var step = 13;

          var month_position = [];
          var current_date = new Date();
          month_position.push({month_index: start_date.getMonth(), x: 0 });
          var using_month = start_date.getMonth();
          for ( var i =0; i < 52; i++ ){
            var g_x =i * step;
            var item_html = '<g transform="translate(' + g_x.toString() + ',0)">';

            for ( var j = 0; j < 7; j++ ){

              if ( start_date > current_date ){
                //Break the loop
                break;
              }
              var y = j * step;

              var month_in_day = start_date.getMonth();
              var data_date = getDisplayDate( start_date );
              //Check first day in week
              if ( j == 0 && month_in_day != using_month ){
                  using_month = month_in_day;
                  month_position.push({month_index: using_month, x: g_x });
              }
              //move on to next day
              start_date.setDate( start_date.getDate() + 1 );
              var count = getCount( data_date );
              var color = getColor( count );

              item_html += '<rect class="day" width="11" height="11" y="'+ y +'" fill="'+ color + '" data-count="'+ count +'" data-date="'+ data_date +'"/>';
            }

            item_html += "</g>";

            loop_html += item_html;

          }

          //trick
          if ( month_position[1].x - month_position[0].x < 40 ){
            //Fix ugly graph by remove first item
            month_position.shift(0);
          }

          for (  var i =0; i < month_position.length; i++){
            var item = month_position[i];
            var month_name =  settings.month_names[ item.month_index ];
            loop_html += '<text x="'+ item.x +'" y="-5" class="month">'+ month_name +'</text>';
          }

          //Add Monday, Wenesday, Friday label
          loop_html +=  '<text text-anchor="middle" class="wday" dx="-10" dy="22">{0}</text>'.formatString( settings.h_days[0] )+
                        '<text text-anchor="middle" class="wday" dx="-10" dy="48">{0}</text>'.formatString( settings.h_days[1] )+
                        '<text text-anchor="middle" class="wday" dx="-10" dy="74">{0}</text>'.formatString( settings.h_days[2] );

          //Fixed size for now with width= 721 and height = 110
          var wire_html =
            '<svg width="721" height="110" class="js-calendar-graph-svg">'+
              '<g transform="translate(20, 20)">'+
                loop_html +
              '</g>'+
            '</svg>';

          wrap_chart.html(wire_html);

          //Mare sure off previous event
          /*$(document).off('mouseenter', _this.find('rect'), mouseEnter );
          $(document).off('mouseleave', _this.find('rect'), mouseLeave );
          $(document).on('mouseenter', _this.find('rect'), mouseEnter );
          $(document).on('mouseleave', _this.find('rect'), mouseLeave );
*/
          _this.find('rect').on("mouseenter", mouseEnter );
          _this.find('rect').on("mouseleave",mouseLeave );
          appendTooltip();

        }

        var mouseLeave =function(evt){
          $('.svg-tip').hide();
        }

        //handle event mouseenter when enter into rect element
        var mouseEnter = function(evt){

          var target_offset = $(evt.target).offset();
          var count = $(evt.target).attr('data-count');
          var date = $(evt.target).attr('data-date');

          var count_text = ( count > 1 ) ? settings.texts[1]: settings.texts[0];
          var text = "{0} {1} on {2}".formatString( count, count_text , date );

          var svg_tip = $('.svg-tip').show();
          svg_tip.html( text );
          var svg_width = Math.round( svg_tip.width()/2 + 5 )  ;
          var svg_height =  svg_tip.height() *2 + 10 ;

          svg_tip.css({top:target_offset.top - svg_height - 5});
          svg_tip.css({left:target_offset.left -svg_width});
        }
        //Append tooltip to display when mouse enter the rect element
        //Default is display:none
        var appendTooltip = function(){
          if ( $('.svg-tip').length == 0 ){
            $('body').append('

');
          }
        }

        var settings = $.extend({
          //Default init settings.colors, user can override
          colors: ['#eeeeee','#d6e685','#8cc665','#44a340','#44a340'],
          //List of name months
          month_names: ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'],
          h_days : ['M','W','F'],
          //Default is empty, it can be overrided
          data:[],
        }, options );

        var _this = $(this);

        start();

    };

}( jQuery ));<|endoftext|>


<commit_before>/*==================================================
 *  Exhibit.LegendWidget
 *==================================================
 */
Exhibit.LegendWidget = function(configuration, containerElmt, uiContext) {
    this._configuration = configuration;
    this._div = containerElmt;
    this._uiContext = uiContext;

    this._sortedKeys = [];
    this._labelNodes = {};

    this._markerGenerator = "markerGenerator" in configuration ?
        configuration.markerGenerator :
        Exhibit.LegendWidget._defaultColorMarkerGenerator;

    this._labelStyler = "labelStyler" in configuration ?
        configuration.labelStyler :
        Exhibit.LegendWidget._defaultColorLabelStyler;

    this._initializeUI();
};

Exhibit.LegendWidget.create = function(configuration, containerElmt, uiContext) {
    return new Exhibit.LegendWidget(configuration, containerElmt, uiContext);
};

Exhibit.LegendWidget.prototype.dispose = function() {
    this._div.innerHTML = "";

    this._div = null;
    this._uiContext = null;
};

Exhibit.LegendWidget.prototype._initializeUI = function() {
    this._div.className = "exhibit-legendWidget";
    this._div.innerHTML = "";
};

Exhibit.LegendWidget.prototype.clear = function() {
    this._div.innerHTML = "";
    this._sortedKeys = [];
    this._labelNodes = {};
};

Exhibit.LegendWidget.prototype.addEntry = function(key, value, label) {
    if (key in this._labelNodes) {
        return;
    }

    var dom = SimileAjax.DOM.createDOMFromString(
        "span",
        "\u00a0" +
            "" +
                label.replace(/\s+/g, "\u00a0") +
            "" +
            "\u00a0\u00a0 ",
        { marker: this._markerGenerator(value) }
    );
    dom.elmt.className = "exhibit-legendWidget-entry";
    this._labelStyler(dom.label, value);

    this._labelNodes[key] = dom;
    this._sortedKeys.push(key);
    this._sortedKeys.sort(Exhibit.LegendWidget._localeSort);

    this._div.innerHTML = "";
    for( var i = 0; dom = this._labelNodes[this._sortedKeys[i]]; i++ ) {
        this._div.appendChild(dom.elmt);
    }
};

Exhibit.LegendWidget._localeSort = function(a,b) {
    return a.localeCompare(b);
}

Exhibit.LegendWidget._defaultColorMarkerGenerator = function(value) {
    var span = document.createElement("span");
    span.className = "exhibit-legendWidget-entry-swatch";
    span.style.background = "#" + value;
    span.innerHTML = "\u00a0\u00a0";
    return span;
};

Exhibit.LegendWidget._defaultColorLabelStyler = function(elmt, value) {
    //elmt.style.color = "#" + value;
};
<commit_msg>Made legend widget not crash when the color key or label is null.<commit_after>/*==================================================
 *  Exhibit.LegendWidget
 *==================================================
 */
Exhibit.LegendWidget = function(configuration, containerElmt, uiContext) {
    this._configuration = configuration;
    this._div = containerElmt;
    this._uiContext = uiContext;

    this._sortedKeys = [];
    this._labelNodes = {};

    this._markerGenerator = "markerGenerator" in configuration ?
        configuration.markerGenerator :
        Exhibit.LegendWidget._defaultColorMarkerGenerator;

    this._labelStyler = "labelStyler" in configuration ?
        configuration.labelStyler :
        Exhibit.LegendWidget._defaultColorLabelStyler;

    this._initializeUI();
};

Exhibit.LegendWidget.create = function(configuration, containerElmt, uiContext) {
    return new Exhibit.LegendWidget(configuration, containerElmt, uiContext);
};

Exhibit.LegendWidget.prototype.dispose = function() {
    this._div.innerHTML = "";

    this._div = null;
    this._uiContext = null;
};

Exhibit.LegendWidget.prototype._initializeUI = function() {
    this._div.className = "exhibit-legendWidget";
    this._div.innerHTML = "";
};

Exhibit.LegendWidget.prototype.clear = function() {
    this._div.innerHTML = "";
    this._sortedKeys = [];
    this._labelNodes = {};
};

Exhibit.LegendWidget.prototype.addEntry = function(key, value, label) {
    if ((key in this._labelNodes) || (key == null)) {
        return;
    }

    label = (label != null) ? label.toString() : key.toString();
    var dom = SimileAjax.DOM.createDOMFromString(
        "span",
        "\u00a0" +
            "" +
                label.replace(/\s+/g, "\u00a0") +
            "" +
            "\u00a0\u00a0 ",
        { marker: this._markerGenerator(value) }
    );
    dom.elmt.className = "exhibit-legendWidget-entry";
    this._labelStyler(dom.label, value);

    this._labelNodes[key] = dom;
    this._sortedKeys.push(key);
    this._sortedKeys.sort(Exhibit.LegendWidget._localeSort);

    this._div.innerHTML = "";
    for( var i = 0; dom = this._labelNodes[this._sortedKeys[i]]; i++ ) {
        this._div.appendChild(dom.elmt);
    }
};

Exhibit.LegendWidget._localeSort = function(a,b) {
    return a.localeCompare(b);
}

Exhibit.LegendWidget._defaultColorMarkerGenerator = function(value) {
    var span = document.createElement("span");
    span.className = "exhibit-legendWidget-entry-swatch";
    span.style.background = "#" + value;
    span.innerHTML = "\u00a0\u00a0";
    return span;
};

Exhibit.LegendWidget._defaultColorLabelStyler = function(elmt, value) {
    //elmt.style.color = "#" + value;
};
<|endoftext|>


<commit_before>const _ = require("lodash");
const remark = require("remark");
const english = require("retext-english");
const remark2retext = require("remark-retext");
const unified = require("unified");
const visit = require("unist-util-visit");
const remove = require("unist-util-remove");
const toString = require("mdast-util-to-string");
const generateTOC = require("mdast-util-toc");
const prune = require("underscore.string/prune");

const debug = require("debug")("gatsby-plugin-mdx:extend-node-type");
const getTableOfContents = require("../utils/get-table-of-content");
const defaultOptions = require("../utils/default-options");
const genMDX = require("../utils/gen-mdx");
const { mdxHTMLLoader: loader } = require("../utils/render-html");

async function getCounts({ mdast }) {
  let counts = {};

  // convert the mdxast to back to mdast
  remove(mdast, "import");
  remove(mdast, "export");
  visit(mdast, "jsx", node => {
    node.type = "html";
  });

  await remark()
    .use(
      remark2retext,
      unified()
        .use(english)
        .use(count)
    )
    .run(mdast);

  function count() {
    return counter;
    function counter(tree) {
      visit(tree, visitor);
      function visitor(node) {
        counts[node.type] = (counts[node.type] || 0) + 1;
      }
    }
  }

  return {
    paragraphs: counts.ParagraphNode,
    sentences: counts.SentenceNode,
    words: counts.WordNode
  };
}

module.exports = (
  { store, pathPrefix, getNode, getNodes, cache, reporter, actions, schema },
  pluginOptions
) => {
  let mdxHTMLLoader;
  const { createTypes } = actions;

  const options = defaultOptions(pluginOptions);

  createTypes(`
    type MdxFrontmatter {
      title: String!
    }

    type MdxHeadingMdx {
      value: String
      depth: Int
    }

    enum HeadingsMdx {
      h1,
      h2,
      h3,
      h4,
      h5,
      h6
    }

    type MdxWordCount {
      paragraphs: Int
      sentences: Int
      words: Int
    }
  `);

  /**
   * Support gatsby-remark parser plugins
   */
  for (let plugin of options.gatsbyRemarkPlugins) {
    debug("requiring", plugin.resolve);
    const requiredPlugin = require(plugin.resolve);
    debug("required", plugin);
    if (_.isFunction(requiredPlugin.setParserPlugins)) {
      for (let parserPlugin of requiredPlugin.setParserPlugins(
        plugin.pluginOptions
      )) {
        if (_.isArray(parserPlugin)) {
          const [parser, parserPluginOptions] = parserPlugin;
          debug(
            "adding remarkPlugin with options",
            plugin,
            parserPluginOptions
          );
          options.remarkPlugins.push([parser, parserPluginOptions]);
        } else {
          debug("adding remarkPlugin", plugin);
          options.remarkPlugins.push(parserPlugin);
        }
      }
    }
  }

  const processMDX = ({ node }) =>
    genMDX({ node, getNode, getNodes, reporter, cache, pathPrefix, options });

  // New Code // Schema
  const MdxType = schema.buildObjectType({
    name: "Mdx",
    fields: {
      rawBody: { type: "String!" },
      fileAbsolutePath: { type: "String!" },
      frontmatter: { type: "MdxFrontmatter" },
      body: {
        type: `String!`,
        async resolve(mdxNode) {
          const { body } = await processMDX({ node: mdxNode });
          return body;
        }
      },
      excerpt: {
        type: `String!`,
        args: {
          pruneLength: {
            type: `Int`,
            defaultValue: 140
          }
        },
        async resolve(mdxNode, { pruneLength }) {
          if (mdxNode.excerpt) {
            return Promise.resolve(mdxNode.excerpt);
          }
          const { mdast } = await processMDX({ node: mdxNode });

          const excerptNodes = [];
          visit(mdast, node => {
            if (node.type === "text" || node.type === "inlineCode") {
              excerptNodes.push(node.value);
            }
            return;
          });

          return prune(excerptNodes.join(" "), pruneLength, "…");
        }
      },
      headings: {
        type: `[MdxHeadingMdx]`,
        args: {
          depth: {
            type: `HeadingsMdx`
          }
        },
        async resolve(mdxNode, { depth }) {
          // TODO: change this to operate on html instead of mdast
          const { mdast } = await processMDX({ node: mdxNode });
          let headings = [];
          visit(mdast, "heading", heading => {
            headings.push({
              value: toString(heading),
              depth: heading.depth
            });
          });
          if (typeof depth === `number`) {
            headings = headings.filter(heading => heading.depth === depth);
          }
          return headings;
        }
      },
      html: {
        type: `String`,
        async resolve(mdxNode) {
          if (mdxNode.html) {
            return Promise.resolve(mdxNode.html);
          }
          const { body } = await processMDX({ node: mdxNode });
          try {
            if (!mdxHTMLLoader) {
              mdxHTMLLoader = loader({ reporter, cache, store });
            }
            const html = await mdxHTMLLoader.load({ ...mdxNode, body });
            return html;
          } catch (e) {
            reporter.error(
              `Error querying the \`html\` field. This field is intended for use with RSS feed generation.
If you're trying to use it in application-level code, try querying for \`Mdx.body\` instead.
Original error:
${e}`
            );
          }
        }
      },
      mdxAST: {
        type: `JSON`,
        async resolve(mdxNode) {
          const { mdast } = await processMDX({ node: mdxNode });
          return mdast;
        }
      },
      tableOfContents: {
        type: `JSON`,
        args: {
          maxDepth: {
            type: `Int`,
            default: 6
          }
        },
        async resolve(mdxNode, { maxDepth }) {
          const { mdast } = await processMDX({ node: mdxNode });
          const toc = generateTOC(mdast, {maxDepth});

          return getTableOfContents(toc.map, {});
        }
      },
      timeToRead: {
        type: `Int`,
        async resolve(mdxNode) {
          const { mdast } = await processMDX({ node: mdxNode });
          const { words } = await getCounts({ mdast });
          let timeToRead = 0;
          const avgWPM = 265;
          timeToRead = Math.round(words / avgWPM);
          if (timeToRead === 0) {
            timeToRead = 1;
          }
          return timeToRead;
        }
      },
      wordCount: {
        type: `MdxWordCount`,
        async resolve(mdxNode) {
          const { mdast } = await processMDX({ node: mdxNode });
          return getCounts({ mdast });
        }
      }
    },
    interfaces: [`Node`]
  });
  createTypes(MdxType);
};
<commit_msg>fix(gatsby-plugin-mdx): fix filter by heading depth (#16344)<commit_after>const _ = require("lodash");
const remark = require("remark");
const english = require("retext-english");
const remark2retext = require("remark-retext");
const unified = require("unified");
const visit = require("unist-util-visit");
const remove = require("unist-util-remove");
const toString = require("mdast-util-to-string");
const generateTOC = require("mdast-util-toc");
const prune = require("underscore.string/prune");

const debug = require("debug")("gatsby-plugin-mdx:extend-node-type");
const getTableOfContents = require("../utils/get-table-of-content");
const defaultOptions = require("../utils/default-options");
const genMDX = require("../utils/gen-mdx");
const { mdxHTMLLoader: loader } = require("../utils/render-html");

async function getCounts({ mdast }) {
  let counts = {};

  // convert the mdxast to back to mdast
  remove(mdast, "import");
  remove(mdast, "export");
  visit(mdast, "jsx", node => {
    node.type = "html";
  });

  await remark()
    .use(
      remark2retext,
      unified()
        .use(english)
        .use(count)
    )
    .run(mdast);

  function count() {
    return counter;
    function counter(tree) {
      visit(tree, visitor);
      function visitor(node) {
        counts[node.type] = (counts[node.type] || 0) + 1;
      }
    }
  }

  return {
    paragraphs: counts.ParagraphNode,
    sentences: counts.SentenceNode,
    words: counts.WordNode
  };
}

module.exports = (
  { store, pathPrefix, getNode, getNodes, cache, reporter, actions, schema },
  pluginOptions
) => {
  let mdxHTMLLoader;
  const { createTypes } = actions;

  const options = defaultOptions(pluginOptions);
  const headingsMdx = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'];
  createTypes(`
    type MdxFrontmatter {
      title: String!
    }

    type MdxHeadingMdx {
      value: String
      depth: Int
    }

    enum HeadingsMdx {
      ${headingsMdx}
    }

    type MdxWordCount {
      paragraphs: Int
      sentences: Int
      words: Int
    }
  `);

  /**
   * Support gatsby-remark parser plugins
   */
  for (let plugin of options.gatsbyRemarkPlugins) {
    debug("requiring", plugin.resolve);
    const requiredPlugin = require(plugin.resolve);
    debug("required", plugin);
    if (_.isFunction(requiredPlugin.setParserPlugins)) {
      for (let parserPlugin of requiredPlugin.setParserPlugins(
        plugin.pluginOptions
      )) {
        if (_.isArray(parserPlugin)) {
          const [parser, parserPluginOptions] = parserPlugin;
          debug(
            "adding remarkPlugin with options",
            plugin,
            parserPluginOptions
          );
          options.remarkPlugins.push([parser, parserPluginOptions]);
        } else {
          debug("adding remarkPlugin", plugin);
          options.remarkPlugins.push(parserPlugin);
        }
      }
    }
  }

  const processMDX = ({ node }) =>
    genMDX({ node, getNode, getNodes, reporter, cache, pathPrefix, options });

  // New Code // Schema
  const MdxType = schema.buildObjectType({
    name: "Mdx",
    fields: {
      rawBody: { type: "String!" },
      fileAbsolutePath: { type: "String!" },
      frontmatter: { type: "MdxFrontmatter" },
      body: {
        type: `String!`,
        async resolve(mdxNode) {
          const { body } = await processMDX({ node: mdxNode });
          return body;
        }
      },
      excerpt: {
        type: `String!`,
        args: {
          pruneLength: {
            type: `Int`,
            defaultValue: 140
          }
        },
        async resolve(mdxNode, { pruneLength }) {
          if (mdxNode.excerpt) {
            return Promise.resolve(mdxNode.excerpt);
          }
          const { mdast } = await processMDX({ node: mdxNode });

          const excerptNodes = [];
          visit(mdast, node => {
            if (node.type === "text" || node.type === "inlineCode") {
              excerptNodes.push(node.value);
            }
            return;
          });

          return prune(excerptNodes.join(" "), pruneLength, "…");
        }
      },
      headings: {
        type: `[MdxHeadingMdx]`,
        args: {
          depth: {
            type: `HeadingsMdx`
          }
        },
        async resolve(mdxNode, { depth }) {
          // TODO: change this to operate on html instead of mdast
          const { mdast } = await processMDX({ node: mdxNode });
          let headings = [];
          visit(mdast, "heading", heading => {
            headings.push({
              value: toString(heading),
              depth: heading.depth
            });
          });
          if (headingsMdx.includes(depth)) {
            headings = headings.filter(heading => `h${heading.depth}` === depth);
          }
          return headings;
        }
      },
      html: {
        type: `String`,
        async resolve(mdxNode) {
          if (mdxNode.html) {
            return Promise.resolve(mdxNode.html);
          }
          const { body } = await processMDX({ node: mdxNode });
          try {
            if (!mdxHTMLLoader) {
              mdxHTMLLoader = loader({ reporter, cache, store });
            }
            const html = await mdxHTMLLoader.load({ ...mdxNode, body });
            return html;
          } catch (e) {
            reporter.error(
              `Error querying the \`html\` field. This field is intended for use with RSS feed generation.
If you're trying to use it in application-level code, try querying for \`Mdx.body\` instead.
Original error:
${e}`
            );
          }
        }
      },
      mdxAST: {
        type: `JSON`,
        async resolve(mdxNode) {
          const { mdast } = await processMDX({ node: mdxNode });
          return mdast;
        }
      },
      tableOfContents: {
        type: `JSON`,
        args: {
          maxDepth: {
            type: `Int`,
            default: 6
          }
        },
        async resolve(mdxNode, { maxDepth }) {
          const { mdast } = await processMDX({ node: mdxNode });
          const toc = generateTOC(mdast, {maxDepth});

          return getTableOfContents(toc.map, {});
        }
      },
      timeToRead: {
        type: `Int`,
        async resolve(mdxNode) {
          const { mdast } = await processMDX({ node: mdxNode });
          const { words } = await getCounts({ mdast });
          let timeToRead = 0;
          const avgWPM = 265;
          timeToRead = Math.round(words / avgWPM);
          if (timeToRead === 0) {
            timeToRead = 1;
          }
          return timeToRead;
        }
      },
      wordCount: {
        type: `MdxWordCount`,
        async resolve(mdxNode) {
          const { mdast } = await processMDX({ node: mdxNode });
          return getCounts({ mdast });
        }
      }
    },
    interfaces: [`Node`]
  });
  createTypes(MdxType);
};
<|endoftext|>


<commit_before>/*
Alessandro Minoccheri
V 1.0.0
15-02-2014
*/

(function ($) {
	var numOptions = 0;

    $.fn.extend({
        customSelect: function (argumentOptions) {
            var defaults = {
				width		: 100,
				height		: 19,
				image       : "select.jpg",
				textAlign   : "left",
				textIndent	: "10"
			}

			var options = $.extend(defaults, argumentOptions);

			return this.each(function () {
                var o 					= options;
				var obj 				= $(this);
				var ul 					= $("ul", obj);
				var li 					= $("li", ul);
				var span 				= $("span", obj);
				var active 				= -1;
				var numberOfLiElement 	= ul.find('li').length;
				var $document 			= $(document);

				unbind = function(){
		    		ul.unbind("mouseleave");
		    		$document.unbind("keyup");
		    		$document.unbind("click");
		    	}

				var input= '<input type="text" value="' + span.text() + '" name="' + obj.attr('id') + '" style="display:none"/>';
				obj.append(input);

				obj.css("background", "url(img/" + o.image + ") no-repeat");
				obj.css("width", o.width);
				obj.css("height", o.height);

				span.css("text-align", o.textAlign);
				span.css("margin-left", o.textIndent + "px");

				ul.css('width', o.width);
				li.css('width', o.width);

				obj.click(function(){
					ul.css("opacity", "1");
					ul.css("display", "block");

					ul.bind("mouseleave", function(){
						 time = setTimeout(function() {
							 ul.animate({
								opacity: 0
							  }, 500, function() {
							  	unbind();
								ul.css("display", "none");
							 });
						}, 400);
					});

					$document.bind("keyup", function(e){
					    if (e.keyCode == 40) {
					        if(active < numberOfLiElement - 1){
					       		active++;
					       		ul.find('li').removeClass('active');
					       		ul.find('li:eq(' + active + ')').addClass('active');
					       	}
					    }
					    if (e.keyCode == 38) {
					        if(active > 0){
					       		active--;
					       		ul.find('li').removeClass('active');
					       		ul.find('li:eq(' + active + ')').addClass('active');
					       	}
					    }
					});

					time2 = setTimeout(function() {
						$document.bind("click", function(){
							ul.animate({
								opacity: 0
								}, 500, function() {
									unbind();
									ul.css("display", "none");
							});
						});
					}, 400);
				});

				li.on("click",function(){
					unbind();
					span.text($(this).text());
					$('input[name="' + obj.attr('id') + '"]').attr("value", $(this).text());

					ul.animate({
						opacity: 0
						}, 500, function() {
							ul.css("display", "none");
					});
				});
            });
        }
    });
})(jQuery);<commit_msg>update version in js file<commit_after>/*
Alessandro Minoccheri
V 2.0.0
26-02-2015
*/

(function ($) {
	var numOptions = 0;

    $.fn.extend({
        customSelect: function (argumentOptions) {
            var defaults = {
				width		: 100,
				height		: 19,
				image       : "select.jpg",
				textAlign   : "left",
				textIndent	: "10"
			}

			var options = $.extend(defaults, argumentOptions);

			return this.each(function () {
                var o 					= options;
				var obj 				= $(this);
				var ul 					= $("ul", obj);
				var li 					= $("li", ul);
				var span 				= $("span", obj);
				var active 				= -1;
				var numberOfLiElement 	= ul.find('li').length;
				var $document 			= $(document);

				unbind = function(){
		    		ul.unbind("mouseleave");
		    		$document.unbind("keyup");
		    		$document.unbind("click");
		    	}

				var input= '<input type="text" value="' + span.text() + '" name="' + obj.attr('id') + '" style="display:none"/>';
				obj.append(input);

				obj.css("background", "url(img/" + o.image + ") no-repeat");
				obj.css("width", o.width);
				obj.css("height", o.height);

				span.css("text-align", o.textAlign);
				span.css("margin-left", o.textIndent + "px");

				ul.css('width', o.width);
				li.css('width', o.width);

				obj.click(function(){
					ul.css("opacity", "1");
					ul.css("display", "block");

					ul.bind("mouseleave", function(){
						 time = setTimeout(function() {
							 ul.animate({
								opacity: 0
							  }, 500, function() {
							  	unbind();
								ul.css("display", "none");
							 });
						}, 400);
					});

					$document.bind("keyup", function(e){
					    if (e.keyCode == 40) {
					        if(active < numberOfLiElement - 1){
					       		active++;
					       		ul.find('li').removeClass('active');
					       		ul.find('li:eq(' + active + ')').addClass('active');
					       	}
					    }
					    if (e.keyCode == 38) {
					        if(active > 0){
					       		active--;
					       		ul.find('li').removeClass('active');
					       		ul.find('li:eq(' + active + ')').addClass('active');
					       	}
					    }
					});

					time2 = setTimeout(function() {
						$document.bind("click", function(){
							ul.animate({
								opacity: 0
								}, 500, function() {
									unbind();
									ul.css("display", "none");
							});
						});
					}, 400);
				});

				li.on("click",function(){
					unbind();
					span.text($(this).text());
					$('input[name="' + obj.attr('id') + '"]').attr("value", $(this).text());

					ul.animate({
						opacity: 0
						}, 500, function() {
							ul.css("display", "none");
					});
				});
            });
        }
    });
})(jQuery);<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2016 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
  The Requires Axiom is used to declare that a class requires/creates objects
  of a particular class. Required classes can be accessed without fully
  qualifying their package names. Required classes are automatically
  created in the sub-context of the creating object.

  Ex.
  foam.CLASS({
    package: 'demo.bank',
    name: 'AccountTester',
    requires: [
      // Require demo.bank.Account so that it can be accessed as this.Account
      'demo.bank.Account',

      // Require SavingsAccount and alias it so that it can be accessed
      // as this.SAccount
      'demo.bank.SavingsAccount as SAccount'
    ],
    methods: [ function init() {
      var a = this.Account.create();
      var s = this.SAccount.create();
    } ]
  });

*/
foam.CLASS({
  package: 'foam.core',
  name: 'Requires',

  properties: [
    {
      name: 'name',
      factory: function() {
        return this.path.split('.').pop();
      },
    },
    'path',
    'flags',
  ],

  methods: [
    function installInProto(proto) {
      var name = this.name;
      var path = this.path;
      var setCls;

      // Create a private_ clone of the Class with the create() method decorated
      // to pass 'this' as the context if not explicitly provided.  This ensures
      // that the created object has access to this object's exported bindings.
      Object.defineProperty(proto, name, {
        get: function requiresGetter() {
          if ( ! this.hasOwnPrivate_(name) ) {
            var cls    = setCls || (this.__context__ || foam).lookup(path);
            var parent = this;
            foam.assert(cls, 'Requires: Unknown class: ', path);

            var c = Object.create(cls);
            c.create = function requiresCreate(args, ctx) { return cls.create(args, ctx || parent); };
            this.setPrivate_(name, c);
          }

          return this.getPrivate_(name);
        },
        set: function(cls) {
          this.clearPrivate_(name);
          setCls = cls;
        },
        configurable: true,
        enumerable: false
      });
    }
  ]
});

foam.CLASS({
  refines: 'foam.core.Model',
  package: 'foam.core',
  name: 'ModelRequiresRefines',
  properties: [
    {
      class: 'AxiomArray',
      of: 'Requires',
      name: 'requires',
      adaptArrayElement: function(o) {
        if ( typeof o === 'string' ) {
          var a    = o.split(' as ');
          var path = a[0];
          var r = foam.core.Requires.create({path: path}, this);
          if ( a[1] ) r.name = a[1];
          return r;
        }
        return foam.core.Requires.create(o, this);
      }
    }
  ]
});
<commit_msg>Fix for Requies/Property-constant conflicts breaking build.<commit_after>/**
 * @license
 * Copyright 2016 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
  The Requires Axiom is used to declare that a class requires/creates objects
  of a particular class. Required classes can be accessed without fully
  qualifying their package names. Required classes are automatically
  created in the sub-context of the creating object.

  Ex.
  foam.CLASS({
    package: 'demo.bank',
    name: 'AccountTester',
    requires: [
      // Require demo.bank.Account so that it can be accessed as this.Account
      'demo.bank.Account',

      // Require SavingsAccount and alias it so that it can be accessed
      // as this.SAccount
      'demo.bank.SavingsAccount as SAccount'
    ],
    methods: [ function init() {
      var a = this.Account.create();
      var s = this.SAccount.create();
    } ]
  });

*/
foam.CLASS({
  package: 'foam.core',
  name: 'Requires',

  properties: [
    {
      name: 'name',
      factory: function() {
        return this.path.split('.').pop();
      },
    },
    // Lower priority so it is set after Properties, so that it can override
    // Property constants if there is a conflict.
    [ 'priority', 90 ],
     'path',
    'flags'
  ],

  methods: [
    function installInProto(proto) {
      var name = this.name;
      var path = this.path;
      var setCls;

      // Create a private_ clone of the Class with the create() method decorated
      // to pass 'this' as the context if not explicitly provided.  This ensures
      // that the created object has access to this object's exported bindings.
      Object.defineProperty(proto, name, {
        get: function requiresGetter() {
          if ( ! this.hasOwnPrivate_(name) ) {
            var cls    = setCls || (this.__context__ || foam).lookup(path);
            var parent = this;
            foam.assert(cls, 'Requires: Unknown class: ', path);

            var c = Object.create(cls);
            c.create = function requiresCreate(args, ctx) { return cls.create(args, ctx || parent); };
            this.setPrivate_(name, c);
          }

          return this.getPrivate_(name);
        },
        set: function(cls) {
          this.clearPrivate_(name);
          setCls = cls;
        },
        configurable: true,
        enumerable: false
      });
    }
  ]
});

foam.CLASS({
  refines: 'foam.core.Model',
  package: 'foam.core',
  name: 'ModelRequiresRefines',
  properties: [
    {
      class: 'AxiomArray',
      of: 'Requires',
      name: 'requires',
      adaptArrayElement: function(o) {
        if ( typeof o === 'string' ) {
          var a    = o.split(' as ');
          var path = a[0];
          var r = foam.core.Requires.create({path: path}, this);
          if ( a[1] ) r.name = a[1];
          return r;
        }
        return foam.core.Requires.create(o, this);
      }
    }
  ]
});
<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2017 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.INTERFACE({
  package: 'foam.lib',
  name: 'Outputter',

  javaExtends: [
    'java.io.Closeable',
    'java.io.Flushable'
  ],

  methods: [
    {
      name: 'close',
      javaThrows: [ 'java.io.IOException' ]
    },
    {
      name: 'flush',
      javaThrows: [ 'java.io.IOException' ]
    },
    {
      name: 'stringify',
      javaReturns: 'String',
      args: [
        {
          name: 'obj',
          javaType: 'foam.core.FObject'
        }
      ]
    },
    {
      name: 'output',
      javaReturns: 'void',
      args: [
        {
          name: 'value',
          javaType: 'Object'
        }
      ]
    }
  ]
});
<commit_msg>Fixed license header<commit_after>/**
 * @license
 * Copyright 2018 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.INTERFACE({
  package: 'foam.lib',
  name: 'Outputter',

  javaExtends: [
    'java.io.Closeable',
    'java.io.Flushable'
  ],

  methods: [
    {
      name: 'close',
      javaThrows: [ 'java.io.IOException' ]
    },
    {
      name: 'flush',
      javaThrows: [ 'java.io.IOException' ]
    },
    {
      name: 'stringify',
      javaReturns: 'String',
      args: [
        {
          name: 'obj',
          javaType: 'foam.core.FObject'
        }
      ]
    },
    {
      name: 'output',
      javaReturns: 'void',
      args: [
        {
          name: 'value',
          javaType: 'Object'
        }
      ]
    }
  ]
});
<|endoftext|>


<commit_before>zeit.cms.MasterSlaveDropDown = Class.extend({

    construct: function(master, slave, update_url) {
        this.master = $(master);
        this.slave = $(slave);
        this.update_url = update_url;

        if (this.master == null || this.slave == null) {
            return
        }
        connect(master, 'onchange', this, 'update');
        this.update();
    },

    update: function(event) {
        var othis = this;
        var d = doSimpleXMLHttpRequest(
            this.update_url, {master_token: this.master.value});
        d.addCallback(function(result) {
            var data = evalJSONRequest(result)
            var selected = othis.slave.value;
            othis.slave.options.length = 1
            forEach(data, function(new_option) {
                var label = new_option[0]
                var value = new_option[1]
                var option = new Option(label, value)
                if (value == selected) {
                    option.selected = true;
                }
                othis.slave.options[othis.slave.options.length] = option;
            });
        });
    },
})

connect(window, 'onload', function(event) {
    var path = window.location.pathname.split('/').slice(0, -1)
    path.push('@@subnavigationupdater.json')
    path = path.join('/')
    new zeit.cms.MasterSlaveDropDown(
        'form.ressort', 'form.sub_ressort', path)
});
<commit_msg>Re #5937: extract ressort-dropdown setup into own function so we can call it from the SubPageForm's after-reload event<commit_after>zeit.cms.MasterSlaveDropDown = Class.extend({

    construct: function(master, slave, update_url) {
        this.master = $(master);
        this.slave = $(slave);
        this.update_url = update_url;

        if (this.master == null || this.slave == null) {
            return
        }
        connect(master, 'onchange', this, 'update');
        this.update();
    },

    update: function(event) {
        var othis = this;
        var d = doSimpleXMLHttpRequest(
            this.update_url, {master_token: this.master.value});
        d.addCallback(function(result) {
            var data = evalJSONRequest(result)
            var selected = othis.slave.value;
            othis.slave.options.length = 1
            forEach(data, function(new_option) {
                var label = new_option[0]
                var value = new_option[1]
                var option = new Option(label, value)
                if (value == selected) {
                    option.selected = true;
                }
                othis.slave.options[othis.slave.options.length] = option;
            });
        });
    },
})

zeit.cms.configure_ressort_dropdown = function() {
    var path = window.location.pathname.split('/').slice(0, -1);
    path.push('@@subnavigationupdater.json');
    path = path.join('/');
    new zeit.cms.MasterSlaveDropDown(
        'form.ressort', 'form.sub_ressort', path);
};

MochiKit.Signal.connect(window, 'onload', function(event) {
    zeit.cms.configure_ressort_dropdown();
});
<|endoftext|>