<commit_before>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

cr.define('print_preview', function() {
  'use strict';

  /**
   * Data model which contains information related to the document to print.
   * @constructor
   * @extends {cr.EventTarget}
   */
  function DocumentInfo() {
    cr.EventTarget.call(this);

    /**
     * Whether the document is styled by CSS media styles.
     * @type {boolean}
     * @private
     */
    this.hasCssMediaStyles_ = false;

    /**
     * Whether the document has selected content.
     * @type {boolean}
     * @private
     */
    this.hasSelection_ = false;

    /**
     * Whether the document to print is modifiable (i.e. can be reflowed).
     * @type {boolean}
     * @private
     */
    this.isModifiable_ = true;

    /**
     * Whether scaling of the document is prohibited.
     * @type {boolean}
     * @private
     */
    this.isScalingDisabled_ = false;

    /**
     * Margins of the document in points.
     * @type {print_preview.Margins}
     * @private
     */
    this.margins_ = null;

    /**
     * Number of pages in the document to print.
     * @type {number}
     * @private
     */
    this.pageCount_ = 0;

    // Create the document info with some initial settings. Actual
    // page-related information won't be set until preview generation occurs,
    // so we'll use some defaults until then. This way, the print ticket store
    // will be valid even if no preview can be generated.
    var initialPageSize = new print_preview.Size(612, 792); // 8.5"x11"

    /**
     * Size of the pages of the document in points.
     * @type {!print_preview.Size}
     * @private
     */
    this.pageSize_ = initialPageSize;

    /**
     * Printable area of the document in points.
     * @type {!print_preview.PrintableArea}
     * @private
     */
    this.printableArea_ = new print_preview.PrintableArea(
        new print_preview.Coordinate2d(0, 0), initialPageSize);

    /**
     * Title of document.
     * @type {string}
     * @private
     */
    this.title_ = '';

    /**
     * Whether this data model has been initialized.
     * @type {boolean}
     * @private
     */
    this.isInitialized_ = false;
  };

  /**
   * Event types dispatched by this data model.
   * @enum {string}
   */
  DocumentInfo.EventType = {
    CHANGE: 'print_preview.DocumentInfo.CHANGE'
  };

  DocumentInfo.prototype = {
    __proto__: cr.EventTarget.prototype,

    /** @return {boolean} Whether the document is styled by CSS media styles. */
    get hasCssMediaStyles() {
      return this.hasCssMediaStyles_;
    },

    /** @return {boolean} Whether the document has selected content. */
    get hasSelection() {
      return this.hasSelection_;
    },

    /**
     * @return {boolean} Whether the document to print is modifiable (i.e. can
     *     be reflowed).
     */
    get isModifiable() {
      return this.isModifiable_;
    },

    /** @return {boolean} Whether scaling of the document is prohibited. */
    get isScalingDisabled() {
      return this.isScalingDisabled_;
    },

    /** @return {print_preview.Margins} Margins of the document in points. */
    get margins() {
      return this.margins_;
    },

    /** @return {number} Number of pages in the document to print. */
    get pageCount() {
      return this.pageCount_;
    },

    /**
     * @return {!print_preview.Size} Size of the pages of the document in
     *     points.
     */
    get pageSize() {
      return this.pageSize_;
    },

    /**
     * @return {!print_preview.PrintableArea} Printable area of the document in
     *     points.
     */
    get printableArea() {
      return this.printableArea_;
    },

    /** @return {string} Title of document. */
    get title() {
      return this.title_;
    },

    /**
     * Initializes the state of the data model and dispatches a CHANGE event.
     * @param {boolean} isModifiable Whether the document is modifiable.
     * @param {string} title Title of the document.
     * @param {boolean} hasSelection Whether the document has user-selected
     *     content.
     */
    init: function(isModifiable, title, hasSelection) {
      this.isModifiable_ = isModifiable;
      this.title_ = title;
      this.hasSelection_ = hasSelection;
      this.isInitialized_ = true;
    },

    /**
     * Updates whether scaling is disabled for the document and dispatches a
     * CHANGE event.
     * @param {boolean} isScalingDisabled Whether scaling of the document is
     *     prohibited.
     */
    updateIsScalingDisabled: function(isScalingDisabled) {
      if (this.isInitialized_ && this.isScalingDisabled_ != isScalingDisabled) {
        this.isScalingDisabled_ = isScalingDisabled;
        cr.dispatchSimpleEvent(this, DocumentInfo.EventType.CHANGE);
      }
    },

    /**
     * Updates the total number of pages in the document and dispatches a CHANGE
     * event.
     * @param {number} pageCount Number of pages in the document.
     */
    updatePageCount: function(pageCount) {
      if (this.isInitialized_ && this.pageCount_ != pageCount) {
        this.pageCount_ = pageCount;
        cr.dispatchSimpleEvent(this, DocumentInfo.EventType.CHANGE);
      }
    },

    /**
     * Updates information about each page and dispatches a CHANGE event.
     * @param {!print_preview.PrintableArea} printableArea Printable area of the
     *     document in points.
     * @param {!print_preview.Size} pageSize Size of the pages of the document
     *     in points.
     * @param {boolean} hasCssMediaStyles Whether the document is styled by CSS
     *     media styles.
     * @param {print_preview.Margins} margins Margins of the document in points.
     */
    updatePageInfo: function(
        printableArea, pageSize, hasCssMediaStyles, margins) {
      if (this.isInitialized_ &&
          (!this.printableArea_.equals(printableArea) ||
           !this.pageSize_.equals(pageSize) ||
           this.hasCssMediaStyles_ != hasCssMediaStyles ||
           this.margins_ == null || !this.margins_.equals(margins))) {
        this.printableArea_ = printableArea;
        this.pageSize_ = pageSize;
        this.hasCssMediaStyles_ = hasCssMediaStyles;
        this.margins_ = margins;
        cr.dispatchSimpleEvent(this, DocumentInfo.EventType.CHANGE);
      }
    }
  };

  // Export
  return {
    DocumentInfo: DocumentInfo
  };
});
<commit_msg>Fires a document info CHANGE event on init.<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

cr.define('print_preview', function() {
  'use strict';

  /**
   * Data model which contains information related to the document to print.
   * @constructor
   * @extends {cr.EventTarget}
   */
  function DocumentInfo() {
    cr.EventTarget.call(this);

    /**
     * Whether the document is styled by CSS media styles.
     * @type {boolean}
     * @private
     */
    this.hasCssMediaStyles_ = false;

    /**
     * Whether the document has selected content.
     * @type {boolean}
     * @private
     */
    this.hasSelection_ = false;

    /**
     * Whether the document to print is modifiable (i.e. can be reflowed).
     * @type {boolean}
     * @private
     */
    this.isModifiable_ = true;

    /**
     * Whether scaling of the document is prohibited.
     * @type {boolean}
     * @private
     */
    this.isScalingDisabled_ = false;

    /**
     * Margins of the document in points.
     * @type {print_preview.Margins}
     * @private
     */
    this.margins_ = null;

    /**
     * Number of pages in the document to print.
     * @type {number}
     * @private
     */
    this.pageCount_ = 0;

    // Create the document info with some initial settings. Actual
    // page-related information won't be set until preview generation occurs,
    // so we'll use some defaults until then. This way, the print ticket store
    // will be valid even if no preview can be generated.
    var initialPageSize = new print_preview.Size(612, 792); // 8.5"x11"

    /**
     * Size of the pages of the document in points.
     * @type {!print_preview.Size}
     * @private
     */
    this.pageSize_ = initialPageSize;

    /**
     * Printable area of the document in points.
     * @type {!print_preview.PrintableArea}
     * @private
     */
    this.printableArea_ = new print_preview.PrintableArea(
        new print_preview.Coordinate2d(0, 0), initialPageSize);

    /**
     * Title of document.
     * @type {string}
     * @private
     */
    this.title_ = '';

    /**
     * Whether this data model has been initialized.
     * @type {boolean}
     * @private
     */
    this.isInitialized_ = false;
  };

  /**
   * Event types dispatched by this data model.
   * @enum {string}
   */
  DocumentInfo.EventType = {
    CHANGE: 'print_preview.DocumentInfo.CHANGE'
  };

  DocumentInfo.prototype = {
    __proto__: cr.EventTarget.prototype,

    /** @return {boolean} Whether the document is styled by CSS media styles. */
    get hasCssMediaStyles() {
      return this.hasCssMediaStyles_;
    },

    /** @return {boolean} Whether the document has selected content. */
    get hasSelection() {
      return this.hasSelection_;
    },

    /**
     * @return {boolean} Whether the document to print is modifiable (i.e. can
     *     be reflowed).
     */
    get isModifiable() {
      return this.isModifiable_;
    },

    /** @return {boolean} Whether scaling of the document is prohibited. */
    get isScalingDisabled() {
      return this.isScalingDisabled_;
    },

    /** @return {print_preview.Margins} Margins of the document in points. */
    get margins() {
      return this.margins_;
    },

    /** @return {number} Number of pages in the document to print. */
    get pageCount() {
      return this.pageCount_;
    },

    /**
     * @return {!print_preview.Size} Size of the pages of the document in
     *     points.
     */
    get pageSize() {
      return this.pageSize_;
    },

    /**
     * @return {!print_preview.PrintableArea} Printable area of the document in
     *     points.
     */
    get printableArea() {
      return this.printableArea_;
    },

    /** @return {string} Title of document. */
    get title() {
      return this.title_;
    },

    /**
     * Initializes the state of the data model and dispatches a CHANGE event.
     * @param {boolean} isModifiable Whether the document is modifiable.
     * @param {string} title Title of the document.
     * @param {boolean} hasSelection Whether the document has user-selected
     *     content.
     */
    init: function(isModifiable, title, hasSelection) {
      this.isModifiable_ = isModifiable;
      this.title_ = title;
      this.hasSelection_ = hasSelection;
      this.isInitialized_ = true;
      cr.dispatchSimpleEvent(this, DocumentInfo.EventType.CHANGE);
    },

    /**
     * Updates whether scaling is disabled for the document and dispatches a
     * CHANGE event.
     * @param {boolean} isScalingDisabled Whether scaling of the document is
     *     prohibited.
     */
    updateIsScalingDisabled: function(isScalingDisabled) {
      if (this.isInitialized_ && this.isScalingDisabled_ != isScalingDisabled) {
        this.isScalingDisabled_ = isScalingDisabled;
        cr.dispatchSimpleEvent(this, DocumentInfo.EventType.CHANGE);
      }
    },

    /**
     * Updates the total number of pages in the document and dispatches a CHANGE
     * event.
     * @param {number} pageCount Number of pages in the document.
     */
    updatePageCount: function(pageCount) {
      if (this.isInitialized_ && this.pageCount_ != pageCount) {
        this.pageCount_ = pageCount;
        cr.dispatchSimpleEvent(this, DocumentInfo.EventType.CHANGE);
      }
    },

    /**
     * Updates information about each page and dispatches a CHANGE event.
     * @param {!print_preview.PrintableArea} printableArea Printable area of the
     *     document in points.
     * @param {!print_preview.Size} pageSize Size of the pages of the document
     *     in points.
     * @param {boolean} hasCssMediaStyles Whether the document is styled by CSS
     *     media styles.
     * @param {print_preview.Margins} margins Margins of the document in points.
     */
    updatePageInfo: function(
        printableArea, pageSize, hasCssMediaStyles, margins) {
      if (this.isInitialized_ &&
          (!this.printableArea_.equals(printableArea) ||
           !this.pageSize_.equals(pageSize) ||
           this.hasCssMediaStyles_ != hasCssMediaStyles ||
           this.margins_ == null || !this.margins_.equals(margins))) {
        this.printableArea_ = printableArea;
        this.pageSize_ = pageSize;
        this.hasCssMediaStyles_ = hasCssMediaStyles;
        this.margins_ = margins;
        cr.dispatchSimpleEvent(this, DocumentInfo.EventType.CHANGE);
      }
    }
  };

  // Export
  return {
    DocumentInfo: DocumentInfo
  };
});
<|endoftext|>


