Source: src/main/javascript/oracle/oj/ojcomponentcore/jqueryui-base.js

Oracle® JavaScript Extension Toolkit (JET)
1.1.2

E65298-01

/**
 * Copyright (c) 2014, Oracle and/or its affiliates.
 * All rights reserved.
 */

/*jslint browser: true*/

/**
 * @private
 */
var _BASE_COMPONENT = 'baseComponent';
  
/**
 * @ojcomponent oj.baseComponent
 * @abstract
 * @since 0.6
 */
$.widget('oj.' + _BASE_COMPONENT, 
{
  options:
  {
    /**
     * <p>JQ selector identifying the JET Menu that the component should launch as a context menu on right-click, <kbd>Shift-F10</kbd>, <kbd>Press & Hold</kbd>, 
     * or component-specific gesture. If specified, the browser's native context menu will be replaced by the specified JET Menu.
     *
     * <p>To specify a JET context menu on a DOM element that is not a JET component, see the <code class="prettyprint">ojContextMenu</code> binding.
     *
     * <p>To make the page semantically accurate from the outset, applications are encouraged to specify the context menu via the standard
     * HTML5 syntax shown in the below example.  When the component is initialized, the context menu thus specified will be set on the component.
     *
     * <p>After create time, the <code class="prettyprint">contextMenu</code> option should be set via this API, not by setting the DOM attribute.  
     *
     * @expose
     * @memberof oj.baseComponent
     * @instance
     * @type {Object}
     * @default <code class="prettyprint">null</code>
     *
     * @example <caption>Initialize a JET component with a context menu:</caption>
     * // via recommended HTML5 syntax:
     * <div id="myComponent" contextmenu="myMenu" data-bind="ojComponent: { ... }>
     *
     * // via JET initializer (less preferred) :
     * // Foo is the component, e.g., InputText, InputNumber, Select, etc.
     * $( ".selector" ).ojFoo({ "contextMenu": "#myMenu" });
     *
     * @example <caption>Get or set the <code class="prettyprint">contextMenu</code> option, after initialization:</caption>
     * // getter
     * // Foo is the component, e.g., Menu, Button, InputText, InputNumber, Select, etc.
     * var menu = $( ".selector" ).ojFoo( "option", "contextMenu" );
     *
     * // setter
     * // Foo is the component, e.g., InputText, InputNumber, Select, etc.
     * $( ".selector" ).ojFoo( "option", "contextMenu", ".my-marker-class" );
     *
     * @example <caption>Set a JET context menu on an ordinary HTML element:</caption>
     * <a href="#" id="myAnchor" contextmenu="myMenu" data-bind="ojContextMenu: {}">Some text</a>
     */
    contextMenu: null,

    /**
     * <p>Attributes specified here will be set on the component's root DOM element at creation time.
     * This is particularly useful for components like Dialog that wrap themselves in a new root element
     * at creation time.
     *
     * <p>The supported attributes are <code class="prettyprint">id</code>, which overwrites any existing value,
     * and <code class="prettyprint">class</code> and <code class="prettyprint">style</code>, which are appended
     * to the current class and style, if any.
     *
     * <p>Setting this option after component creation has no effect.  At that time, the root element already 
     * exists, and can be accessed directly via the <code class="prettyprint">widget</code> method, per the second example below.
     *
     * @example <caption>Initialize a JET component, specifying a set of attributes to be set
     * on the component's root DOM element:</caption>
     * // Foo is the component, e.g., Menu, Button, InputText, InputNumber, Select, etc.
     * $( ".selector" ).ojFoo({ "rootAttributes": {
     *   "id": "myId",
     *   "style": "max-width:100%; color:blue;",
     *   "class": "my-class"
     * }});
     *
     * @example <caption>After initialization, <code class="prettyprint">rootAttributes</code> should not be used.  It is 
     * not needed at that time, as attributes of the root DOM element can simply be set directly, using 
     * <code class="prettyprint">widget</code>:</caption>
     * // Foo is the component, e.g., Menu, Button, InputText, InputNumber, Select, etc.
     * $( ".selector" ).ojFoo( "widget" ).css( "height", "100px" );
     * $( ".selector" ).ojFoo( "widget" ).addClass( "my-class" );
     *
     * @expose
     * @memberof oj.baseComponent
     * @instance
     * @type {?Object}
     * @default <code class="prettyprint">null</code>
     */
    rootAttributes: null,

    /**
     * <p>A collection of translated resources from the translation bundle, or <code class="prettyprint">null</code> if this
     * component has no resources.  Resources may be accessed and overridden individually or collectively, as seen in the examples.
     *
     * <p>If this component has (or inherits) translations, their documentation immediately follows this doc entry.
     *
     * @member
     * @name translations
     * @memberof oj.baseComponent
     * @instance
     * @type {Object}
     * @default an object containing all resources relevant to the component and all its superclasses, or <code class="prettyprint">null</code> if none
     *
     * @example <caption>Initialize the component, overriding some translated resources.  This syntax leaves the other translations intact at create
     * time, but not if called after create time:</caption>
     * // Foo is InputDate, InputNumber, etc.
     * $( ".selector" ).ojFoo({ "translations": { someKey: "someValue",
     *                                            someOtherKey: "someOtherValue" } });
     *
     * @example <caption>Get or set the <code class="prettyprint">translations</code> option, after initialization:</caption>
     * // Get one.  (Foo is InputDate, InputNumber, etc.)
     * var value = $( ".selector" ).ojFoo( "option", "translations.someResourceKey" );
     *
     * // Get all.  (Foo is InputDate, InputNumber, etc.)
     * var values = $( ".selector" ).ojFoo( "option", "translations" );
     *
     * // Set one, leaving the others intact.  (Foo is InputDate, InputNumber, etc.)
     * $( ".selector" ).ojFoo( "option", "translations.someResourceKey", "someValue" );
     *
     * // Set many.  Any existing resource keys not listed are lost.  (Foo is InputDate, InputNumber, etc.)
     * $( ".selector" ).ojFoo( "option", "translations", { someKey: "someValue",
     *                                                     someOtherKey: "someOtherValue" } );
     *
     */
    // translations option is initialized programmatically, so this top-level API doc lives in this virtual comment.
    // Translations for all components are listed and JSDoc'ed in rt\src\main\resources\nls\root\ojtranslations.js.
    // That JSDoc appears in the same generated doc page as this top-level doc.


    // Events
    /**
     * <p>Triggered when any option changes. The event payload has the following properties:
     *
     * @property {Event} event <code class="prettyprint">jQuery</code> event object
     * @property {Object} data event payload
     * @property {string} data.option the name of the option that changed.
     * @property {Object} data.previousValue - an Object holding the previous value of the option.
     * When previousValue is not a primitive type, i.e., is an Object, it may hold the same value as
     * the value property.
     * @property {Object} data.value - an Object holding the current value of the option.
     * @property {Object} data.optionMetadata information about the option that changed
     * @property {string} data.optionMetadata.writeback <code class="prettyprint">"shouldWrite"</code> or
     *  <code class="prettyprint">"shouldNotWrite"</code>. For use by the JET writeback mechanism;
     *  'shouldWrite' indicates that the value should be written to the observable.
     *
     * @example <caption>Initialize component with the <code class="prettyprint">optionChange</code> callback</caption>
     * // Foo is Button, InputText, etc.
     * $(".selector").ojFoo({
     *   'optionChange': function (event, data) {}
     * });
     * @example <caption>Bind an event listener to the ojoptionchange event</caption>
     * $(".selector").on({
     *   'ojoptionchange': function (event, data) {
     *       window.console.log("option that changed is: " + data['option']);
     *   };
     * });
     *
     * @memberof oj.baseComponent
     * @expose
     * @event
     * @instance
     */
    optionChange: undefined,

    /**
     * <p>Triggered before the component is destroyed. This event cannot be canceled; the
     * component will always be destroyed regardless.
     *
     * @example <caption>Initialize component with the <code class="prettyprint">destroy</code> callback</caption>
     * // Foo is Button, InputText, etc.
     * $(".selector").ojFoo({
     *   'destroy': function (event, data) {}
     * });
     * @example <caption>Bind an event listener to the destroy event</caption>
     * $(".selector").on({
     *   'ojdestroy': function (event, data) {
     *       window.console.log("The DOM node id for the destroyed component is : %s", event.target.id);
     *   };
     * });
     *
     * @memberof oj.baseComponent
     * @expose
     * @event
     * @instance
     */
    destroy: undefined
  },

  // TODO: flesh out JSDoc verbiage, re: call after dom changes underneath component...
  /**
   * <p>Refreshes the component.
   *
   * @expose
   * @memberof oj.baseComponent
   * @instance
   */
  refresh: function()
  {
    this._propertyContext = null;
  },

  /**
   * <p>Overridden to save off component's default options and the options passed into the constructor (to be passed into
   * the _InitOptions() call).
   * 
   * <p>This method is final. Components should instead override one or more of the overridable create-time methods
   * listed in <a href="#_ComponentCreate">_ComponentCreate</a>.
   * 
   * @memberof oj.baseComponent
   * @instance
   * @private
   * @final
   */
  _createWidget: function(options, element)
  {
    // There is no need to clone these objects since they are not modified by the _createWidget() in the base class
    this._originalDefaults = this.options || {};
    this._constructorOptions = options || {};

    this._super(options, element);
    this._AfterCreateEvent();
  },

  /**
   * <p>Reads the <code class="prettyprint">rootAttributes</code> option, and sets the root attributes on the
   * component's root DOM element.  See <a href="#rootAttributes">rootAttributes</a> for the set of supported
   * attributes and how they are handled.
   *
   * @memberof oj.baseComponent
   * @instance
   * @protected
   * @throws if unsupported attributes are supplied.
   */
  _SetRootAttributes : function ()
  {
    var value = this.options.rootAttributes;
    if (value)
    {
      var widget = this.widget();
      if (widget == null)
        return;

      var classValue = value["class"];

      if (classValue)
      {
        widget.addClass(classValue);
      }

      var styleValue = value["style"];

      if (styleValue)
      {
        var currStyle = widget.attr('style');

        if (currStyle)
        {
          widget.attr('style', currStyle + ';' + styleValue);
        }
        else
        {
          widget.attr('style', styleValue);
        }
      }

      // make shallow copy, remove class and style from the copy, and set all
      // remaining attrs on the element.  Currently id is the only remaining attr
      // that we support.
      value = $.extend({}, value);
      delete value['class'];
      delete value['style'];

      widget.attr(value);

      delete value['id']; // remove the remaining supported value
      var unsupportedAttrs = Object.keys(value);
      if (unsupportedAttrs.length)
        throw new Error("Unsupported values passed to rootAttributes option: " + unsupportedAttrs.toString());
    }
  },

  /**
   * <p>This method is final in JET. Components should instead override one or more of the overridable create-time methods
   * listed in <a href="#_ComponentCreate">_ComponentCreate</a>.
   * 
   * @memberof oj.baseComponent
   * @instance
   * @protected
   * @final
   */
  _create : function()
  {
    this._SaveAttributes(this.element);
    this._InitOptions(this._originalDefaults, this._constructorOptions);

    delete this._originalDefaults;
    delete this._constructorOptions;

    this._ComponentCreate();
    this._AfterCreate();
    
    // Marker class for all JET components on the init node (as opposed to the outer node)
    // This marker class is used to:
    // 1) find all JET components within a subtree
    // 2) to prevent FOUC:  init nodes NOT yet having this class are hidden.
    this.element.addClass(_OJ_COMPONENT_NODE_CLASS);
  },
  
  /**
   * <p>This method is not used in JET. Components should instead override <a href="#_InitOptions">_InitOptions</a>.
   * 
   * @method
   * @name oj.baseComponent#_getCreateOptions
   * @memberof oj.baseComponent
   * @instance
   * @protected
   * @final
   */

  /**
   * <p>This method is called before <a href="#_ComponentCreate">_ComponentCreate</a>, at which point 
   * the component has not yet been rendered.  Component options should be initialized in this method, 
   * so that their final values are in place when <a href="#_ComponentCreate">_ComponentCreate</a> is called.
   *
   * <p>This includes getting option values from the DOM, where applicable, and coercing option
   * values (however derived) to their appropriate data type if needed.
   * 
   * <p>No work other than setting options should be done in this method.  In particular, nothing should be 
   * set on the DOM until <a href="#_ComponentCreate">_ComponentCreate</a>, e.g. setting the <code class="prettyprint">disabled</code> 
   * DOM attribute from the <code class="prettyprint">disabled</code> option.
   * 
   * <p>A given option (like <code class="prettyprint">disabled</code>) appears in the <code class="prettyprint">constructorOptions</code> 
   * param iff the app set it in the constructor:
   * 
   * <ul>
   *   <li>If it appears in <code class="prettyprint">constructorOptions</code>, it should win over what's in the DOM 
   *     (e.g. <code class="prettyprint">disabled</code> DOM attribute).  If for some reason you need to tweak the value 
   *     that the app set, then enable writeback when doing so:
   *     <code class="prettyprint">this.option('foo', bar, {'_context': {writeback: true, internalSet: true}})</code>.</li>
   *   <li>If it doesn't appear in <code class="prettyprint">constructorOptions</code>, then that option definitely is not bound, 
   *     so writeback is not needed.  So if you need to set the option (e.g. from a DOM attribute), use 
   *     <code class="prettyprint">this.option('foo', bar, {'_context': {internalSet: true}})</code>.</li>
   * </ul>
   * 
   * <p>Overrides of this method should call <code class="prettyprint">this._super</code> first.
   * 
   * @param {!Object} originalDefaults - original default options defined on the component and its ancestors
   * @param {?Object} constructorOptions - options passed into the widget constructor
   *
   * @memberof oj.baseComponent
   * @instance
   * @protected
   */
  _InitOptions : function (originalDefaults, constructorOptions)
  {
    this._setupDefaultOptions(originalDefaults, constructorOptions);
    this._initContextMenuOption(constructorOptions);
  },

  /**
   * <p>All component create-time initialization lives in this method, except the logic that specifically
   * needs to live in <a href="#_InitOptions">_InitOptions</a>, <a href="#_AfterCreate">_AfterCreate</a>, 
   * or <a href="#_AfterCreateEvent">_AfterCreateEvent</a>,
   * per the documentation for those methods.  All DOM creation must happen here, since the intent of
   * <a href="#_AfterCreate">_AfterCreate</a>, which is called next, is to contain superclass logic that must 
   * run after that DOM is created.
   *
   * <p>Overrides of this method should call <code class="prettyprint">this._super</code> first.
   * 
   * <p>Summary of create-time methods that components can override, in the order that they are called:
   * 
   * <ol>
   *   <li><a href="#_InitOptions">_InitOptions</a></li>
   *   <li><a href="#_ComponentCreate">_ComponentCreate</a> (this method)</li>
   *   <li><a href="#_AfterCreate">_AfterCreate</a></li>
   *   <li>(The <code class="prettyprint">create</code> event is fired here.)</li>
   *   <li><a href="#_AfterCreateEvent">_AfterCreateEvent</a></li>
   * </ol>
   * 
   * <p>For all of these methods, the contract is that overrides must call <code class="prettyprint">this._super</code> <i>first</i>, so e.g., the 
   * <code class="prettyprint">_ComponentCreate</code> entry means <code class="prettyprint">baseComponent._ComponentCreate</code>, 
   * then <code class="prettyprint">_ComponentCreate</code> in any intermediate subclasses, then 
   * <code class="prettyprint">_ComponentCreate</code> in the leaf subclass.
   * 
   * @memberof oj.baseComponent
   * @instance
   * @protected
   */
  _ComponentCreate : function ()
  {
    this['activeable'] = $();

    // Store widget name, so that oj.Components.getWidgetConstructor() can get widget from the element
    _storeWidgetName(this.element, this.widgetName);
  },

  /**
   * <p>This method is called after <a href="#_ComponentCreate">_ComponentCreate</a>, but before the 
   * <code class="prettyprint">create</code> event is fired.  The JET base component does
   * tasks here that must happen after the component (subclass) has created itself in its override of
   * <a href="#_ComponentCreate">_ComponentCreate</a>.  Notably, the base component handles the
   * <a href="#rootAttributes">rootAttributes</a> and <a href="#contextMenu">contextMenu</a> options here,
   * since those options operate on the component root node, which for some components is created in their override
   * of <a href="#_ComponentCreate">_ComponentCreate</a>.
   *
   * <p>Subclasses should override this method only if they have tasks that must happen after a superclass's
   * implementation of this method, e.g. tasks that must happen after the context menu is set on the component.
   *
   * <p>Overrides of this method should call <code class="prettyprint">this._super</code> first.
   *
   * @memberof oj.baseComponent
   * @instance
   * @protected
   */
  _AfterCreate : function ()
  {
    this._SetRootAttributes(); // do first, since has no dependencies, but other stuff might care about these attrs

    // namespace facilitates removing contextMenu handlers separately, if app clears the "contextMenu" option
    this.contextMenuEventNamespace = this.eventNamespace + "contextMenu";
    this._setupContextMenu(true); 
  },

  /**
   * <p>This method is called after the <code class="prettyprint">create</code> event is fired.
   * Components usually should not override this method, as it is rarely correct to wait until after the 
   * <code class="prettyprint">create</code> event to perform a create-time task.
   * 
   * <p>An example of a correct usage of this method is [Dialog's auto-open behavior]{@link oj.ojDialog#initialVisibility}, 
   * which needs to happen after the <code class="prettyprint">create</code> event.
   * 
   * <p>Only <i>behaviors</i> (like Dialog auto-open behavior) should occur in this method.  Component <i>initialization</i>
   * must occur earlier, before the <code class="prettyprint">create</code> event is fired, so that 
   * <code class="prettyprint">create</code> listeners see a fully inited component.
   * 
   * <p>Overrides of this method should call <code class="prettyprint">this._super</code> first.
   *
   * <p>Do not confuse this method with the <a href="#_AfterCreate">_AfterCreate</a> method, which is more commonly used.
   * 
   * @method
   * @memberof oj.baseComponent
   * @instance
   * @protected
   */
  _AfterCreateEvent : $.noop,
  
  /**
   * <p>JET components should almost never implement this JQUI method.  Please consult an architect if you believe you have an exception.  Reasons:
   * <ul>
   *   <li>This method is called at create time, after the <code class="prettyprint">create</code> event is fired.  It is rare 
   *       for that to be the appropriate time to perform a create-time task.  For those rare cases, we have the 
   *       <a href="#_AfterCreateEvent">_AfterCreateEvent</a> method, which is preferred over this method since it is called only 
   *       at that time, not also at re-init time (see next).</li>
   *   <li>This method is also called at "re-init" time, i.e. when the initializer is called after the component has already been created.
   *       JET has not yet identified any desired semantics for re-initing a component.</li>
   * </ul>
   * 
   * @method
   * @name oj.baseComponent#_init
   * @memberof oj.baseComponent
   * @instance
   * @protected
   */

  /**
   * <p>Saves the element's attributes. This is called during _create.
   * <a href="#_RestoreAttributes">_RestoreAttributes</a> will restore all these attributes 
   * and is called during _destroy.
   * </p>
   * <p> This base class default implementation does nothing. 
   * </p>
   * <p>We also have <a href="#_SaveAllAttributes">_SaveAllAttributes</a> and 
   * <a href="#_RestoreAllAttributes">_RestoreAllAttributes</a> methods
   *  that save and restore <i>all</i> the attributes on an element.
   *  Component subclasses can opt into these _SaveAllAttributes/_RestoreAllAttributes 
   *  implementations by overriding _SaveAttributes and _RestoreAttributes to call
   *  _SaveAllAttributes/_RestoreAllAttributes. If the subclass wants a different implementation
   *  (like save only the 'class' attribute), it can provide the implementation itself in
   *  _SaveAttributes/_RestoreAttributes.
   *
   *
   * @param {Object} element - jQuery selection to save attributes for
   * @memberof oj.baseComponent
   * @instance
   * @protected
   */
  _SaveAttributes : function (element)
  {
    // default implementation does nothing. 
  },
  /**
   * <p>Saves all the element's attributes within an internal variable.
   * <a href="#_RestoreAllAttributes">_RestoreAllAttributes</a> will restore the attributes 
   * from this internal variable.</p>  
   * <p>
   * This method is final in JET. 
   * Subclasses can override _RestoreAttributes and call _RestoreAllAttributes.
   * </p>
   *
   * <p>The JSON variable will be held as:
   *
   * <pre class="prettyprint">
   * <code>[
   *   {
   *   "element" : element[i],
   *   "attributes" :
   *     {
   *       attributes[m]["name"] : {"attr": attributes[m]["value"], "prop": $(element[i]).prop(attributes[m]["name"])
   *     }
   *   }
   * ]
   * </code></pre>
   *
   * @param {Object} element - jQuery selection to save attributes for
   * @memberof oj.baseComponent
   * @instance
   * @protected
   * @final
   */
  _SaveAllAttributes : function (element)
  {
    var self = this;
    this._savedAttributes = [];

    $.each(element, function (index, ele)
    {
      //need to be able to save for multiple elements
      var saveAttributes = {},
          save = { "element" : ele, "attributes" : saveAttributes },
          attributes = ele.attributes;

      self._savedAttributes.push(save);

      $.each(attributes, function (index, attr)
      {
        // for proper access certain so called attributes should be accessed as properties
        // [i.e. required, disabled] so fetch them initially
        var attrName = attr["name"];

        saveAttributes[attrName] = { "attr" : attr["value"], "prop" : $(ele).prop(attrName) };
      });

    });

  },

  /**
   * <p>Gets the saved attributes for the provided element. 
   * 
   * <p>If you don't override <a href="#_SaveAttributes">_SaveAttributes</a> and 
   * <a href="#_RestoreAttributes">_RestoreAttributes</a>, then this will return null.
   * <p>If you override _SaveAttributes to call <a href="#_SaveAllAttributes">_SaveAllAttributes</a>, 
   * then this will return all the attributes. 
   * If you override _SaveAttributes/_RestoreAttributes to do your own thing, then you may also have
   * to override _GetSavedAttributes to return whatever you saved if you need access to the saved
   * attributes.
   *
   * @param {Object} element - jQuery selection, should be a single entry
   * @return {Object|null} savedAttributes - attributes that were saved for this element 
   * in <a href="#_SaveAttributes">_SaveAttributes</a>, or null if none were saved.
   *
   * @memberof oj.baseComponent
   * @instance
   * @protected
   */
  _GetSavedAttributes : function (element)
  {
    var savedAttributes = this._savedAttributes;
    
    // The component may not have saved any attributes. If so, return.
    if (savedAttributes === undefined)
      return null;

    element = element[0];

    for (var i = 0, j = savedAttributes.length;i < j;i++)
    {
      var curr = savedAttributes[i];

      if (curr["element"] === element)
      {
        return curr["attributes"];
      }
    }

    return {};
  },
  /**
   * <p>Restore the attributes saved in <a href="#_SaveAttributes">_SaveAttributes</a>.</p>
   * <p>
   * _SaveAttributes is called during _create. And _RestoreAttributes is called during _destroy.
   * </p>
   * <p> This base class default implementation does nothing. 
   * </p>
   * <p>We also have <a href="#_SaveAllAttributes">_SaveAllAttributes</a> and 
   * <a href="#_RestoreAllAttributes">_RestoreAllAttributes</a> methods
   *  that save and restore <i>all</i> the attributes on an element.
   *  Component subclasses can opt into these _SaveAllAttributes/_RestoreAllAttributes 
   *  implementations by overriding _SaveAttributes and _RestoreAttributes to call
   *  _SaveAllAttributes/_RestoreAllAttributes. If the subclass wants a different implementation
   *  (like save only the 'class' attribute), it can provide the implementation itself in
   *  _SaveAttributes/_GetSavedAttributes/_RestoreAttributes.
   * @memberof oj.baseComponent
   * @instance
   * @protected
   */
  _RestoreAttributes : function ()
  {
    // default implementation does nothing.
  },
  /**
   * <p>Restores <i>all</i> the element's attributes which were saved in 
   * <a href="#_SaveAllAttributes">_SaveAllAttributes</a>.  
   * This method is final in JET.</p>
   * <p>
   * If a subclass wants to save/restore all attributes on create/destroy, then the
   * subclass can override <a href="#_SaveAttributes">_SaveAttributes</a>
   *  and call  <a href="#_SaveAllAttributes">_SaveAllAttributes</a> and also 
   *  override <a href="#_RestoreAttributes">_RestoreAttributes</a> 
   *  and call <a href="#_RestoreAllAttributes">_RestoreAllAttributes</a>.
   *
   *
   * @memberof oj.baseComponent
   * @instance
   * @protected
   * @final
   */
  _RestoreAllAttributes : function ()
  {

    $.each(this._savedAttributes, function (index, savedAttr)
    {
      var element = $(savedAttr["element"]),
          attributes = savedAttr["attributes"];

      //sanity check
      if (element.length === 1)
      {
        var currAttr = savedAttr["element"].attributes,
            removeAttr = [];

        //request is to remove any attributes that didn't exist previously
        //need to store the attributes in an array and remove them afterwards as otherwise there are side affects
        for(var i=0, j=currAttr.length; i < j; i++)
        {
          if(!(currAttr[i]["name"] in attributes))
          {
            removeAttr.push(currAttr[i]["name"]);
          }
        }

        for(var i=0, j=removeAttr.length; i < j; i++)
        {
          element.removeAttr(removeAttr[i]);
        }

        for (var attribute in attributes)
        {
          element.attr(attribute, attributes[attribute]["attr"]);
        }
      }

    });

  },


  /**
   * <p>Determines the name of the translation bundle section for this component.
   *
   * @return {string} the name of this component's translations section
   * @memberof oj.baseComponent
   * @protected
   */
  _GetTranslationsSectionName: function()
  {
    return this.widgetFullName;
  },


  /**
   * <p>Compares 2 option values for equality and returns true if they are equal; false otherwise.
   *
   * @param {String} option - the name of the option
   * @param {Object} value1 first value
   * @param {Object} value2 another value
   * @return {boolean}
   *
   * @memberof oj.baseComponent
   * @instance
   * @protected
   */
  _CompareOptionValues : function (option, value1, value2)
  {
    return value1 == value2;
  },


  /**
   * <p>Retrieves a translated string after inserting optional parameters.
   *
   * @param {string} key the translations resource key
   * The key is used to retrieve a format pattern from the component options, or if none
   * is found - from the translated resource bundle.
   * Tokens like {0}, {1}, {name} within the pattern will be used to define placement
   * for the optional parameters.  Token strings should not contain comma (,)
   * or space characters, since they are reserved for future format type enhancements.
   * The reserved characters within a pattern are:
   * $ { } [ ]
   * These characters will not appear in the formatted output unless they are escaped
   * with a dollar character ('$').
   *
   * @param {...string|Object|Array} var_args  - optional parameters to be inserted into the
   * translated pattern.
   *
   * If more than one var_args arguments are passed, they will be treated as an array
   * for replacing positional tokens like {0}, {1}, etc.
   * If a single argument is passed, it will be treated as a Javascript Object whose
   * keys will be matched to tokens within the pattern. Note that an Array is just
   * a special kind of such an Object.
   *
   * For backward compatibility, a var_args argument whose type is neither
   * Object or Array will be used to replace {0} in the pattern.
   *
   * @return formatted translated string or the key argument if the resource for the
   * key was not found
   *
   * @memberof oj.baseComponent
   * @instance
   * @private
   */
  // TODO: non-public methods need to start with "_".  Pinged architect, who thinks this 
  // method should become protected post-V1, which would imply a capital _GetTranslatedString
  getTranslatedString : function (key, var_args)
  {
    var params = {}, pattern;

    if (arguments.length > 2)
    {
      params = Array.prototype.slice.call(arguments, 1);
    }
    else if (arguments.length == 2)
    {
      params = arguments[1];
      if (typeof params !== 'object' && !(params instanceof Array))
      {
        params = [params];
      }

    }
    pattern = this.option(_OJ_TRANSLATIONS_PREFIX + key);
    // pattern could be undefined
    return (pattern == null) ? key : oj.Translations.applyParameters(pattern.toString(), params);
  },

  /**
   * <p>Returns the component DOM node indicated by the <code class="prettyprint">locator</code> parameter.
   *
   * <p>If the <code class="prettyprint">locator</code> or its <code class="prettyprint">subId</code> is
   * <code class="prettyprint">null</code>, then this method returns the element on which this component was initialized.
   *
   * <p>If a <code class="prettyprint">subId</code> was provided but no corresponding node
   * can be located, then this method returns <code class="prettyprint">null</code>.
   * 
   * For more details on subIds, see the <a href="#subids-section">subIds section</a>.
   *
   * @expose
   * @memberof oj.baseComponent
   * @instance
   *
   * @param {Object} locator An Object containing, at minimum, a <code class="prettyprint">subId</code>
   * property, whose value is a string that identifies a particular DOM node in this component.
   *
   * <p>If this component has (or inherits) any subIds, then they are documented in the
   * "Sub-ID's" section of this document.
   *
   * <p>Subclasses of this component may support additional fields of the
   * <code class="prettyprint">locator</code> Object, to further specify the desired node.
   *
   * @returns {Element|null} The DOM node located by the <code class="prettyprint">subId</code> string passed in
   * <code class="prettyprint">locator</code>, or <code class="prettyprint">null</code> if none is found.
   *
   * @example <caption>Get the node for a certain subId:</caption>
   * // Foo is ojInputNumber, ojInputDate, etc.
   * var node = $( ".selector" ).ojFoo( "getNodeBySubId", {'subId': 'oj-some-sub-id'} );
   */
  getNodeBySubId: function(locator)
  {
    if (locator == null || locator['subId'] == null)
    {
      return this.element ? this.element[0] : null;
    }

    // Non-null locators have to be handled by the component subclasses
    return null;
  },

  /**
   * <p>Returns the subId string for the given child DOM node.  For more details, see
   * <a href="#getNodeBySubId">getNodeBySubId</a>.
   *
   * For more details on subIds, see the <a href="#subids-section">subIds section</a>.
   * @expose
   * @memberof oj.baseComponent
   * @instance
   *
   * @param {!Element} node - child DOM node
   * @return {Object|null} The locator for the DOM node, or <code class="prettyprint">null</code> when none is found.
   *
   * @example <caption>Get the subId for a certain DOM node:</caption>
   * // Foo is ojInputNumber, ojInputDate, etc.
   * var locator = $( ".selector" ).ojFoo( "getSubIdByNode", nodeInsideComponent );
   *
   * @private
   */
  getSubIdByNode: function(node)
  {
    return null;
  },

  // Overridden to set oj-hover and oj-focus classes
  // TODO: Move JSDoc from subclasses to here.  Don't include above internal comment.  Make at-final.
  destroy: function()
  {
    // Fire 'destroy' event
    this._trigger('destroy');

    this._super();

    this._removeContextMenuBehavior();
    
    // clean up states
    this.element.removeClass(_OJ_COMPONENT_NODE_CLASS);
    this.widget().removeClass( "oj-disabled" );
    this['hoverable'].removeClass( "oj-hover" );
    this['focusable'].removeClass( "oj-focus" );
    this['activeable'].removeClass( "oj-active" );

    _removeWidgetName(this.element, this.widgetName);

    this._RestoreAttributes();
    
    // TODO: move this to _RestoreAttributes?
    if (this._initialCmDomAttr)
      this.element.attr("contextmenu", this._initialCmDomAttr);
    else
      this.element.removeAttr("contextmenu");
  },

  /*
   * Internal notes:
   * Overridden to pass extra flags to _setOption
   * param {...Object} var_args - key (or map), value, flags
   */
  /**
   * <p>This method has several overloads, which get and set component options and their fields.  The functionality is unchanged from
   * that provided by JQUI.  See the examples for details on each overload.
   *
   * @expose
   * @memberof oj.baseComponent
   * @instance
   * @final
   *
   * @param {string|Object=} optionName the option name (string, first two overloads), or the map (Object, last overload).
   *        Omitted in the third overload.
   * @param {Object=} value a value to set for the option.  Second overload only.
   * @return {Object|undefined} The getter overloads return the retrieved value(s).  When called via the public jQuery syntax, the setter overloads
   *         return the object on which they were called, to facilitate method chaining.
   *
   * @example <caption>First overload: get one option:
   * <p>This overload accepts a (possibly dot-separated) <code class="prettyprint">optionName</code> param as a string, and returns
   * the current value of that option.</caption>
   * var isDisabled = $( ".selector" ).ojFoo( "option", "disabled" ); // Foo is Button, Menu, etc.
   *
   * // For object-valued options, dot notation can be used to get the value of a field or nested field.
   * var startIcon = $( ".selector" ).ojButton( "option", "icons.start" ); // icons is object with "start" field
   *
   * @example <caption>Second overload: set one option:
   * <p>This overload accepts two params: a (possibly dot-separated) <code class="prettyprint">optionName</code> string, and a new value to
   * which that option will be set.</caption>
   * $( ".selector" ).ojFoo( "option", "disabled", true ); // Foo is Button, Menu, etc.
   *
   * // For object-valued options, dot notation can be used to set the value
   * // of a field or nested field, without altering the rest of the object.
   * $( ".selector" ).ojButton( "option", "icons.start", myStartIcon ); // icons is object with "start" field
   *
   * @example <caption>Third overload: get all options:
   * <p>This overload accepts no params, and returns a map of key/value pairs representing all the component
   * options and their values.</caption>
   * var options = $( ".selector" ).ojFoo( "option" ); // Foo is Button, Menu, etc.
   *
   * @example <caption>Fourth overload: set one or more options:
   * <p>This overload accepts a single map of option-value pairs to set on the component.  Unlike the first two
   * overloads, dot notation cannot be used.</caption>
   * $( ".selector" ).ojFoo( "option", { disabled: true, bar: 42 } ); // Foo is Button, Menu, etc.
   */
  option: function(optionName, value) // actually varArgs per comment above the JSDoc, but GCC warns unless matches the @param that we wish to doc
  {
    if (arguments.length === 0)
    {
      // don't return a reference to the internal hash
      return $.widget.extend({}, this.options);
    }

    var key = arguments[0];

    var options = key;
    var subkey = null;

    var flags = {};

    if (typeof key === "string")
    {
      // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
      options = {};
      var parts = key.split(".");
      key = parts.shift();
      if (parts.length)
      {
        subkey = parts.join(".");

        var curOption;
        try
        {
          // Inform dynamic getters that the subkey is being set
          if (arguments.length > 1)
          {
            this._settingNestedKey = subkey;
          }

          curOption = options[key] = $.widget.extend({}, this.options[key]);
        }
        finally
        {
          this._settingNestedKey = null;
        }

        for (var i = 0; i < parts.length - 1; i++)
        {
          curOption[parts[i]] = curOption[parts[i]] || {};
          curOption = curOption[parts[i]];
        }

        key = parts.pop();
        if (arguments.length === 1)
        {
          return curOption[key] === undefined ? null : curOption[key];
        }

        curOption[key] = value;
      }
      else
      {
        if (arguments.length === 1)
        {
          return this.options[key] === undefined ? null : this.options[key];
        }
        options[key] = value;
      }

      flags = arguments[2] || flags;
    }
    else
    {
      flags = arguments[1] || flags;
    }

    // Store subkey on the flags to let _setOption() know that dot notation was used
    if (subkey != null)
    {
      flags = $.widget.extend({}, flags, {'subkey': subkey});
    }

    var context = flags ? flags['_context'] : null;
    var internalSet = context ? context.internalSet : false;

    // Avoid _setOption() calls for internal sets, since component's _setOption()
    // and setOptions() overrides do not expect to be called in that case
    if (internalSet)
    {
      this._internalSetOptions(options, flags);
    }
    else
    {
      this._setOptions(options, flags);
    }

    return this;

  },

  /**
   * option() calls this rather than _setOption() if the caller was internal.
   * 
   * @memberof oj.baseComponent
   * @instance
   * @private
   */
  _internalSetOptions: function (options, flags)
  {
    for (var key in options)
    {
      var value = options[key];
      var oldValue = this.options[key];
      this.options[key] = value;
      this._optionChanged(key, value, oldValue, flags);
    }
  },

  /**
   * <p>Overridden to pass extra flags to _setOption.
   *
   * @memberof oj.baseComponent
   * @instance
   * @protected
   * @ignore
   */
  _setOptions : function (options, flags)
  {
    for (var key in options)
    {
      this._setOption(key, options[key], flags);
    }

    return this;
  },

  /**
   * <p>Overridden to set oj-hover and oj-focus classes.
   *
   * @memberof oj.baseComponent
   * @instance
   * @protected
   * @ignore
   */
  _setOption: function(key, value, flags)
  {
    var originalValue = this.options[key];


    if (key === "disabled" )
    {
      // The JQUI superclass method has hard-coded style classes in the 'if key === "disabled"' block, so unfortunately
      // we must copy that logic here with updated style classes, and NOT call _super() for the disabled case.
      // TBD: keep this logic updated if superclass method changes.
      this.options[ key ] = value;

      // TBD: widget() is not always the thing that should have aria-disabled on it.  E.g. for the checkbox/radio flavors of ojButton,
      // widget() returns the root node, but aria-disabled belongs on the <input>.  We fixed this JQUI bug in ojButton by having ojButton
      // override this method to remove it from the root node and add it to the input.  Would be better for each component to know which
      // element to apply that to, e.g. an overridable method returning that element, or copying "hoverable" paradigm if appropriate.
      // In the cases where this.element is different than widget(), this.element is more likely to be the right thing, so maybe change
      // default to that.
      // Update: this issue is getting even more awkward now that we have "effectively disabled".  Probably need to refactor this code!
      this.widget()
	  .toggleClass( "oj-disabled", !!value )
	  .attr( "aria-disabled", value );

      if (value)
      {
          this['hoverable'].removeClass( "oj-hover" );
          this['focusable'].removeClass( "oj-focus" );
          // TODO: when we have worked out the 'create' super code change,
          // this this check should not be necessary. Right now, this gets
          // called before _create for radioset (and possibly others) when
          // we create a component like ojRadioset({disabled: true});
          if (!this['activeable'])
            this['activeable'] = $();
          this['activeable'].removeClass( "oj-active" );
      }
    }
    else {
      try
      {
        var subkey = (flags == null)? null :flags['subkey'];
        if (subkey != null)
        {
          this._settingNestedKey = subkey;
        }

        this._super(key, value);
      }
      finally
      {
        this._settingNestedKey = null;
      }

      if ( key === "contextMenu" )
        this._setupContextMenu(false);
    }

    this._optionChanged(key, value, originalValue, flags);

    return this;
  },

  /**
   * @memberof oj.baseComponent
   * @instance
   * @private
   */
  _optionChanged: function(key, value, originalValue, flags)
  {
    // TODO: add option change notification
    var changed = false;
    var context = null;

    var writeback = false;
    var originalEvent = null;

    var optionMetadata = null;

    if (flags)
    {
      changed = flags['changed'];
      context = flags['_context'];

      if (context)
      {
        originalEvent = context.originalEvent;
        writeback = (context.writeback === undefined) ? originalEvent != null : context.writeback;
        optionMetadata = context.optionMetadata;
      }
    }

    if (changed || !this._CompareOptionValues(key, originalValue, value))
    {

      optionMetadata = optionMetadata || {};
      optionMetadata['writeback'] =  writeback ? "shouldWrite" : "shouldNotWrite";

      var optionChangeData =
      {
        "option" : key,
        "previousValue" : originalValue,
        "value" : value,
        "optionMetadata" : optionMetadata
      };

      this._trigger("optionChange", originalEvent, optionChangeData);
    }
  },

  /**
   * <p>Overridden to change the way the component events are treating original events:
   *
   * 1) preventDefault(), stopPropagation() and stopImmediatePropagation() no longer invoke
   *    the corresponding methods on the .originalEvent
   * 2) Properties of the .originalEvent are no longer copied to the new event being
   *    triggered
   *
   * @param {string} type - component event type
   * @param {?Object} event - original event
   * @param {Object=} data - event data
   *
   * @private
   */
  _trigger : function (type, event, data)
  {
    var prop, orig, callback = this.options[type];

    data = data || {};
    event = $.Event(event, _OJ_COMPONENT_EVENT_OVERRIDES);
    event.type = (this.widgetEventPrefix + type).toLowerCase();

    // the original event may come from any element
    // so we need to reset the target on the new event
    event.target = this.element[0];

    this.element.trigger(event, data);

    return !($.isFunction(callback) && callback.apply(this.element[0], [event].concat(data)) === false || event.isDefaultPrevented());
  },

  /**
   * <p>Sets contextMenu option from DOM if option not set.
   *
   * <p>Do not override.  To be called only from _InitOptions().
   * 
   * @memberof oj.baseComponent
   * @instance
   * @private
   * @final
   */
  _initContextMenuOption: function(constructorOptions)
  {
    var contextMenu = this.element.attr("contextmenu");

    this._initialCmDomAttr = contextMenu; // TODO: remove this after the _RestoreAttributes() call in destroy() is uncommented

    if (contextMenu && !('contextMenu' in constructorOptions)) // if app set DOM attr but not option, then set the option from the DOM
    {
      this.option("contextMenu", 
                  "#" + contextMenu,
                  {'_context': {internalSet: true}}); // writeback not needed since "not in constructorOptions" means "not bound"
    }
  },

  /**
   * <p>Call this method from _AfterCreate() and _setOption("contextMenu").
   * 
   * <p>- This method first removes contextMenu listeners/attr from the component root node.
   * <p>- Then, if the component's "contextMenu" option is set, then it sets those things on the component root node.
   * 
   * <p>We don't look for the menu until _getContextMenu() is called on the first launch, 
   * so that the menu needn't be inited before this component.  
   *
   * <p>If needed, override <code class="prettyprint">_NotifyContextMenuGesture()</code>, not this private method.
   * 
   * @memberof oj.baseComponent
   * @instance
   * @private
   */
  _setupContextMenu: function(isCreateTime)
  {
    this._removeContextMenuBehavior();

    if ( this.options.contextMenu )
    {
        var rootNode = this.widget();
        var initNode = this.element;

        // if the context menu was specified via DOM attr of the init node at create time, and if that node is 
        // different than the root node (i.e. if this component wraps itself in a new root node in 
        // _ComponentCreate()), then remove the attr from the init node.
        if (isCreateTime && !initNode.is(rootNode))
            initNode.removeAttr("contextmenu");
        
        // if menu elem exists already and has an id, then set id on the *root* node's contextmenu DOM attr
        var id = $(this.options.contextMenu).attr("id");
        if (id)
            rootNode.attr("contextmenu", id);
        
        var self = this;

        //Bug 18745622, on Chrome preventDefault on "keyup" will avoid triggering contextmenu event 
        //which will display native contextmenu.This also need to be added on document as event target is not menu launcher.
        this._preventKeyUpEventIfMenuOpen = function(event){
          if (event.which == 121 && event.shiftKey) // Shift-F10
          {
            if (self._getContextMenuNode().is(":visible"))
              event.preventDefault();
          }
        };
        
        // Note: Whether or not we use Hammer to detect press-hold, this code would need to do the following things seen below:
        // 
        // (1) Prevent the compatibility mousedown event from triggering Menu's clickAway logic.
        // (2) Prevent press-hold from also generating a click (unless Hammer does this automatically; I'm guessing it doesn't).
        // (3) Ensure we don't respond to *both* press-hold and contextmenu events on Android.
        // 
        // So the only thing that Hammer would replace is:
        // 
        // (4) Detecting the press-hold.
        // 
        // Not currently using Hammer for (4), since:
        // 
        // - This code predates Hammer, and was already stable after extensive iteration / fine-tuning.
        // - We use the same listeners for parts of 1-4. If moved 4 off to Hammer (separate listener), just need to ensure that
        //   we don't introduce any race conditions, etc.  (May be easy or hard, just need to look.)
        // - Hammer only wants to have one instance per DOM node, else they fight to control some things like touch-action. So
        //   a prereq for having this baseComponent logic put Hammer on components is to work out a protocol for super- and sub-
        //   classes to share the same instance and not step on each other.  Not insurmountable; just need to have the conversation.
        
        var pressHoldThreshold = 750; // per UX spec.  Point of reference: JQ Mobile uses 750ms by default.
        var isPressHold = false; // to prevent pressHold from generating a click
        
        var touchInProgress = false;
        
        var doubleOpenTimer; // to prevent double open.  see usage below.
        var doubleOpenThreshold = 300; // made up this number.  TBD: Tweak as needed to make all platforms happy.
        var doubleOpenType = null; // "touchstart" or "contextmenu"
        
        var launch = function(event, eventType, pressHold) {
            // ensure that pressHold doesn't result in a click.  Set this before the bailouts below.
            isPressHold = pressHold;
            
            var menu = self._getContextMenu();
            
            // In Mobile Safari only, mousedown fires *after* the touchend, which causes at least 2 problems:
            // 1) CM launches after 750ms (good), then disappears when lift finger (bad), because touchend --> 
            // mousedown, which calls Menu's "clikAway" mousedown listener, which dismisses Menu.  
            // 2) The isPressHold logic needs to reset the isPressHold ivar on any event that can start a click, 
            // including mousedown.  This problem causes the mousedown listener to incorrectly clear the ivar 
            // after a pressHold, which broke the whole mechanism.
            // SOLUTION FOR 1-2:  On each launch (at 750ms), set a one-time touchend listener that will set a 
            // var and clear it 50ms later.  While the var is set, both mousedown listeners can disregard the 
            // mousedown.  Make the var a static var in Menu, since Menu's listener is static, and since this 
            // launcher component can get/set it via an (effectively static) menu method.
            // NON-SOLUTIONS:  Cancelling touchstart or touchend, via pD() and sP(), doesn't cancel iPad's mousedown.  
            // Cancelling mousedown from here doesn't work even if capture phase, since ojMenu's listener is capture phase.
            // TIMING: The following block should be before the doubleOpen bailout.
            if (isPressHold)
            {
                rootNode.one( "touchend" + self.contextMenuEventNamespace, function( event ) {
                    var touchendMousedownThreshold = 50; // 50ms.  Make as small as possible to prevent unwanted side effects.
                    menu.__contextMenuPressHoldJustEnded(true);
                    setTimeout(function() { 
                        menu.__contextMenuPressHoldJustEnded(false);
                    }, touchendMousedownThreshold);
                });
            }
            
            // On platforms like Android Chrome where long presses already fire the contextmenu event, the pressHold 
            // logic causes the menu to open twice, once for the pressHold, once for the contextmenu.  There's no 
            // guarantee which will happen first, but as long as they happen within doubleOpenThreshold ms 
            // of each other, this logic should prevent the double open.
            // Note: Another option is a platform-specific solution where we only use pressHold for platforms that need 
            // it (that don't already fire a contextmenu event for pressHold), but architectural preference is to avoid 
            // platform-specific solutions if possible.
            if ((doubleOpenType === "touchstart" && event.type === "contextmenu")
                    || (doubleOpenType === "contextmenu" && event.type === "touchstart")) 
            {
                doubleOpenType = null;
                clearTimeout(doubleOpenTimer);
                return;
            }
            
            // If a nested element or component already showed a JET context menu for this event, don't replace it with ours.
            // Hack: must check defaultPrevented on the nested event too, because for touchstart events on iOS7 at least, when 
            // the outer component reaches this point, event is a different JQ wrapper event than the one on which the inner 
            // component previously called preventDefault, although they both wrap the same native originalEvent.  The new wrapper 
            // never had its isDefaultPrevented field set to the returnTrue method, so must check the nested originalEvent.
            // This never seems to happen with right-click and Shift-F10 events.  Has nothing to do with the setTimeout: the events 
            // received by the rootNode.on("touchstart"...) code are different (firstWrapper==secondWrapper returns false).
            // TODO: link to JQ bug once filed.
            if (event.isDefaultPrevented() || (event.originalEvent && event.originalEvent.defaultPrevented))
                return;

            // For components like Button where "effectively disabled" --> "not focusable", keyboard CM launch is impossible, so 
            // allowing right-click access would be an a11y issue.  If there's ever a need to enable this for focusable effectively 
            // disabled components, we can always replace the _IsEffectivelyDisabled() call with a new protected method whose 
            // baseComponent impl returns _IsEffectivelyDisabled().
            if (self._IsEffectivelyDisabled()) 
                return;
            
            self._NotifyContextMenuGesture(menu, event, eventType);
            
            // if _NotifyContextMenuGesture() (or subclass override of it) actually opened the CM, and if that launch wasn't 
            // cancelled by a beforeOpen listener...
            if (self._getContextMenuNode().is(":visible"))
            {
                event.preventDefault(); // don't show native context menu
                document.addEventListener("keyup", self._preventKeyUpEventIfMenuOpen);
                
                // see double-open comments above
                if (event.type === "touchstart" || event.type === "contextmenu")
                {
                    doubleOpenType = event.type;
                    doubleOpenTimer = setTimeout(function(){ 
                        doubleOpenType = null;
                    }, doubleOpenThreshold);
                }
            }
        };
        
        // At least some of the time, the pressHold gesture also fires a click event same as a short tap.  Prevent that here.
        this._clickListener = function( event ) {
            if (isPressHold) {
                // For Mobile Safari capture phase at least, returning false doesn't work; must use pD() and sP() explicitly.
                event.preventDefault();
                event.stopPropagation();
                isPressHold = false;
            }
        };
        
        // Use capture phase to make sure we cancel it before any regular bubble listeners hear it.
        rootNode[0].addEventListener("click", this._clickListener, true);
        
        rootNode
            .on( "touchstart" + this.contextMenuEventNamespace + " " + 
                 "mousedown" + this.contextMenuEventNamespace + " " +  
                 "keydown" + this.contextMenuEventNamespace + " ", function( event ) {
                // for mousedown-after-touchend Mobile Safari issue explained above where __contextMenuPressHoldJustEnded is set.
                if (event.type === "mousedown" && self._getContextMenu().__contextMenuPressHoldJustEnded())
                    return;

                // reset isPressHold flag for all events that can start a click.  
                isPressHold = false;
                
                // start a pressHold timer on touchstart.  If not cancelled before 750ms by touchend/etc., will launch the CM.
                if (event.type === "touchstart") {
                    touchInProgress = true;
                    this._contextMenuPressHoldTimer = setTimeout(launch.bind(undefined, event, "touch", true), pressHoldThreshold);
                }
                
                return true;
            })
        
            // if the touch ends before the 750ms is up, it's not a long enough tap-and-hold to show the CM
            .on( "touchend" + this.contextMenuEventNamespace + " " + 
                 "touchcancel" + this.contextMenuEventNamespace, function( event ) {
                touchInProgress = false;
                clearTimeout(this._contextMenuPressHoldTimer);
                return true;
            })
            .on( "keydown" + this.contextMenuEventNamespace + " " + 
                 "contextmenu" + this.contextMenuEventNamespace, function( event ) {
                if (event.type === "contextmenu" // right-click.  pressHold for Android but not iOS
                        || (event.which == 121 && event.shiftKey)) // Shift-F10
                {
                    var eventType = touchInProgress ? "touch" : event.type === "keydown" ? "keyboard" : "mouse";
                    launch(event, eventType, false);
                }

                return true;
            })

            // Does 2 things: 
            // 1) Prevents native context menu / callout from appearing in Mobile Safari.  E.g. for links, native CM has "Open in New Tab".
            // 2) In Mobile Safari and Android Chrome, prevents tap-hold from selecting the text and showing the selection handles and (in Safari) the Copy/Define callout.
            // In UX discussion, we decided to prevent both of these things for all JET components for now.  If problems, can always, say, add protected method allowing 
            // subclass to opt out (e.g. if they need 1 and/or 2 to work).
            // Per comments in scss file, this suppression has issues in specific versions of Mobile Safari.
            .addClass("oj-menu-context-menu-launcher");
    }
  },

  /** 
   * <p>Sets the ivars used by _getContextMenu() and _getContextMenuNode().  These 2 _ivars should be set/cleared in lockstep.
   * 
   * <p>This method should be called only by those 2 methods.
   * 
   * @memberof oj.baseComponent
   * @instance
   * @throws if no Menu found, which is app error since Menu should be inited by the time this is called
   * @private
   */
  _setContextMenuIvars: function()
  {
    // JQ obj containing the menu element.  Empty if no element found.
    this._contextMenuNode = $(this.options.contextMenu).first();

    // Menu component.  undefined if _contextMenuNode empty, or if its one node has no JET Menu.
    this._contextMenu = this._contextMenuNode.data( "oj-ojMenu" );

    if (!this._contextMenu) 
        throw new Error('"contextMenu" option set to "' + this.options.contextMenu + '", which does not reference a valid JET Menu.');
    
    var self = this;
    this._contextMenuNode.on( "oj__dismiss" + this.contextMenuEventNamespace , function( event, ui ) {
        document.removeEventListener("keyup", self._preventKeyUpEventIfMenuOpen);
    });
  },
  
  /** 
   * <p>Lazy getter for the context menu.
   * 
   * <p>This method should be called only by the "user is launching the context menu" listeners, which should only be registered 
   * if the "contextMenu" option is set.  Do not call at create time.
   * 
   * <p>We wait until menu-launch time to lazily get the menu, to avoid an init-order dependency.  It should be OK to 
   * init the component before its context menu.
   * 
   * @return the JET Menu component pointed to by the "contextMenu" option
   * @throws if no Menu found, which is app error since Menu should be inited by the time this is called
   * 
   * @memberof oj.baseComponent
   * @instance
   * @private
   */
  _getContextMenu: function()
  {
    if (!this._contextMenu)
        this._setContextMenuIvars();
        
    return this._contextMenu;
  },
  
  /** 
   * <p>All _getContextMenu doc applies to this method too, except this method returns 
   * the menu node, not the menu itself.
   * 
   * @return the root DOM node of the JET Menu
   * @throws if no Menu found, which is app error since Menu should be inited by the time this is called
   * 
   * @memberof oj.baseComponent
   * @instance
   * @private
   */
  _getContextMenuNode: function()
  {
    if (!this._contextMenuNode)
        this._setContextMenuIvars();
        
    return this._contextMenuNode;
  },
  
  /**
   * <p>This method removes contextMenu functionality from the component.
   *
   * @memberof oj.baseComponent
   * @instance
   * @private
   */
  _removeContextMenuBehavior: function()
  {
    this.widget()
        .removeAttr( "contextmenu" )
        .off( this.contextMenuEventNamespace )
        .removeClass("oj-menu-context-menu-launcher")
        [0].removeEventListener("click", this._clickListener, true);
    
    this._contextMenuNode && this._contextMenuNode.off( this.contextMenuEventNamespace );
    
    // the other 2 contextMenu timeouts don't need to be cleared here
    clearTimeout(this._contextMenuPressHoldTimer);
    
    // set/unset these ivars in lockstep
    this._contextMenu = undefined;
    this._contextMenuNode = undefined;
  },

  /**
   * <p>When the <a href="#contextMenu">contextMenu</a> option is set, this method is called when the user invokes the context menu via
   * the default gestures: right-click, <kbd>Press & Hold</kbd>, and <kbd>Shift-F10</kbd>.  Components should not call this method directly.
   * 
   * <p>The default implementation simply calls <a href="#_OpenContextMenu">this._OpenContextMenu(event, eventType)</a>.  
   * Overrides of this method should call that same method, perhaps with additional params, not [menu.open()]{@link oj.ojMenu#open}.  
   *
   * <p>This method may be overridden by components needing to do things like the following:
   * 
   * <ul>
   * <li>Customize the [launcher]{@link oj.ojMenu#openOptions.launcher} or [position]{@link oj.ojMenu#openOptions.position} passed to   
   * <a href="#_OpenContextMenu">_OpenContextMenu()</a>.  See that method for guidance on these customizations.</li>
   * 
   * <li>Customize the menu contents.  E.g. some components need to enable/disable built-in commands like <kbd>Cut</kbd> and <kbd>Paste</kbd>, 
   * based on state at launch time.</li>
   * 
   * <li>Bail out in some cases.  E.g. components with UX approval to use <kbd>PressHoldRelease</kbd> rather than <kbd>Press & Hold</kbd> can override this method 
   * to say <code class="prettyprint">if (eventType !== "touch") this._OpenContextMenu(event, eventType);</code>.  When those components 
   * detect the alternate context menu gesture (e.g. <kbd>PressHoldRelease</kbd>), that separate listener should call <a href="#_OpenContextMenu">this._OpenContextMenu()</a>, 
   * not this method (<code class="prettyprint">_NotifyContextMenuGesture()</code>), and not [menu.open()]{@link oj.ojMenu#open}.  </li>
   * </ul>
   * 
   * <p>Components needing to do per-launch setup like the above tasks should do so in an override of this method, <i>not</i> in 
   * a [beforeOpen]{@link oj.ojMenu#event:beforeOpen} listener or an <a href="#_OpenContextMenu">_OpenContextMenu()</a> override.  
   * This is discussed more fully <a href="#_OpenContextMenu">here</a>.
   * 
   * @memberof oj.baseComponent
   * @instance
   * @protected
   *
   * @param {!Object} menu The JET Menu to open as a context menu.  Always non-<code class="prettyprint">null</code>.
   * @param {!Event} event What triggered the menu launch.  Always non-<code class="prettyprint">null</code>.
   * @param {string} eventType "mouse", "touch", or "keyboard".  Never <code class="prettyprint">null</code>.
   */
  _NotifyContextMenuGesture: function(menu, event, eventType)
  {
    this._OpenContextMenu(event, eventType);
  },

  /**
   * <p>The only correct way for a component to open its context menu is by calling this method, not by calling [Menu.open()]{@link oj.ojMenu#open} or 
   * <a href="#_NotifyContextMenuGesture">_NotifyContextMenuGesture()</a>.  This method should be called in two cases:
   * 
   * <ul>
   * <li>This method is called by <a href="#_NotifyContextMenuGesture">_NotifyContextMenuGesture()</a> and its overrides.  That method is 
   * called when the baseComponent detects the default context menu gestures: right-click, <kbd>Press & Hold</kbd>, and <kbd>Shift-F10</kbd>.</li>
   * 
   * <li>Components with UX-approved support for alternate context menu gestures like <kbd>PressHoldRelease</kbd> should call this method directly 
   * when those gestures are detected.</li>
   * </ul>
   * 
   * <p>Components needing to customize how the context menu is launched, or do any per-launch setup, should do so in the caller of this method, 
   * (which is one of the two callers listed above), often by customizing the params passed to this method 
   * (<code class="prettyprint">_OpenContextMenu</code>) per the guidance below.  This setup should <i>not</i> be done in the following ways:
   * 
   * <ul>
   * <li>Components should not perform setup in a [beforeOpen]{@link oj.ojMenu#event:beforeOpen} listener, as this can cause a race 
   * condition where behavior depends on who got their listener registered first: the component or the app.  The only correct component use 
   * of a <code class="prettyprint">beforeOpen</code> listener is when there's a need to detect whether <i>something else</i> launched the menu.</li>
   * 
   * <li>Components should not override this method (<code class="prettyprint">_OpenContextMenu</code>), as this method is final.  Instead, customize 
   * the params that are passed to it.</li>
   * </ul>
   * 
   * <p><b>Guidance on setting OpenOptions fields:</b>
   *
   * <p><b>Launcher:</b>
   *
   * <p>Depending on individual component needs, any focusable element within the component can be the appropriate 
   * [launcher]{@link oj.ojMenu#openOptions.launcher} for this launch.  
   * 
   * <p>Browser focus returns to the launcher on menu dismissal, so the launcher must at least be focusable.  Typically a tabbable (not just
   * focusable) element is safer, since it just focuses something the user could have focused on their own.
   *
   * <p>By default (i.e. if <code class="prettyprint">openOptions</code> is not passed, or if it lacks a <code class="prettyprint">launcher</code> 
   * field), the component init node is used as the launcher for this launch.  If that is not focusable or is suboptimal for a given 
   * component, that component should pass something else.  E.g. components with a "roving tabstop" (like Toolbar) should typically choose the 
   * current tabstop as their launcher.
   *
   * <p>The [:focusable]{@link http://api.jqueryui.com/focusable-selector/} and [:tabbable]{@link http://api.jqueryui.com/tabbable-selector/} selectors
   * may come in handy for choosing a launcher, e.g. something like <code class="prettyprint">this.widget().find(".my-class:tabbable").first()</code>.
   * 
   * <p><b>Position:</b>
   * 
   * <p>By default, this method applies [positioning]{@link oj.ojMenu#openOptions.position} that differs from Menu's default in the following ways:  
   * (The specific settings are subject to change.)
   * 
   * <ul>
   * <li>For mouse and touch events, the menu is positioned relative to the event, not the launcher.</li>
   * 
   * <li>For touch events, <code class="prettyprint">"my"</code> is set to <code class="prettyprint">"start>40 center"</code>, 
   * to avoid having the context menu obscured by the user's finger, and <code class="prettyprint">"collision"</code> is set to 
   * <code class="prettyprint">"flipfit"</code>, to avoid auto-scrolling on tablets.</li>
   * </ul>
   * 
   * <p>Usually, if <code class="prettyprint">position</code> needs to be customized at all, the only thing that needs changing is its 
   * <code class="prettyprint">"of"</code> field, and only for keyboard launches (since mouse/touch launches should almost certainly keep 
   * the default <code class="prettyprint">"event"</code> positioning).  This situation arises anytime the element relative to which the menu 
   * should be positioned for keyboard launches is different than the <code class="prettyprint">launcher</code> element (the element to which 
   * focus should be returned upon dismissal).  For this case, <code class="prettyprint">{ "position": {"of": eventType==="keyboard" ? someElement : "event"} }</code> 
   * can be passed as the <code class="prettyprint">openOptions</code> param.
   * 
   * <p>Be careful not to clobber useful defaults by specifying too much.  E.g. if you only want to customize <code class="prettyprint">"of"</code>, 
   * don't pass other fields like <code class="prettyprint">"my"</code>, since your value will be used for all modalities (mouse, touch, keyboard), 
   * replacing the modality-specific defaults that are usually correct.  Likewise, don't forget the 
   * <code class="prettyprint">eventType==="keyboard"</code> check if you only want to customize <code class="prettyprint">"of"</code> for keyboard launches.
   * 
   * <p><b>InitialFocus:</b>
   * 
   * <p>This method forces [initialFocus]{@link oj.ojMenu#openOptions.initialFocus} to <code class="prettyprint">"menu"</code> for this 
   * launch, so the caller needn't specify it.
   * 
   * @memberof oj.baseComponent
   * @instance
   * @protected
   * @final
   *
   * @param {!Event} event What triggered the context menu launch.  Must be non-<code class="prettyprint">null</code>.
   * @param {string} eventType "mouse", "touch", or "keyboard".  Must be non-<code class="prettyprint">null</code>.  Passed explicitly since caller 
   *        knows what it's listening for, and since events like <code class="prettyprint">contextmenu</code> and 
   *        <code class="prettyprint">click</code> can be generated by various input modalities, making it potentially error-prone for 
   *        this method to determine how they were generated.
   * @param {Object=} openOptions Options to merge with this method's defaults, which are discussed above.  The result will be passed to 
   *        [Menu.open()]{@link oj.ojMenu#open}.  May be <code class="prettyprint">null</code> or omitted.  See also the 
   *        <code class="prettyprint">shallow</code> param.
   * @param {Object=} submenuOpenOptions Options to be passed through to [Menu.open()]{@link oj.ojMenu#open}.  May be <code class="prettyprint">null</code> 
   *        or omitted.
   * @param {boolean=} shallow Whether to perform a deep or shallow merge of <code class="prettyprint">openOptions</code> with this method's default 
   *        value.  The default and most commonly correct / useful value is <code class="prettyprint">false</code>. 
   *        
   *        <ul>
   *        <li>If <code class="prettyprint">true</code>, a shallow merge is performed, meaning that the caller's <code class="prettyprint">position</code>
   *        object, if passed, will completely replace this method's default <code class="prettyprint">position</code> object.</li>
   *        
   *        <li>If <code class="prettyprint">false</code> or omitted, a deep merge is performed.  For example, if the caller wishes to tweak 
   *        <code class="prettyprint">position.of</code> while keeping this method's defaults for <code class="prettyprint">position.my</code>, 
   *        <code class="prettyprint">position.at</code>, etc., it can pass <code class="prettyprint">{"of": anOfValue}</code> as the 
   *        <code class="prettyprint">position</code> value.</li>
   *        </ul>
   *        
   *        <p>The <code class="prettyprint">shallow</code> param is n/a for <code class="prettyprint">submenuOpenOptions</code>, since this method doesn't 
   *        apply any defaults to that.  (It's a direct pass-through.)
   */
  _OpenContextMenu: function(event, eventType, openOptions, submenuOpenOptions, shallow)
  {
    // Note: our touch positioning is similar to that of the iOS touch callout (bubble with "Open in New Tab", etc.), which is offset from the pressHold location as follows:
    // - to the right, vertically centered.  (by default)
    // - to the left, vertically centered.  (if fits better)
    // - above or below, horizontally centered.  (if fits better)
    // An offset like 40 prevents it from opening right under your finger, and is similar to iOS's offset.  It also prevents the issue (on iOS7 at least) 
    // where touchend after the pressHold can dismiss the CM b/c the menu gets the touchend.

    var position = {
      "mouse": {
        "my": "start top", 
        "at": "start bottom", 
        "of": event 
      }, 
      "touch": {
        "my": "start>40 center", 
        "at": "start bottom", 
        "of": event,
        "collision": "flipfit"
      }, 
      "keyboard": {
        "my": "start top", 
        "at": "start bottom", 
        "of": "launcher"
      }
    };
    
    var defaults = {"launcher": this.element, "position": position[eventType]}; // used for fields caller omitted
    var forcedOptions = {"initialFocus": "menu"};
    
    openOptions = (shallow) 
      ? $.extend(defaults, openOptions, forcedOptions)
      : $.extend(true, defaults, openOptions, forcedOptions);
    
    var menu = this._getContextMenu();
    menu.__openingContextMenu = true; // Hack.  See todo on this ivar in Menu.open().
    menu.open(event, openOptions, submenuOpenOptions);
    menu.__openingContextMenu = false;
  },

  /**
   * <p>Overridden to set oj-hover class.
   *
   * @memberof oj.baseComponent
   * @instance
   * @private
   */
  _hoverable: function( element )
  {
    // The JQUI superclass method has hard-coded style classes, so unfortunately
    // we must copy that logic here with updated style classes, and NOT call _super().
    // TBD: keep this logic updated if superclass method changes.
    this['hoverable'] = this['hoverable'].add( element );
    this._on( element, {
      mouseenter: function( event ) {
        if (!$( event.currentTarget ).hasClass( "oj-disabled" ))
        {
          $( event.currentTarget ).addClass( "oj-hover" );
        }
      },
      mouseleave: function( event ) {
        $( event.currentTarget ).removeClass( "oj-hover" );
      }
    });
  },

  /**
   * <p>Overridden to set oj-focus class.
   *
   * @memberof oj.baseComponent
   * @instance
   * @private
   */
  _focusable: function( element )
  {
    // The JQUI superclass method has hard-coded style classes, so unfortunately
    // we must copy that logic here with updated style classes, and NOT call _super().
    // TBD: keep this logic updated if superclass method changes.
    this['focusable'] = this['focusable'].add( element );
    this._on( element, {
      focusin: function( event ) {
	  $( event.currentTarget ).addClass( "oj-focus" );
	},
	focusout: function( event ) {
	  $( event.currentTarget ).removeClass( "oj-focus" );
	}
    });
  },

  /**
   * <p>Set oj-active class on mousedown and remove it on mouseup.
   * oj-active is one of JET's 'marker' style classes. It emulates
   * the css :active pseudo-class.
   *
   * @memberof oj.baseComponent
   * @instance
   * @private
   */
  _activeable: function( element )
  {
    this['activeable'] = this['activeable'].add( element );

    this._on( element, {
    mousedown: function( event )
    {
      $( event.currentTarget ).addClass( "oj-active" );
    },
    mouseup: function( event )
    {
      $( event.currentTarget ).removeClass( "oj-active" );
    }
    });
  },

  /**
   * Remove all listener references that were attached to the element
   * which includes _activeable, _focusable and hoverable.
   *
   * @memberof oj.baseComponent
   * @instance
   * @protected
   */
  _UnregisterChildNode: function(element)
  {
    if (element) {
      $(element).off(this.eventNamespace);

      if (this.bindings) {
        this.bindings = $(this.bindings.not(element));
      }
      this['activeable'] = $(this['activeable'].not( element ));
      this['focusable'] = $(this['focusable'].not( element ));
      this['hoverable'] = $(this['hoverable'].not( element ));
    }
  },

  /**
   * <p>Retrieves a translated resource for a given key.
   *
   * @param {string} key
   * @return {Object} resource associated with the key or null if none was found

   * @memberof oj.baseComponent
   * @instance
   * @private
   */
  // TODO: non-public methods need to start with "_".  Pinged architect, who thinks this 
  // method should become protected post-V1, which would imply a capital _GetResource
  getResource : function (key)
  {
    return this.option(_OJ_TRANSLATIONS_PREFIX + key);
  },

  /**
   * <p>Determines whether the component is LTR or RTL.
   *
   * <p>Component responsibilities:
   *
   * <ul>
   * <li>All components must determine directionality exclusively by calling this protected superclass method.
   *     (So that any future updates to the logic can be made in this one place.)</li>
   * <li>Components that need to know the directionality must call this method at create-time 
   *     and from <code class="prettyprint">refresh()</code>, and cache the value.
   * <li>Components should not call this at other times, and should instead use the cached value.  (This avoids constant DOM
   *     queries, and avoids any future issues with component reparenting (i.e. popups) if support for directional islands is added.)</li>
   * </ul>
   *
   * <p>App responsibilities:
   *
   * <ul>
   * <li>The app specifies directionality by setting the HTML <code class="prettyprint">"dir"</code> attribute on the
   *     <code class="prettyprint"><html></code> node.  When omitted, the default is <code class="prettyprint">"ltr"</code>.
   *     (Per-component directionality / directional islands are not currently supported due to inadequate CSS support.)</li>
   * <li>As with any DOM change, the app must <code class="prettyprint">refresh()</code> the component if the directionality changes dynamically.
   *   (This provides a hook for component housekeeping, and allows caching.)</li>
   * </ul>
   *
   * @memberof oj.baseComponent
   * @instance
   * @protected
   * @return {string} the reading direction, either <code class="prettyprint">"ltr"</code> or <code class="prettyprint">"rtl"</code>
   * @default <code class="prettyprint">"ltr"</code>
   */
  _GetReadingDirection: function( )
  {
    return oj.DomUtils.getReadingDirection();
  },

  /**
   * <p>Notifies the component that its subtree has been connected to the document programmatically after the component has
   * been created.
   *
   * @memberof oj.baseComponent
   * @instance
   * @protected
   */
  _NotifyAttached: function()
  {
    this._propertyContext = null;
  },

  /**
   * <p>Notifies the component that its subtree has been removed from the document programmatically after the component has
   * been created.
   *
   * @memberof oj.baseComponent
   * @instance
   * @protected
   */
  _NotifyDetached: function()
  {
    this._propertyContext = null;
  },

  /**
   * <p>Notifies the component that its subtree has been made visible programmatically after the component has
   * been created.
   *
   * @memberof oj.baseComponent
   * @instance
   * @protected
   */
  _NotifyShown: function()
  {

  },

  /**
   * <p>Notifies the component that its subtree has been made hidden programmatically after the component has
   * been created.
   *
   * @memberof oj.baseComponent
   * @instance
   * @protected
   */
  _NotifyHidden: function()
  {

  },

  /**
   * <p>Determines whether this component is effectively disabled, i.e. it has its 'disabled' attribute set to true
   * or it has been disabled by its ancestor component.
   *
   * @memberof oj.baseComponent
   * @instance
   * @protected
   * @return {boolean} true if the component has been effectively disabled, false otherwise
   */
  _IsEffectivelyDisabled: function()
  {
    return (this.options['disabled'] || this._ancestorDisabled) ? true : false;
  },

  /**
   * <p>Sets the ancestor-provided disabled state on this component.
   *
   * @memberof oj.baseComponent
   * @instance
   * @private
   * @param {boolean} disabled - true if this component is being disabled by its ancestor component, false otherwise
   */
  __setAncestorComponentDisabled: function(disabled)
  {
    this._ancestorDisabled = disabled;
  },


  /**
   * @memberof oj.baseComponent
   * @instance
   * @private
   */
  _getTranslationSectionLoader: function()
  {
    var sectionNames = [];

    var self = this;

    var index = 0;

    this._traverseWidgetHierarchy(
      function(proto)
      {
        // retrive translation section name for the widget and all of its ancestors

        // Since _GetTranslationsSectionName() is a protected method, we can only call it on the widget instance.
        // For superclases, we will assume that their section names can only be their full widget name

        var name = (index == 0) ? self._GetTranslationsSectionName() : proto.widgetFullName;
        index++;

        var section = oj.Translations.getComponentTranslations(name);

        if (section != null && !$.isEmptyObject(section))
        {
          sectionNames.push(name);
        }
      }
    );

    var count = sectionNames.length;

    if (count > 0)
    {
      return function()
            {
              // Optimize for the most common case where superclasses do not define translations
              if (count == 1)
              {
                return oj.Translations.getComponentTranslations(sectionNames[0]);
              }
              else
              {
                var trs = {};

                for (var i = count-1; i>=0; i--)
                {
                  $.widget.extend(trs, oj.Translations.getComponentTranslations(sectionNames[i]));
                }

                return trs;
              }
            };
    }
    return null;
  },

  /**
   * @memberof oj.baseComponent
   * @instance
   * @private
   */
  _getDynamicPropertyContext: function()
  {
    if (!this._propertyContext)
    {
      var c = {};
      this._propertyContext = c;
      c['containers'] = _getSpecialContainerNames(this.element[0]);
    }
    return this._propertyContext;
  },

  /**
   * @memberof oj.baseComponent
   * @instance
   * @private
   */
  _setupDefaultOptions: function(originalDefaults, constructorOptions)
  {
    var options = this.options;

    // Load component translations
    var translationLoader = this._getTranslationSectionLoader();

    var currVal = constructorOptions[_OJ_TRANSLATIONS_OPTION];

    if (translationLoader != null && (currVal === undefined || $.isPlainObject(currVal) ))
    {
      _defineDynamicProperty(this, undefined, constructorOptions[_OJ_TRANSLATIONS_OPTION],
                             options,  _OJ_TRANSLATIONS_OPTION, translationLoader);
    }


    // Load options specified with oj.Components.setDefaultOptions()
    this._loadGlobalDefaultOptions(originalDefaults, constructorOptions)

  },

  /**
   * @memberof oj.baseComponent
   * @instance
   * @private
   */
  _loadGlobalDefaultOptions: function(originalDefaults, constructorOptions)
  {
    var options = this.options;

    var defaults = {};

    var widgetHierNames = [];

    // walk up the widget hierarchy
    this._traverseWidgetHierarchy(
              function(proto)
              {
                 widgetHierNames.push(proto.widgetName);
              }
    );

    var allProperties = oj.Components.getDefaultOptions();
    widgetHierNames.push('default');


    // merge properties applicable to this component
    for (var i = widgetHierNames.length-1; i>=0; i--)
    {
      var name = widgetHierNames[i];
      var props = allProperties[name];
      if (props !== undefined)
      {
        defaults = $.widget.extend(defaults, props);
      }
    }

    if ($.isEmptyObject(defaults))
    {
      return;
    }

    var self = this;

    var contextCallback = function()
    {
      return self._getDynamicPropertyContext();
    };


    for (var prop in defaults)
    {
      var val = constructorOptions[prop];

      if (val === undefined || $.isPlainObject(val))
      {
        var defaultVal = defaults[prop];

        if (defaultVal != null && defaultVal instanceof __ojDynamicGetter)
        {
          var callback = defaultVal.getCallback();
          if ($.isFunction(callback))
          {
            _defineDynamicProperty(this, originalDefaults[prop], val, options, prop, callback, contextCallback);
          }
          else
          {
            oj.Logger.error("Dynamic getter for property %s is not a function", prop);
          }
        }
        else
        {
          options[prop] = _mergeOptionLayers([originalDefaults[prop], defaultVal, val]);
        }
      }
    }
  },

  /**
   * @memberof oj.baseComponent
   * @instance
   * @private
   */
  _traverseWidgetHierarchy: function(callback)
  {
    var proto = this.constructor.prototype;
    while (proto != null && 'oj' === proto['namespace'])
    {
      callback(proto);
      proto = Object.getPrototypeOf(proto);
    }
  }
});

