[FEATURE] BE: Use proper placeholder shim for IE <= 9 30/31830/5
authorBenjamin Mack <benni@b13.de>
Fri, 25 Jul 2014 18:14:47 +0000 (20:14 +0200)
committerWouter Wolters <typo3@wouterwolters.nl>
Tue, 26 Aug 2014 21:15:39 +0000 (23:15 +0200)
The current solution to add HTML5 placeholder
attribute support for unsupported browsers
(which are IE9 and lower) is using a combination
of ExtJS and Prototype, which both need
to be loaded for that.

Currently this is used in FormEngine and
the backend login form.

However, there are better ways of creating
these fallbacks, one being Placeholder.JS
(see http://jamesallardice.github.io/Placeholders.js/)
which can seamlessly be integrated,
and only be loaded for IE9 and less.

Resolves: #60578
Releases: 6.3
Change-Id: If8443276b85d15222c4fc0954e3f79b50ce6a4c9
Reviewed-on: http://review.typo3.org/31830
Reviewed-by: Felix Kopp <felix-source@phorax.com>
Tested-by: Felix Kopp <felix-source@phorax.com>
Reviewed-by: Wouter Wolters <typo3@wouterwolters.nl>
Tested-by: Wouter Wolters <typo3@wouterwolters.nl>
typo3/contrib/placeholdersjs/placeholders.jquery.min.js [new file with mode: 0644]
typo3/sysext/backend/Classes/Controller/LoginController.php
typo3/sysext/backend/Classes/Form/FormEngine.php
typo3/sysext/backend/Resources/Private/Templates/login.html
typo3/sysext/backend/Resources/Public/JavaScript/jsfunc.placeholder.js [deleted file]

diff --git a/typo3/contrib/placeholdersjs/placeholders.jquery.min.js b/typo3/contrib/placeholdersjs/placeholders.jquery.min.js
new file mode 100644 (file)
index 0000000..f931d11
--- /dev/null
@@ -0,0 +1,5 @@
+/* Placeholders.js v3.0.2
+ * Released under the MIT license
+ * see http://jamesallardice.github.io/Placeholders.js/
+ */
+(function(t){"use strict";function e(t,e,r){return t.addEventListener?t.addEventListener(e,r,!1):t.attachEvent?t.attachEvent("on"+e,r):void 0}function r(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(t[r]===e)return!0;return!1}function n(t,e){var r;t.createTextRange?(r=t.createTextRange(),r.move("character",e),r.select()):t.selectionStart&&(t.focus(),t.setSelectionRange(e,e))}function a(t,e){try{return t.type=e,!0}catch(r){return!1}}t.Placeholders={Utils:{addEventListener:e,inArray:r,moveCaret:n,changeType:a}}})(this),function(t){"use strict";function e(){}function r(){try{return document.activeElement}catch(t){}}function n(t,e){var r,n,a=!!e&&t.value!==e,u=t.value===t.getAttribute(V);return(a||u)&&"true"===t.getAttribute(P)?(t.removeAttribute(P),t.value=t.value.replace(t.getAttribute(V),""),t.className=t.className.replace(R,""),n=t.getAttribute(z),parseInt(n,10)>=0&&(t.setAttribute("maxLength",n),t.removeAttribute(z)),r=t.getAttribute(D),r&&(t.type=r),!0):!1}function a(t){var e,r,n=t.getAttribute(V);return""===t.value&&n?(t.setAttribute(P,"true"),t.value=n,t.className+=" "+I,r=t.getAttribute(z),r||(t.setAttribute(z,t.maxLength),t.removeAttribute("maxLength")),e=t.getAttribute(D),e?t.type="text":"password"===t.type&&K.changeType(t,"text")&&t.setAttribute(D,"password"),!0):!1}function u(t,e){var r,n,a,u,i,l,o;if(t&&t.getAttribute(V))e(t);else for(a=t?t.getElementsByTagName("input"):f,u=t?t.getElementsByTagName("textarea"):h,r=a?a.length:0,n=u?u.length:0,o=0,l=r+n;l>o;o++)i=r>o?a[o]:u[o-r],e(i)}function i(t){u(t,n)}function l(t){u(t,a)}function o(t){return function(){b&&t.value===t.getAttribute(V)&&"true"===t.getAttribute(P)?K.moveCaret(t,0):n(t)}}function c(t){return function(){a(t)}}function s(t){return function(e){return A=t.value,"true"===t.getAttribute(P)&&A===t.getAttribute(V)&&K.inArray(C,e.keyCode)?(e.preventDefault&&e.preventDefault(),!1):void 0}}function d(t){return function(){n(t,A),""===t.value&&(t.blur(),K.moveCaret(t,0))}}function v(t){return function(){t===r()&&t.value===t.getAttribute(V)&&"true"===t.getAttribute(P)&&K.moveCaret(t,0)}}function g(t){return function(){i(t)}}function p(t){t.form&&(T=t.form,"string"==typeof T&&(T=document.getElementById(T)),T.getAttribute(U)||(K.addEventListener(T,"submit",g(T)),T.setAttribute(U,"true"))),K.addEventListener(t,"focus",o(t)),K.addEventListener(t,"blur",c(t)),b&&(K.addEventListener(t,"keydown",s(t)),K.addEventListener(t,"keyup",d(t)),K.addEventListener(t,"click",v(t))),t.setAttribute(j,"true"),t.setAttribute(V,x),(b||t!==r())&&a(t)}var f,h,b,m,A,y,E,x,L,T,S,N,w,B=["text","search","url","tel","email","password","number","textarea"],C=[27,33,34,35,36,37,38,39,40,8,46],k="#ccc",I="placeholdersjs",R=RegExp("(?:^|\\s)"+I+"(?!\\S)"),V="data-placeholder-value",P="data-placeholder-active",D="data-placeholder-type",U="data-placeholder-submit",j="data-placeholder-bound",q="data-placeholder-focus",Q="data-placeholder-live",z="data-placeholder-maxlength",F=document.createElement("input"),G=document.getElementsByTagName("head")[0],H=document.documentElement,J=t.Placeholders,K=J.Utils;if(J.nativeSupport=void 0!==F.placeholder,!J.nativeSupport){for(f=document.getElementsByTagName("input"),h=document.getElementsByTagName("textarea"),b="false"===H.getAttribute(q),m="false"!==H.getAttribute(Q),y=document.createElement("style"),y.type="text/css",E=document.createTextNode("."+I+" { color:"+k+"; }"),y.styleSheet?y.styleSheet.cssText=E.nodeValue:y.appendChild(E),G.insertBefore(y,G.firstChild),w=0,N=f.length+h.length;N>w;w++)S=f.length>w?f[w]:h[w-f.length],x=S.attributes.placeholder,x&&(x=x.nodeValue,x&&K.inArray(B,S.type)&&p(S));L=setInterval(function(){for(w=0,N=f.length+h.length;N>w;w++)S=f.length>w?f[w]:h[w-f.length],x=S.attributes.placeholder,x?(x=x.nodeValue,x&&K.inArray(B,S.type)&&(S.getAttribute(j)||p(S),(x!==S.getAttribute(V)||"password"===S.type&&!S.getAttribute(D))&&("password"===S.type&&!S.getAttribute(D)&&K.changeType(S,"text")&&S.setAttribute(D,"password"),S.value===S.getAttribute(V)&&(S.value=x),S.setAttribute(V,x)))):S.getAttribute(P)&&(n(S),S.removeAttribute(V));m||clearInterval(L)},100)}K.addEventListener(t,"beforeunload",function(){J.disable()}),J.disable=J.nativeSupport?e:i,J.enable=J.nativeSupport?e:l}(this),function(t){"use strict";var e=t.fn.val,r=t.fn.prop;Placeholders.nativeSupport||(t.fn.val=function(t){var r=e.apply(this,arguments),n=this.eq(0).data("placeholder-value");return void 0===t&&this.eq(0).data("placeholder-active")&&r===n?"":r},t.fn.prop=function(t,e){return void 0===e&&this.eq(0).data("placeholder-active")&&"value"===t?"":r.apply(this,arguments)})}(TYPO3.jQuery || jQuery);
\ No newline at end of file
index bb6494f..68bae6e 100644 (file)
@@ -198,6 +198,12 @@ class LoginController {
                $pageRenderer->loadExtJS();
                $pageRenderer->loadPrototype();
                $pageRenderer->loadScriptaculous();
+               $pageRenderer->loadJquery();
+               // support placeholders for IE9 and lower
+               $clientInfo = GeneralUtility::clientInfo();
+               if ($clientInfo['BROWSER'] == 'msie' && $clientInfo['VERSION'] <= 9) {
+                       $pageRenderer->addJsLibrary('placeholders', 'contrib/placeholdersjs/placeholders.jquery.min.js');
+               }
                // Set JavaScript for creating a MD5 hash of the password:
                $GLOBALS['TBE_TEMPLATE']->JScode .= $this->getJScode();
                // Checking, if we should make a redirect.
index 931f06b..eb6f210 100644 (file)
@@ -6019,7 +6019,12 @@ TBE_EDITOR.customEvalFunctions[\'' . $evalData . '\'] = function(value) {
                        $pageRenderer->addInlineSettingArray('', $resizableSettings);
                        $this->loadJavascriptLib('sysext/backend/Resources/Public/JavaScript/jsfunc.evalfield.js');
                        $this->loadJavascriptLib('sysext/backend/Resources/Public/JavaScript/jsfunc.tbe_editor.js');
-                       $this->loadJavascriptLib('sysext/backend/Resources/Public/JavaScript/jsfunc.placeholder.js');
+
+                       // support placeholders for IE9 and lower
+                       if ($this->clientInfo['BROWSER'] == 'msie' && $this->clientInfo['VERSION'] <= 9) {
+                               $this->loadJavascriptLib('contrib/placeholdersjs/placeholders.jquery.min.js');
+                       }
+
                        // Needed for tceform manipulation (date picker)
                        $typo3Settings = array(
                                'datePickerUSmode' => $GLOBALS['TYPO3_CONF_VARS']['SYS']['USdateFormat'] ? 1 : 0,
index 468387e..09f1c4f 100644 (file)
@@ -29,7 +29,6 @@
                </div>
        </div>
        <script type="text/javascript" src="sysext/backend/Resources/Public/JavaScript/login.js"></script>
-       <script type="text/javascript" src="sysext/backend/Resources/Public/JavaScript/jsfunc.placeholder.js"></script>
 
        ###NEWS###
 
diff --git a/typo3/sysext/backend/Resources/Public/JavaScript/jsfunc.placeholder.js b/typo3/sysext/backend/Resources/Public/JavaScript/jsfunc.placeholder.js
deleted file mode 100644 (file)
index bc19790..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/**
- * This file is part of the TYPO3 CMS project.
- *
- * It is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License, either version 2
- * of the License, or any later version.
- *
- * For the full copyright and license information, please read the
- * LICENSE.txt file that was distributed with this source code.
- *
- * The TYPO3 project - inspiring people to share!
- */
-
-Ext.onReady(function() {
-       // Only use placeholder JavaScript fallback in Internet Explorer
-       if (!Ext.isIE) {
-               return;
-       }
-
-       // TODO rewrite in ExtJS
-       $$('[placeholder]').each(function(el) {
-               if (el.getAttribute('placeholder') != "") {
-                       el.observe('TYPO3:focus', function() {
-                               var input = Ext.get(this);
-                               if (this.getValue() == this.getAttribute('placeholder')) {
-                                       this.setValue('');
-                                       input.removeClass('placeholder');
-                               }
-                       });
-                       el.observe('focus', function() { el.fire('TYPO3:focus'); });
-                       el.observe('TYPO3:blur', function() {
-                               var input = Ext.get(this);
-                               if (input.getValue() == '' || this.getValue() == this.getAttribute('placeholder')) {
-                                       this.setValue(this.getAttribute('placeholder'));
-                                       input.addClass('placeholder');
-                               }
-                       });
-                       el.observe('blur', function() { el.fire('TYPO3:blur'); });
-                       el.fire('TYPO3:blur');
-               }
-       });
-});
\ No newline at end of file