Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

https://issues.apache.org/jira/browse/MYFACES-3653 fixup for the focu…

…s issue, thanks to the icefaces team for providing the patch

git-svn-id: https://svn.apache.org/repos/asf/myfaces/core/trunk@1412781 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information...
commit db92fb659cdaa3e171ffd4039d05f775b3679726 1 parent 968b859
@weblets weblets authored
Showing with 194 additions and 19 deletions.
  1. +194 −19 api/src/main/javascript/META-INF/resources/myfaces/_impl/_util/_Dom.js
View
213 api/src/main/javascript/META-INF/resources/myfaces/_impl/_util/_Dom.js
@@ -373,6 +373,176 @@ _MF_SINGLTN(_PFX_UTIL + "_Dom", Object, /** @lends myfaces._impl._util._Dom.prot
return ret;
},
+ propertyToAttribute: function(name) {
+ if (name === 'className') {
+ return 'class';
+ } else if (name === 'xmllang') {
+ return 'xml:lang';
+ } else {
+ return name.toLowerCase();
+ }
+ },
+
+ isFunctionNative: function(func) {
+ return /^\s*function[^{]+{\s*\[native code\]\s*}\s*$/.test(String(func));
+ },
+
+ detectAttributes: function(element) {
+ //test if 'hasAttribute' method is present and its native code is intact
+ //for example, Prototype can add its own implementation if missing
+ if (element.hasAttribute && this.isFunctionNative(element.hasAttribute)) {
+ return function(name) {
+ return element.hasAttribute(name);
+ }
+ } else {
+ try {
+ //when accessing .getAttribute method without arguments does not throw an error then the method is not available
+ element.getAttribute;
+
+ var html = element.outerHTML;
+ var startTag = html.match(/^<[^>]*>/)[0];
+ return function(name) {
+ return startTag.indexOf(name + '=') > -1;
+ }
+ } catch (ex) {
+ return function(name) {
+ return element.getAttribute(name);
+ }
+ }
+ }
+ },
+
+ /**
+ * copy all attributes from one element to another - except id
+ * @param target element to copy attributes to
+ * @param source element to copy attributes from
+ * @ignore
+ */
+ cloneAttributes: function(target, source) {
+
+ // enumerate core element attributes - without 'dir' as special case
+ var coreElementProperties = ['className', 'title', 'lang', 'xmllang'];
+ // enumerate additional input element attributes
+ var inputElementProperties = [
+ 'name', 'value', 'size', 'maxLength', 'src', 'alt', 'useMap', 'tabIndex', 'accessKey', 'accept', 'type'
+ ];
+ // enumerate additional boolean input attributes
+ var inputElementBooleanProperties = [
+ 'checked', 'disabled', 'readOnly'
+ ];
+
+ // Enumerate all the names of the event listeners
+ var listenerNames =
+ [ 'onclick', 'ondblclick', 'onmousedown', 'onmousemove', 'onmouseout',
+ 'onmouseover', 'onmouseup', 'onkeydown', 'onkeypress', 'onkeyup',
+ 'onhelp', 'onblur', 'onfocus', 'onchange', 'onload', 'onunload', 'onabort',
+ 'onreset', 'onselect', 'onsubmit'
+ ];
+
+ var sourceAttributeDetector = this.detectAttributes(source);
+ var targetAttributeDetector = this.detectAttributes(target);
+
+ var isInputElement = target.nodeName.toLowerCase() === 'input';
+ var propertyNames = isInputElement ? coreElementProperties.concat(inputElementProperties) : coreElementProperties;
+ var isXML = !source.ownerDocument.contentType || source.ownerDocument.contentType == 'text/xml';
+ for (var iIndex = 0, iLength = propertyNames.length; iIndex < iLength; iIndex++) {
+ var propertyName = propertyNames[iIndex];
+ var attributeName = this.propertyToAttribute(propertyName);
+ if (sourceAttributeDetector(attributeName)) {
+
+ //With IE 7 (quirks or standard mode) and IE 8/9 (quirks mode only),
+ //you cannot get the attribute using 'class'. You must use 'className'
+ //which is the same value you use to get the indexed property. The only
+ //reliable way to detect this (without trying to evaluate the browser
+ //mode and version) is to compare the two return values using 'className'
+ //to see if they exactly the same. If they are, then use the property
+ //name when using getAttribute.
+ if( attributeName == 'class'){
+ if( this._RT.browser.isIE && (source.getAttribute(propertyName) === source[propertyName]) ){
+ attributeName = propertyName;
+ }
+ }
+
+ var newValue = isXML ? source.getAttribute(attributeName) : source[propertyName];
+ var oldValue = target[propertyName];
+ if (oldValue != newValue) {
+ target[propertyName] = newValue;
+ }
+ } else {
+ target.removeAttribute(attributeName);
+ if (attributeName == "value") {
+ target[propertyName] = '';
+ }
+ }
+ }
+
+ var booleanPropertyNames = isInputElement ? inputElementBooleanProperties : [];
+ for (var jIndex = 0, jLength = booleanPropertyNames.length; jIndex < jLength; jIndex++) {
+ var booleanPropertyName = booleanPropertyNames[jIndex];
+ var newBooleanValue = source[booleanPropertyName];
+ var oldBooleanValue = target[booleanPropertyName];
+ if (oldBooleanValue != newBooleanValue) {
+ target[booleanPropertyName] = newBooleanValue;
+ }
+ }
+
+ //'style' attribute special case
+ if (sourceAttributeDetector('style')) {
+ var newStyle;
+ var oldStyle;
+ if (this._RT.browser.isIE) {
+ newStyle = source.style.cssText;
+ oldStyle = target.style.cssText;
+ if (newStyle != oldStyle) {
+ target.style.cssText = newStyle;
+ }
+ } else {
+ newStyle = source.getAttribute('style');
+ oldStyle = target.getAttribute('style');
+ if (newStyle != oldStyle) {
+ target.setAttribute('style', newStyle);
+ }
+ }
+ } else if (targetAttributeDetector('style')){
+ target.removeAttribute('style');
+ }
+
+ // Special case for 'dir' attribute
+ if (!this._RT.browser.isIE && source.dir != target.dir) {
+ if (sourceAttributeDetector('dir')) {
+ target.dir = source.dir;
+ } else if (targetAttributeDetector('dir')) {
+ target.dir = '';
+ }
+ }
+
+ for (var lIndex = 0, lLength = listenerNames.length; lIndex < lLength; lIndex++) {
+ var name = listenerNames[lIndex];
+ target[name] = source[name] ? source[name] : null;
+ if (source[name]) {
+ source[name] = null;
+ }
+ }
+
+ //clone HTML5 data-* attributes
+ try{
+ var targetDataset = target.dataset;
+ var sourceDataset = source.dataset;
+ if (targetDataset || sourceDataset) {
+ //cleanup the dataset
+ for (var tp in targetDataset) {
+ delete targetDataset[tp];
+ }
+ //copy dataset's properties
+ for (var sp in sourceDataset) {
+ targetDataset[sp] = sourceDataset[sp];
+ }
+ }
+ } catch (ex) {
+ //most probably dataset properties are not supported
+ }
+ },
+
/**
* outerHTML replacement which works cross browserlike
@@ -383,28 +553,33 @@ _MF_SINGLTN(_PFX_UTIL + "_Dom", Object, /** @lends myfaces._impl._util._Dom.prot
*/
outerHTML : function(item, markup) {
this._assertStdParams(item, markup, "outerHTML");
+ if (item.nodeName.toLowerCase() === 'input') {
+ var replacingInput = this._buildEvalNodes(item, markup)[0];
+ this.cloneAttributes(item, replacingInput);
+ return item;
+ } else {
+ markup = this._Lang.trim(markup);
+ if (markup !== "") {
+ var ret = null;
+
+ // we try to determine the browsers compatibility
+ // level to standards dom level 2 via various methods
+ if (this.isDomCompliant()) {
+ ret = this._outerHTMLCompliant(item, markup);
+ } else {
+ //call into abstract method
+ ret = this._outerHTMLNonCompliant(item, markup);
+ }
- markup = this._Lang.trim(markup);
- if (markup !== "") {
- var ret = null;
-
- // we try to determine the browsers compatibility
- // level to standards dom level 2 via various methods
- if (this.isDomCompliant()) {
- ret = this._outerHTMLCompliant(item, markup);
- } else {
- //call into abstract method
- ret = this._outerHTMLNonCompliant(item, markup);
+ // and remove the old item
+ //first we have to save the node newly insert for easier access in our eval part
+ this._eval(ret);
+ return ret;
}
-
- // and remove the old item
- //first we have to save the node newly insert for easier access in our eval part
- this._eval(ret);
- return ret;
+ // and remove the old item, in case of an empty newtag and do nothing else
+ this._removeNode(item, false);
+ return null;
}
- // and remove the old item, in case of an empty newtag and do nothing else
- this._removeNode(item, false);
- return null;
},
/**
Please sign in to comment.
Something went wrong with that request. Please try again.