// Remove base component from the jQuery prototype, so it could not be created 
// directly by page authors

delete $['fn'][_BASE_COMPONENT];


/**
 * <p>This method is our version of $.widget, i.e. the static initializer of a component such as ojButton.
 * It calls that method, plus does any other static init we need.
 *
 * TODO:
 * - Consider moving this method into its own file.
 * - For base param, make the type oj.baseComponent rather than Object, but need to declare that as a type first.  Review how that's done.
 *
 * @private
 * @param {string} name typically of the form "oj.ojMenu"
 * @param {Object} base NOT optional (unlike JQUI)
 * @param {Object} prototype
 * @param {boolean=} isHidden - if true, indicates that the component name should not
 * be available on jQuery prototype
 */
oj.__registerWidget = function(name, base, prototype, isHidden)
{
  $.widget( name, base, prototype );

  if (isHidden)
  {
    var globalName = name.split('.')[1];
    delete $['fn'][globalName];
  }

  // create single-OJ pseudo-selector for component, e.g. ":oj-menu", in addition to the ":oj-ojMenu" that $.widget() creates.
  // for private components it will begin with an underscore, e.g.,  ":_oj-radio"
  if (name.substring(0, 5) === "oj.oj" || name.substring(0, 6) === "oj._oj")
  {
    var nameArray = name.split( "." ); // ["oj", "ojMenu"], ["oj", "_ojRadio"]
    var namespace = nameArray[ 0 ];    // "oj"
    var simpleName = nameArray [ 1 ];  // "ojMenu", "_ojRadio"
    var fullName = namespace + "-" + simpleName; // "oj-ojMenu", "oj-_ojRadio"
    var isPrivate = simpleName.substring(0, 1) === "_";
    // if private, make the single-oj pseudo-selector start with an underscore, like this -> "_oj-radio"
    var modifiedFullName; // "oj-Menu", "_oj-Radio".  Lowercased below.
    if (isPrivate)
    {
      modifiedFullName = "_" + namespace + "-" + simpleName.substring(3);
    }
    else
    {
      modifiedFullName = namespace + "-" + simpleName.substring(2);
    }

    // Capitalization doesn't seem to matter with JQ pseudos, e.g. for the existing double-oj pseudo, both $(":oj-ojMenu") and $(":oj-ojmenu") work.
    // So, follow JQUI's pattern of using toLowerCase here, which will lowercase not only the "M' in "Menu", but also any camelcased chars after that.
    $.expr[ ":" ][ modifiedFullName.toLowerCase() ] = function( elem ) {
      return !!$.data( elem, fullName );
    };
  }
};