<commit_before>/* See license.txt for terms of usage */
/*jshint esnext:true, es5:true, curly:false */
/*global FBTrace:true, XPCNativeWrapper:true, Window:true, define:true */

define([
    "firebug/firebug",
    "firebug/lib/object",
    "firebug/lib/array",
    "firebug/lib/wrapper",
    "firebug/lib/dom",
    "firebug/lib/trace",
    "firebug/lib/locale",
    "firebug/console/closureInspector",
    "firebug/chrome/reps",
],
function(Firebug, Obj, Arr, Wrapper, Dom, FBTrace, Locale, ClosureInspector, FirebugReps) {

// ********************************************************************************************* //
// Constants

// ********************************************************************************************* //
// DOM Member Provider

function DOMMemberProvider(context)
{
    this.context = context;
}

DOMMemberProvider.prototype =
{
    /**
     * @param object a user-level object wrapped in security blanket
     * @param level for a.b.c, level is 2
     */
    getMembers: function(object, level)
    {
        if (!level)
            level = 0;

        var ordinals = [];
        var userProps = [];
        var userClasses = [];
        var userFuncs = [];
        var domProps = [];
        var domClasses = [];
        var domFuncs = [];
        var domConstants = [];
        var proto = [];
        var domHandlers = [];

        var isScope = ClosureInspector.isScopeWrapper(object);

        try
        {
            // Special case for "arguments", which is not enumerable by for...in statement.
            if (isArguments(object))
                object = Arr.cloneArray(object);

            var properties;
            var contentView = this.getObjectView(object);
            try
            {
                // Make sure not to touch the prototype chain of the magic scope objects.
                var ownOnly = Firebug.showOwnProperties || isScope;
                var enumerableOnly = Firebug.showEnumerableProperties;

                properties = this.getObjectProperties(contentView, enumerableOnly, ownOnly);
                properties = Arr.sortUnique(properties);

                var addOwn = function(prop)
                {
                    // Apparently, Object.prototype.hasOwnProperty.call(contentView, p) lies
                    // when 'contentView' is content and 'Object' is chrome... Bug 658909?
                    if (Object.getOwnPropertyDescriptor(contentView, prop) &&
                        properties.indexOf(prop) === -1)
                    {
                        properties.push(prop);
                    }
                };
                addOwn("constructor");
                addOwn("prototype");
                addOwn("wrappedJSObject");

                // __proto__ never shows in enumerations, so add it here. We currently
                // we don't want it when only showing own properties.
                if (contentView.__proto__ && Obj.hasProperties(contentView.__proto__) &&
                    properties.indexOf("__proto__") === -1 && !Firebug.showOwnProperties)
                {
                    properties.push("__proto__");
                }
            }
            catch (exc)
            {
                if (FBTrace.DBG_ERRORS || FBTrace.DBG_DOM)
                    FBTrace.sysout("dom.getMembers: property lookups failed", exc);
            }

            var name, val;
            var add = function(type, where)
            {
                this.addMember(object, type, where, name, val, level, isScope);
            }.bind(this);

            for (var i=0; i<properties.length; i++)
            {
                name = properties[i];

                // Ignore only global variables (properties of the |window| object).
                if (Wrapper.shouldIgnore(name) && (object instanceof Window))
                {
                    if (FBTrace.DBG_DOM)
                    {
                        FBTrace.sysout("dom.getMembers: Wrapper.ignoreVars: " + name + ", " +
                            level, object);
                    }
                    continue;
                }

                try
                {
                    val = contentView[name];
                }
                catch (exc)
                {
                    // Sometimes we get exceptions trying to access certain members
                    if (FBTrace.DBG_ERRORS && FBTrace.DBG_DOM)
                        FBTrace.sysout("dom.getMembers cannot access "+name, exc);

                    val = undefined;
                }

                if (!isNaN(parseInt(name, 10)))
                {
                    add("ordinal", ordinals);
                }
                else if (typeof val === "function")
                {
                    var classFunc = isClassFunction(val);
                    var domMember = Dom.isDOMMember(object, name);
                    if (domMember && classFunc)
                    {
                        add("domClass", domClasses);
                    }
                    else if (domMember)
                    {
                        add("domFunction", domFuncs);
                    }
                    else if (classFunc)
                    {
                        add("userClass", userClasses);
                    }
                    else if (!Firebug.showUserFuncs && Firebug.showInlineEventHandlers &&
                        Dom.isInlineEventHandler(name))
                    {
                        add("userFunction", domHandlers);
                    }
                    else
                    {
                        add("userFunction", userFuncs);
                    }
                }
                else
                {
                    if (isPrototype(name))
                    {
                        add("proto", proto);
                    }
                    else if (Dom.isDOMMember(object, name))
                    {
                        add("dom", domProps);
                    }
                    else if (Dom.isDOMConstant(object, name))
                    {
                        add("dom", domConstants);
                    }
                    else if (Dom.isInlineEventHandler(name))
                    {
                        add("user", domHandlers);
                    }
                    else
                    {
                        add("user", userProps);
                    }
                }
            }

            if (isScope || (typeof object === "function" && Firebug.showClosures && this.context))
            {
                this.maybeAddClosureMember(object, "proto", proto, level, isScope);
            }
        }
        catch (exc)
        {
            // Sometimes we get exceptions just from trying to iterate the members
            // of certain objects, like StorageList, but don't let that gum up the works
            if (FBTrace.DBG_DOM)
                FBTrace.sysout("dom.getMembers FAILS: ", exc);
        }

        function sortName(a, b) { return a.name > b.name ? 1 : -1; }
        function sortOrdinal(a, b) { return a.name - b.name; }

        var members = [];

        ordinals.sort(sortOrdinal);
        members.push.apply(members, ordinals);

        if (Firebug.showUserProps)
        {
            userProps.sort(sortName);
            members.push.apply(members, userProps);
        }

        if (Firebug.showUserFuncs)
        {
            userClasses.sort(sortName);
            members.push.apply(members, userClasses);

            userFuncs.sort(sortName);
            members.push.apply(members, userFuncs);
        }

        if (Firebug.showDOMProps)
        {
            domProps.sort(sortName);
            members.push.apply(members, domProps);
        }

        if (Firebug.showDOMFuncs)
        {
            domClasses.sort(sortName);
            members.push.apply(members, domClasses);

            domFuncs.sort(sortName);
            members.push.apply(members, domFuncs);
        }

        if (Firebug.showDOMConstants)
            members.push.apply(members, domConstants);

        members.push.apply(members, proto);

        if (Firebug.showInlineEventHandlers)
        {
            domHandlers.sort(sortName);
            members.push.apply(members, domHandlers);
        }

        if (FBTrace.DBG_DOM)
        {
            var showEnum = Firebug.showEnumerableProperties;
            var showOwn = Firebug.showOwnProperties;
            FBTrace.sysout("dom.getMembers; Report: enum-only: " + showEnum +
                ", own-only: " + showOwn,
            {
                object: object,
                ordinals: ordinals,
                userProps: userProps,
                userFuncs: userFuncs,
                userClasses: userClasses,
                domProps: domProps,
                domFuncs: domFuncs,
                domConstants: domConstants,
                domHandlers: domHandlers,
                proto: proto
            });
        }

        return members;
    },

    addMember: function()
    {
        try
        {
            return this.addMemberInternal.apply(this, arguments);
        }
        catch (err)
        {
            if (FBTrace.DBG_ERRORS)
                FBTrace.sysout("domPanel.addMember; EXCEPTION " + err, err);
        }
    },

    addMemberInternal: function(object, type, props, name, value, level, parentIsScope)
    {
        // Do this first in case a call to instanceof (= QI, for XPCOM things) reveals contents.
        var rep = Firebug.getRep(value);
        var tag = rep.shortTag ? rep.shortTag : rep.tag;

        var hasProperties = Obj.hasProperties(value, !Firebug.showEnumerableProperties,
            Firebug.showOwnProperties);

        var valueType = typeof value;
        var hasChildren = hasProperties && !(value instanceof FirebugReps.ErrorCopy) &&
            ((valueType === "function") ||
             (valueType === "object" && value !== null));

        // Special case for closure inspection.
        if (!hasChildren && valueType === "function" && Firebug.showClosures && this.context)
        {
            try
            {
                var win = this.context.getCurrentGlobal();
                ClosureInspector.getEnvironmentForObject(win, value, this.context);
                hasChildren = true;
            }
            catch (e) {}
        }

        // Special case for "arguments", which is not enumerable by for...in statement
        // and so, Obj.hasProperties always returns false.
        hasChildren = hasChildren || (!!value && isArguments(value));

        if (valueType === "function" && !hasChildren)
        {
            try
            {
                // Special case for functions with a prototype that has values
                var proto = value.prototype;
                if (proto)
                {
                    hasChildren = Obj.hasProperties(proto, !Firebug.showEnumerableProperties,
                        Firebug.showOwnProperties);
                }
            }
            catch (exc) {}
        }

        var descriptor = getPropertyDescriptor(object, name);

        var member = {
            object: object,
            name: name,
            value: value,
            type: type,
            rowClass: "memberRow-" + type,
            open: "",
            level: level,
            indent: level * 16,
            hasChildren: hasChildren,
            tag: tag,
            prefix: "",
            readOnly: (descriptor && !descriptor.writable && !descriptor.set),
            // XXX should probably move the tests from getContextMenuItems here
            deletable: (!parentIsScope && !(descriptor && !descriptor.configurable))
        };

        // The context doesn't have to be specified (e.g. in case of Watch panel that is based
        // on the same template as the DOM panel, but doesn't show any breakpoints).
        if (this.context)
        {
            // xxxHonza: Support for object change not implemented yet.
            member.breakable = !hasChildren && !parentIsScope;

            var breakpoints = this.context.dom.breakpoints;
            var bp = breakpoints.findBreakpoint(object, name);
            if (bp)
            {
                member.breakpoint = true;
                member.disabledBreakpoint = !bp.checked;
            }
        }

        if (parentIsScope)
            member.scopeNameTooltip = Locale.$STRF("dom.tip.scopeMemberName", ["%" + name]);

        // Set prefix for user defined properties. This prefix help the user to distinguish
        // among simple properties and those defined using getter and/or (only a) setter.
        // XXX This should be rewritten to use 'descriptor', and I believe the unwrapping
        // test is wrong (see issue 5377).
        var o = this.getObjectView(object);
        if (o && !Dom.isDOMMember(object, name) && (XPCNativeWrapper.unwrap(object) !== object))
        {
            var getter = (o.__lookupGetter__) ? o.__lookupGetter__(name) : null;
            var setter = (o.__lookupSetter__) ? o.__lookupSetter__(name) : null;

            // both, getter and setter
            if (getter && setter)
                member.type = "userFunction";

            // only getter
            if (getter && !setter)
            {
                member.readOnly = true;
                member.prefix = "get";
            }

            // only setter
            if (!getter && setter)
            {
                member.prefix = "set";
            }
        }

        props.push(member);
        return member;
    },

    // Add the magic "(closure)" property.
    maybeAddClosureMember: function(object, type, props, level, isScope)
    {
        var win = this.context.getCurrentGlobal();
        var wrapper = ClosureInspector.getScopeWrapper(object, win, this.context, isScope);
        if (!wrapper)
            return;

        var name = (isScope ? Locale.$STR("dom.scopeParentName") : Locale.$STR("dom.scopeName"));
        var title = (isScope ? undefined : Locale.$STR("dom.tip.scopeName"));
        var rep = Firebug.getRep(wrapper);
        var tag = rep.shortTag ? rep.shortTag : rep.tag;

        var member = {
            object: object,
            name: name,
            value: wrapper,
            type: type,
            rowClass: "memberRow-" + type,
            open: "",
            level: level,
            indent: level*16,
            hasChildren: true,
            tag: tag,
            prefix: "",
            title: title,
            readOnly: true,
            deletable: false,
            ignoredPath: true
        };
        props.push(member);
    },

    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
    // Object properties

    /**
     * Returns a list of properties available on an object, filtered on enumerability and prototype
     * chain position. Due to prototype traversal, some property names may appear several times.
     *
     * @param {Object} object The object we want to get the list of properties for.
     * @param {Boolean} enumerableOnly If set to true, only enumerable properties are returned.
     * @param {Boolean} ownOnly If set to true, only own properties (not those from the
     *      prototype chain) are returned.
     */
    getObjectProperties: function(object, enumerableOnly, ownOnly)
    {
        var props = [];

        // Get all enumerable-only or all-properties of the object (but not inherited).
        if (enumerableOnly)
            props = Object.keys(object);
        else
            props = Object.getOwnPropertyNames(object);

        // Not interested in inherited properties, bail out.
        if (ownOnly)
            return props;

        // Climb the prototype chain.
        var inheritedProps = [];
        var parent = Object.getPrototypeOf(object);
        if (parent)
            inheritedProps = this.getObjectProperties(parent, enumerableOnly, ownOnly);

        // Push everything onto the returned array, to avoid O(nm) runtime behavior.
        inheritedProps.push.apply(inheritedProps, props);
        return inheritedProps;
    },

    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
    // Wrappers

    getObjectView: function(object)
    {
        if (!Firebug.viewChrome)
        {
            // Unwrap native, wrapped objects.
            var contentView = Wrapper.getContentView(object);
            if (contentView)
                return contentView;
        }
        return object;
    },
}

// ********************************************************************************************* //
// Helpers

function isArguments(obj)
{
    try
    {
        return isFinite(obj.length) && obj.length > 0 && typeof obj.callee === "function";
    }
    catch (exc)
    {
    }

    return false;
}

function isClassFunction(fn)
{
    try
    {
        for (var name in fn.prototype)
            return true;
    }
    catch (exc)
    {
    }

    return false;
}

function isPrototype(name)
{
    return (name === "prototype" || name === "__proto__");
}

function getPropertyDescriptor(object, propName)
{
    try
    {
        var desc;
        while (object)
        {
            desc = Object.getOwnPropertyDescriptor(object, propName);
            if (desc)
                return desc;
            object = Object.getPrototypeOf(object);
        }
    }
    catch (e)
    {
    }
    return undefined;
}

// ********************************************************************************************* //
// Registration

return DOMMemberProvider;

// ********************************************************************************************* //
});
<commit_msg>Issue 6900: The "Show inline event handlers" option should only apply to built-ins<commit_after>/* See license.txt for terms of usage */
/*jshint esnext:true, es5:true, curly:false */
/*global FBTrace:true, XPCNativeWrapper:true, Window:true, define:true */

