├── assets-demo ├── before-after.png └── browser-support.png ├── .editorconfig ├── .gitignore ├── package.json ├── README.md ├── LICENSE ├── demo.html └── lib └── polyfill-resize.js /assets-demo/before-after.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CezaryDanielNowak/css-resize-polyfill/HEAD/assets-demo/before-after.png -------------------------------------------------------------------------------- /assets-demo/browser-support.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CezaryDanielNowak/css-resize-polyfill/HEAD/assets-demo/browser-support.png -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | insert_final_newline = true 6 | charset = utf-8 7 | indent_style = space 8 | indent_size = 2 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | 5 | # Runtime data 6 | pids 7 | *.pid 8 | *.seed 9 | 10 | # Directory for instrumented libs generated by jscoverage/JSCover 11 | lib-cov 12 | 13 | # Coverage directory used by tools like istanbul 14 | coverage 15 | 16 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 17 | .grunt 18 | 19 | # node-waf configuration 20 | .lock-wscript 21 | 22 | # Compiled binary addons (http://nodejs.org/api/addons.html) 23 | build/Release 24 | 25 | # Dependency directory 26 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git 27 | node_modules 28 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "resize-polyfill", 3 | "version": "1.1.1", 4 | "description": "Polyfill for Textarea resize handler for IE, Edge, Safari, etc", 5 | "main": "lib/polyfill-resize.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/CezaryDanielNowak/css-resize-polyfill.git" 12 | }, 13 | "author": "Cezary Daniel Nowak", 14 | "license": "MIT", 15 | "bugs": { 16 | "url": "https://github.com/CezaryDanielNowak/css-resize-polyfill/issues" 17 | }, 18 | "homepage": "https://github.com/CezaryDanielNowak/css-resize-polyfill#readme" 19 | } 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | CSS Resize Polyfill 2 | ======== 3 | Resize handler for textarea or any given element. 4 | Supports Internet Explorer, Edge, Firefox, Chrome, Safari etc. 5 | 6 | ![Browser support](/assets-demo/browser-support.png) 7 | 8 | [link to CanIUse](http://caniuse.com/#search=resize) 9 | 10 | 11 | Preview 12 | --- 13 | ![Edge Preview](/assets-demo/before-after.png) 14 | 15 | 16 | How to use it 17 | --- 18 | - copy `lib/*` or `npm install --save resize-polyfill` 19 | - [apply Reverse engineering to demo.html :-)](/demo.html) 20 | 21 | React integration 22 | --- 23 | It's trivial to integrate with react: 24 | ``` 25 | import resizePolyfill from 'resize-polyfill'; 26 | 27 | class MyComponent { 28 | render ( 29 | 36 | ) 37 | } 38 | ``` 39 | 40 | Why CSS Resize Polyfill is the best 41 | --- 42 | - There are no many alternatives. I found just [Resizable as a part of jQuery UI](https://jqueryui.com/resizable/). 43 | - It's really small (9.15KB uncompressed) 44 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Cezary Nowak 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /demo.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Resize-polyfill 6 | 17 | 18 | 19 | 20 |
21 |

Before

22 |
23 | 24 |
25 | 26 |
27 | 28 |
30 | I am DIV 31 |
32 |
33 | 34 |
35 |

After

36 | 37 | 38 | 39 |
40 | 41 |
42 | 43 |
44 | 45 |
47 | I am DIV 48 |
49 |
50 | 51 |
52 |

After (force=true)