/**
 * @param {Object} self
 * @param {Object|undefined} originalDefaultValue
 * @param {?Object} constructorValue
 * @param {!Object} options
 * @param {string} prop
 * @param {Function} getter
 * @param {Function=} contextCallback
 * @private
 */
 function _defineDynamicProperty(self, originalDefaultValue, constructorValue, options, prop, getter, contextCallback)
 {
   var override = constructorValue;
   var replaced = false;
   var overriddenSubkeys = {};

   delete options[prop];

   Object.defineProperty(options, prop,
     {
       'get': function()
              {
                // Once the option is replaced, we no longer merge in defaults
                if (replaced)
                {
                  return override;
                }

                if (self._settingNestedKey != null)
                {
                  // The getter is getting called from the option() method that will be mutating the current
                  // object. We need to return only the override portion in this case to avoid the defaults being
                  // reapplied as an override

                  return override;

                }

                var defaultVal = getter(contextCallback? contextCallback() : prop);

                return _mergeOptionLayers([originalDefaultValue, defaultVal, override], overriddenSubkeys)
              },
       'set': function(value)
              {
                override = value;

                if (self._settingNestedKey != null)
                {
                  overriddenSubkeys[self._settingNestedKey] = true;
                }
                else // The entire option has been replaced
                {
                  replaced = true;
                }
              },
       'enumerable' : true
     }
   );
 };

 /**
  * @private
  */
 function _getSpecialContainerNames(elem)
 {
    var containers = [];
    while (elem)
    {
      var ga =  elem.getAttribute;
      var name = ga ? ga.call(elem, oj.Components._OJ_CONTAINER_ATTR) : null;
      if (name != null)
      {
        containers.push(name);
      }
      elem = elem.parentNode;
    }

    return containers;
 };

 /**
  * @private
  */
 function _storeWidgetName(element, widgetName)
 {
   var data = element.data(_OJ_WIDGET_NAMES_DATA);
   if (!data)
   {
     data = [];
     element.data(_OJ_WIDGET_NAMES_DATA, data);
   }
   if (data.indexOf(widgetName) < 0)
   {
     data.push(widgetName);
   }
 }

 /**
  * @private
  */
 function _removeWidgetName(element, widgetName)
 {
   var data = element.data(_OJ_WIDGET_NAMES_DATA);
   if (data)
   {
     var index = data.indexOf(widgetName);
     if (index >= 0)
     {
       data.splice(index, 1);
       if (data.length === 0)
       {
         element.removeData(_OJ_WIDGET_NAMES_DATA);
       }
     }
   }
 }

 /**
  * @private
  * @param {Array} values - values to merge
  * @param {Object=} overriddenSubkeys subkeys where the merging should not occur, i.e.
  * the value from corresponsing subkey on the last element of values array should win
  */
 function _mergeOptionLayers(values, overriddenSubkeys)
 {
   var result = undefined;
   for (var i=0; i<values.length; i++)
   {
      var value = values[i];
      if (value !== undefined )
      {
        if ($.isPlainObject(value))
        {
          var input =  $.isPlainObject(result) ? [result, value] : [value];
          // The last object (overrides) is always fully merged in
          result = _mergeObjectsWithExclusions({}, input, (i == values.length - 1)? null: overriddenSubkeys, null);
        }
        else
        {
          result = value;
        }
      }
    }
    return result;
 }

 /**
 * @private
 */