define([
    "firebug/firebug",
    "firebug/lib/object",
    "firebug/lib/array",
    "firebug/lib/wrapper",
    "firebug/lib/dom",
    "firebug/lib/trace",
    "firebug/lib/locale",
    "firebug/console/closureInspector",
    "firebug/chrome/reps",
],
function(Firebug, Obj, Arr, Wrapper, Dom, FBTrace, Locale, ClosureInspector, FirebugReps) {

// ********************************************************************************************* //
// Constants

// ********************************************************************************************* //
// DOM Member Provider

function DOMMemberProvider(context)
{
    this.context = context;
}

DOMMemberProvider.prototype =
{
    /**
     * @param object a user-level object wrapped in security blanket
     * @param level for a.b.c, level is 2
     */
    getMembers: function(object, level)
    {
        if (!level)
            level = 0;

        var ordinals = [];
        var userProps = [];
        var userClasses = [];
        var userFuncs = [];
        var domProps = [];
        var domClasses = [];
        var domFuncs = [];
        var domConstants = [];
        var proto = [];
        var domHandlers = [];

        var isScope = ClosureInspector.isScopeWrapper(object);

        try
        {
            // Special case for "arguments", which is not enumerable by for...in statement.
            if (isArguments(object))
                object = Arr.cloneArray(object);

            var properties;
            var contentView = this.getObjectView(object);
            try
            {
                // Make sure not to touch the prototype chain of the magic scope objects.
                var ownOnly = Firebug.showOwnProperties || isScope;
                var enumerableOnly = Firebug.showEnumerableProperties;

                properties = this.getObjectProperties(contentView, enumerableOnly, ownOnly);
                properties = Arr.sortUnique(properties);

                var addOwn = function(prop)
                {
                    // Apparently, Object.prototype.hasOwnProperty.call(contentView, p) lies
                    // when 'contentView' is content and 'Object' is chrome... Bug 658909?
                    if (Object.getOwnPropertyDescriptor(contentView, prop) &&
                        properties.indexOf(prop) === -1)
                    {
                        properties.push(prop);
                    }
                };
                addOwn("constructor");
                addOwn("prototype");
                addOwn("wrappedJSObject");

                // __proto__ never shows in enumerations, so add it here. We currently
                // we don't want it when only showing own properties.
                if (contentView.__proto__ && Obj.hasProperties(contentView.__proto__) &&
                    properties.indexOf("__proto__") === -1 && !Firebug.showOwnProperties)
                {
                    properties.push("__proto__");
                }
            }
            catch (exc)
            {
                if (FBTrace.DBG_ERRORS || FBTrace.DBG_DOM)
                    FBTrace.sysout("dom.getMembers: property lookups failed", exc);
            }

            var name, val;
            var add = function(type, where)
            {
                this.addMember(object, type, where, name, val, level, isScope);
            }.bind(this);

            for (var i=0; i<properties.length; i++)
            {
                name = properties[i];

                // Ignore only global variables (properties of the |window| object).
                if (Wrapper.shouldIgnore(name) && (object instanceof Window))
                {
                    if (FBTrace.DBG_DOM)
                    {
                        FBTrace.sysout("dom.getMembers: Wrapper.ignoreVars: " + name + ", " +
                            level, object);
                    }
                    continue;
                }

                try
                {
                    val = contentView[name];
                }
                catch (exc)
                {
                    // Sometimes we get exceptions trying to access certain members
                    if (FBTrace.DBG_ERRORS && FBTrace.DBG_DOM)
                        FBTrace.sysout("dom.getMembers cannot access "+name, exc);

                    val = undefined;
                }

                if (!isNaN(parseInt(name, 10)))
                {
                    add("ordinal", ordinals);
                }
                else if (typeof val === "function")
                {
                    var classFunc = isClassFunction(val);
                    var domMember = Dom.isDOMMember(object, name);
                    if (domMember && classFunc)
                    {
                        add("domClass", domClasses);
                    }
                    else if (domMember)
                    {
                        add("domFunction", domFuncs);
                    }
                    else if (classFunc)
                    {
                        add("userClass", userClasses);
                    }
                    else if (!Firebug.showUserFuncs && Firebug.showInlineEventHandlers &&
                        Dom.isInlineEventHandler(name))
                    {
                        add("userFunction", domHandlers);
                    }
                    else
                    {
                        add("userFunction", userFuncs);
                    }
                }
                else
                {
                    if (isPrototype(name))
                    {
                        add("proto", proto);
                    }
                    else if (Dom.isDOMMember(object, name))
                    {
                        add("dom", domProps);
                    }
                    else if (Dom.isDOMConstant(object, name))
                    {
                        add("dom", domConstants);
                    }
                    else if (val === null && object instanceof EventTarget &&
                        Dom.isInlineEventHandler(name))
                    {
                        add("user", domHandlers);
                    }
                    else
                    {
                        add("user", userProps);
                    }
                }
            }

            if (isScope || (typeof object === "function" && Firebug.showClosures && this.context))
            {
                this.maybeAddClosureMember(object, "proto", proto, level, isScope);
            }
        }
        catch (exc)
        {
            // Sometimes we get exceptions just from trying to iterate the members
            // of certain objects, like StorageList, but don't let that gum up the works
            if (FBTrace.DBG_DOM)
                FBTrace.sysout("dom.getMembers FAILS: ", exc);
        }

        function sortName(a, b) { return a.name > b.name ? 1 : -1; }
        function sortOrdinal(a, b) { return a.name - b.name; }

        var members = [];

        ordinals.sort(sortOrdinal);
        members.push.apply(members, ordinals);

        if (Firebug.showUserProps)
        {
            userProps.sort(sortName);
            members.push.apply(members, userProps);
        }

        if (Firebug.showUserFuncs)
        {
            userClasses.sort(sortName);
            members.push.apply(members, userClasses);

            userFuncs.sort(sortName);
            members.push.apply(members, userFuncs);
        }

        if (Firebug.showDOMProps)
        {
            domProps.sort(sortName);
            members.push.apply(members, domProps);
        }

        if (Firebug.showDOMFuncs)
        {
            domClasses.sort(sortName);
            members.push.apply(members, domClasses);

            domFuncs.sort(sortName);
            members.push.apply(members, domFuncs);
        }

        if (Firebug.showDOMConstants)
            members.push.apply(members, domConstants);

        members.push.apply(members, proto);

        if (Firebug.showInlineEventHandlers)
        {
            domHandlers.sort(sortName);
            members.push.apply(members, domHandlers);
        }

        if (FBTrace.DBG_DOM)
        {
            var showEnum = Firebug.showEnumerableProperties;
            var showOwn = Firebug.showOwnProperties;
            FBTrace.sysout("dom.getMembers; Report: enum-only: " + showEnum +
                ", own-only: " + showOwn,
            {
                object: object,
                ordinals: ordinals,
                userProps: userProps,
                userFuncs: userFuncs,
                userClasses: userClasses,
                domProps: domProps,
                domFuncs: domFuncs,
                domConstants: domConstants,
                domHandlers: domHandlers,
                proto: proto
            });
        }

        return members;
    },

    addMember: function()
    {
        try
        {
            return this.addMemberInternal.apply(this, arguments);
        }
        catch (err)
        {
            if (FBTrace.DBG_ERRORS)
                FBTrace.sysout("domPanel.addMember; EXCEPTION " + err, err);
        }
    },

    addMemberInternal: function(object, type, props, name, value, level, parentIsScope)
    {
        // Do this first in case a call to instanceof (= QI, for XPCOM things) reveals contents.
        var rep = Firebug.getRep(value);
        var tag = rep.shortTag ? rep.shortTag : rep.tag;

        var hasProperties = Obj.hasProperties(value, !Firebug.showEnumerableProperties,
            Firebug.showOwnProperties);

        var valueType = typeof value;
        var hasChildren = hasProperties && !(value instanceof FirebugReps.ErrorCopy) &&
            ((valueType === "function") ||
             (valueType === "object" && value !== null));

        // Special case for closure inspection.
        if (!hasChildren && valueType === "function" && Firebug.showClosures && this.context)
        {
            try
            {
                var win = this.context.getCurrentGlobal();
                ClosureInspector.getEnvironmentForObject(win, value, this.context);
                hasChildren = true;
            }
            catch (e) {}
        }

        // Special case for "arguments", which is not enumerable by for...in statement
        // and so, Obj.hasProperties always returns false.
        hasChildren = hasChildren || (!!value && isArguments(value));

        if (valueType === "function" && !hasChildren)
        {
            try
            {
                // Special case for functions with a prototype that has values
                var proto = value.prototype;
                if (proto)
                {
                    hasChildren = Obj.hasProperties(proto, !Firebug.showEnumerableProperties,
                        Firebug.showOwnProperties);
                }
            }
            catch (exc) {}
        }

        var descriptor = getPropertyDescriptor(object, name);

        var member = {
            object: object,
            name: name,
            value: value,
            type: type,
            rowClass: "memberRow-" + type,
            open: "",
            level: level,
            indent: level * 16,
            hasChildren: hasChildren,
            tag: tag,
            prefix: "",
            readOnly: (descriptor && !descriptor.writable && !descriptor.set),
            // XXX should probably move the tests from getContextMenuItems here
            deletable: (!parentIsScope && !(descriptor && !descriptor.configurable))
        };

        // The context doesn't have to be specified (e.g. in case of Watch panel that is based
        // on the same template as the DOM panel, but doesn't show any breakpoints).
        if (this.context)
        {
            // xxxHonza: Support for object change not implemented yet.
            member.breakable = !hasChildren && !parentIsScope;

            var breakpoints = this.context.dom.breakpoints;
            var bp = breakpoints.findBreakpoint(object, name);
            if (bp)
            {
                member.breakpoint = true;
                member.disabledBreakpoint = !bp.checked;
            }
        }

        if (parentIsScope)
            member.scopeNameTooltip = Locale.$STRF("dom.tip.scopeMemberName", ["%" + name]);

        // Set prefix for user defined properties. This prefix help the user to distinguish
        // among simple properties and those defined using getter and/or (only a) setter.
        // XXX This should be rewritten to use 'descriptor', and I believe the unwrapping
        // test is wrong (see issue 5377).
        var o = this.getObjectView(object);
        if (o && !Dom.isDOMMember(object, name) && (XPCNativeWrapper.unwrap(object) !== object))
        {
            var getter = (o.__lookupGetter__) ? o.__lookupGetter__(name) : null;
            var setter = (o.__lookupSetter__) ? o.__lookupSetter__(name) : null;

            // both, getter and setter
            if (getter && setter)
                member.type = "userFunction";

            // only getter
            if (getter && !setter)
            {
                member.readOnly = true;
                member.prefix = "get";
            }

            // only setter
            if (!getter && setter)
            {
                member.prefix = "set";
            }
        }

        props.push(member);
        return member;
    },

    // Add the magic "(closure)" property.
    maybeAddClosureMember: function(object, type, props, level, isScope)
    {
        var win = this.context.getCurrentGlobal();
        var wrapper = ClosureInspector.getScopeWrapper(object, win, this.context, isScope);
        if (!wrapper)
            return;

        var name = (isScope ? Locale.$STR("dom.scopeParentName") : Locale.$STR("dom.scopeName"));
        var title = (isScope ? undefined : Locale.$STR("dom.tip.scopeName"));
        var rep = Firebug.getRep(wrapper);
        var tag = rep.shortTag ? rep.shortTag : rep.tag;

        var member = {
            object: object,
            name: name,
            value: wrapper,
            type: type,
            rowClass: "memberRow-" + type,
            open: "",
            level: level,
            indent: level*16,
            hasChildren: true,
            tag: tag,
            prefix: "",
            title: title,
            readOnly: true,
            deletable: false,
            ignoredPath: true
        };
        props.push(member);
    },

    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
    // Object properties

    /**
     * Returns a list of properties available on an object, filtered on enumerability and prototype
     * chain position. Due to prototype traversal, some property names may appear several times.
     *
     * @param {Object} object The object we want to get the list of properties for.
     * @param {Boolean} enumerableOnly If set to true, only enumerable properties are returned.
     * @param {Boolean} ownOnly If set to true, only own properties (not those from the
     *      prototype chain) are returned.
     */
    getObjectProperties: function(object, enumerableOnly, ownOnly)
    {
        var props = [];

        // Get all enumerable-only or all-properties of the object (but not inherited).
        if (enumerableOnly)
            props = Object.keys(object);
        else
            props = Object.getOwnPropertyNames(object);

        // Not interested in inherited properties, bail out.
        if (ownOnly)
            return props;

        // Climb the prototype chain.
        var inheritedProps = [];
        var parent = Object.getPrototypeOf(object);
        if (parent)
            inheritedProps = this.getObjectProperties(parent, enumerableOnly, ownOnly);

        // Push everything onto the returned array, to avoid O(nm) runtime behavior.
        inheritedProps.push.apply(inheritedProps, props);
        return inheritedProps;
    },

    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
    // Wrappers

    getObjectView: function(object)
    {
        if (!Firebug.viewChrome)
        {
            // Unwrap native, wrapped objects.
            var contentView = Wrapper.getContentView(object);
            if (contentView)
                return contentView;
        }
        return object;
    },
}

// ********************************************************************************************* //
// Helpers

function isArguments(obj)
{
    try
    {
        return isFinite(obj.length) && obj.length > 0 && typeof obj.callee === "function";
    }
    catch (exc)
    {
    }

    return false;
}

function isClassFunction(fn)
{
    try
    {
        for (var name in fn.prototype)
            return true;
    }
    catch (exc)
    {
    }

    return false;
}

function isPrototype(name)
{
    return (name === "prototype" || name === "__proto__");
}

function getPropertyDescriptor(object, propName)
{
    try
    {
        var desc;
        while (object)
        {
            desc = Object.getOwnPropertyDescriptor(object, propName);
            if (desc)
                return desc;
            object = Object.getPrototypeOf(object);
        }
    }
    catch (e)
    {
    }
    return undefined;
}

// ********************************************************************************************* //
// Registration

return DOMMemberProvider;

// ********************************************************************************************* //
});
<|endoftext|>