53 |
54 | 55 |
56 | 57 |
58 | 59 |
61 | I am DIV 62 |
63 |
64 | 65 | 66 |
67 | Resize handler added: 68 |
69 | 70 | 71 | 72 | 73 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /lib/polyfill-resize.js: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | DragResize v1.0@74147644ad1f26597f1c8d1c42a065f57d9b2e8b 4 | (c) 2005-2013 Angus Turnbull, TwinHelix Designs http://www.twinhelix.com 5 | 6 | Licensed under the GNU LGPL, version 3 or later: 7 | https://www.gnu.org/copyleft/lesser.html 8 | This is distributed WITHOUT ANY WARRANTY; without even the implied 9 | warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 10 | */ 11 | if(typeof addEvent!='function'){var addEvent=function(o,t,f,l){var d='addEventListener',n='on'+t,rO=o,rT=t,rF=f,rL=l;if(o[d]&&!l)return o[d](t,f,false);if(!o._evts)o._evts={};if(!o._evts[t]){o._evts[t]=o[n]?{b:o[n]}:{};o[n]=new Function('e','var r=true,o=this,a=o._evts["'+t+'"],i;for(i in a){o._f=a[i];r=o._f(e||window.event)!=false&&r;o._f=null}return r');if(t!='unload')addEvent(window,'unload',function(){removeEvent(rO,rT,rF,rL)})}if(!f._i)f._i=addEvent._i++;o._evts[t][f._i]=f};addEvent._i=1;var removeEvent=function(o,t,f,l){var d='removeEventListener';if(o[d]&&!l)return o[d](t,f,false);if(o._evts&&o._evts[t]&&f._i)delete o._evts[t][f._i]}}function cancelEvent(e,c){e.returnValue=false;if(e.preventDefault)e.preventDefault();if(c){e.cancelBubble=true;if(e.stopPropagation)e.stopPropagation()}};function DragResize(myName,config){var props={myName:myName,enabled:true,handles:['tl','tm','tr','ml','mr','bl','bm','br'],isElement:null,isHandle:null,element:null,handle:null,minWidth:10,minHeight:10,minLeft:0,maxLeft:9999,minTop:0,maxTop:9999,gridX:1,gridY:1,zIndex:1,mouseX:0,mouseY:0,lastMouseX:0,lastMouseY:0,mOffX:0,mOffY:0,elmX:0,elmY:0,elmW:0,elmH:0,allowBlur:true,ondragfocus:null,ondragstart:null,ondragmove:null,ondragend:null,ondragblur:null};for(var p in props)this[p]=(typeof config[p]=='undefined')?props[p]:config[p]};DragResize.prototype.apply=function(node){var obj=this;addEvent(node,'mousedown',function(e){obj.mouseDown(e)});addEvent(node,'mousemove',function(e){obj.mouseMove(e)});addEvent(node,'mouseup',function(e){obj.mouseUp(e)});addEvent(node,'touchstart',function(e){obj.mouseDown(e)});addEvent(node,'touchmove',function(e){obj.mouseMove(e)});addEvent(node,'touchend',function(e){obj.mouseUp(e)})};DragResize.prototype.select=function(newElement){with(this){if(!document.getElementById||!enabled)return;if(newElement&&(newElement!=element)&&enabled){element=newElement;element.style.zIndex=++zIndex;if(this.resizeHandleSet)this.resizeHandleSet(element,true);var eCS=element.currentStyle||window.getComputedStyle(element,null);if(eCS.right){element.style.left=element.offsetLeft+'px';element.style.right=''}if(eCS.bottom){element.style.top=element.offsetTop+'px';element.style.bottom=''}elmX=parseInt(element.style.left);elmY=parseInt(element.style.top);elmW=element.clientWidth||element.offsetWidth;elmH=element.clientHeight||element.offsetHeight;if(ondragfocus)this.ondragfocus()}}};DragResize.prototype.deselect=function(delHandles){with(this){if(!document.getElementById||!enabled)return;if(delHandles){if(ondragblur)this.ondragblur();if(this.resizeHandleSet)this.resizeHandleSet(element,false);element=null}handle=null;mOffX=0;mOffY=0}};DragResize.prototype.mouseDown=function(e){with(this){if(!document.getElementById||!enabled)return true;if(e.touches&&e.touches.length)this.mouseMove(e);var elm=e.target||e.srcElement,newElement=null,newHandle=null,hRE=new RegExp(myName+'-([trmbl]{2})','');while(elm){if(elm.className){if(!newHandle&&(hRE.test(elm.className)||isHandle(elm)))newHandle=elm;if(isElement(elm)){newElement=elm;break}} elm=elm.parentNode}if(element&&(element!=newElement)&&allowBlur)deselect(true);if(newElement&&(!element||(newElement==element))){if(newHandle)cancelEvent(e);select(newElement,newHandle);handle=newHandle;if(handle&&ondragstart)this.ondragstart(hRE.test(handle.className))}}};DragResize.prototype.mouseMove=function(e){with(this){if(!document.getElementById||!enabled)return true;var mt=(e.touches&&e.touches.length)?e.touches[0]:e;mouseX=mt.pageX||mt.clientX+document.documentElement.scrollLeft;mouseY=mt.pageY||mt.clientY+document.documentElement.scrollTop;var diffX=mouseX-lastMouseX+mOffX;var diffY=mouseY-lastMouseY+mOffY;mOffX=mOffY=0;lastMouseX=mouseX;lastMouseY=mouseY;if(!handle)return true;var isResize=false;if(this.resizeHandleDrag&&this.resizeHandleDrag(diffX,diffY)){isResize=true}else{var dX=diffX,dY=diffY;if(elmX+dXmaxLeft)mOffX=(dX-(diffX=maxLeft-elmX-elmW));if(elmY+dYmaxTop)mOffY=(dY-(diffY=maxTop-elmY-elmH));elmX+=diffX;elmY+=diffY}element.style.left=(Math.round(elmX/gridX)*gridX)+'px';element.style.top=(Math.round(elmY/gridY)*gridY)+'px';if(isResize){element.style.width=(Math.round(elmW/gridX)*gridX)+'px';element.style.height=(Math.round(elmH/gridY)*gridY)+'px'}if(window.opera&&document.documentElement){var oDF=document.getElementById('op-drag-fix');if(!oDF){var oDF=document.createElement('input');oDF.id='op-drag-fix';oDF.style.display='none';document.body.appendChild(oDF)}oDF.focus()}if(ondragmove)this.ondragmove(isResize);cancelEvent(e)}};DragResize.prototype.mouseUp=function(e){with(this){if(!document.getElementById||!enabled)return;var hRE=new RegExp(myName+'-([trmbl]{2})','');if(handle&&ondragend)this.ondragend(hRE.test(handle.className));deselect(false)}};DragResize.prototype.resizeHandleSet=function(elm,show){with(this){if(!elm._handle_tr){for(var h=0;h=0){if(elmH-dY=0){if(elmH+dYmaxTop)mOffY=(dY-(diffY=maxTop-elmY-elmH));elmH+=diffY;processed=true}if(hClass.indexOf('l')>=0){if(elmW-dX=0){if(elmW+dXmaxLeft)mOffX=(dX-(diffX=maxLeft-elmX-elmW));elmW+=diffX;processed=true}return processed}}; 12 | 13 | /* 14 | * resize-polyfill 1.1.0 15 | * (c) 2005-2013 Cezary Daniel Nowak 16 | * https://github.com/CezaryDanielNowak/css-resize-polyfill 17 | * Licenced under the MIT 18 | */ 19 | (function() { 20 | var resizeSupported = document.createElement('textarea').style.resize !== undefined; 21 | var resizeHandlerPolyfill = function(target, force) { 22 | if (!target) { 23 | return resizeSupported ? 'native' : 'polyfill'; 24 | } 25 | 26 | if (target.length) { 27 | // element list provided 28 | for (var i = target.length; i--;) { 29 | resizeHandlerPolyfill(target[i], force); 30 | } 31 | } else { 32 | if (target.tagName === 'TEXTAREA') { 33 | target = target.parentNode; 34 | } 35 | target.className += ' resize-polyfill-wrapper'; 36 | if (resizeSupported && !force) { 37 | return; 38 | } 39 | 40 | var dragresize = new DragResize('resize-polyfill', { 41 | handles: ['br'], 42 | minWidth: 50, 43 | minHeight: 50, 44 | allowBlur: false 45 | }); 46 | 47 | dragresize.isElement = function(elm) { 48 | return elm === target; 49 | }; 50 | dragresize.isHandle = function(elm) {return false}; 51 | 52 | dragresize.ondragfocus = function() { }; 53 | dragresize.ondragstart = function(isResize) { }; 54 | dragresize.ondragmove = function(isResize) { }; 55 | dragresize.ondragend = function(isResize) { }; 56 | dragresize.ondragblur = function() { }; 57 | 58 | var child = target.children[0]; 59 | if (child && child.tagName === "TEXTAREA") { 60 | target.style.width = child.offsetWidth + 'px'; 61 | target.style.height = child.offsetHeight + 'px'; 62 | child.style.resize = 'none'; 63 | } else { 64 | target.style.resize = 'none'; 65 | } 66 | 67 | dragresize.apply(document); 68 | dragresize.select(target); // required to show handler on bottom-right 69 | target.className += ' resize-polyfill-polyfilled'; 70 | } 71 | } 72 | 73 | if (typeof module !== 'undefined') { 74 | module.exports = resizeHandlerPolyfill; 75 | } else { 76 | window.resizeHandlerPolyfill = resizeHandlerPolyfill; 77 | } 78 | 79 | if (typeof window !== 'undefined') { 80 | var css = '.resize-polyfill-wrapper {position: relative;top: auto !important;left: auto !important;}\n\ 81 | .resize-polyfill-polyfilled textarea {width: 100%;height: 100%;}\n\ 82 | .resize-polyfill-br {background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAALUlEQVR42mNgwAH279//H4QZyFYAAv///5fBqQurCQQVEHQMVjaMAQQc2BQAABXMU79BvB5bAAAAAElFTkSuQmCC") no-repeat center center;border: 2px solid transparent;bottom: 0px;cursor: se-resize;height: 8px;position: absolute;right: 0px;width: 8px;}', 83 | head = document.head || document.getElementsByTagName('head')[0], 84 | style = document.createElement('style'); 85 | 86 | if (style.styleSheet){ 87 | style.styleSheet.cssText = css; 88 | } else { 89 | style.appendChild(document.createTextNode(css)); 90 | } 91 | 92 | head.appendChild(style); 93 | } 94 | })(); 95 | --------------------------------------------------------------------------------