SHARE
TWEET

Enyo 1.0 Textarea Kind

erupnu Feb 4th, 2012 252 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.  
  2. enyo.kind({
  3.         name: "Textarea",
  4.         kind: enyo.Control,
  5.         published: {
  6.                 hint: enyo._$L("Tap Here To Type"),
  7.                 value: "",
  8.                 tabIndex: "",
  9.                 // HTML5 'spellcheck' attribute
  10.                 spellcheck: true,
  11.                 // maps to Mobile Safari 'autocorrect' attribute
  12.                 autocorrect: true,
  13.                 //* Possible settings: "num-lock", "caps-lock", "shift-lock", "shift-single", "num-single",
  14.                 autoKeyModifier: "",
  15.                 //* Possible settings: "sentence", "title", "lowercase" (actual attribute is cap +)
  16.                 autoCapitalize: "sentence",
  17.                 //* Set to true to enable auto-emoticons support
  18.                 autoEmoticons: false,
  19.                 //* Set to true to enable auto-linking support
  20.                 autoLinking: false,
  21.                 //* Set to false to disable automatic word completion
  22.                 autoWordComplete: true,
  23.                 //* Specifies the 'type' attribute on the input field.  On webOS, this modifies the virtual keyboard layout, supported values are "email" and "url".
  24.                 inputType: "",
  25.                 //* css class to apply to the inner input control
  26.                 inputClassName: "",
  27.                 //* css class to apply on focus
  28.                 focusClassName: "enyo-input-focus",
  29.                 //* css class to apply inner controls to control spacing
  30.                 spacingClassName: "enyo-input-spacing",
  31.                 //* Set to true to make the input look focused when it's not.
  32.                 alwaysLooksFocused: false,
  33.                 /**
  34.                 The selection property is an object describing selected text. The start and end properties
  35.                 specify the zero-based starting and ending indexes of the selection.
  36.                 For example, if an input value is "Value"
  37.                 and getSelection returns {start: 1, end: 3} then "al" is selected. To select "alu," call:
  38.  
  39.                         this.$.input.setSelection({start: 1, end: 4});
  40.                 */
  41.                 selection: null,
  42.                 disabled: false,
  43.                 /**
  44.                 Set to true to fire the onchange event as well as the oninput event
  45.                 whenever the input content is changed.
  46.                 */
  47.                 changeOnInput: false,
  48.                 /**
  49.                 Set to the number of milliseconds to delay the input event when a key is pressed.
  50.                 If another key is pressed within the delay interval, the input will be postponed
  51.                 and fired once only after the delay has elapsed without a key being pressed.
  52.                 */
  53.                 keypressInputDelay: 0,
  54.                 //* Set to false to avoid any default styling from being applied
  55.                 styled: true,
  56.                 //* Set to true to select all text when the input gains focus
  57.                 selectAllOnFocus: false
  58.         },
  59.         events: {
  60.                 onfocus: "",
  61.                 onblur: "",
  62.                 onchange: "",
  63.                 oninput: "",
  64.                 onmousedown: "",
  65.                 onmouseup: "",
  66.                 //* The onkeypress event can be used to filter out disallowed characters.
  67.                 onkeypress: ""
  68.         },
  69.         className: "enyo-input",
  70.         //* @protected
  71.         chrome: [
  72.                 {name: "input", flex: 1, kind: "BasicTextarea", className: "enyo-input-input"}
  73.         ],
  74.         clientChrome: [
  75.                 {name: "client", kind: "HFlexBox", align: "center"}
  76.         ],
  77.         create: function() {
  78.                 this.inherited(arguments);
  79.                 this.updateSpacingControl();
  80.                 this.disabledChanged();
  81.                 this.inputTypeChanged();
  82.                 this.tabIndexChanged();
  83.                 this.valueChanged();
  84.                 this.hintChanged();
  85.                 this.alwaysLooksFocusedChanged();
  86.                 this.inputClassNameChanged();
  87.                 this.styledChanged();
  88.                 this.applySmartTextOptions();
  89.         },
  90.         destroy: function() {
  91.                 this.stopInputDelayJob();
  92.                 this.inherited(arguments);
  93.         },
  94.         addControl: function(inControl) {
  95.                 if (!inControl.isChrome && !this.$.client) {
  96.                         this.createChrome(this.clientChrome);
  97.                         this.$.input.setParent(this.$.client);
  98.                         this.updateSpacingControl();
  99.                 }
  100.                 this.inherited(arguments);
  101.         },
  102.         selectAllHandler: function() {
  103.                 document.execCommand("selectAll");
  104.         },
  105.         cutHandler: function() {
  106.                 document.execCommand("cut");
  107.         },
  108.         copyHandler: function() {
  109.                 document.execCommand("copy");
  110.         },
  111.         pasteHandler: function() {
  112.                 if (PalmSystem && PalmSystem.paste) {
  113.                         PalmSystem.paste();
  114.                 }
  115.         },
  116.         mousedownHandler: function(inSender, inEvent) {
  117.                 var r = this.doMousedown(inEvent);
  118.                 this.chromeMousedown = (inEvent.dispatchTarget != this.$.input) ? inEvent : null;
  119.                 if (this.chromeMousedown) {
  120.                         this.handleChromeMousedown(inEvent);
  121.                 }
  122.                 return r;
  123.         },
  124.         handleChromeMousedown: function(inEvent) {
  125.                 // FIXME: when clicking chrome, always prevent default so that chrome can never be focused.
  126.                 // Do this to prevent virtual keyboard from toggling briefly (because focusAtPoint api is asynchronous).
  127.                 // Because of this track cancelling of the mousedown chrome event specially.
  128.                 inEvent.chromeEventPrevented = inEvent.prevented;
  129.                 inEvent.preventDefault();
  130.                 inEvent.preventDefault = function() {
  131.                         inEvent.chromeEventPrevented = true;
  132.                 }
  133.         },
  134.         focusHandler: function(inSender, inEvent) {
  135.                 if (this.styled && !this.alwaysLooksFocused) {
  136.                         this.addClass(this.focusClassName);
  137.                 }
  138.                 if (this.selectAllOnFocus) {
  139.                         this.forceSelect();
  140.                 }
  141.                 return this.doFocus(inEvent);
  142.         },
  143.         mouseupHandler: function(inSender, inEvent) {
  144.                 // force input to be focused when: there's a mousedown on chrome that's not cancelled,
  145.                 // there's been no drag, and not disabled
  146.                 if (this.chromeMousedown && !this.disabled && !inEvent.didDrag
  147.                         && !this.chromeMousedown.chromeEventPrevented) {
  148.                         this.forceFocus(null, true);
  149.                 }
  150.                 return this.doMouseup(inEvent);
  151.         },
  152.         blurHandler: function(inSender, inEvent) {
  153.                 if (!this.alwaysLooksFocused) {
  154.                         this.removeClass(this.focusClassName);
  155.                 }
  156.                 if (this.selectAllOnFocus) {
  157.                         document.execCommand("Unselect");
  158.                 }
  159.                 return this.doBlur(inEvent);
  160.         },
  161.         clickHandler: function(inSender, inEvent) {
  162.                 // note: follow webkit behavior to not send clicks on input elements
  163.                 // this is done automatically for the input node; enforcing here to catch
  164.                 // any chrome around the input.
  165.                 return this.disabled ? true : this.doClick(inEvent);
  166.         },
  167.         rendered: function() {
  168.                 this.inherited(arguments);
  169.                 this.selectionChanged();
  170.         },
  171.         inputClassNameChanged: function() {
  172.                 this.$.input.addClass(this.inputClassName);
  173.         },
  174.         alwaysLooksFocusedChanged: function() {
  175.                 if (this.alwaysLooksFocused && this.styled) {
  176.                         this.addClass(this.focusClassName);
  177.                 }
  178.         },
  179.         inputTypeChanged: function() {
  180.                 this.$.input.domAttributes.type = this.inputType;
  181.                 if (this.hasNode()) {
  182.                         this.$.input.render();
  183.                 }
  184.         },
  185.         valueChanged: function() {
  186.                 this.$.input.setValue(this.value);
  187.         },
  188.         getDomValue: function() {
  189.                 return this.$.input.getDomValue();
  190.         },
  191.         getValue: function() {
  192.                 return this.$.input.getValue();
  193.         },
  194.         tabIndexChanged: function() {
  195.                 this.$.input.setTabIndex(this.tabIndex);
  196.         },
  197.         // dom event handler
  198.         changeHandler: function(inSender, e) {
  199.                 if (!this.changeOnInput) {
  200.                         this.value = inSender.getValue();
  201.                         this.doChange(e, this.value);
  202.                 }
  203.                 return true;
  204.         },
  205.         inputHandler: function(inSender, e) {
  206.                 this.value = inSender.getValue();
  207.                 if (this.keypressInputDelay) {
  208.                         var fn = enyo.bind(this, "processInputEvent", e);
  209.                         enyo.job(this.id + "-inputDelay", fn, Number(this.keypressInputDelay));
  210.                 } else {
  211.                         this.processInputEvent(e);
  212.                 }
  213.                 return true;
  214.         },
  215.         processInputEvent: function(e) {
  216.                 this.doInput(e, this.value);
  217.                 if (this.changeOnInput) {
  218.                         this.doChange(e, this.value);
  219.                 }
  220.         },
  221.         keypressInputDelayChanged: function() {
  222.                 this.stopInputDelayJob();
  223.         },
  224.         stopInputDelayJob: function() {
  225.                 enyo.job.stop(this.id + "-inputDelay");
  226.         },
  227.         selectionChanged: function() {
  228.                 var n = this.$.input.hasNode();
  229.                 if (n && this.selection) {
  230.                         n.selectionStart = this.selection.start;
  231.                         n.selectionEnd = this.selection.end;
  232.                 }
  233.         },
  234.         getSelection: function() {
  235.                 var n = this.$.input.hasNode();
  236.                 return n ? {start: n.selectionStart, end: n.selectionEnd} : {start: 0, end: 0};
  237.         },
  238.         disabledChanged: function() {
  239.                 this.$.input.setDisabled(this.disabled);
  240.         },
  241.         hintChanged: function() {
  242.                 this.$.input.setPlaceholder(this.hint);
  243.         },
  244.         // FIXME: Smart text replace options (could be factored out)
  245.         autoKeyModifierChanged: function() {
  246.                 this.$.input.setAttribute("x-palm-text-entry", this.autoKeyModifier ? this.autoKeyModifier : null);
  247.         },
  248.         autoCapitalizeChanged: function() {
  249.                 if (this.autoCapitalize === "lowercase") {
  250.                         this.$.input.setAttribute("x-palm-disable-auto-cap", "true");
  251.                         this.$.input.setAttribute("x-palm-title-cap", null);
  252.                 } else {
  253.                         this.$.input.setAttribute("x-palm-disable-auto-cap", null);
  254.                         this.$.input.setAttribute("x-palm-title-cap", (this.autoCapitalize === "title") ? true : null);
  255.                 }
  256.         },
  257.         autocorrectChanged: function() {
  258.                 // FIXME: our WebKit implementation of 'autocorrect' and 'spellcheck' doesn't work for all 4 possible values
  259.                 this.$.input.setAttribute("autocorrect", this.autocorrect ? "on" : "off");
  260.         },
  261.         spellcheckChanged: function() {
  262.                 // FIXME: our WebKit implementation of 'autocorrect' and 'spellcheck' doesn't work for all 4 possible values
  263.                 this.$.input.setAttribute("spellcheck", !!this.spellcheck);
  264.         },
  265.  
  266.         autoLinkingChanged: function() {
  267.                 this.$.input.setAttribute("x-palm-enable-linker", this.autoLinking ? this.autoLinking : null);
  268.         },
  269.         autoEmoticonsChanged: function() {
  270.                 this.$.input.setAttribute("x-palm-enable-emoticons", this.autoEmoticons ? this.autoEmoticons : null);
  271.         },
  272.         autoWordCompleteChanged: function() {
  273.                 this.$.input.setAttribute("x-palm-word-completions", this.autoWordComplete ? null : "disabled");
  274.         },
  275.         applySmartTextOptions: function() {
  276.                 this.spellcheckChanged();
  277.                 this.autoWordCompleteChanged();
  278.                 this.autocorrectChanged();
  279.                 this.autoLinkingChanged();
  280.                 this.autoEmoticonsChanged();
  281.                 this.autoCapitalizeChanged();
  282.                 this.autoKeyModifierChanged();
  283.         },
  284.         // control used to reclaim space, can be either input or client
  285.         updateSpacingControl: function() {
  286.                 var c = this.$.client || this.$.input;
  287.                 if (c != this.spacingControl) {
  288.                         if (this.spacingControl) {
  289.                                 this.spacingControl.removeClass(this.spacingClassName);
  290.                         }
  291.                         this.spacingControl = c;
  292.                 }
  293.                 this.spacingClassNameChanged();
  294.         },
  295.         spacingClassNameChanged: function(inOldValue) {
  296.                 if (this.spacingControl) {
  297.                         if (inOldValue) {
  298.                                 this.spacingControl.removeClass(inOldValue);
  299.                         }
  300.                         this.spacingControl.addClass(this.spacingClassName);
  301.                 }
  302.         },
  303.         styledChanged: function(inOldValue) {
  304.                 this.addRemoveClass(this.ctor.prototype.className, this.styled);
  305.                 if (this.spacingControl) {
  306.                         this.spacingControl.addRemoveClass(this.spacingClassName, this.styled);
  307.                 }
  308.         },
  309.         //* @public
  310.         isEmpty: function() {
  311.                 return this.$.input.isEmpty();
  312.         },
  313.         /**
  314.                 Forces this input to be focused.
  315.         */
  316.         forceFocus: function(inCallback, inSync) {
  317.                 this.$.input.forceFocus(inCallback, inSync);
  318.         },
  319.         /**
  320.                 Force this input to be focused and set the keyboard to automatic mode.
  321.         */
  322.         forceFocusEnableKeyboard: function() {
  323.                 this.forceFocus(enyo.bind(enyo, enyo.keyboard.setManualMode, false));
  324.         },
  325.         /**
  326.                 Forces this input to be blurred (lose focus).
  327.         */
  328.         forceBlur: function(inCallback, inSync) {
  329.                 this.$.input.forceBlur(inCallback, inSync);
  330.         },
  331.         /**
  332.                 Force select all text in this input.
  333.         */
  334.         forceSelect: function(inCallback, inSync) {
  335.                 this.$.input.forceSelect(inCallback, inSync);
  336.         },
  337.         /**
  338.                 Returns true if the input has keyboard focus.
  339.         */
  340.         hasFocus: function() {
  341.                 return this.$.input.hasFocus();
  342.         }
  343. });
  344.  
  345.  
  346.  
  347.  
  348.  
  349.  
  350.  
  351. enyo.kind({
  352.         name: "BasicTextarea",
  353.         kind: enyo.Control,
  354.         published: {
  355.                 value: "",
  356.                 disabled: false,
  357.                 readonly: false,
  358.                 placeholder: "",
  359.                 placeholderClassName: "",
  360.                 disabledClassName: "enyo-input-disabled",
  361.                 tabIndex: ""
  362.         },
  363.         events: {
  364.                 onfocus: "",
  365.                 onblur: "",
  366.                 onchange: "",
  367.                 onkeypress: "",
  368.                 onkeyup: ""
  369.         },
  370.         //* @protected
  371.         nodeTag: "textarea",
  372.         style: "font-family: Prelude, Prelude Medium, Segoe UI, Arial, Helvetica, Sans-Serif;", //--> Added this so we do not have to modify the textarea base css class
  373.         // NOTE: only required in browser, overridden below
  374.         requiresDomMousedown: true,
  375.         create: function() {
  376.                 this.inherited(arguments);
  377.                
  378.                 //==========================================================
  379.                 //--> For sizing:
  380.                 //              min-height - is obeyed
  381.                 //              height     - is transformed into min-height since this is a multi-line textbox and will grow in height, silly!
  382.                 //==========================================================
  383.                 if(this.parent.domStyles["min-height"]){
  384.                         this.applyStyle("min-height", this.parent.domStyles["min-height"]);
  385.                 }else if (this.parent.domStyles["height"]){
  386.                         this.applyStyle("min-height", this.parent.domStyles["height"]);
  387.                         this.parent.applyStyle("height", "");
  388.                 }
  389.                 if (window.PalmSystem) {
  390.                         this.requiresDomMousedown = true;
  391.                 }
  392.                 //==========================================================
  393.                
  394.                 this.placeholder = this.placeholder || this.hint || "";
  395.                 enyo.mixin(this.domAttributes, {
  396.                         onfocus: enyo.bubbler,
  397.                         onblur: enyo.bubbler
  398.                 });
  399.                 this.disabledChanged();
  400.                 this.readonlyChanged();
  401.                 this.valueChanged();
  402.                 this.placeholderChanged();
  403.         },
  404.         keyupHandler: function(){
  405.                 //==========================================================
  406.                 //--> NOTE: keypress does not capture backspace, delete, or enter so use keyup
  407.                 //==========================================================
  408.                 this.resize();
  409.         },
  410.         resize: function(){
  411.                 //==========================================================
  412.                 //--> First clear the height to reset the scrollHeight
  413.                 //==========================================================
  414.                 this.applyStyle("height", "0px");
  415.                
  416.                 //==========================================================
  417.                 //--> Now apply the scrollHeight to the current box
  418.                 //==========================================================
  419.                 this.applyStyle("height", this.node.scrollHeight + "px");
  420.         },
  421.         getDomValue: function() {
  422.                 if (this.hasNode()) {
  423.                         return this.node.value;
  424.                 }
  425.         },
  426.         setDomValue: function(inValue) {
  427.                 this.setAttribute("value", inValue);
  428.                 // FIXME: it's not clear when we need to set .value vs. using setAttribute above
  429.                 if (this.hasNode()) {
  430.                         this.node.value = inValue;
  431.                 }
  432.                 if (!this.isEmpty()) {
  433.                         this.addRemovePlaceholderClassName(false);
  434.                 }
  435.         },
  436.         mousedownHandler: function(inSender, inEvent) {
  437.                 if (this.disabled) {
  438.                         inEvent.preventDefault();
  439.                 }
  440.                 return this.fire("mousedown", inEvent);
  441.         },
  442.         changeHandler: function(inSender, inEvent) {
  443.                 // if we are re-rendered we won't show the proper value unless we capture it in domAttributes
  444.                 // we don't call setAttribute (or setDomValue) because of potential side-effects of altering the DOM
  445.                 this.domAttributes.value = this.getValue();
  446.                 //--> Resize for auto-growth:
  447.                 this.resize()
  448.                 // we have the option/responsibility to propagate this event to owner
  449.                 this.doChange(inEvent);
  450.         },
  451.         isEmpty: function() {
  452.                 return !this.getValue();
  453.         },
  454.         getValue: function() {
  455.                 if (this.hasNode()) {
  456.                         var v = this.getDomValue();
  457.                         if (enyo.isString(v)) {
  458.                                 this.value = v;
  459.                         }
  460.                 }
  461.                 return this.value;
  462.         },
  463.         valueChanged: function() {
  464.                 this.setDomValue(this.value);
  465.                 //--> Resize for auto-growth:
  466.                 //this.resize()
  467.         },
  468.         disabledChanged: function() {
  469.                 // NOTE: standard disabled attribute prevents all mouse events;
  470.                 // this could be avoided by not using this attribute;
  471.                 // however, this would make dealing with focus tab order complex
  472.                 // (e.g. keyboard next focuses control: it should
  473.                 // not focus, but next control after this one should)
  474.                 this.setAttribute("disabled", this.disabled ? "disabled" : null);
  475.                 this.addRemoveClass(this.disabledClassName, this.disabled);
  476.         },
  477.         readonlyChanged: function() {
  478.                 this.setAttribute("readonly", this.readonly ? "readonly" : null);
  479.         },
  480.         placeholderChanged: function() {
  481.                 this.setAttribute("placeholder", this.placeholder);
  482.         },
  483.         tabIndexChanged: function() {
  484.                 this.setAttribute("tabindex", this.tabIndex);
  485.         },
  486.         focusHandler: function(inSender, e) {
  487.                 this.didFocus = true;
  488.                 if (this.hasNode()) {
  489.                         if (this.isEmpty()) {
  490.                                 this.updatePlaceholder(false);
  491.                         }
  492.                 }
  493.                 return this.disabled ? true : this.doFocus();
  494.         },
  495.         blurHandler: function(inSender, inEvent) {
  496.                 this.didFocus = false;
  497.                 if (this.isEmpty()) {
  498.                         this.updatePlaceholder(true);
  499.                 }
  500.                 return this.doBlur();
  501.         },
  502.         updatePlaceholder: function(inApplyPlaceholder) {
  503.                 this.addRemovePlaceholderClassName(inApplyPlaceholder);
  504.         },
  505.         addRemovePlaceholderClassName: function(inApplyPlaceholder) {
  506.                 this.addRemoveClass(this.placeholderClassName, inApplyPlaceholder);
  507.         },
  508.         //* @public
  509.         /**
  510.         Force the input to receive keyboard focus.
  511.         */
  512.         forceFocus: function(inCallback, inSync) {
  513.                 // has to be async in many cases (when responding to dom events, in particular) or it just fails
  514.                 if (inSync) {
  515.                         this.applyFocus(inCallback);
  516.                 } else {
  517.                         enyo.asyncMethod(this, "applyFocus", inCallback);
  518.                 }
  519.         },
  520.         //* @protected
  521.         applyFocus: function(inCallback) {
  522.                 if (this.hasNode()) {
  523.                         this.node.focus();
  524.                         if (inCallback) {
  525.                                 inCallback();
  526.                         }
  527.                 }
  528.         },
  529.         //* @public
  530.         /**
  531.                 Forces this input to be blurred (lose focus).
  532.         */
  533.         forceBlur: function(inCallback, inSync) {
  534.                 if (inSync) {
  535.                         this.applyBlur(inCallback);
  536.                 } else {
  537.                         enyo.asyncMethod(this, "applyBlur", inCallback);
  538.                 }
  539.         },
  540.         //* @protected
  541.         applyBlur: function(inCallback) {
  542.                 if (this.hasNode()) {
  543.                         this.node.blur();
  544.                         if (inCallback) {
  545.                                 inCallback();
  546.                         }
  547.                 }
  548.         },
  549.         //* @public
  550.         /**
  551.                 Force select all text in this input.
  552.         */
  553.         forceSelect: function(inCallback, inSync) {
  554.                 if (inSync) {
  555.                         this.applySelect(inCallback);
  556.                 } else {
  557.                         enyo.asyncMethod(this, "applySelect", inCallback);
  558.                 }
  559.         },
  560.         //* @protected
  561.         applySelect: function(inCallback) {
  562.                 if (this.hasNode()) {
  563.                         this.node.select();
  564.                         if (inCallback) {
  565.                                 inCallback();
  566.                         }
  567.                 }
  568.         },
  569.         /**
  570.                 Returns true if the input has keyboard focus.
  571.         */
  572.         hasFocus: function() {
  573.                 if (this.hasNode()) {
  574.                         return Boolean(this.node.parentNode.querySelector(this.nodeTag +":focus"));
  575.                 }
  576.         }
  577. });
  578.  
  579. // on devices with focusAtPoint api, do not need special mousedown handling.
  580. enyo.requiresWindow(function() {
  581.         //if (window.PalmSystem) {
  582.                 BasicTextarea.prototype.requiresDomMousedown = false;
  583.         //}
  584. });
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Not a member of Pastebin yet?
Sign Up, it unlocks many cool features!
 
Top