<commit_before>var assert = require('assert')
var Id = require('./identifier')
var push = [].push
var RBTree = require('bintrees').RBTree;

function Legislator (id) {
    this.id = id
    this.proposal = { id: [ 0x0 ] }
    this.promisedId = [ 0x1 ]
    this.log = new RBTree(function (a, b) { return Id.compare(a.id, b.id) })
    this.government = {
        leader: 0,
        majority: [ 0, 1, 2 ],
        members: [ 0, 1, 2, 3, 4 ]
    }
}

Legislator.dispatch = function (messages, legislators) {
    var responses = []
    messages.forEach(function (message) {
        var type = message.type
        var method = 'receive' + type[0].toUpperCase() + type.substring(1)
        legislators.forEach(function (legislator) {
            if (!message.to || ~message.to.indexOf(legislator.id)) {
                push.apply(responses, legislator[method](message))
                if (message.forward) { // todo: validator.forward(message)
                    var forward = {}
                    for (var key in message) {
                        forward[key] = message[key]
                    }
                    forward.to = [ message.forward[0] ]
                    if (message.forward.length == 1) {
                        delete forward.forward
                    } else {
                        forward.forward = message.forward.slice(1)
                    }
                    responses.push(forward)
                }
            }
        })
        if (!message.to) {
            responses.push(message)
        }
    })
    return responses
}

