Author: bargull
Date: 2008-01-09 14:02:01 -0800 (Wed, 09 Jan 2008)
New Revision: 7793
Modified:
openlaszlo/trunk/WEB-INF/lps/lfc/kernel/dhtml/LzInputTextSprite.js
openlaszlo/trunk/WEB-INF/lps/lfc/kernel/dhtml/LzSprite.js
openlaszlo/trunk/WEB-INF/lps/lfc/views/LzInputText.lzs
openlaszlo/trunk/WEB-INF/lps/lfc/views/LzText.lzs
Log:
Change 20080106-bargull-2 by [EMAIL PROTECTED] on 2008-01-06 17:19:46
in /home/Admin/src/svn/openlaszlo/trunk
for http://svn.openlaszlo.org/openlaszlo/trunk
Summary: Adding maxlength for multiline-inputtext (DHTML)
New Features:
Bugs Fixed: LPP-4747 - "Edittext maxlength does not work"
Technical Reviewer: max
QA Reviewer: promanik
Doc Reviewer: (pending)
Documentation:
Release Notes:
Details:
The HTML-<textarea> object does not support maxlength natively, so we need to
implement a js-solution for DHTML.
To get the best visual experience, I'm using the "onkeypress"-event, this way
we can easily interrupt any user-input as soon as the maxlength for the
inputtext has been reached.
As keyboard-events are handled quite differently across all supported browsers,
I needed to add a couple of new quirks to LzSprite, but most of them should be
self-explanatory (also see http://www.quirksmode.org/js/keys.html).
Pasting text into an inputtext is special-handled to match Flash's behaviour as
much as possible:
- for IE/Safari, I'm simply using the "onbeforepaste"-event
- for Firefox/Opera, I need to detect paste manually because these browsers do
not support "onbeforepaste"
Flash-behaviour: you can only paste that much chars, as you have still
available in the inputtext.
Changes in LzText and LzInputText fixes two "stale-data" bugs: you cannot use
LzInputText#text to retrieve the current text-value, because this property does
not get updated when the user types in any text. Instead of that, you must use
LzInputText#getText().
Tests:
see bug-description
Modified: openlaszlo/trunk/WEB-INF/lps/lfc/kernel/dhtml/LzInputTextSprite.js
===================================================================
--- openlaszlo/trunk/WEB-INF/lps/lfc/kernel/dhtml/LzInputTextSprite.js
2008-01-09 21:15:53 UTC (rev 7792)
+++ openlaszlo/trunk/WEB-INF/lps/lfc/kernel/dhtml/LzInputTextSprite.js
2008-01-09 22:02:01 UTC (rev 7793)
@@ -1,7 +1,7 @@
/**
* LzInputTextSprite.js
*
- * @copyright Copyright 2007 Laszlo Systems, Inc. All Rights Reserved.
+ * @copyright Copyright 2007-2008 Laszlo Systems, Inc. All Rights Reserved.
* Use is subject to license terms.
*
* @topic Kernel
@@ -34,6 +34,7 @@
// Should reflect CSS defaults in LzSprite.js
LzInputTextSprite.prototype.____hpadding = 2;
LzInputTextSprite.prototype.____wpadding = 2;
+LzInputTextSprite.prototype.____crregexp = new RegExp('\\r\\n', 'g');
LzInputTextSprite.prototype.__createInputText = function(t) {
if (this.__LzInputDiv) return;
@@ -216,8 +217,12 @@
this.__LzInputDiv.onclick = function (e) { this.owner.__textEvent(e,
'onclick') }
this.__LzInputDiv.onkeyup = function (e) { this.owner.__textEvent(e,
'onkeyup') }
this.__LzInputDiv.onkeydown = function (e) { this.owner.__textEvent(e,
'onkeydown') }
+ this.__LzInputDiv.onkeypress = function (e) {
this.owner.__textEvent(e, 'onkeypress') }
this.__LzInputDiv.onselect = function (e) { this.owner.__textEvent(e,
'onselect') }
this.__LzInputDiv.onchange = function (e) { this.owner.__textEvent(e,
'onchange') }
+ if (this.quirks.ie_paste_event || this.quirks.safari_paste_event) {
+ this.__LzInputDiv.onpaste = function (e) {
this.owner.__pasteHandlerEx(e) }
+ }
} else {
this.__LzInputDiv.onblur = null;
this.__LzInputDiv.onmousedown = null;
@@ -225,11 +230,108 @@
this.__LzInputDiv.onclick = null;
this.__LzInputDiv.onkeyup = null;
this.__LzInputDiv.onkeydown = null;
+ this.__LzInputDiv.onkeypress = null;
this.__LzInputDiv.onselect = null;
this.__LzInputDiv.onchange = null;
+ if (this.quirks.ie_paste_event || this.quirks.safari_paste_event) {
+ this.__LzInputDiv.onpaste = null;
+ }
}
}
+LzInputTextSprite.prototype.__pasteHandlerEx = function (evt) {
+ if (this.multiline && this.owner.maxlength > 0) {
+ evt = evt ? evt : window.event;
+
+ if (this.quirks.safari_paste_event) {
+ var clipboardTxt = evt.clipboardData.getData("text/plain");
+ } else {
+ var clipboardTxt = window.clipboardData.getData("TEXT");
+ clipboardTxt = clipboardTxt.replace(this.____crregexp, '\n');
+ }
+
+ if (this.quirks.text_ie_carriagereturn) {
+ var len = this.__LzInputDiv.value.replace(this.____crregexp,
'\n').length;
+ } else {
+ var len = this.__LzInputDiv.value.length;
+ }
+
+ var selsize = this.getSelectionSize();
+ if (selsize < 0) selsize = 0;//[TODO anba 2008-01-06] remove after
LPP-5330
+ var max = this.owner.maxlength + selsize;
+ var stopPaste = false;
+
+ var maxchars = max - len;
+ if (maxchars > 0) {
+ var txt = clipboardTxt;
+ var txtLen = txt.length;
+
+ if (txtLen > maxchars) {
+ txt = txt.substring(0, maxchars);
+ stopPaste = true;
+ }
+ } else {
+ var txt = "";
+ stopPaste = true;
+ }
+
+ if (stopPaste) {
+ evt.returnValue = false;
+ if (evt.preventDefault) {
+ evt.preventDefault();
+ }
+
+ if (txt.length > 0) {
+ if (this.quirks.safari_paste_event) {
+ var val = this.__LzInputDiv.value;
+ var selpos = this.getSelectionPosition();
+
+ //update value
+ this.__LzInputDiv.value = val.substring(0, selpos) + txt +
val.substring(selpos + selsize);
+
+ //fix selection
+ this.__LzInputDiv.setSelectionRange(selpos + txt.length,
selpos + txt.length);
+ } else {
+ var range = document.selection.createRange();
+ //this updates value and ensures right selection
+ range.text = txt;
+ }
+ }
+ }
+ }
+}
+
+LzInputTextSprite.prototype.__pasteHandler = function () {
+ var selpos = this.getSelectionPosition();
+ var selsize = this.getSelectionSize();
+ var val = this.__LzInputDiv.value;
+ var that = this;
+
+ //use 1ms timeout to give UI enough time for updating
+ setTimeout(function() {
+ var newval = that.__LzInputDiv.value;
+ var newlen = newval.length;
+ var max = that.owner.maxlength;
+
+ if (newlen > max) {
+ var len = val.length;
+ var maxchars = max + selsize - len;
+
+ //this was pasted
+ var newc = newval.substr(selpos, newlen - len + selsize);
+ //but we can only take at max that many chars
+ newc = newc.substring(0, maxchars);
+
+ //update value
+ that.__LzInputDiv.value = val.substring(0, selpos) + newc +
val.substring(selpos + selsize);
+
+ //fix selection
+ //note: we're in Firefox/Opera, so we can savely call
"setSelectionRange"
+ that.__LzInputDiv.setSelectionRange(selpos + newc.length, selpos +
newc.length);
+ }
+ }, 1);
+}
+
LzInputTextSprite.prototype.__textEvent = function ( e, eventname ){
if (this.__LZdeleted == true) return;
var keycode = e ? e.keyCode : event.keyCode;
@@ -258,6 +360,70 @@
this.__setglobalclickable(true);
}
+ if (this.multiline && this.owner.maxlength > 0) {
+ if (eventname == 'onkeypress') {
+ var evt = e ? e : event;
+ var charcode = this.quirks.text_event_charcode ? evt.charCode :
evt.keyCode;
+
+ /* BUG:
+ * env: Safari - Win
+ * -> last char is \n, delete per backspace, notice Safari-UI did
update,
+ * but __LzInputDiv.value still holds the \n!
+ * blur inputtext, focus again -> \n is again there, also in UI!
+ * what about Safari - Mac?
+ */
+
+ //Debug.write("charCode = %s, keyCode = %s, ctrlKey = %s, altKey =
%s, shiftKey = %s", charcode, keycode, evt.ctrlKey, evt.altKey, evt.shiftKey);
+
+ if (!(evt.ctrlKey || evt.altKey) && (charcode || keycode == 13) &&
keycode != 8) {
+ var selsize = this.getSelectionSize();
+ //[TODO anba 2008-01-06] use selsize==0 when LPP-5330 is fixed
+ if (selsize <= 0) {
+ if (this.quirks.text_ie_carriagereturn) {
+ var val =
this.__LzInputDiv.value.replace(this.____crregexp, '\n');
+ } else {
+ var val = this.__LzInputDiv.value;
+ }
+
+ var len = val.length, max = this.owner.maxlength;
+ if (len >= max) {
+ evt.returnValue = false;
+ if (evt.preventDefault) {
+ evt.preventDefault();
+ }
+ }
+ }
+ } else {
+ /* IE and Safari do not send 'onkeypress' for function-keys, */
+ /* but Firefox and Opera! */
+ if (this.quirks.keypress_function_keys) {
+ if (evt.ctrlKey && !evt.altKey && !evt.shiftKey) {
+ var c = String.fromCharCode(charcode);
+ /* 'v' for Firefox and 'V' for Opera */
+ if (c == 'v' || c == 'V') {
+ //pasting per ctrl + v
+ //[TODO anba 2008-01-06] how to detect paste per
context-menu?
+ var len = this.__LzInputDiv.value.length, max =
this.owner.maxlength;
+ if (len < max || this.getSelectionSize() > 0) {
+ this.__pasteHandler();
+ } else {
+ evt.returnValue = false;
+ if (evt.preventDefault) {
+ evt.preventDefault();
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (eventname == 'onkeypress') {
+ /* we need to leave here, else LzInputText.inputtextevent(..) will
freak out */
+ return;
+ }
+
//Debug.info('__textEvent', eventname, keycode);
if (this.owner) {
// Generate the event. onkeyup/onkeydown sent by LzKeys.js
@@ -623,7 +789,11 @@
}
LzInputTextSprite.prototype.getText = function () {
- return this.__LzInputDiv.value;
+ if (this.multiline && this.quirks.text_ie_carriagereturn) {
+ return this.__LzInputDiv.value.replace(this.____crregexp, '\n');
+ } else {
+ return this.__LzInputDiv.value;
+ }
}
LzInputTextSprite.prototype.getTextfieldHeight = function () {
Modified: openlaszlo/trunk/WEB-INF/lps/lfc/kernel/dhtml/LzSprite.js
===================================================================
--- openlaszlo/trunk/WEB-INF/lps/lfc/kernel/dhtml/LzSprite.js 2008-01-09
21:15:53 UTC (rev 7792)
+++ openlaszlo/trunk/WEB-INF/lps/lfc/kernel/dhtml/LzSprite.js 2008-01-09
22:02:01 UTC (rev 7793)
@@ -229,6 +229,11 @@
,text_measurement_use_insertadjacenthtml: false
,text_selection_use_range: false
,document_size_use_offsetheight: false
+ ,text_ie_carriagereturn: false
+ ,ie_paste_event: false
+ ,safari_paste_event: false
+ ,text_event_charcode: true
+ ,keypress_function_keys: true
}
LzSprite.prototype.capabilities = {
@@ -292,6 +297,16 @@
// text size measurement uses insertAdjacentHTML()
quirks['text_measurement_use_insertadjacenthtml'] = true;
quirks['text_selection_use_range'] = true;
+
+ // IE uses "\r\n" for newlines, which gives different text-lengths
compared to SWF and
+ // to other browsers
+ quirks['text_ie_carriagereturn'] = true;
+ // IE has got a special event for pasting
+ quirks['ie_paste_event'] = true;
+ // IE does not send onkeypress for function keys
+ quirks['keypress_function_keys'] = false;
+ // IE does not use charCode for onkeypress
+ quirks['text_event_charcode'] = false;
} else if (Lz.__BrowserDetect.isSafari) {
// Fix bug in where if any parent of an image is hidden the size
is 0
// TODO: Tucker claims this is fixed in the latest version of
webkit
@@ -313,6 +328,11 @@
if (Lz.__BrowserDetect.version > 523.10) {
this.capabilities['rotation'] = true;
}
+
+ // Safari has got a special event for pasting
+ quirks['safari_paste_event'] = true;
+ // Safari does not send onkeypress for function keys
+ quirks['keypress_function_keys'] = false;
} else if (Lz.__BrowserDetect.isOpera) {
// Fix bug in where if any parent of an image is hidden the size
is 0
quirks['invisible_parent_image_sizing_fix'] = true;
@@ -320,6 +340,8 @@
quirks['absolute_position_accounts_for_offset'] = true;
quirks['canvas_div_cannot_be_clipped'] = true;
quirks['document_size_use_offsetheight'] = true;
+ // Opera does not use charCode for onkeypress
+ quirks['text_event_charcode'] = false;
} else if (Lz.__BrowserDetect.isFirefox && Lz.__BrowserDetect.version
< 2) {
// see
http://groups.google.ca/group/netscape.public.mozilla.dom/browse_thread/thread/821271ca11a1bdbf/46c87b49c026246f?lnk=st&q=+focus+nsIAutoCompletePopup+selectedIndex&rnum=1
quirks['firefox_autocomplete_bug'] = true;
Modified: openlaszlo/trunk/WEB-INF/lps/lfc/views/LzInputText.lzs
===================================================================
--- openlaszlo/trunk/WEB-INF/lps/lfc/views/LzInputText.lzs 2008-01-09
21:15:53 UTC (rev 7792)
+++ openlaszlo/trunk/WEB-INF/lps/lfc/views/LzInputText.lzs 2008-01-09
22:02:01 UTC (rev 7793)
@@ -1,6 +1,6 @@
/**
*
- * @copyright Copyright 2001-2007 Laszlo Systems, Inc. All Rights Reserved.
+ * @copyright Copyright 2001-2008 Laszlo Systems, Inc. All Rights Reserved.
* Use is subject to license terms.
*
* @access public
@@ -171,7 +171,7 @@
* @access protected
*/
function updateData (){
- return this.sprite.text;
+ return this.sprite.getText();
}
Modified: openlaszlo/trunk/WEB-INF/lps/lfc/views/LzText.lzs
===================================================================
--- openlaszlo/trunk/WEB-INF/lps/lfc/views/LzText.lzs 2008-01-09 21:15:53 UTC
(rev 7792)
+++ openlaszlo/trunk/WEB-INF/lps/lfc/views/LzText.lzs 2008-01-09 22:02:01 UTC
(rev 7793)
@@ -1,6 +1,6 @@
/**
*
- * @copyright Copyright 2001-2007 Laszlo Systems, Inc. All Rights Reserved.
+ * @copyright Copyright 2001-2008 Laszlo Systems, Inc. All Rights Reserved.
* Use is subject to license terms.
*
* @access public
@@ -459,8 +459,9 @@
this.maxlength = val;
if (this.onmaxlength.ready) this.onmaxlength.sendEvent(val);
- if(this.text && this.text.length > this.maxlength){
- this.setText (this.text, true);
+ var t = this.getText();
+ if(t && t.length > this.maxlength){
+ this.setText (t, true);
}
}
_______________________________________________
Laszlo-checkins mailing list
[email protected]
http://www.openlaszlo.org/mailman/listinfo/laszlo-checkins