{"version":3,"file":"XURL.min.mjs","sources":["../../../../src/shapes/canvasx/XURL.ts"],"sourcesContent":["import { TClassProperties } from '../../typedefs';\nimport { classRegistry } from '../../ClassRegistry';\nimport { Shadow } from '../../Shadow';\nimport { Rect } from '../../shapes/Rect';\nimport { FabricImage } from '../Image';\nimport { createFileDefaultControls } from '../../controls/commonControls';\nimport type { FabricObjectProps, SerializedObjectProps } from '../Object/types';\nimport { getFabricDocument } from '../../env';\n\nimport { LoadImageOptions, loadImage } from '../../util/misc/objectEnlive';\n\nimport type { TOptions } from '../../typedefs';\n\nexport type ImageSource =\n  | string\n  | HTMLImageElement\n  | HTMLVideoElement\n  | HTMLCanvasElement;\n\ninterface UniqueImageProps {\n  srcFromAttribute: boolean;\n  minimumScaleTrigger: number;\n  cropX: number;\n  cropY: number;\n  imageSmoothing: boolean;\n  crossOrigin: string | null;\n  url: string;\n}\n\nexport const UrlImageDefaultValues: Partial<TClassProperties<XURL>> = {\n  minWidth: 20,\n  dynamicMinWidth: 2,\n  lockScalingFlip: true,\n  noScaleCache: false,\n  splitByGrapheme: true,\n  objType: 'XURL',\n  height: 200,\n  maxHeight: 200,\n  width: 230,\n};\n\nexport interface SerializedImageProps extends SerializedObjectProps {\n  src: string;\n  crossOrigin: string | null;\n  filters: any[];\n  resizeFilter?: any;\n  cropX: number;\n  cropY: number;\n  url: string;\n}\nexport interface UrlImageProps extends FabricObjectProps, UniqueImageProps {}\n\nexport class XURL<\n  Props extends TOptions<UrlImageProps> = Partial<UrlImageProps>\n> extends FabricImage<Props> {\n  declare minWidth: number;\n\n  /* boardx cusotm function */\n  declare id: string;\n  declare maxHeight: number;\n\n  declare objType: string;\n\n  declare locked: boolean;\n\n  declare whiteboardId: string;\n\n  declare userId: string;\n\n  declare timestamp: Date;\n\n  declare verticalAlign: string;\n\n  declare zIndex: number;\n\n  declare url: string | undefined;\n\n  declare lines: object[];\n\n  declare title: string;\n\n  declare relationship: object[];\n\n  declare description: string;\n\n  public extendPropeties = [\n    'objType',\n    'whiteboardId',\n    'userId',\n    'timestamp',\n    'zIndex',\n    'locked',\n    'verticalAlign',\n    'lines',\n    'id',\n    'zIndex',\n    'relationship',\n    'url',\n    'title',\n  ];\n\n  declare dynamicMinWidth: number;\n\n  /**\n   * Use this boolean property in order to split strings that have no white space concept.\n   * this is a cheap way to help with chinese/japanese\n   * @type Boolean\n   * @since 2.6.0\n   */\n  declare splitByGrapheme: boolean;\n\n  static ownDefaults: Record<string, any> = UrlImageDefaultValues;\n\n  static getDefaults() {\n    return {\n      ...super.getDefaults(),\n      controls: createFileDefaultControls(),\n      ...XURL.ownDefaults,\n    };\n  }\n\n  //@ts-ignore\n  constructor(element: ImageSource, options: Props) {\n    super(element.toString(), options);\n    this.filters = [];\n\n    this.url = options.url;\n    this.title = options.title;\n    this.description = options.description;\n\n    this.shadow = new Shadow({\n      color: 'rgba(217, 161, 177, 0.54)',\n      offsetX: 1,\n      offsetY: 2,\n      blur: 4,\n      id: 310,\n    });\n\n    (this.clipPath = new Rect({\n      left: 0,\n      top: 0,\n      rx: 8,\n      ry: 8,\n      width: 230,\n      height: 248,\n      fill: '#000000',\n    })),\n      // double click\n      this.InitializeEvent();\n    // this.initDoubleClickSimulation();\n    this.width = 230;\n    this.height = 248;\n  }\n  //   setElement(element: ImageSource, size: Partial<TSize> = {}) {\n  //     this.removeTexture(this.cacheKey);\n  //     this.removeTexture(`${this.cacheKey}_filtered`);\n  //     this._element = element as ImageSource;\n  //     this._originalElement = element as ImageSource;\n  //     this._setWidthHeight(size);\n  //     // element.classList.add(XURL.CSS_CANVAS);\n  //     if (this.filters.length !== 0) {\n  //         this.applyFilters();\n  //     }\n  //     // resizeFilters work on the already filtered copy.\n  //     // we need to apply resizeFilters AFTER normal filters.\n  //     // applyResizeFilters is run more often than normal filters\n  //     // and is triggered by user interactions rather than dev code\n  //     if (this.resizeFilter) {\n  //       this.applyResizeFilters();\n  //     }\n  //   }\n\n  //   toObject(propertiesToInclude: Array<any>): object {\n  //     return super.toObject(\n  //       [...this.extendPropeties, 'minWidth', 'splitByGrapheme'].concat(\n  //         propertiesToInclude\n  //       )\n  //     );\n  //   }\n  getWidgetMenuList() {\n    if (this.locked) {\n      return ['objectLock'];\n    }\n    return ['more', 'objectLock', 'delete'];\n  }\n  getWidgetMenuLength() {\n    if (this.locked) return 50;\n    return 60;\n  }\n  getContextMenuList() {\n    let menuList;\n    if (this.locked) {\n      menuList = [\n        'Bring forward',\n        'Bring to front',\n        'Send backward',\n        'Send to back',\n      ];\n    } else {\n      menuList = [\n        'Bring forward',\n        'Bring to front',\n        'Send backward',\n        'Send to back',\n        'Duplicate',\n        'Copy',\n        'Paste',\n        'Cut',\n        'Delete',\n      ];\n    }\n\n    if (this.locked) {\n      menuList.push('Unlock');\n    } else {\n      menuList.push('Lock');\n    }\n    return menuList;\n  }\n\n  InitializeEvent = () => {\n    const zoom = this.canvas?.getZoom() || 1;\n    // this.on('mousedblclick', (memo) => {\n    //   const offsetX =\n    //     (memo.e as MouseEvent).offsetX - (this.left - this.width / 2);\n    //   const offsetY =\n    //     (memo.e as MouseEvent).offsetY - (this.top - this.height / 2);\n\n    //   if (\n    //     offsetX < 20 ||\n    //     offsetX > 480 ||\n    //     offsetY < 20 ||\n    //     offsetY > 480 ||\n    //     (offsetY > 64 && offsetY < 446)\n    //   ) {\n    //     getWindow()?.open(this.url, '_blank').focus();\n    //   } else {\n    //     let text = this.title;\n    //     const textarea = document.getElementById('urlTextarea');\n    //     const cvsPosition = document\n    //       .getElementById('canvasContainer')\n    //       ?.getBoundingClientRect();\n    //     let fontSize = 20 * this.scaleX * zoom;\n    //     const left = `${\n    //       cvsPosition.left +\n    //       (this.left - (this.width / 2 - 22) * this.scaleX) * zoom\n    //     }px`;\n    //     let top = `${\n    //       cvsPosition?.top +\n    //       (this.top - (this.height / 2 - 22) * this.scaleY) * zoom\n    //     }px`;\n    //     const newWidth = (this.width - 44) * this.scaleX * zoom;\n    //     const width = `${newWidth}px`;\n    //     let height = `${40 * this.scaleY * zoom}px`;\n    //     const paddingLeft = `${10 * this.scaleY * zoom}px`;\n    //     let lineHeight = '40px';\n    //     textarea.data('type', 'title');\n    //     if (offsetY >= 446) {\n    //       text = this.description;\n    //       fontSize = 15 * this.scaleX * zoom;\n    //       top = `${\n    //         cvsPosition.top +\n    //         (this.top + (this.height / 2 - 52) * this.scaleY) * zoom\n    //       }px`;\n    //       height = `${30 * this.scaleY * zoom}px`;\n    //       lineHeight = '30px';\n    //       textarea.data('type', 'description');\n    //     }\n    //     textarea\n    //       .data('widget', this)\n    //       .css('left', left)\n    //       .css('top', top)\n    //       .css('padding-left', paddingLeft)\n    //       .css('width', width)\n    //       .css('height', height)\n    //       .css('background-color', 'white')\n    //       .css('font-size', `${fontSize}px`)\n    //       .css('font-family', 'Arial')\n    //       .css('line-height', lineHeight)\n    //       .val(text)\n    //       .show()\n    //       .focus();\n    //   }\n    // });\n    // this.on('removed', this.removedListener);\n  };\n  //   removedListener() {\n  //     if (this.loading) {\n  //       this.loading.remove();\n  //       this.loading = null;\n  //     }\n  //   }\n  //   initDoubleClickSimulation() {\n  //     this.__lastClickTime = +new Date();\n  //     this.on('touchstart', this.onMouseDown.bind(this));\n  //     this.on('mousedown', this.onMouseDown.bind(this));\n  //   }\n  //   onMouseDown(options) {\n  //     this.__newClickTime = +new Date();\n  //     if (this.__newClickTime - this.__lastClickTime < 500) {\n  //       this.lockMovementX = true;\n  //       this.lockMovementY = true;\n  //       this.fire('dblclick', options);\n  //       this._stopEvent(options.e);\n  //     } else {\n  //       this.lockMovementX = false;\n  //       this.lockMovementY = false;\n  //     }\n\n  //     this.__lastClickTime = this.__newClickTime;\n  //   }\n  _stopEvent(e: any) {\n    e.preventDefault();\n    e.stopPropagation();\n  }\n\n  drawObject(ctx: CanvasRenderingContext2D) {\n    let elementToDraw = null;\n\n    // draw border\n    ctx.beginPath();\n    ctx.fillStyle = 'rgba(255,255,255,0)';\n    ctx.fillRect(-this.width / 2, -this.height / 2, this.width, this.height);\n    ctx.lineWidth = 0;\n    ctx.strokeStyle = '#ffffff';\n    ctx.moveTo(-this.width / 2, -this.height / 2);\n    ctx.stroke();\n\n    if (\n      this.isMoving === false &&\n      //   this.resizeFilters.length &&\n      this._needsResize()\n    ) {\n      this._lastScaleX = this.scaleX;\n      this._lastScaleY = this.scaleY;\n      //   elementToDraw = this.applyFilters(\n      //     null,\n      //     this.resizeFilters,\n      //     this._filteredEl || this._originalElement,\n      //     true\n      //   );\n    } else {\n      elementToDraw = this._element;\n    }\n\n    if (elementToDraw) {\n      ctx.drawImage(elementToDraw, -this.width / 2, -this.height / 2, 230, 160);\n    }\n\n    this.renderTitle(ctx, this.title);\n\n    this._renderStroke(ctx);\n  }\n  renderDescription(ctx: any) {\n    const maxWidth = this.width;\n\n    ctx.font = '10px Arial';\n    ctx.fillStyle = 'rgba(255, 255, 255, 0.5)';\n    const x = -this.width / 2;\n    const y = this.height / 2;\n\n    ctx.font = '18px Arial';\n    ctx.fillStyle = 'rgba(0, 0, 0)';\n    this.splitByGrapheme = true;\n    this.wrapText(ctx, this.description, x, y, maxWidth, 18);\n  }\n  renderTitle(ctx: any, title: any) {\n    const maxWidth = this.width;\n    const x = -this.width / 2;\n    const y = this.height / 2 - 60;\n\n    ctx.font = '16px Arial';\n    ctx.fillStyle = 'rgba(255, 255, 255, 1)';\n\n    // white board behind the title\n    ctx.fillRect(x, y - 29, maxWidth, 90);\n    ctx.fillStyle = '#190FA1';\n\n    // helper function to convert string\n    const GB2312UnicodeConverter = {\n      ToUnicode(str: string) {\n        return escape(str).toLocaleLowerCase().replace(/%u/gi, '\\\\u');\n      },\n      ToGB2312(str: string) {\n        return unescape(str.replace(/\\\\u/gi, '%u'));\n      },\n    };\n    // Handle non-unicode or non-utf8 coding string\n    const unicodeTitle = GB2312UnicodeConverter.ToUnicode(title);\n    if (!this.url && this.src) {\n      this.url = this.src;\n    }\n    // handle the situation that the website's title is null\n    if (\n      (title === null || unicodeTitle.indexOf('\\\\ufffd') !== -1 || !title) &&\n      this.url\n    ) {\n      const firstChar = this.url.indexOf('.');\n      const lastChar = this.url.indexOf('.', firstChar + 1);\n      this.title = this.url.substring(firstChar + 1, lastChar);\n    }\n\n    // title setting\n    this.wrapText(ctx, title, x + 15, y - 5, maxWidth - 20, 23);\n\n    // url setting\n    const newurl = `${this.url?.split('/')[0]}/${this.url?.split('/')[1]}/${\n      this.url?.split('/')[2]\n    }`;\n    ctx.font = '12px Arial';\n    ctx.fillStyle = 'rgba(35, 41, 48, 0.65)';\n    // gray square in front of website\n    this.wrapText(ctx, newurl, x + 15, y + 45, maxWidth - 20, 25);\n  }\n  renderPublishDate(ctx: any) {\n    const maxWidth = this.width;\n\n    ctx.font = '10px Arial';\n    ctx.fillStyle = 'rgba(255, 255, 255, 0.5)';\n    const x = -this.width / 2 + 20;\n    const y = this.height / 2 - 10;\n    ctx.fillStyle = 'rgba(0, 0, 0, 0.5)';\n\n    ctx.fillRect(-this.width / 2, y - 20, maxWidth, 30);\n\n    ctx.font = '18px Arial';\n    ctx.fillStyle = 'rgba(255, 255, 255, 1)';\n    // this.wrapText(\n    //   ctx,\n    //   `${this.publisher}:${new Date(this.publishedDate).toDateString()}`,\n    //   x,\n    //   y,\n    //   maxWidth,\n    //   18\n    // );\n  }\n  wrapText(\n    context: any,\n    text: any,\n    x: any,\n    y: any,\n    maxWidth: number,\n    lineHeight: number\n  ) {\n    let words = '';\n    if (text) words = text.split(' ');\n\n    let line = '';\n    let lineCount = 1;\n    let tempLine = '';\n    let _y = y;\n\n    // handle non-English char\n    if (escape(text).indexOf('%u') < 0) {\n      // only the English char\n      for (let n = 0; n < words.length; n++) {\n        if (lineCount === 3) return;\n        if (n !== 0) tempLine = `${line.slice(0, -3)}...`;\n        const testLine = `${line + words[n]} `;\n        const metrics = context.measureText(testLine);\n        const testWidth = metrics.width;\n        if (testWidth > maxWidth && n > 0) {\n          if (lineCount === 2) {\n            line = tempLine;\n          }\n          context.fillText(line, x, _y);\n          line = `${words[n]} `;\n          _y += lineHeight;\n          lineCount++;\n        } else {\n          line = testLine;\n        }\n      }\n    } else {\n      for (let n = 0; n < text.length; n++) {\n        if (lineCount === 3) return;\n        if (n !== 0) tempLine = `${line.slice(0, -2)}...`;\n        const testLine = `${line + text[n]}`;\n        const metrics = context.measureText(testLine);\n        const testWidth = metrics.width;\n        if (testWidth > maxWidth && n > 0) {\n          if (lineCount === 2) {\n            line = tempLine;\n          }\n          context.fillText(line, x, _y);\n          line = `${text[n]}`;\n          _y += lineHeight;\n          lineCount++;\n        } else {\n          line = testLine;\n        }\n      }\n    }\n    if (lineCount < 3) context.fillText(line, x, _y);\n  }\n\n  fromURL<T extends TOptions<SerializedImageProps>>(\n    url: string,\n    options: any\n  ): Promise<XURL> {\n    return new Promise((resolve, reject) => {\n      const img = new Image();\n      const cvs = getFabricDocument().createElement('canvas');\n      const ctx = cvs.getContext('2d');\n      //   img.crossOrigin = '';\n      //@ts-ignore\n      img.onload = async function () {\n        // fix size version\n        cvs.width = 230;\n        cvs.height = 160; // 230 / img.width * img.height;\n        ctx?.drawImage(img, 0, 0, 230, 160);\n\n        const imgOptions: LoadImageOptions = {\n          crossOrigin: 'anonymous',\n          ...options,\n        };\n\n        try {\n          const loadedImg = await loadImage(cvs.toDataURL(), imgOptions);\n          resolve(new XURL(loadedImg, options));\n        } catch (error) {\n          reject(error);\n        }\n      };\n\n      img.onerror = function (error: any) {\n        reject(error);\n      };\n\n      img.src = url;\n    });\n  }\n}\n\nclassRegistry.setClass(XURL);\n"],"names":["UrlImageDefaultValues","minWidth","dynamicMinWidth","lockScalingFlip","noScaleCache","splitByGrapheme","objType","height","maxHeight","width","XURL","FabricImage","getDefaults","_objectSpread","super","controls","createFileDefaultControls","ownDefaults","constructor","element","options","toString","_defineProperty","this","_this$canvas","canvas","getZoom","filters","url","title","description","shadow","Shadow","color","offsetX","offsetY","blur","id","clipPath","Rect","left","top","rx","ry","fill","InitializeEvent","getWidgetMenuList","locked","getWidgetMenuLength","getContextMenuList","menuList","push","_stopEvent","e","preventDefault","stopPropagation","drawObject","ctx","elementToDraw","beginPath","fillStyle","fillRect","lineWidth","strokeStyle","moveTo","stroke","isMoving","_needsResize","_lastScaleX","scaleX","_lastScaleY","scaleY","_element","drawImage","renderTitle","_renderStroke","renderDescription","maxWidth","font","x","y","wrapText","_this$url","_this$url2","_this$url3","unicodeTitle","ToUnicode","str","escape","toLocaleLowerCase","replace","ToGB2312","unescape","src","indexOf","firstChar","lastChar","substring","newurl","concat","split","renderPublishDate","context","text","lineHeight","words","line","lineCount","tempLine","_y","n","length","slice","testLine","measureText","fillText","fromURL","Promise","resolve","reject","img","Image","cvs","getFabricDocument","createElement","getContext","onload","async","imgOptions","crossOrigin","loadedImg","loadImage","toDataURL","error","onerror","classRegistry","setClass"],"mappings":"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"}