Legislator.prototype.propose = function (value) {
    // assert(~this.quorum.indexOf(this.id), 'quorom includes self')
    this.proposal = {
        id: Id.increment(this.proposal.id),
        value: value,
        quorum: this.government.majority,
        promises: [],
        accepts: []
    }
    this.promisedId = this.proposal.id
    // todo: pass around quorum?
    return [{
        from: this.id,
        to: this.proposal.quorum,
        type: 'prepare',
        id: this.proposal.id
    }]
}

Legislator.prototype.receivePrepare = function (message) {
    var compare = Id.compare(this.proposal.id, message.id)

    if (compare == 0) {
        return []
    }

    if (compare < 0) {
        this.promise = { id: message.id }
        return [{
            from: [ this.id ],
            to: [ message.from ],
            type: 'promise',
            id: this.promise.id
        }]
    }

    return [{
        from: [ this.id ],
        to: [ message.from ],
        type: 'promised',
        id: this.promisedId
    }]
}

Legislator.prototype.receivePromise = function (message) {
    var compare = Id.compare(this.proposal.id, message.id)

    if (compare != 0) {
        return []
    }

    if (!~this.proposal.quorum.indexOf(message.from[0])) {
        return []
    }

    if (!~this.proposal.promises.indexOf(message.from[0])) {
        this.proposal.promises.push(message.from[0])
    } else {
        // We have already received a promise. Something is probably wrong.
        return []
    }

    if (this.proposal.promises.length == this.proposal.quorum.length - 1) {
        this._entry(this.proposal.id, {
            quorum: this.government.majority.length,
            value: this.proposal.value
        })
        return [{
            from: [ this.id ],
            to: [ this.proposal.quorum[1] ],
            forward: this.proposal.quorum.slice(2),
            type: 'accept',
            quorum: this.government.majority.length,
            id: this.proposal.id,
            value: this.proposal.value
        }, {
            // todo: value amalgamation prior to sending.
            from: [ this.id ],
            to: this.government.majority,
            type: 'accepted',
            quorum: this.government.majority.length,
            id: this.proposal.id,
            value: this.proposal.value
        }]
    }

    return []
}

Legislator.prototype._entry = function (id, message) {
    var entry = this.log.find({ id: id })
    if (!entry) {
        assert(message.quorum != null, 'quorum missing')
        assert('value' in message, 'value missing')
        var entry = {
            id: id,
            accepts: [],
            learns: [],
            quorum: message.quorum,
            value: message.value
        }
        this.log.insert(entry)
    }
    return entry
}

Legislator.prototype.receiveAccept = function (message) {
    var compare = Id.compare(this.promisedId, message.id)
    if (compare > 0) {
        return [{
            type: 'reject'
        }]
    } else if (compare < 0) {
    } else {
        this._entry(message.id, message)
        return [{
            type: 'accepted',
            from: [ this.id ],
            to: this.government.majority,
            quorum: message.quorum,
            id: message.id,
            value: message.value
        }]
    }
}

Legislator.prototype.receiveAccepted = function (message) {
    var entry = this._entry(message.id, message), messages = []
    message.from.forEach(function (id) {
        if (!~entry.accepts.indexOf(id)) {
            entry.accepts.push(id)
        }
        if (entry.accepts.length >= entry.quorum && !entry.learned)  {
            entry.learned = true
            if (~this.government.majority.indexOf(this.id)) {
                messages.push({
                    from: [ this.id ],
                    to: [ this.government.leader ],
                    type: 'learned',
                    id: message.id
                })
            }
        }
    }, this)
    return messages
}

Legislator.prototype.receiveLearned = function (message) {
    var entry = this._entry(message.id, message), messages = []
    message.from.forEach(function (id) {
        if (!~entry.learns.indexOf(id)) {
            entry.learns.push(id)
        }
        if (entry.learns.length == entry.quorum) {
            entry.actionable = true
        }
        if (entry.actionable && Id.compare(this.proposal.id, message.id) == 0) {
            messages.push({
                from: this.government.majority,
                to: this.government.majority.filter(function (id) {
                    return id != this.id
                }.bind(this)),
                type: 'learned',
                id: message.id
            })
        }
    }, this)
    return messages
}

Legislator.prototype.recieveDequeue = function (message) {
}

module.exports = Legislator
<commit_msg>Remove old perpetuate message.<commit_after>var assert = require('assert')
var Id = require('./identifier')
var push = [].push
var RBTree = require('bintrees').RBTree;

function Legislator (id) {
    this.id = id
    this.proposal = { id: [ 0x0 ] }
    this.promisedId = [ 0x1 ]
    this.log = new RBTree(function (a, b) { return Id.compare(a.id, b.id) })
    this.government = {
        leader: 0,
        majority: [ 0, 1, 2 ],
        members: [ 0, 1, 2, 3, 4 ]
    }
}

Legislator.dispatch = function (messages, legislators) {
    var responses = []
    messages.forEach(function (message) {
        var type = message.type
        var method = 'receive' + type[0].toUpperCase() + type.substring(1)
        legislators.forEach(function (legislator) {
            if (!message.to || ~message.to.indexOf(legislator.id)) {
                push.apply(responses, legislator[method](message))
                if (message.forward) { // todo: validator.forward(message)
                    var forward = {}
                    for (var key in message) {
                        forward[key] = message[key]
                    }
                    forward.to = [ message.forward[0] ]
                    if (message.forward.length == 1) {
                        delete forward.forward
                    } else {
                        forward.forward = message.forward.slice(1)
                    }
                    responses.push(forward)
                }
            }
        })
    })
    return responses
}

Legislator.prototype.propose = function (value) {
    // assert(~this.quorum.indexOf(this.id), 'quorom includes self')
    this.proposal = {
        id: Id.increment(this.proposal.id),
        value: value,
        quorum: this.government.majority,
        promises: [],
        accepts: []
    }
    this.promisedId = this.proposal.id
    // todo: pass around quorum?
    return [{
        from: this.id,
        to: this.proposal.quorum,
        type: 'prepare',
        id: this.proposal.id
    }]
}

Legislator.prototype.receivePrepare = function (message) {
    var compare = Id.compare(this.proposal.id, message.id)

    if (compare == 0) {
        return []
    }

    if (compare < 0) {
        this.promise = { id: message.id }
        return [{
            from: [ this.id ],
            to: [ message.from ],
            type: 'promise',
            id: this.promise.id
        }]
    }

    return [{
        from: [ this.id ],
        to: [ message.from ],
        type: 'promised',
        id: this.promisedId
    }]
}

Legislator.prototype.receivePromise = function (message) {
    var compare = Id.compare(this.proposal.id, message.id)

    if (compare != 0) {
        return []
    }

    if (!~this.proposal.quorum.indexOf(message.from[0])) {
        return []
    }

    if (!~this.proposal.promises.indexOf(message.from[0])) {
        this.proposal.promises.push(message.from[0])
    } else {
        // We have already received a promise. Something is probably wrong.
        return []
    }

    if (this.proposal.promises.length == this.proposal.quorum.length - 1) {
        this._entry(this.proposal.id, {
            quorum: this.government.majority.length,
            value: this.proposal.value
        })
        return [{
            from: [ this.id ],
            to: [ this.proposal.quorum[1] ],
            forward: this.proposal.quorum.slice(2),
            type: 'accept',
            quorum: this.government.majority.length,
            id: this.proposal.id,
            value: this.proposal.value
        }, {
            // todo: value amalgamation prior to sending.
            from: [ this.id ],
            to: this.government.majority,
            type: 'accepted',
            quorum: this.government.majority.length,
            id: this.proposal.id,
            value: this.proposal.value
        }]
    }

    return []
}

Legislator.prototype._entry = function (id, message) {
    var entry = this.log.find({ id: id })
    if (!entry) {
        assert(message.quorum != null, 'quorum missing')
        assert('value' in message, 'value missing')
        var entry = {
            id: id,
            accepts: [],
            learns: [],
            quorum: message.quorum,
            value: message.value
        }
        this.log.insert(entry)
    }
    return entry
}

Legislator.prototype.receiveAccept = function (message) {
    var compare = Id.compare(this.promisedId, message.id)
    if (compare > 0) {
        return [{
            type: 'reject'
        }]
    } else if (compare < 0) {
    } else {
        this._entry(message.id, message)
        return [{
            type: 'accepted',
            from: [ this.id ],
            to: this.government.majority,
            quorum: message.quorum,
            id: message.id,
            value: message.value
        }]
    }
}

Legislator.prototype.receiveAccepted = function (message) {
    var entry = this._entry(message.id, message), messages = []
    message.from.forEach(function (id) {
        if (!~entry.accepts.indexOf(id)) {
            entry.accepts.push(id)
        }
        if (entry.accepts.length >= entry.quorum && !entry.learned)  {
            entry.learned = true
            if (~this.government.majority.indexOf(this.id)) {
                messages.push({
                    from: [ this.id ],
                    to: [ this.government.leader ],
                    type: 'learned',
                    id: message.id
                })
            }
        }
    }, this)
    return messages
}