function _mergeObjectsWithExclusions(target, input, ignoreSubkeys, basePath)
{
  var inputLength = input.length;

  for (var inputIndex = 0; inputIndex < inputLength; inputIndex++)
  {
    var source = input[inputIndex];
    var keys = Object.keys(source);
    for (var i=0; i<keys.length; i++)
    {
      var key = keys[i];
      var path = (ignoreSubkeys == null)? null:  (basePath == null ? key : basePath + '.' + key);
      // Ignore all sources when the current path is registered in ignoreSubkeys
      if (ignoreSubkeys == null || !ignoreSubkeys[path])
      {
        var value = source[key];
        if (value !== undefined)
        {
          if ($.isPlainObject(value))
          {
            var params = $.isPlainObject(target[key])? [target[key], value]: [value];
            target[key] = _mergeObjectsWithExclusions({}, params, ignoreSubkeys, path);
          }
          else
          {
            target[key] = value;
          }
        }
      }
    }
  }
  return target;
}


 /**
  * @private
  */
  var _OJ_TRANSLATIONS_OPTION = "translations";

  /**
   * @private
   */
  var _OJ_TRANSLATIONS_PREFIX = _OJ_TRANSLATIONS_OPTION + ".";


  /**
   * @private
   */
  function _returnTrue()
  {
    return true;
  };


  /**
   * @private
   */
  var _OJ_COMPONENT_EVENT_OVERRIDES =
  {
    preventDefault : function ()
    {
      this.isDefaultPrevented = _returnTrue;
    },
    stopPropagation : function ()
    {
      this.isPropagationStopped = _returnTrue;
    },
    stopImmediatePropagation : function ()
    {
      this.isImmediatePropagationStopped = _returnTrue;
    }
  };
  
/**
 * Returns an object with context for the given child DOM node. This will always contain the subid for the node, 
 * defined as the 'subId' property on the context object. Additional component specific information may also be included.
 * 
 * For more details on returned objects, see <a href="#contextobjects-section">context objects</a>.
 * 
 * @ojfragment nodeContextDoc
 * @memberof oj.baseComponent
 */

/**
 * The child DOM node
 * 
 * @ojfragment nodeContextParam
 * @memberof oj.baseComponent
 */
 
/**
 * The context for the DOM node, or <code class="prettyprint">null</code> when none is found.
 * 
 * @ojfragment nodeContextReturn
 * @memberof oj.baseComponent
 */

/**
 * // Foo is ojInputNumber, ojInputDate, etc.
 * // Returns {'subId': oj-foo-subid, 'property1': componentSpecificProperty, ...}
 * var context = $( ".selector" ).ojFoo( "getContextByNode", nodeInsideComponent );
 * 
 * @ojfragment nodeContextExample
 * @memberof oj.baseComponent
 */