浏览代码

androidHack: Caret positioning needs some fine tuning #1412

Robin Herbots 9 年之前
父节点
当前提交
3d51166bdf

+ 1 - 0
CHANGELOG.md

@@ -15,6 +15,7 @@ All notable changes to this project will be documented in this file.
 - improve inputfallback (Android support)
 
 ### Fixed
+- androidHack: Caret positioning needs some fine tuning #1412
 - How can I get "-$123.45", not "$-123.45"? #1360
 - Placeholder color #972
 - Other color on placeholder (wrap placeholder in span, using contenteditable?) #873

+ 1 - 1
bower.json

@@ -1,6 +1,6 @@
 {
   "name": "jquery.inputmask",
-  "version": "3.3.4-44",
+  "version": "3.3.4-45",
   "main": [
 	  "./dist/inputmask/inputmask.loader.js"
   ],

+ 1 - 1
component.json

@@ -2,7 +2,7 @@
   "name": "jquery_inputmask",
   "repository": "robinherbots/jquery.inputmask",
   "description": "jquery.inputmask is a jquery plugin which create an input mask.",
-  "version": "3.3.4-44",
+  "version": "3.3.4-45",
   "keywords": ["jquery", "plugins", "input", "form", "inputmask", "mask"],
   "main": "./dist/inputmask/inputmask.loader.js",
   "scripts": [

+ 1 - 1
composer.json

@@ -1,7 +1,7 @@
 {
   "name": "robinherbots/jquery.inputmask",
   "description": "jquery.inputmask is a jquery plugin which create an input mask.",
-  "version": "3.3.4-44",
+  "version": "3.3.4-45",
   "type": "library",
   "keywords": ["jquery", "plugins", "input", "form", "inputmask", "mask"],
   "homepage": "http://robinherbots.github.io/jquery.inputmask",

+ 1 - 1
dist/inputmask/inputmask.date.extensions.js

@@ -3,7 +3,7 @@
 * https://github.com/RobinHerbots/jquery.inputmask
 * Copyright (c) 2010 - 2016 Robin Herbots
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-* Version: 3.3.4-44
+* Version: 3.3.4-45
 */
 !function(factory) {
     "function" == typeof define && define.amd ? define([ "inputmask.dependencyLib", "inputmask" ], factory) : "object" == typeof exports ? module.exports = factory(require("./inputmask.dependencyLib"), require("./inputmask")) : factory(window.dependencyLib || jQuery, window.Inputmask);

+ 1 - 1
dist/inputmask/inputmask.dependencyLib.js

@@ -3,7 +3,7 @@
 * https://github.com/RobinHerbots/jquery.inputmask
 * Copyright (c) 2010 - 2016 Robin Herbots
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-* Version: 3.3.4-44
+* Version: 3.3.4-45
 */
 !function(factory) {
     "function" == typeof define && define.amd ? define("inputmask.dependencyLib", [ "jquery" ], factory) : "object" == typeof exports ? module.exports = factory(require("jquery")) : factory(jQuery);

+ 1 - 1
dist/inputmask/inputmask.extensions.js

@@ -3,7 +3,7 @@
 * https://github.com/RobinHerbots/jquery.inputmask
 * Copyright (c) 2010 - 2016 Robin Herbots
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-* Version: 3.3.4-44
+* Version: 3.3.4-45
 */
 !function(factory) {
     "function" == typeof define && define.amd ? define([ "inputmask.dependencyLib", "inputmask" ], factory) : "object" == typeof exports ? module.exports = factory(require("./inputmask.dependencyLib"), require("./inputmask")) : factory(window.dependencyLib || jQuery, window.Inputmask);

+ 21 - 10
dist/inputmask/inputmask.js

@@ -3,7 +3,7 @@
 * https://github.com/RobinHerbots/jquery.inputmask
 * Copyright (c) 2010 - 2016 Robin Herbots
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-* Version: 3.3.4-44
+* Version: 3.3.4-45
 */
 !function(factory) {
     "function" == typeof define && define.amd ? define("inputmask", [ "inputmask.dependencyLib" ], factory) : "object" == typeof exports ? module.exports = factory(require("./inputmask.dependencyLib")) : factory(window.dependencyLib || jQuery);
@@ -1155,11 +1155,22 @@
             }, 0);
         }
         function initializeColorMask(input) {
-            function charSize() {
-                var e = document.createElement("span"), width = 0;
-                return e.style.visibility = "hidden", e.style.whiteSpace = "nowrap", e.style.fontSize = computedStyle.fontSize, 
-                e.style.fontFamily = computedStyle.fontFamily, e.innerHTML = "0", parentNode.insertBefore(e, input.nextSibling), 
-                width = e.offsetWidth, parentNode.removeChild(e), width;
+            function findCaretPos(clientx) {
+                var caretPos, e = document.createElement("span");
+                for (var style in computedStyle) isNaN(style) && style.indexOf("font") !== -1 && (e.style[style] = computedStyle[style]);
+                e.style.textTransform = computedStyle.textTransform, e.style.letterSpacing = computedStyle.letterSpacing, 
+                e.style.position = "absolute", e.style.height = "auto", e.style.width = "auto", 
+                e.style.visibility = "hidden", e.style.whiteSpace = "nowrap", document.body.appendChild(e);
+                var itl, inputText = input.inputmask._valueGet(), previousWidth = 0;
+                for (caretPos = 0, itl = inputText.length; caretPos <= itl; caretPos++) {
+                    if (e.innerHTML += inputText.charAt(caretPos) || "_", e.offsetWidth >= clientx) {
+                        var offset1 = clientx - previousWidth, offset2 = e.offsetWidth - clientx;
+                        e.innerHTML = inputText.charAt(caretPos), offset1 -= e.offsetWidth / 3, caretPos = offset1 < offset2 ? caretPos - 1 : caretPos;
+                        break;
+                    }
+                    previousWidth = e.offsetWidth;
+                }
+                return document.body.removeChild(e), caretPos;
             }
             function position() {
                 colorMask.style.position = "absolute", colorMask.style.top = offset.top + parseInt(computedStyle.borderTopWidth) + "px", 
@@ -1168,9 +1179,10 @@
                 colorMask.style.height = parseInt(input.offsetHeight) - parseInt(computedStyle.paddingTop) - parseInt(computedStyle.paddingBottom) - parseInt(computedStyle.borderTopWidth) - parseInt(computedStyle.borderBottomWidth) + "px", 
                 colorMask.style.lineHeight = colorMask.style.height, colorMask.style.border = "";
             }
-            var offset = $(input).position(), computedStyle = (input.ownerDocument.defaultView || window).getComputedStyle(input, null), parentNode = input.parentNode;
+            var offset = $(input).position(), computedStyle = (input.ownerDocument.defaultView || window).getComputedStyle(input, null);
+            input.parentNode;
             colorMask = document.createElement("div"), document.body.appendChild(colorMask);
-            for (var style in computedStyle) $.inArray(style, [ "font", "border", "background", "margin", "padding", "text" ]) !== -1 && (colorMask.style[style] = computedStyle[style]);
+            for (var style in computedStyle) isNaN(style) && "cssText" !== style && style.indexOf("webkit") == -1 && (colorMask.style[style] = computedStyle[style]);
             position(), $(window).on("resize", function(e) {
                 offset = $(input).position(), computedStyle = (input.ownerDocument.defaultView || window).getComputedStyle(input, null), 
                 position();
@@ -1179,8 +1191,7 @@
             }), $(colorMask).on("mouseleave", function(e) {
                 mouseleaveEvent.call(input, e);
             }), $(colorMask).on("click", function(e) {
-                input.focus(), caret(input, Math.floor((e.clientX - parseInt(computedStyle.paddingLeft)) / charSize())), 
-                $(input).trigger("click");
+                input.focus(), caret(input, findCaretPos(e.clientX)), $(input).trigger("click");
             });
         }
         function renderColorMask(input, buffer, caretPos) {

文件差异内容过多而无法显示
+ 1 - 1
dist/inputmask/inputmask.loader.js


+ 1 - 1
dist/inputmask/inputmask.numeric.extensions.js

@@ -3,7 +3,7 @@
 * https://github.com/RobinHerbots/jquery.inputmask
 * Copyright (c) 2010 - 2016 Robin Herbots
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-* Version: 3.3.4-44
+* Version: 3.3.4-45
 */
 !function(factory) {
     "function" == typeof define && define.amd ? define([ "inputmask.dependencyLib", "inputmask" ], factory) : "object" == typeof exports ? module.exports = factory(require("./inputmask.dependencyLib"), require("./inputmask")) : factory(window.dependencyLib || jQuery, window.Inputmask);

+ 1 - 1
dist/inputmask/inputmask.phone.extensions.js

@@ -3,7 +3,7 @@
 * https://github.com/RobinHerbots/jquery.inputmask
 * Copyright (c) 2010 - 2016 Robin Herbots
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-* Version: 3.3.4-44
+* Version: 3.3.4-45
 */
 !function(factory) {
     "function" == typeof define && define.amd ? define([ "inputmask.dependencyLib", "inputmask" ], factory) : "object" == typeof exports ? module.exports = factory(require("./inputmask.dependencyLib"), require("./inputmask")) : factory(window.dependencyLib || jQuery, window.Inputmask);

+ 1 - 1
dist/inputmask/inputmask.regex.extensions.js

@@ -3,7 +3,7 @@
 * https://github.com/RobinHerbots/jquery.inputmask
 * Copyright (c) 2010 - 2016 Robin Herbots
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-* Version: 3.3.4-44
+* Version: 3.3.4-45
 */
 !function(factory) {
     "function" == typeof define && define.amd ? define([ "inputmask.dependencyLib", "inputmask" ], factory) : "object" == typeof exports ? module.exports = factory(require("./inputmask.dependencyLib"), require("./inputmask")) : factory(window.dependencyLib || jQuery, window.Inputmask);

+ 1 - 1
dist/inputmask/jquery.inputmask.js

@@ -3,7 +3,7 @@
 * https://github.com/RobinHerbots/jquery.inputmask
 * Copyright (c) 2010 - 2016 Robin Herbots
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-* Version: 3.3.4-44
+* Version: 3.3.4-45
 */
 !function(factory) {
     "function" == typeof define && define.amd ? define([ "jquery", "inputmask" ], factory) : "object" == typeof exports ? module.exports = factory(require("jquery"), require("./inputmask")) : factory(jQuery, window.Inputmask);

+ 21 - 10
dist/jquery.inputmask.bundle.js

@@ -3,7 +3,7 @@
 * https://github.com/RobinHerbots/jquery.inputmask
 * Copyright (c) 2010 - 2016 Robin Herbots
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-* Version: 3.3.4-44
+* Version: 3.3.4-45
 */
 !function($) {
     function Inputmask(alias, options) {
@@ -1153,11 +1153,22 @@
             }, 0);
         }
         function initializeColorMask(input) {
-            function charSize() {
-                var e = document.createElement("span"), width = 0;
-                return e.style.visibility = "hidden", e.style.whiteSpace = "nowrap", e.style.fontSize = computedStyle.fontSize, 
-                e.style.fontFamily = computedStyle.fontFamily, e.innerHTML = "0", parentNode.insertBefore(e, input.nextSibling), 
-                width = e.offsetWidth, parentNode.removeChild(e), width;
+            function findCaretPos(clientx) {
+                var caretPos, e = document.createElement("span");
+                for (var style in computedStyle) isNaN(style) && style.indexOf("font") !== -1 && (e.style[style] = computedStyle[style]);
+                e.style.textTransform = computedStyle.textTransform, e.style.letterSpacing = computedStyle.letterSpacing, 
+                e.style.position = "absolute", e.style.height = "auto", e.style.width = "auto", 
+                e.style.visibility = "hidden", e.style.whiteSpace = "nowrap", document.body.appendChild(e);
+                var itl, inputText = input.inputmask._valueGet(), previousWidth = 0;
+                for (caretPos = 0, itl = inputText.length; caretPos <= itl; caretPos++) {
+                    if (e.innerHTML += inputText.charAt(caretPos) || "_", e.offsetWidth >= clientx) {
+                        var offset1 = clientx - previousWidth, offset2 = e.offsetWidth - clientx;
+                        e.innerHTML = inputText.charAt(caretPos), offset1 -= e.offsetWidth / 3, caretPos = offset1 < offset2 ? caretPos - 1 : caretPos;
+                        break;
+                    }
+                    previousWidth = e.offsetWidth;
+                }
+                return document.body.removeChild(e), caretPos;
             }
             function position() {
                 colorMask.style.position = "absolute", colorMask.style.top = offset.top + parseInt(computedStyle.borderTopWidth) + "px", 
@@ -1166,9 +1177,10 @@
                 colorMask.style.height = parseInt(input.offsetHeight) - parseInt(computedStyle.paddingTop) - parseInt(computedStyle.paddingBottom) - parseInt(computedStyle.borderTopWidth) - parseInt(computedStyle.borderBottomWidth) + "px", 
                 colorMask.style.lineHeight = colorMask.style.height, colorMask.style.border = "";
             }
-            var offset = $(input).position(), computedStyle = (input.ownerDocument.defaultView || window).getComputedStyle(input, null), parentNode = input.parentNode;
+            var offset = $(input).position(), computedStyle = (input.ownerDocument.defaultView || window).getComputedStyle(input, null);
+            input.parentNode;
             colorMask = document.createElement("div"), document.body.appendChild(colorMask);
-            for (var style in computedStyle) $.inArray(style, [ "font", "border", "background", "margin", "padding", "text" ]) !== -1 && (colorMask.style[style] = computedStyle[style]);
+            for (var style in computedStyle) isNaN(style) && "cssText" !== style && style.indexOf("webkit") == -1 && (colorMask.style[style] = computedStyle[style]);
             position(), $(window).on("resize", function(e) {
                 offset = $(input).position(), computedStyle = (input.ownerDocument.defaultView || window).getComputedStyle(input, null), 
                 position();
@@ -1177,8 +1189,7 @@
             }), $(colorMask).on("mouseleave", function(e) {
                 mouseleaveEvent.call(input, e);
             }), $(colorMask).on("click", function(e) {
-                input.focus(), caret(input, Math.floor((e.clientX - parseInt(computedStyle.paddingLeft)) / charSize())), 
-                $(input).trigger("click");
+                input.focus(), caret(input, findCaretPos(e.clientX)), $(input).trigger("click");
             });
         }
         function renderColorMask(input, buffer, caretPos) {

文件差异内容过多而无法显示
+ 1 - 1
dist/min/inputmask/inputmask.date.extensions.min.js


+ 1 - 1
dist/min/inputmask/inputmask.dependencyLib.min.js

@@ -3,6 +3,6 @@
 * https://github.com/RobinHerbots/jquery.inputmask
 * Copyright (c) 2010 - 2016 Robin Herbots
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-* Version: 3.3.4-44
+* Version: 3.3.4-45
 */
 !function(a){"function"==typeof define&&define.amd?define("inputmask.dependencyLib",["jquery"],a):"object"==typeof exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return window.dependencyLib=a,a});

文件差异内容过多而无法显示
+ 1 - 1
dist/min/inputmask/inputmask.extensions.min.js


文件差异内容过多而无法显示
+ 1 - 1
dist/min/inputmask/inputmask.loader.min.js


文件差异内容过多而无法显示
+ 2 - 2
dist/min/inputmask/inputmask.min.js


文件差异内容过多而无法显示
+ 1 - 1
dist/min/inputmask/inputmask.numeric.extensions.min.js


文件差异内容过多而无法显示
+ 1 - 1
dist/min/inputmask/inputmask.phone.extensions.min.js


文件差异内容过多而无法显示
+ 1 - 1
dist/min/inputmask/inputmask.regex.extensions.min.js


文件差异内容过多而无法显示
+ 1 - 1
dist/min/inputmask/jquery.inputmask.min.js


文件差异内容过多而无法显示
+ 3 - 3
dist/min/jquery.inputmask.bundle.min.js


+ 32 - 11
js/inputmask.js

@@ -2709,18 +2709,38 @@
 		}
 
 		function initializeColorMask(input) {
-			function charSize() {
+			function findCaretPos(clientx) {
 				//calculate text width
-				var e = document.createElement('span'), width = 0;
+				var e = document.createElement('span'), caretPos;
+				for (var style in computedStyle) { //clone styles
+					if (isNaN(style) && style.indexOf("font") !== -1) {
+						e.style[style] = computedStyle[style];
+					}
+				}
+				e.style.textTransform = computedStyle.textTransform;
+				e.style.letterSpacing = computedStyle.letterSpacing;
+				e.style.position = "absolute";
+				e.style.height = "auto";
+				e.style.width = "auto";
 				e.style.visibility = "hidden";
 				e.style.whiteSpace = "nowrap";
-				e.style.fontSize = computedStyle.fontSize;
-				e.style.fontFamily = computedStyle.fontFamily;
-				e.innerHTML = "0";
-				parentNode.insertBefore(e, input.nextSibling);
-				width = e.offsetWidth;
-				parentNode.removeChild(e);
-				return width;
+
+				document.body.appendChild(e);
+				var inputText = input.inputmask._valueGet(), previousWidth = 0, itl;
+				for (caretPos = 0, itl = inputText.length; caretPos <= itl; caretPos++) {
+					e.innerHTML += inputText.charAt(caretPos) || "_";
+					if (e.offsetWidth >= clientx) {
+						var offset1 = (clientx - previousWidth);
+						var offset2 = e.offsetWidth - clientx;
+						e.innerHTML = inputText.charAt(caretPos);
+						offset1 -= (e.offsetWidth / 3);
+						caretPos = offset1 < offset2 ? caretPos - 1 : caretPos;
+						break;
+					}
+					previousWidth = e.offsetWidth;
+				}
+				document.body.removeChild(e);
+				return caretPos;
 			}
 
 			function position() {
@@ -2741,8 +2761,9 @@
 			colorMask = document.createElement("div");
 			document.body.appendChild(colorMask); //insert at body to prevent css clash :last-child for example
 			for (var style in computedStyle) { //clone styles
-				if ($.inArray(style, ["font", "border", "background", "margin", "padding", "text"]) !== -1)
+				if (isNaN(style) && style !== "cssText" && style.indexOf("webkit") == -1) {
 					colorMask.style[style] = computedStyle[style];
+				}
 			}
 			position();
 
@@ -2760,7 +2781,7 @@
 			});
 			$(colorMask).on("click", function (e) {
 				input.focus();
-				caret(input, Math.floor((e.clientX - parseInt(computedStyle.paddingLeft)) / charSize()));
+				caret(input, findCaretPos(e.clientX));
 				$(input).trigger("click");
 			});
 		}

+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
   "name": "jquery.inputmask",
-  "version": "3.3.4-44",
+  "version": "3.3.4-45",
   "description": "jquery.inputmask is a jquery plugin which create an input mask.",
   "main": "./dist/inputmask/inputmask.loader.js",
   "files": [