Legislator.prototype.receiveLearned = function (message) {
    var entry = this._entry(message.id, message), messages = []
    message.from.forEach(function (id) {
        if (!~entry.learns.indexOf(id)) {
            entry.learns.push(id)
        }
        if (entry.learns.length == entry.quorum) {
            entry.actionable = true
        }
        if (entry.actionable && Id.compare(this.proposal.id, message.id) == 0) {
            messages.push({
                from: this.government.majority,
                to: this.government.majority.filter(function (id) {
                    return id != this.id
                }.bind(this)),
                type: 'learned',
                id: message.id
            })
        }
    }, this)
    return messages
}

Legislator.prototype.recieveDequeue = function (message) {
}

module.exports = Legislator
<|endoftext|>


<commit_before>#!/usr/bin/env node

// Node vs browser behavior
if (typeof module === 'undefined') {
    var tasks = {},
        exports = tasks;
}

// parseTasks: takes a string with the contents of a task file and
// parses it. Returns an object/hashmap containing num_of_tasks,
// total_time and task_queue.
function parseTasks (data) {
    var input=data.split('\n');
    var line1 = input[0].split(' ');
    // First line has num_of_tasks and total_time
    var num_of_tasks=parseInt(line1[0], 10);
    var total_time=parseInt(line1[1], 10);

    // read in the tasks
    var queue= [];

    for(var j=1; j <= num_of_tasks; j++) {
        var task_data=input[j].split(' ');
        // Create a new task object and add it to the queue
        var task = {id         :          task_data[0],
                    start_time : parseInt(task_data[1], 10),
                    duration   : parseInt(task_data[2], 10)};
        queue.push(task);
    }

    // Numeric sort the task queue by the start_time attribute
    function sort_function (a, b) {
        return a.start_time - b.start_time;
    }
    queue.sort(sort_function);

    return {num_of_tasks: num_of_tasks,
            total_time:   total_time,
            task_queue:   queue};
}

// generateTasks: generate n tasks that each start at time 1 and all
// run for duration
function generateTasks (n, start, duration, start_max, duration_max) {
    if (typeof start_max === 'undefined') {
        start_max = start;
    }
    if (typeof duration_max === 'undefined') {
        duration_max = duration;
    }
    var queue = [], total_duration = 0;
    for (var i=0; i<n; i++) {
        var stime = Math.floor(Math.random()*(start_max-start+1)+start),
            dur = Math.floor(Math.random()*(duration_max-duration+1)+duration);
        total_duration += dur;
        var task = {id: "t" + (i+1),
                    start_time: stime,
                    duration: dur};
        queue.push(task);
    }
    return {num_of_tasks: n,
            total_time: total_duration+1,
            task_queue: queue};
}

function tasksToString(tasks) {
    var str = tasks.num_of_tasks + " " + tasks.total_time + "\n";
    for (var i=0; i < tasks.task_queue.length; i++) {
        var t = tasks.task_queue[i];
        str += t.id + " " + t.start_time + " " + t.duration + "\n";
    }
    return str;
}

if (typeof require !== 'undefined' && require.main === module) {
    function usage() {
        console.log("node tasks.js read TASK_FILE");
        console.log("node tasks.js write TASK_FILE tasks start duration [start_max [duration_max]]");
        process.exit(2);
    }
    // we are being run directly so load the file specified and print
    // the data from the file
    if (process.argv.length < 3) { usage(); }

    var fs = require('fs');
    var mode = process.argv[2].toLowerCase();
    var fileName = process.argv[3];

    switch (mode) {
    case 'read':
        var data = fs.readFileSync(fileName, 'utf8');
        var tasks = parseTasks(data);
        console.log(tasks);
        break;
    case 'write':
        var no_tasks = parseInt(process.argv[4],10),
            start = parseInt(process.argv[5],10),
            duration = parseInt(process.argv[6],10),
            start_max, duration_max;
        if (process.argv.length > 7) {
            start_max = parseInt(process.argv[7],10);
        }
        if (process.argv.length > 8) {
            duration_max = parseInt(process.argv[8],10);
        }
        var tstr = tasksToString(generateTasks(no_tasks,
                                               start,
                                               duration,
                                               start_max,
                                               duration_max));
        fs.writeFileSync(fileName, tstr);
        break;
    default:
        usage();
    }
} else {
    // we are being required as a module so export the parseTasks
    // function
    exports.parseTasks = parseTasks;
    exports.generateTasks = generateTasks;
    exports.tasksToString = tasksToString;
}
<commit_msg>Remove shebang from tasks.js<commit_after>// Node vs browser behavior
if (typeof module === 'undefined') {
    var tasks = {},
        exports = tasks;
}

// parseTasks: takes a string with the contents of a task file and
// parses it. Returns an object/hashmap containing num_of_tasks,
// total_time and task_queue.
function parseTasks (data) {
    var input=data.split('\n');
    var line1 = input[0].split(' ');
    // First line has num_of_tasks and total_time
    var num_of_tasks=parseInt(line1[0], 10);
    var total_time=parseInt(line1[1], 10);

    // read in the tasks
    var queue= [];

    for(var j=1; j <= num_of_tasks; j++) {
        var task_data=input[j].split(' ');
        // Create a new task object and add it to the queue
        var task = {id         :          task_data[0],
                    start_time : parseInt(task_data[1], 10),
                    duration   : parseInt(task_data[2], 10)};
        queue.push(task);
    }

    // Numeric sort the task queue by the start_time attribute
    function sort_function (a, b) {
        return a.start_time - b.start_time;
    }
    queue.sort(sort_function);

    return {num_of_tasks: num_of_tasks,
            total_time:   total_time,
            task_queue:   queue};
}

// generateTasks: generate n tasks that each start at time 1 and all
// run for duration
function generateTasks (n, start, duration, start_max, duration_max) {
    if (typeof start_max === 'undefined') {
        start_max = start;
    }
    if (typeof duration_max === 'undefined') {
        duration_max = duration;
    }
    var queue = [], total_duration = 0;
    for (var i=0; i<n; i++) {
        var stime = Math.floor(Math.random()*(start_max-start+1)+start),
            dur = Math.floor(Math.random()*(duration_max-duration+1)+duration);
        total_duration += dur;
        var task = {id: "t" + (i+1),
                    start_time: stime,
                    duration: dur};
        queue.push(task);
    }
    return {num_of_tasks: n,
            total_time: total_duration+1,
            task_queue: queue};
}

function tasksToString(tasks) {
    var str = tasks.num_of_tasks + " " + tasks.total_time + "\n";
    for (var i=0; i < tasks.task_queue.length; i++) {
        var t = tasks.task_queue[i];
        str += t.id + " " + t.start_time + " " + t.duration + "\n";
    }
    return str;
}

if (typeof require !== 'undefined' && require.main === module) {
    function usage() {
        console.log("node tasks.js read TASK_FILE");
        console.log("node tasks.js write TASK_FILE tasks start duration [start_max [duration_max]]");
        process.exit(2);
    }
    // we are being run directly so load the file specified and print
    // the data from the file
    if (process.argv.length < 3) { usage(); }

    var fs = require('fs');
    var mode = process.argv[2].toLowerCase();
    var fileName = process.argv[3];

    switch (mode) {
    case 'read':
        var data = fs.readFileSync(fileName, 'utf8');
        var tasks = parseTasks(data);
        console.log(tasks);
        break;
    case 'write':
        var no_tasks = parseInt(process.argv[4],10),
            start = parseInt(process.argv[5],10),
            duration = parseInt(process.argv[6],10),
            start_max, duration_max;
        if (process.argv.length > 7) {
            start_max = parseInt(process.argv[7],10);
        }
        if (process.argv.length > 8) {
            duration_max = parseInt(process.argv[8],10);
        }
        var tstr = tasksToString(generateTasks(no_tasks,
                                               start,
                                               duration,
                                               start_max,
                                               duration_max));
        fs.writeFileSync(fileName, tstr);
        break;
    default:
        usage();
    }
} else {
    // we are being required as a module so export the parseTasks
    // function
    exports.parseTasks = parseTasks;
    exports.generateTasks = generateTasks;
    exports.tasksToString = tasksToString;
}
<|endoftext|>


<commit_before>// @flow

import * as React from 'react'
import {StyleSheet, View, Animated, Dimensions, Platform} from 'react-native'
import {TabBarIcon} from '../../components/tabbar-icon'
import * as c from '../../components/colors'
import {CourseSearchBar} from '../components/searchbar'
import debounce from 'lodash/debounce'
import {updateCourseData} from '../../../flux/parts/sis'
import type {CourseType} from '../../../lib/course-search'
import type {ReduxState} from '../../../flux'
import type {TopLevelViewPropsType} from '../../types'
import {connect} from 'react-redux'
import groupBy from 'lodash/groupBy'
import sortBy from 'lodash/sortBy'
import toPairs from 'lodash/toPairs'
import {CourseSearchResultsList} from './list'

type ReactProps = TopLevelViewPropsType

type ReduxStateProps = {
	allCourses: Array<CourseType>,
	courseDataState: string,
}

type ReduxDispatchProps = {
	updateCourseData: () => any,
}

type Props = ReactProps &
	ReduxStateProps &
	ReduxDispatchProps & {
		navigation: {state: {params: {}}},
	}

type State = {
	searchResults: Array<{title: string, data: Array<CourseType>}>,
	searchActive: boolean,
}

class CourseSearchView extends React.PureComponent<Props, State> {
	static navigationOptions = {
		tabBarLabel: 'Course Search',
		tabBarIcon: TabBarIcon('search'),
		title: 'SIS',
	}

	state = {
		searchResults: [],
		searchActive: false,
	}

	componentDidMount() {
		this.props.updateCourseData()
	}

	searchBar: any = null
	headerOpacity = new Animated.Value(1)
	searchBarTop = new Animated.Value(71)
	containerHeight = new Animated.Value(125)

	_performSearch = (text: string | Object) => {
		// Android clear button returns an object
		// if (typeof text !== 'string') {
		// 	return this.props.onSearch(null)
		// }
		const query = text.toLowerCase()
		let results = this.props.allCourses.filter(course => {
			const section = course.section ? course.section.toLowerCase() : ''
			return (
				course.name.toLowerCase().includes(query) ||
				(course.instructors || []).some(name =>
					name.toLowerCase().includes(query),
				) ||
				`${course.departments
					.join('/')
					.toLowerCase()} ${course.number.toString()}${section}`.startsWith(
					query,
				)
			)
		})

		let grouped = groupBy(results, r => r.term)
		let groupedCourses = toPairs(grouped).map(([key, value]) => ({
			title: key,
			data: value,
		}))
		let sortedCourses = sortBy(groupedCourses, course => course.title).reverse()
		this.setState({searchResults: sortedCourses})
	}

