fabric
Version:
Object model for HTML5 canvas, and SVG-to-canvas parser. Backed by jsdom and node-canvas.
3 lines (2 loc) • 11.9 kB
JavaScript
import{defineProperty as t,objectSpread2 as e}from"../../../_virtual/_rollupPluginBabelHelpers.min.mjs";import{Point as s}from"../../Point.min.mjs";import{FabricText as i}from"../Text/Text.min.mjs";import{animate as n}from"../../util/animation/animate.min.mjs";import{getDocumentFromElement as o}from"../../util/dom_misc.min.mjs";import{reNewline as r,MODIFIED as h,LEFT as a,RIGHT as l}from"../../constants.min.mjs";const c=/[ \n\.,;!\?\-]/;class d extends i{constructor(){super(...arguments),t(this,"_currentCursorOpacity",1)}initBehavior(){this._tick=this._tick.bind(this),this._onTickComplete=this._onTickComplete.bind(this),this.updateSelectionOnMouseMove=this.updateSelectionOnMouseMove.bind(this)}onDeselect(t){return this.isEditing&&this.exitEditing(),this.selected=!1,super.onDeselect(t)}_animateCursor(t){let{toValue:e,duration:s,delay:i,onComplete:o}=t;return n({startValue:this._currentCursorOpacity,endValue:e,duration:s,delay:i,onComplete:o,abort:()=>!this.canvas||this.selectionStart!==this.selectionEnd,onChange:t=>{this._currentCursorOpacity=t,this.renderCursorOrSelection()}})}_tick(t){this._currentTickState=this._animateCursor({toValue:0,duration:this.cursorDuration/2,delay:Math.max(t||0,100),onComplete:this._onTickComplete})}_onTickComplete(){var t;null===(t=this._currentTickCompleteState)||void 0===t||t.abort(),this._currentTickCompleteState=this._animateCursor({toValue:1,duration:this.cursorDuration,onComplete:this._tick})}initDelayedCursor(t){this.abortCursorAnimation(),this._tick(t?0:this.cursorDelay)}abortCursorAnimation(){let t=!1;[this._currentTickState,this._currentTickCompleteState].forEach((e=>{e&&!e.isDone()&&(t=!0,e.abort())})),this._currentCursorOpacity=1,t&&this.clearContextTop()}restartCursorIfNeeded(){[this._currentTickState,this._currentTickCompleteState].some((t=>!t||t.isDone()))&&this.initDelayedCursor()}selectAll(){return this.selectionStart=0,this.selectionEnd=this._text.length,this._fireSelectionChanged(),this._updateTextarea(),this}cmdAll(){this.selectAll(),this.renderCursorOrSelection()}getSelectedText(){return this._text.slice(this.selectionStart,this.selectionEnd).join("")}findWordBoundaryLeft(t){let e=0,s=t-1;if(this._reSpace.test(this._text[s]))for(;this._reSpace.test(this._text[s]);)e++,s--;for(;/\S/.test(this._text[s])&&s>-1;)e++,s--;return t-e}findWordBoundaryRight(t){let e=0,s=t;if(this._reSpace.test(this._text[s]))for(;this._reSpace.test(this._text[s]);)e++,s++;for(;/\S/.test(this._text[s])&&s<this._text.length;)e++,s++;return t+e}findLineBoundaryLeft(t){let e=0,s=t-1;for(;!/\n/.test(this._text[s])&&s>-1;)e++,s--;return t-e}findLineBoundaryRight(t){let e=0,s=t;for(;!/\n/.test(this._text[s])&&s<this._text.length;)e++,s++;return t+e}searchWordBoundary(t,e){const s=this._text;let i=t>0&&this._reSpace.test(s[t])&&(-1===e||!r.test(s[t-1]))?t-1:t,n=s[i];for(;i>0&&i<s.length&&!c.test(n);)i+=e,n=s[i];return-1===e&&c.test(n)&&i++,i}selectWord(t){var e;t=null!==(e=t)&&void 0!==e?e:this.selectionStart;const s=this.searchWordBoundary(t,-1),i=Math.max(s,this.searchWordBoundary(t,1));this.selectionStart=s,this.selectionEnd=i,this._fireSelectionChanged(),this._updateTextarea(),this.renderCursorOrSelection()}selectLine(t){var e;t=null!==(e=t)&&void 0!==e?e:this.selectionStart;const s=this.findLineBoundaryLeft(t),i=this.findLineBoundaryRight(t);this.selectionStart=s,this.selectionEnd=i,this._fireSelectionChanged(),this._updateTextarea()}enterEditing(t){!this.isEditing&&this.editable&&(this.enterEditingImpl(),this.fire("editing:entered",t?{e:t}:void 0),this._fireSelectionChanged(),this.canvas&&(this.canvas.fire("text:editing:entered",{target:this,e:t}),this.canvas.requestRenderAll()))}enterEditingImpl(){this.canvas&&(this.canvas.calcOffset(),this.canvas.textEditingManager.exitTextEditing()),this.isEditing=!0,this.initHiddenTextarea(),this.hiddenTextarea.focus(),this.hiddenTextarea.value=this.text,this._updateTextarea(),this._saveEditingProps(),this._setEditingProps(),this._textBeforeEdit=this.text,this._tick()}updateSelectionOnMouseMove(t){if(this.getActiveControl())return;const e=this.hiddenTextarea;o(e).activeElement!==e&&e.focus();const s=this.getSelectionStartFromPointer(t),i=this.selectionStart,n=this.selectionEnd;(s===this.__selectionStartOnMouseDown&&i!==n||i!==s&&n!==s)&&(s>this.__selectionStartOnMouseDown?(this.selectionStart=this.__selectionStartOnMouseDown,this.selectionEnd=s):(this.selectionStart=s,this.selectionEnd=this.__selectionStartOnMouseDown),this.selectionStart===i&&this.selectionEnd===n||(this._fireSelectionChanged(),this._updateTextarea(),this.renderCursorOrSelection()))}_setEditingProps(){this.hoverCursor="text",this.canvas&&(this.canvas.defaultCursor=this.canvas.moveCursor="text"),this.borderColor=this.editingBorderColor,this.hasControls=this.selectable=!1,this.lockMovementX=this.lockMovementY=!0}fromStringToGraphemeSelection(t,e,s){const i=s.slice(0,t),n=this.graphemeSplit(i).length;if(t===e)return{selectionStart:n,selectionEnd:n};const o=s.slice(t,e);return{selectionStart:n,selectionEnd:n+this.graphemeSplit(o).length}}fromGraphemeToStringSelection(t,e,s){const i=s.slice(0,t).join("").length;if(t===e)return{selectionStart:i,selectionEnd:i};return{selectionStart:i,selectionEnd:i+s.slice(t,e).join("").length}}_updateTextarea(){if(this.cursorOffsetCache={},this.hiddenTextarea){if(!this.inCompositionMode){const t=this.fromGraphemeToStringSelection(this.selectionStart,this.selectionEnd,this._text);this.hiddenTextarea.selectionStart=t.selectionStart,this.hiddenTextarea.selectionEnd=t.selectionEnd}this.updateTextareaPosition()}}updateFromTextArea(){if(!this.hiddenTextarea)return;this.cursorOffsetCache={};const t=this.hiddenTextarea;this.text=t.value,this.set("dirty",!0),this.initDimensions(),this.setCoords();const e=this.fromStringToGraphemeSelection(t.selectionStart,t.selectionEnd,t.value);this.selectionEnd=this.selectionStart=e.selectionEnd,this.inCompositionMode||(this.selectionStart=e.selectionStart),this.updateTextareaPosition()}updateTextareaPosition(){if(this.selectionStart===this.selectionEnd){const t=this._calcTextareaPosition();this.hiddenTextarea.style.left=t.left,this.hiddenTextarea.style.top=t.top}}_calcTextareaPosition(){if(!this.canvas)return{left:"1px",top:"1px"};const t=this.inCompositionMode?this.compositionStart:this.selectionStart,e=this._getCursorBoundaries(t),i=this.get2DCursorLocation(t),n=i.lineIndex,o=i.charIndex,r=this.getValueOfPropertyAt(n,o,"fontSize")*this.lineHeight,h=e.leftOffset,a=this.getCanvasRetinaScaling(),l=this.canvas.upperCanvasEl,c=l.width/a,d=l.height/a,u=c-r,f=d-r,p=new s(e.left+h,e.top+e.topOffset+r).transform(this.calcTransformMatrix()).transform(this.canvas.viewportTransform).multiply(new s(l.clientWidth/c,l.clientHeight/d));return p.x<0&&(p.x=0),p.x>u&&(p.x=u),p.y<0&&(p.y=0),p.y>f&&(p.y=f),p.x+=this.canvas._offset.left,p.y+=this.canvas._offset.top,{left:"".concat(p.x,"px"),top:"".concat(p.y,"px"),fontSize:"".concat(r,"px"),charHeight:r}}_saveEditingProps(){this._savedProps={hasControls:this.hasControls,borderColor:this.borderColor,lockMovementX:this.lockMovementX,lockMovementY:this.lockMovementY,hoverCursor:this.hoverCursor,selectable:this.selectable,defaultCursor:this.canvas&&this.canvas.defaultCursor,moveCursor:this.canvas&&this.canvas.moveCursor}}_restoreEditingProps(){this._savedProps&&(this.hoverCursor=this._savedProps.hoverCursor,this.hasControls=this._savedProps.hasControls,this.borderColor=this._savedProps.borderColor,this.selectable=this._savedProps.selectable,this.lockMovementX=this._savedProps.lockMovementX,this.lockMovementY=this._savedProps.lockMovementY,this.canvas&&(this.canvas.defaultCursor=this._savedProps.defaultCursor||this.canvas.defaultCursor,this.canvas.moveCursor=this._savedProps.moveCursor||this.canvas.moveCursor),delete this._savedProps)}_exitEditing(){const t=this.hiddenTextarea;this.selected=!1,this.isEditing=!1,t&&(t.blur&&t.blur(),t.parentNode&&t.parentNode.removeChild(t)),this.hiddenTextarea=null,this.abortCursorAnimation(),this.selectionStart!==this.selectionEnd&&this.clearContextTop()}exitEditingImpl(){this._exitEditing(),this.selectionEnd=this.selectionStart,this._restoreEditingProps(),this._forceClearCache&&(this.initDimensions(),this.setCoords())}exitEditing(){const t=this._textBeforeEdit!==this.text;return this.exitEditingImpl(),this.fire("editing:exited"),t&&this.fire(h),this.canvas&&(this.canvas.fire("text:editing:exited",{target:this}),t&&this.canvas.fire("object:modified",{target:this})),this}_removeExtraneousStyles(){for(const t in this.styles)this._textLines[t]||delete this.styles[t]}removeStyleFromTo(t,e){const{lineIndex:s,charIndex:i}=this.get2DCursorLocation(t,!0),{lineIndex:n,charIndex:o}=this.get2DCursorLocation(e,!0);if(s!==n){if(this.styles[s])for(let t=i;t<this._unwrappedTextLines[s].length;t++)delete this.styles[s][t];if(this.styles[n])for(let t=o;t<this._unwrappedTextLines[n].length;t++){const e=this.styles[n][t];e&&(this.styles[s]||(this.styles[s]={}),this.styles[s][i+t-o]=e)}for(let t=s+1;t<=n;t++)delete this.styles[t];this.shiftLineStyles(n,s-n)}else if(this.styles[s]){const t=this.styles[s],e=o-i;for(let e=i;e<o;e++)delete t[e];for(const i in this.styles[s]){const s=parseInt(i,10);s>=o&&(t[s-e]=t[i],delete t[i])}}}shiftLineStyles(t,e){const s=Object.assign({},this.styles);for(const i in this.styles){const n=parseInt(i,10);n>t&&(this.styles[n+e]=s[n],s[n-e]||delete this.styles[n])}}insertNewlineStyleObject(t,s,i,n){const o={},r=this._unwrappedTextLines[t].length,h=r===s;let a=!1;i||(i=1),this.shiftLineStyles(t,i);const l=this.styles[t]?this.styles[t][0===s?s:s-1]:void 0;for(const e in this.styles[t]){const i=parseInt(e,10);i>=s&&(a=!0,o[i-s]=this.styles[t][e],h&&0===s||delete this.styles[t][e])}let c=!1;for(a&&!h&&(this.styles[t+i]=o,c=!0),(c||r>s)&&i--;i>0;)n&&n[i-1]?this.styles[t+i]={0:e({},n[i-1])}:l?this.styles[t+i]={0:e({},l)}:delete this.styles[t+i],i--;this._forceClearCache=!0}insertCharStyleObject(t,s,i,n){this.styles||(this.styles={});const o=this.styles[t],r=o?e({},o):{};i||(i=1);for(const t in r){const e=parseInt(t,10);e>=s&&(o[e+i]=r[e],r[e-i]||delete o[e])}if(this._forceClearCache=!0,n){for(;i--;)Object.keys(n[i]).length&&(this.styles[t]||(this.styles[t]={}),this.styles[t][s+i]=e({},n[i]));return}if(!o)return;const h=o[s?s-1:1];for(;h&&i--;)this.styles[t][s+i]=e({},h)}insertNewStyleBlock(t,e,s){const i=this.get2DCursorLocation(e,!0),n=[0];let o,r=0;for(let e=0;e<t.length;e++)"\n"===t[e]?(r++,n[r]=0):n[r]++;for(n[0]>0&&(this.insertCharStyleObject(i.lineIndex,i.charIndex,n[0],s),s=s&&s.slice(n[0]+1)),r&&this.insertNewlineStyleObject(i.lineIndex,i.charIndex+n[0],r),o=1;o<r;o++)n[o]>0?this.insertCharStyleObject(i.lineIndex+o,0,n[o],s):s&&this.styles[i.lineIndex+o]&&s[0]&&(this.styles[i.lineIndex+o][0]=s[0]),s=s&&s.slice(n[o]+1);n[o]>0&&this.insertCharStyleObject(i.lineIndex+o,0,n[o],s)}removeChars(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:t+1;this.removeStyleFromTo(t,e),this._text.splice(t,e-t),this.text=this._text.join(""),this.set("dirty",!0),this.initDimensions(),this.setCoords(),this._removeExtraneousStyles()}insertChars(t,e,s){let i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:s;i>s&&this.removeStyleFromTo(s,i);const n=this.graphemeSplit(t);this.insertNewStyleBlock(n,s,e),this._text=[...this._text.slice(0,s),...n,...this._text.slice(i)],this.text=this._text.join(""),this.set("dirty",!0),this.initDimensions(),this.setCoords(),this._removeExtraneousStyles()}setSelectionStartEndWithShift(t,e,s){s<=t?(e===t?this._selectionDirection=a:this._selectionDirection===l&&(this._selectionDirection=a,this.selectionEnd=t),this.selectionStart=s):s>t&&s<e?this._selectionDirection===l?this.selectionEnd=s:this.selectionStart=s:(e===t?this._selectionDirection=l:this._selectionDirection===a&&(this._selectionDirection=l,this.selectionStart=e),this.selectionEnd=s)}}export{d as ITextBehavior};
//# sourceMappingURL=ITextBehavior.min.mjs.map