	// We need to make the search run slightly behind the UI,
	// so I'm slowing it down by 50ms. 0ms also works, but seems
	// rather pointless.
	performSearch = debounce(this._performSearch, 50)

	onFocus = () => {
		Animated.timing(this.headerOpacity, {
			toValue: 0,
			duration: 800,
		}).start()
		Animated.timing(this.searchBarTop, {
			toValue: 10,
			duration: 800,
		}).start()
		Animated.timing(this.containerHeight, {
			toValue: 64,
			duration: 800,
		}).start()
		this.setState(() => ({searchActive: true}))
	}

	onCancel = () => {
		Animated.timing(this.headerOpacity, {
			toValue: 1,
			duration: 800,
		}).start()
		Animated.timing(this.searchBarTop, {
			toValue: 71,
			duration: 800,
		}).start()
		Animated.timing(this.containerHeight, {
			toValue: 125,
			duration: 800,
		}).start()
		this.setState(() => ({searchActive: false}))
	}

	render() {
		const screenWidth = Dimensions.get('window').width
		const searchBarWidth = screenWidth - 20
		const headerAnimation = {opacity: this.headerOpacity}
		const searchBarAnimation = {
			top: this.searchBarTop,
		}
		const containerAnimation = {height: this.containerHeight}
		const {searchActive} = this.state

		return (
			<View style={styles.container}>
				<Animated.View
					style={[styles.searchContainer, styles.common, containerAnimation]}
				>
					<Animated.Text style={[styles.header, headerAnimation]}>
						Search Courses
					</Animated.Text>
					<Animated.View
						style={[
							styles.searchBarWrapper,
							{width: searchBarWidth},
							searchBarAnimation,
						]}
					>
						<CourseSearchBar
							getRef={ref => (this.searchBar = ref)}
							onCancel={this.onCancel}
							onFocus={this.onFocus}
							onSearchButtonPress={text => {
								if (Platform.OS === 'ios') {
									this.searchBar.blur()
								}
								this.performSearch(text)
							}}
							searchActive={searchActive}
						/>
					</Animated.View>
				</Animated.View>
				{searchActive ? (
					<CourseSearchResultsList
						navigation={this.props.navigation}
						terms={this.state.searchResults}
					/>
				) : (
					<View />
				)}
			</View>
		)
	}
}

function mapState(state: ReduxState): ReduxStateProps {
	return {
		allCourses: state.sis ? state.sis.allCourses : [],
		courseDataState: state.sis ? state.sis.courseDataState : '',
	}
}

function mapDispatch(dispatch): ReduxDispatchProps {
	return {
		updateCourseData: () => dispatch(updateCourseData()),
	}
}

export default connect(mapState, mapDispatch)(CourseSearchView)

let styles = StyleSheet.create({
	container: {
		flex: 1,
	},

	common: {
		backgroundColor: c.white,
	},

	searchContainer: {
		margin: 0,
	},

	searchBarWrapper: {
		position: 'absolute',
		left: 10,
	},

	header: {
		fontSize: 30,
		fontWeight: 'bold',
		padding: 22,
		paddingLeft: 17,
	},
})
<commit_msg>added loading view to course search<commit_after>// @flow

import * as React from 'react'
import {StyleSheet, View, Animated, Dimensions, Platform} from 'react-native'
import {TabBarIcon} from '../../components/tabbar-icon'
import * as c from '../../components/colors'
import {CourseSearchBar} from '../components/searchbar'
import debounce from 'lodash/debounce'
import {updateCourseData} from '../../../flux/parts/sis'
import type {CourseType} from '../../../lib/course-search'
import type {ReduxState} from '../../../flux'
import type {TopLevelViewPropsType} from '../../types'
import {connect} from 'react-redux'
import groupBy from 'lodash/groupBy'
import sortBy from 'lodash/sortBy'
import toPairs from 'lodash/toPairs'
import {CourseSearchResultsList} from './list'
import LoadingView from '../../components/loading'

type ReactProps = TopLevelViewPropsType

type ReduxStateProps = {
	allCourses: Array<CourseType>,
	courseDataState: string,
}

type ReduxDispatchProps = {
	updateCourseData: () => any,
}

type Props = ReactProps &
	ReduxStateProps &
	ReduxDispatchProps & {
		navigation: {state: {params: {}}},
	}

type State = {
	searchResults: Array<{title: string, data: Array<CourseType>}>,
	searchActive: boolean,
}

class CourseSearchView extends React.PureComponent<Props, State> {
	static navigationOptions = {
		tabBarLabel: 'Course Search',
		tabBarIcon: TabBarIcon('search'),
		title: 'SIS',
	}

	state = {
		searchResults: [],
		searchActive: false,
	}

	componentDidMount() {
		this.props.updateCourseData()
	}

	searchBar: any = null
	headerOpacity = new Animated.Value(1)
	searchBarTop = new Animated.Value(71)
	containerHeight = new Animated.Value(125)

	_performSearch = (text: string | Object) => {
		// Android clear button returns an object
		// if (typeof text !== 'string') {
		// 	return this.props.onSearch(null)
		// }
		const query = text.toLowerCase()
		let results = this.props.allCourses.filter(course => {
			const section = course.section ? course.section.toLowerCase() : ''
			return (
				course.name.toLowerCase().includes(query) ||
				(course.instructors || []).some(name =>
					name.toLowerCase().includes(query),
				) ||
				`${course.departments
					.join('/')
					.toLowerCase()} ${course.number.toString()}${section}`.startsWith(
					query,
				)
			)
		})

		let grouped = groupBy(results, r => r.term)
		let groupedCourses = toPairs(grouped).map(([key, value]) => ({
			title: key,
			data: value,
		}))
		let sortedCourses = sortBy(groupedCourses, course => course.title).reverse()
		this.setState({searchResults: sortedCourses})
	}

	// We need to make the search run slightly behind the UI,
	// so I'm slowing it down by 50ms. 0ms also works, but seems
	// rather pointless.
	performSearch = debounce(this._performSearch, 50)

	onFocus = () => {
		Animated.timing(this.headerOpacity, {
			toValue: 0,
			duration: 800,
		}).start()
		Animated.timing(this.searchBarTop, {
			toValue: 10,
			duration: 800,
		}).start()
		Animated.timing(this.containerHeight, {
			toValue: 64,
			duration: 800,
		}).start()
		this.setState(() => ({searchActive: true}))
	}

	onCancel = () => {
		Animated.timing(this.headerOpacity, {
			toValue: 1,
			duration: 800,
		}).start()
		Animated.timing(this.searchBarTop, {
			toValue: 71,
			duration: 800,
		}).start()
		Animated.timing(this.containerHeight, {
			toValue: 125,
			duration: 800,
		}).start()
		this.setState(() => ({searchActive: false}))
	}

	render() {
		const screenWidth = Dimensions.get('window').width
		const searchBarWidth = screenWidth - 20
		const headerAnimation = {opacity: this.headerOpacity}
		const searchBarAnimation = {
			top: this.searchBarTop,
		}
		const containerAnimation = {height: this.containerHeight}
		const {searchActive} = this.state
		const loading = this.props.courseDataState === 'updating'
		if (loading) {
			return (<LoadingView text="Loading Course Data..." />)
		}

		return (
			<View style={styles.container}>
				<Animated.View
					style={[styles.searchContainer, styles.common, containerAnimation]}
				>
					<Animated.Text style={[styles.header, headerAnimation]}>
						Search Courses
					</Animated.Text>
					<Animated.View
						style={[
							styles.searchBarWrapper,
							{width: searchBarWidth},
							searchBarAnimation,
						]}
					>
						<CourseSearchBar
							getRef={ref => (this.searchBar = ref)}
							onCancel={this.onCancel}
							onFocus={this.onFocus}
							onSearchButtonPress={text => {
								if (Platform.OS === 'ios') {
									this.searchBar.blur()
								}
								this.performSearch(text)
							}}
							searchActive={searchActive}
						/>
					</Animated.View>
				</Animated.View>
				{searchActive ? (
					<CourseSearchResultsList
						navigation={this.props.navigation}
						terms={this.state.searchResults}
					/>
				) : (
					<View />
				)}
			</View>
		)
	}
}

function mapState(state: ReduxState): ReduxStateProps {
	return {
		allCourses: state.sis ? state.sis.allCourses : [],
		courseDataState: state.sis ? state.sis.courseDataState : '',
	}
}

function mapDispatch(dispatch): ReduxDispatchProps {
	return {
		updateCourseData: () => dispatch(updateCourseData()),
	}
}

export default connect(mapState, mapDispatch)(CourseSearchView)

let styles = StyleSheet.create({
	container: {
		flex: 1,
	},

	common: {
		backgroundColor: c.white,
	},

	searchContainer: {
		margin: 0,
	},

	searchBarWrapper: {
		position: 'absolute',
		left: 10,
	},

	header: {
		fontSize: 30,
		fontWeight: 'bold',
		padding: 22,
		paddingLeft: 17,
	},
})
<|endoftext|>


<commit_before>/* exported restApiFactory */
'use strict';

function restApiFactory($resource) {
    return {
        createSurveyDraftApi: function (id) {
            var customMethods = {};
            id = id === 'new' ? null : id;
            if (id === null) {
                return $resource('/api/survey_drafts', {}, {
                    save: { method: 'POST' }
                });
            } else {
                return $resource('/api/survey_drafts/:id', { id: id }, {
                    save: { method: 'PATCH' }
                });
            }

        },
        create_question_api: function () {
            return $resource('/api/library_assets');
        }
    };
}<commit_msg>more concise use of "id" in the restApi.Factory<commit_after>/* exported restApiFactory */
'use strict';

function restApiFactory($resource) {
    return {
        createSurveyDraftApi: function (id) {
            var customMethods = {};
            if (id === 'new') {
                return $resource('/api/survey_drafts', {}, {
                    save: { method: 'POST' }
                });
            } else {
                return $resource('/api/survey_drafts/:id', { id: id }, {
                    save: { method: 'PATCH' }
                });
            }

        },
        create_question_api: function () {
            return $resource('/api/library_assets');
        }
    };
}<|endoftext|>


<commit_before>const PLAYER_SPEED = 6.5
const PLAYER_SCALE = 1
const PLAYER_SHOOT_DELAY = 22

function Player() {
  this.x = 300
  this.y = 300
  this.nextX = 0
  this.nextY = 0
  this.velX = 0
  this.velY = 0
  this.shootTimer = 0
  // 0 Top 1 Right 2 Bottom 3 left
  this.dir = 0

  this.img

  this.goingUp = false
  this.goingRight = false
  this.goingDown = false
  this.goingLeft = false

  this.goingUpKey
  this.goingRightKey
  this.goingDownKey
  this.goingLeftKey
  this.shootKey

  this.init = function (img) {
    this.img = img
  }

  this.setupInput = function (upKey, downKey, rightKey, leftKey, shootKey) {
    this.goingUpKey = upKey
    this.goingRightKey = rightKey
    this.goingDownKey = downKey
    this.goingLeftKey = leftKey
    this.shootKey = shootKey
  }

  this.getBundingBox = function (face) {
    // 0 Top 1 Bottom 2 Left 3 Right
    //  + (this.img.height * PLAYER_SCALE)  + (this.img.width * PLAYER_SCALE)

    if (face == 0) {
      return [this.nextX+ (this.img.width * PLAYER_SCALE) / 2,this.nextY]

    } else if (face == 1) {
      return [this.nextX + (this.img.width * PLAYER_SCALE) / 2,this.nextY + (this.img.height * PLAYER_SCALE)]

    } else if (face == 2) {
      return [this.nextX,this.nextY + (this.img.height * PLAYER_SCALE)/2]

    } else if (face == 3) {
      return [this.nextX + (this.img.width * PLAYER_SCALE),this.nextY + (this.img.height * PLAYER_SCALE)/2]
    }
  }

  this.move = function () {

    this.nextX = this.x
    this.nextY = this.y

    if (this.goingUp) {
      this.nextY -= PLAYER_SPEED
      this.dir = 0
    }
    if (this.goingRight) {
      this.nextX += PLAYER_SPEED
      this.dir = 1
    }
    if (this.goingDown) {
      this.nextY += PLAYER_SPEED
      this.dir = 2
    }
    if (this.goingLeft) {
      this.nextX -= PLAYER_SPEED
      this.dir = 3
    }

    this.handleCollision()
    if (this.shootTimer > 0) {
      this.shootTimer--
    }
  }

    this.shoot = function () {
      if (this.shootTimer == 0) {
        switch (this.dir) {
          case 0:
            var angle = Math.radians(-90)
            bulletManager.createBullet(this.x, this.y, 33, angle)
            this.shootTimer = PLAYER_SHOOT_DELAY
            break;
          case 1:
            var angle = Math.radians(0)
            bulletManager.createBullet(this.x, this.y, 33, angle)
            this.shootTimer = PLAYER_SHOOT_DELAY
            break;
          case 2:
            var angle = Math.radians(90)
            bulletManager.createBullet(this.x, this.y, 33, angle)
            this.shootTimer = PLAYER_SHOOT_DELAY
            break;
          case 3:
            var angle = Math.radians(180)
            bulletManager.createBullet(this.x, this.y, 33, angle)
            this.shootTimer = PLAYER_SHOOT_DELAY
            break;
          default:
        }

      }
    }

    this.handleCollision = function () {
      var walkingIntoTileIndex = mapHandler.getTileAtPixelCoord(this.nextX,this.nextY)
      var walkingIntoTileType = MAP_WALL
      if (walkingIntoTileIndex != undefined) {
        walkingIntoTileType = mapGrid[walkingIntoTileIndex]
      }

      switch (walkingIntoTileType) {
        case MAP_FLOOR:
          this.x = this.nextX
          this.y = this.nextY
          break;
      }
      //Faces = 3
      /*
      var hitPoints = []
      for (var i = 0; i < 3; i++) {
        var face = this.getBundingBox(i)
        //console.log(face);

        var walkingIntoTileIndex = mapHandler.getTileAtPixelCoord(face[0],face[1])
        var walkingIntoTileType = MAP_WALL
        if (walkingIntoTileIndex != undefined) {
          walkingIntoTileType = mapGrid[walkingIntoTileIndex]
        }
        if (mapHandler.isTileSoild(walkingIntoTileType)) {
          hitPoints.push(i)
        }
    }
    this.checkIfCollidedWithTile(hitPoints)
    */
  }
  /*
  this.checkIfCollidedWithTile = function (hitPoints) {
    if (!hitPoints.length == 0) {
      for (var i = 0; i < hitPoints.length; i++) {
        switch (hitPoints[i]) {
          case 0:
            this.x = this.nextX
            break;
          case 1:
            this.x = this.nextX
            break;
          case 2:
            this.y = this.nextY
            break;
          case 3:
            this.y = this.nextY
        }
      }
    } else {
      this.x = this.nextX
      this.y = this.nextY
    }
  }*/

  this.draw = function () {
    drawBitMapCenteredWithScale(this.img, this.x, this.y, PLAYER_SCALE)
  }
}
<commit_msg>Removed player scale<commit_after>const PLAYER_SPEED = 6.5
const PLAYER_SCALE = 1
const PLAYER_SHOOT_DELAY = 22

function Player() {
  this.x = 300
  this.y = 300
  this.nextX = 0
  this.nextY = 0
  this.velX = 0
  this.velY = 0
  this.shootTimer = 0
  // 0 Top 1 Right 2 Bottom 3 left
  this.dir = 0

  this.img

  this.goingUp = false
  this.goingRight = false
  this.goingDown = false
  this.goingLeft = false

  this.goingUpKey
  this.goingRightKey
  this.goingDownKey
  this.goingLeftKey
  this.shootKey

  this.init = function (img) {
    this.img = img
  }

  this.setupInput = function (upKey, downKey, rightKey, leftKey, shootKey) {
    this.goingUpKey = upKey
    this.goingRightKey = rightKey
    this.goingDownKey = downKey
    this.goingLeftKey = leftKey
    this.shootKey = shootKey
  }

  this.getBundingBox = function (face) {
    // 0 Top 1 Bottom 2 Left 3 Right
    //  + (this.img.height * PLAYER_SCALE)  + (this.img.width * PLAYER_SCALE)

    if (face == 0) {
      return [this.nextX+ (this.img.width * PLAYER_SCALE) / 2,this.nextY]

    } else if (face == 1) {
      return [this.nextX + (this.img.width * PLAYER_SCALE) / 2,this.nextY + (this.img.height * PLAYER_SCALE)]

    } else if (face == 2) {
      return [this.nextX,this.nextY + (this.img.height * PLAYER_SCALE)/2]

    } else if (face == 3) {
      return [this.nextX + (this.img.width * PLAYER_SCALE),this.nextY + (this.img.height * PLAYER_SCALE)/2]
    }
  }

  this.move = function () {

    this.nextX = this.x
    this.nextY = this.y

    if (this.goingUp) {
      this.nextY -= PLAYER_SPEED
      this.dir = 0
    }
    if (this.goingRight) {
      this.nextX += PLAYER_SPEED
      this.dir = 1
    }
    if (this.goingDown) {
      this.nextY += PLAYER_SPEED
      this.dir = 2
    }
    if (this.goingLeft) {
      this.nextX -= PLAYER_SPEED
      this.dir = 3
    }

    this.handleCollision()
    if (this.shootTimer > 0) {
      this.shootTimer--
    }
  }

    this.shoot = function () {
      if (this.shootTimer == 0) {
        switch (this.dir) {
          case 0:
            var angle = Math.radians(-90)
            bulletManager.createBullet(this.x, this.y, 33, angle)
            this.shootTimer = PLAYER_SHOOT_DELAY
            break;
          case 1:
            var angle = Math.radians(0)
            bulletManager.createBullet(this.x, this.y, 33, angle)
            this.shootTimer = PLAYER_SHOOT_DELAY
            break;
          case 2:
            var angle = Math.radians(90)
            bulletManager.createBullet(this.x, this.y, 33, angle)
            this.shootTimer = PLAYER_SHOOT_DELAY
            break;
          case 3:
            var angle = Math.radians(180)
            bulletManager.createBullet(this.x, this.y, 33, angle)
            this.shootTimer = PLAYER_SHOOT_DELAY
            break;
          default:
        }

      }
    }

    this.handleCollision = function () {
      var walkingIntoTileIndex = mapHandler.getTileAtPixelCoord(this.nextX,this.nextY)
      var walkingIntoTileType = MAP_WALL
      if (walkingIntoTileIndex != undefined) {
        walkingIntoTileType = mapGrid[walkingIntoTileIndex]
      }

      switch (walkingIntoTileType) {
        case MAP_FLOOR:
          this.x = this.nextX
          this.y = this.nextY
          break;
      }
      //Faces = 3
      /*
      var hitPoints = []
      for (var i = 0; i < 3; i++) {
        var face = this.getBundingBox(i)
        //console.log(face);

        var walkingIntoTileIndex = mapHandler.getTileAtPixelCoord(face[0],face[1])
        var walkingIntoTileType = MAP_WALL
        if (walkingIntoTileIndex != undefined) {
          walkingIntoTileType = mapGrid[walkingIntoTileIndex]
        }
        if (mapHandler.isTileSoild(walkingIntoTileType)) {
          hitPoints.push(i)
        }
    }
    this.checkIfCollidedWithTile(hitPoints)
    */
  }
  /*
  this.checkIfCollidedWithTile = function (hitPoints) {
    if (!hitPoints.length == 0) {
      for (var i = 0; i < hitPoints.length; i++) {
        switch (hitPoints[i]) {
          case 0:
            this.x = this.nextX
            break;
          case 1:
            this.x = this.nextX
            break;
          case 2:
            this.y = this.nextY
            break;
          case 3:
            this.y = this.nextY
        }
      }
    } else {
      this.x = this.nextX
      this.y = this.nextY
    }
  }*/

  this.draw = function () {
    //drawBitMapCenteredWithScale(this.img, this.x, this.y, PLAYER_SCALE)
    ctx.drawImage(this.img, this.x, this.y)
  }
}
<|endoftext|>