1836 lines
		
	
	
		
			52 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
			
		
		
	
	
			1836 lines
		
	
	
		
			52 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
/**
 | 
						||
 * 原生js项目widget模块化框架
 | 
						||
 */
 | 
						||
 | 
						||
;(function () {
 | 
						||
  const Loader = window.Loader //loader.js中定义
 | 
						||
  const jQuery = window.jQuery
 | 
						||
  if (!jQuery) {
 | 
						||
    throw new Error("请引入 jQuery 库")
 | 
						||
  }
 | 
						||
 | 
						||
  const layer = window.layer // 请引入layer弹窗插件
 | 
						||
  if (!window.layer) {
 | 
						||
    throw new Error("请引入 layer.js弹窗 库")
 | 
						||
  }
 | 
						||
 | 
						||
  // 内部参数
 | 
						||
  let thismap
 | 
						||
  let basePath = ""
 | 
						||
  let widgetsdata = []
 | 
						||
  let defoptions
 | 
						||
  let cacheVersion
 | 
						||
  let isdebuger
 | 
						||
  const removeKeys = ["_class"]
 | 
						||
 | 
						||
  /**
 | 
						||
   * widget事件类型枚举
 | 
						||
   *  @enum {string}
 | 
						||
   */
 | 
						||
  const WidgetEventType = {
 | 
						||
    /**
 | 
						||
     * 在实例初始化之后、创建之前执行
 | 
						||
     */
 | 
						||
    beforeCreate: "beforeCreate",
 | 
						||
    /**
 | 
						||
     * 实例创建后执行
 | 
						||
     */
 | 
						||
    created: "created",
 | 
						||
    /**
 | 
						||
     * 在activat挂载开始之前调用
 | 
						||
     */
 | 
						||
    beforeActivate: "beforeActivate",
 | 
						||
    /**
 | 
						||
     * activate方法调用后
 | 
						||
     */
 | 
						||
    activated: "activated",
 | 
						||
    /**
 | 
						||
     *view弹窗构造完成后后调用
 | 
						||
     */
 | 
						||
    openView: "openView",
 | 
						||
    /**
 | 
						||
     * 实例销毁之前调用
 | 
						||
     */
 | 
						||
    beforeDisable: "beforeDisable",
 | 
						||
    /**
 | 
						||
     *实例销毁完成调用
 | 
						||
     */
 | 
						||
    disabled: "disabled",
 | 
						||
 | 
						||
    /**
 | 
						||
     *加载完成 未做任何其他处理前
 | 
						||
     */
 | 
						||
    loadBefore: "loadBefore",
 | 
						||
    /**
 | 
						||
     *加载完成,执行所有内部处理后
 | 
						||
     */
 | 
						||
    load: "load"
 | 
						||
  }
 | 
						||
 | 
						||
 /**
 | 
						||
 * 初始化widget管理器,在构造完成map后调用一次即可。
 | 
						||
 *
 | 
						||
 * @param {Map} map 地图对象
 | 
						||
 * @param {object} [widgetcfg={}] 全局配置(一般存放在widget.json),包括:
 | 
						||
 * @param {BaseWidget.widgetOptions} [widgetcfg.defaultOptions] 所有widget的默认参数值,可以系统内所有widget相同配置统一在此处传入,额外的个性化的再配置到各widget中。
 | 
						||
 * @param {BaseWidget.widgetOptions[]} [widgetcfg.openAtStart] 默认自启动并不可释放的插件,其中autoDisable和openAtStart固定,设置无效。
 | 
						||
 * @param {BaseWidget.widgetOptions[]} [widgetcfg.widgets] 所有插件配置,传入后后续激活时,只用传入uri即可。
 | 
						||
 * @param {string} [widgetcfg.version] 加载资源时,附加的参数,主要为了清理浏览器缓存,可选值:"time"(实时时间戳)或固定的字符串值,每次发布新版本换下固定值。
 | 
						||
 * @param {boolean} [widgetcfg.debugger] 是否显示插件测试栏,true时会在地图下侧显示所有插件测试按钮,方便测试。
 | 
						||
 *
 | 
						||
 * @param {string} [_basePath=''] widgets目录所在的主路径(统一前缀), 如果widgets目录不在主页面一起或存在路由时,可以传入自定义主目录,值为 widgets目录相对于当前html页面的相对路径。
 | 
						||
 * @return {void}  无
 | 
						||
 * @example
 | 
						||
let widgetCfg ={
 | 
						||
  "version": "2017",
 | 
						||
  "defaultOptions": {
 | 
						||
    "style": "dark",
 | 
						||
    "windowOptions": {
 | 
						||
      "skin": "layer-mars-dialog animation-scale-up",
 | 
						||
      "position": {
 | 
						||
        "top": 50,
 | 
						||
        "right": 10
 | 
						||
      },
 | 
						||
      "maxmin": false,
 | 
						||
      "resize": true
 | 
						||
    },
 | 
						||
    "autoReset": false,
 | 
						||
    "autoDisable": true,
 | 
						||
    "disableOther": true
 | 
						||
  },
 | 
						||
  "openAtStart": [
 | 
						||
    {
 | 
						||
      "name": "放大缩小按钮",
 | 
						||
      "uri": "widgets/toolButton/zoom.js"
 | 
						||
    }
 | 
						||
  ],
 | 
						||
  "widgets": [
 | 
						||
    {
 | 
						||
      "name": "模板-div弹窗",
 | 
						||
      "uri": "widgets/_example_divwin/widget.js"
 | 
						||
    },
 | 
						||
    {
 | 
						||
      "name": "模板-append模板",
 | 
						||
      "uri": "widgets/_example_append/widget.js"
 | 
						||
    }
 | 
						||
  ]
 | 
						||
}
 | 
						||
es5widget.init(map, widgetCfg, './')
 | 
						||
 */
 | 
						||
  function init(map, widgetcfg = {}, _basePath = "") {
 | 
						||
    thismap = map
 | 
						||
    basePath = _basePath
 | 
						||
 | 
						||
    widgetsdata = []
 | 
						||
    defoptions = mars3d.Util.merge(
 | 
						||
      {
 | 
						||
        windowOptions: { position: "rt", maxmin: false, resize: true },
 | 
						||
        autoDisable: true,
 | 
						||
        disableOther: true
 | 
						||
      },
 | 
						||
      widgetcfg.defaultOptions
 | 
						||
    )
 | 
						||
 | 
						||
    cacheVersion = widgetcfg.version
 | 
						||
    if (cacheVersion === "time") {
 | 
						||
      cacheVersion = new Date().getTime()
 | 
						||
    }
 | 
						||
 | 
						||
    // 将自启动的加入
 | 
						||
    let arrtemp = widgetcfg.openAtStart
 | 
						||
    if (arrtemp && arrtemp.length > 0) {
 | 
						||
      for (let i = 0; i < arrtemp.length; i++) {
 | 
						||
        const item = arrtemp[i]
 | 
						||
        if (!item.hasOwnProperty("uri") || item.uri === "") {
 | 
						||
          // eslint-disable-next-line no-console
 | 
						||
          console.error("widget未配置uri", item)
 | 
						||
          continue
 | 
						||
        }
 | 
						||
        if (item.hasOwnProperty("visible") && !item.visible) {
 | 
						||
          continue
 | 
						||
        }
 | 
						||
 | 
						||
        item.autoDisable = false
 | 
						||
        item.openAtStart = true
 | 
						||
        item._nodebug = true
 | 
						||
 | 
						||
        bindDefOptions(item)
 | 
						||
 | 
						||
        item._firstConfigBak = { ...item }
 | 
						||
        widgetsdata.push(item)
 | 
						||
      }
 | 
						||
    }
 | 
						||
 | 
						||
    // 显示测试栏
 | 
						||
    // 为了方便测试,所有widget会在页面下侧生成一排按钮,每个按钮对应一个widget,单击后激活对应widget
 | 
						||
    isdebuger = widgetcfg.debugger
 | 
						||
    if (isdebuger) {
 | 
						||
      const inhtml =
 | 
						||
        '<div id="widget-testbar" class="mars3d-widgetbar animation-slide-bottom no-print-view" > ' +
 | 
						||
        '     <div style="height: 30px; line-height:30px;"><b style="color: #4db3ff;">widget测试栏</b>  <button  id="widget-testbar-remove"  type="button" class="btn btn-link btn-xs">关闭</button> </div>' +
 | 
						||
        '     <button id="widget-testbar-disableAll" type="button" class="btn btn-info" ><i class="fa fa-globe"></i>漫游</button>' +
 | 
						||
        "</div>"
 | 
						||
      jQuery("body").append(inhtml)
 | 
						||
 | 
						||
      jQuery("#widget-testbar-remove").click(function (e) {
 | 
						||
        removeDebugeBar()
 | 
						||
      })
 | 
						||
      jQuery("#widget-testbar-disableAll").click(function (e) {
 | 
						||
        disableAll()
 | 
						||
      })
 | 
						||
    }
 | 
						||
 | 
						||
    // 将配置的加入
 | 
						||
    arrtemp = widgetcfg.widgets
 | 
						||
    if (arrtemp && arrtemp.length > 0) {
 | 
						||
      for (let i = 0; i < arrtemp.length; i++) {
 | 
						||
        const item = arrtemp[i]
 | 
						||
        if (item.type === "group") {
 | 
						||
          let inhtml =
 | 
						||
            ' <div class="btn-group dropup">  <button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-expanded="false"><i class="fa fa-align-justify"></i>' +
 | 
						||
            item.name +
 | 
						||
            ' <span class="caret"></span></button> <ul class="dropdown-menu">'
 | 
						||
          for (let j = 0; j < item.children.length; j++) {
 | 
						||
            const childItem = item.children[j]
 | 
						||
            if (!childItem.hasOwnProperty("uri") || childItem.uri === "") {
 | 
						||
              // eslint-disable-next-line no-console
 | 
						||
              console.error("widget未配置uri", childItem)
 | 
						||
              continue
 | 
						||
            }
 | 
						||
 | 
						||
            inhtml +=
 | 
						||
              ' <li data-widget="' + childItem.uri + '" class="widget-btn" ><a href="#"><i class="fa fa-star"></i>' + childItem.name + "</a></li>"
 | 
						||
 | 
						||
            bindDefOptions(childItem)
 | 
						||
            childItem._firstConfigBak = { ...childItem }
 | 
						||
            widgetsdata.push(childItem) // 将配置的加入
 | 
						||
          }
 | 
						||
          inhtml += "</ul></div>"
 | 
						||
 | 
						||
          if (isdebuger && !item._nodebug) {
 | 
						||
            jQuery("#widget-testbar").append(inhtml)
 | 
						||
          }
 | 
						||
        } else {
 | 
						||
          if (!item.hasOwnProperty("uri") || item.uri === "") {
 | 
						||
            // eslint-disable-next-line no-console
 | 
						||
            console.error("widget未配置uri", item)
 | 
						||
            continue
 | 
						||
          }
 | 
						||
 | 
						||
          // 显示测试栏
 | 
						||
          if (isdebuger && !item._nodebug) {
 | 
						||
            const inhtml =
 | 
						||
              '<button type="button" class="btn btn-primary widget-btn" data-widget="' +
 | 
						||
              item.uri +
 | 
						||
              '"  > <i class="fa fa-globe"></i>' +
 | 
						||
              item.name +
 | 
						||
              " </button>"
 | 
						||
            jQuery("#widget-testbar").append(inhtml)
 | 
						||
          }
 | 
						||
 | 
						||
          bindDefOptions(item)
 | 
						||
          item._firstConfigBak = { ...item }
 | 
						||
          widgetsdata.push(item) // 将配置的加入
 | 
						||
        }
 | 
						||
      }
 | 
						||
 | 
						||
      if (isdebuger) {
 | 
						||
        jQuery("#widget-testbar .widget-btn").each(function () {
 | 
						||
          jQuery(this).click(function (e) {
 | 
						||
            const uri = jQuery(this).attr("data-widget")
 | 
						||
            if (!uri || uri === "") {
 | 
						||
              return
 | 
						||
            }
 | 
						||
 | 
						||
            if (isActivate(uri)) {
 | 
						||
              disable(uri)
 | 
						||
            } else {
 | 
						||
              activate(uri)
 | 
						||
            }
 | 
						||
          })
 | 
						||
        })
 | 
						||
      }
 | 
						||
    }
 | 
						||
 | 
						||
    for (let i = 0; i < widgetsdata.length; i++) {
 | 
						||
      const item = widgetsdata[i]
 | 
						||
 | 
						||
      if (item.openAtStart || item.createAtStart) {
 | 
						||
        _arrLoadWidget.push(item)
 | 
						||
      }
 | 
						||
    }
 | 
						||
 | 
						||
    jQuery(window).resize(function () {
 | 
						||
      for (let i = 0; i < widgetsdata.length; i++) {
 | 
						||
        const item = widgetsdata[i]
 | 
						||
        if (item._class) {
 | 
						||
          item._class.indexResize() // BaseWidget: indexResize
 | 
						||
        }
 | 
						||
      }
 | 
						||
    })
 | 
						||
 | 
						||
    if (isdebuger) {
 | 
						||
      const hash = getLocationParam()
 | 
						||
      if (hash) {
 | 
						||
        activate(hash)
 | 
						||
      }
 | 
						||
    }
 | 
						||
 | 
						||
    loadWidgetJs()
 | 
						||
  }
 | 
						||
 | 
						||
  /**
 | 
						||
   * 获取默认init时中传入配置的 windowOptions 参数
 | 
						||
   * @return {object} windowOptions参数默认值
 | 
						||
   * @see BaseWidget.widgetOptions
 | 
						||
   */
 | 
						||
  function getDefWindowOptions() {
 | 
						||
    return mars3d.Util.clone(defoptions.windowOptions, removeKeys)
 | 
						||
  }
 | 
						||
 | 
						||
  function getLocationParam() {
 | 
						||
    let param = window.location.toString()
 | 
						||
    if (param.indexOf("#") === -1) {
 | 
						||
      return ""
 | 
						||
    }
 | 
						||
    param = param.split("#")
 | 
						||
    if (param && param.length > 0) {
 | 
						||
      return param[1]
 | 
						||
    }
 | 
						||
  }
 | 
						||
 | 
						||
  function bindDefOptions(item) {
 | 
						||
    // 赋默认值至options(跳过已存在设置值)
 | 
						||
    if (defoptions) {
 | 
						||
      for (const aa in defoptions) {
 | 
						||
        if (aa === "windowOptions") {
 | 
						||
          // for (var jj in defoptions['windowOptions']) {
 | 
						||
          //    if (!item['windowOptions'].hasOwnProperty(jj)) {
 | 
						||
          //        item['windowOptions'][jj] = defoptions['windowOptions'][jj];
 | 
						||
          //    }
 | 
						||
          // }
 | 
						||
        } else if (!item.hasOwnProperty(aa)) {
 | 
						||
          item[aa] = defoptions[aa]
 | 
						||
        }
 | 
						||
      }
 | 
						||
    }
 | 
						||
 | 
						||
    // 赋值内部使用属性
 | 
						||
    item.path = getFilePath(basePath + item.uri)
 | 
						||
    item.name = item.name || item.label // 兼容name和label命名
 | 
						||
  }
 | 
						||
 | 
						||
  /**
 | 
						||
 * 激活指定 widget模块
 | 
						||
 *
 | 
						||
 * @param {string|BaseWidget.widgetOptions} item 指widget模块的uri 或 指模块的配置参数,当有配置参数时,参数优先级是:
 | 
						||
 * 【activate方法传入的配置 > init方法传入的配置(widget.json) > widget.js内部配置的】
 | 
						||
 * @param {Map} [item.map] 当单页面简单场景没有init时,也可以传入map来使用单个widget
 | 
						||
 * @param {boolean} [noDisableOther=false]  不释放其他已激活的widget
 | 
						||
 * @return {BaseWidget.widgetOptions}  指widget模块对象
 | 
						||
 * @example
 | 
						||
//常用方式,直接使用uri
 | 
						||
es5widget.activate("widgets/bookmark/widget.js");
 | 
						||
 | 
						||
//使用对象,可以传入更多参数,具体参数参看配置项手册,。
 | 
						||
es5widget.activate({
 | 
						||
  name:"视角书签"
 | 
						||
  uri: "widgets/bookmark/widget.js",
 | 
						||
  autoDisable: true,
 | 
						||
  testdata:'测试数据1987', //传数据进widget内部,widget内部使用this.config.testdata获取到传的数据
 | 
						||
  success:function(thisWidget){
 | 
						||
    //创建完成的回调方法
 | 
						||
  }
 | 
						||
});
 | 
						||
 */
 | 
						||
  function activate(item, noDisableOther) {
 | 
						||
    if (!thismap && item.map) {
 | 
						||
      init(item.map, {}, item.basePath)
 | 
						||
    }
 | 
						||
 | 
						||
    // 参数是字符串id或uri时
 | 
						||
    if (typeof item === "string") {
 | 
						||
      item = { uri: item }
 | 
						||
 | 
						||
      if (noDisableOther != null) {
 | 
						||
        // 是否释放其他已激活的widget
 | 
						||
        item.disableOther = !noDisableOther
 | 
						||
      }
 | 
						||
    } else {
 | 
						||
      if (!item.uri) {
 | 
						||
        // eslint-disable-next-line no-console
 | 
						||
        console.error("activate激活widget时需要uri参数!", item)
 | 
						||
      }
 | 
						||
    }
 | 
						||
 | 
						||
    let thisItem
 | 
						||
    for (let i = 0; i < widgetsdata.length; i++) {
 | 
						||
      const othitem = widgetsdata[i]
 | 
						||
      if (item.uri === othitem.uri || (othitem.id && item.uri === othitem.id)) {
 | 
						||
        thisItem = othitem
 | 
						||
        if (thisItem.isloading) {
 | 
						||
          return thisItem
 | 
						||
        } // 激活了正在loading的widget 防止快速双击了菜单
 | 
						||
 | 
						||
        // 赋值
 | 
						||
        for (const aa in item) {
 | 
						||
          if (aa === "uri") {
 | 
						||
            continue
 | 
						||
          }
 | 
						||
          thisItem[aa] = item[aa]
 | 
						||
        }
 | 
						||
        break
 | 
						||
      }
 | 
						||
    }
 | 
						||
 | 
						||
    if (!thisItem) {
 | 
						||
      bindDefOptions(item)
 | 
						||
      thisItem = item
 | 
						||
      // 非config中配置的,外部传入,首次激活
 | 
						||
      if (!item._firstConfigBak) {
 | 
						||
        item._firstConfigBak = { ...item }
 | 
						||
      }
 | 
						||
      widgetsdata.push(item)
 | 
						||
    }
 | 
						||
 | 
						||
    if (isdebuger) {
 | 
						||
      // eslint-disable-next-line no-console
 | 
						||
      console.log("开始激活widget:" + thisItem.uri)
 | 
						||
      window.location.hash = "#" + thisItem.uri
 | 
						||
    }
 | 
						||
 | 
						||
    // 释放其他已激活的widget
 | 
						||
    if (thisItem.disableOther) {
 | 
						||
      if (Array.isArray(thisItem.disableOther)) {
 | 
						||
        disable(thisItem.disableOther)
 | 
						||
      } else {
 | 
						||
        disableAll(thisItem.uri, thisItem.group)
 | 
						||
      }
 | 
						||
    }
 | 
						||
 | 
						||
    if (thisItem.group) {
 | 
						||
      disableGroup(thisItem.group, thisItem.uri)
 | 
						||
    }
 | 
						||
 | 
						||
    // 激活本widget
 | 
						||
    if (thisItem._class) {
 | 
						||
      if (thisItem._class.isActivate) {
 | 
						||
        // 已激活时
 | 
						||
        if (thisItem._class.update) {
 | 
						||
          // 刷新
 | 
						||
          thisItem._class.update()
 | 
						||
        } else {
 | 
						||
          // 重启
 | 
						||
          _reStart(thisItem)
 | 
						||
        }
 | 
						||
      } else {
 | 
						||
        thisItem._class.activateBase() // BaseWidget: activateBase
 | 
						||
      }
 | 
						||
    } else {
 | 
						||
      for (let i = 0; i < _arrLoadWidget.length; i++) {
 | 
						||
        if (_arrLoadWidget[i].uri === thisItem.uri) {
 | 
						||
          // 如果已在加载列表中的直接跳出
 | 
						||
          return _arrLoadWidget[i]
 | 
						||
        }
 | 
						||
      }
 | 
						||
      _arrLoadWidget.push(thisItem)
 | 
						||
 | 
						||
      if (_arrLoadWidget.length === 1) {
 | 
						||
        loadWidgetJs()
 | 
						||
      }
 | 
						||
    }
 | 
						||
    return thisItem
 | 
						||
  }
 | 
						||
 | 
						||
  let timetemp
 | 
						||
  // 重启
 | 
						||
  function _reStart(thisItem) {
 | 
						||
    clearInterval(timetemp)
 | 
						||
 | 
						||
    thisItem._class.disableBase()
 | 
						||
    timetemp = setInterval(function () {
 | 
						||
      if (thisItem._class.isActivate) {
 | 
						||
        return
 | 
						||
      }
 | 
						||
      thisItem._class.activateBase()
 | 
						||
      clearInterval(timetemp)
 | 
						||
    }, 200)
 | 
						||
  }
 | 
						||
 | 
						||
  /**
 | 
						||
   * 获取指定的widget配置信息
 | 
						||
   *
 | 
						||
   * @param {string} uri widget的uri 或 id
 | 
						||
   * @return {BaseWidget.widgetOptions} widget配置信息
 | 
						||
   */
 | 
						||
  function getWidget(uri) {
 | 
						||
    for (let i = 0; i < widgetsdata.length; i++) {
 | 
						||
      const item = widgetsdata[i]
 | 
						||
 | 
						||
      if (uri === item.uri || uri === item.id) {
 | 
						||
        return item
 | 
						||
      }
 | 
						||
    }
 | 
						||
  }
 | 
						||
 | 
						||
  /**
 | 
						||
   * 获取指定的widget 对应的实例化对象
 | 
						||
   *
 | 
						||
   * @param {string} uri widget的uri 或 id
 | 
						||
   * @return {BaseWidget} widget对应的实例化对象
 | 
						||
   */
 | 
						||
  function getClass(uri) {
 | 
						||
    const item = getWidget(uri)
 | 
						||
    if (item) {
 | 
						||
      return item._class
 | 
						||
    } else {
 | 
						||
      return null
 | 
						||
    }
 | 
						||
  }
 | 
						||
 | 
						||
  /**
 | 
						||
   * 获取widget的当前激活状态
 | 
						||
   *
 | 
						||
   * @param {string} uri widget的uri 或 id
 | 
						||
   * @return {boolean} 是否激活
 | 
						||
   */
 | 
						||
  function isActivate(uri) {
 | 
						||
    const _class = getClass(uri)
 | 
						||
    if (!_class) {
 | 
						||
      return false
 | 
						||
    }
 | 
						||
    return _class.isActivate
 | 
						||
  }
 | 
						||
 | 
						||
  /**
 | 
						||
   * 设置view弹窗的显示和隐藏,基于修改css实现
 | 
						||
   *
 | 
						||
   * @param {string} uri widget的uri 或 id
 | 
						||
   * @param {boolean} show 是否显示
 | 
						||
   * @param {number} [index] 当有多个view时,可以指定单个操作的view的index
 | 
						||
   * @return {boolean} 是否成功设置
 | 
						||
   */
 | 
						||
  function setViewShow(uri, show, index) {
 | 
						||
    const _class = getClass(uri)
 | 
						||
    if (_class) {
 | 
						||
      _class.setViewShow(show, index)
 | 
						||
    }
 | 
						||
    return _class?.isActivate
 | 
						||
  }
 | 
						||
 | 
						||
  /**
 | 
						||
   * 释放指定的widget
 | 
						||
   *
 | 
						||
   * @param {string|string[]} uri widget的uri 或 id
 | 
						||
   * @return {boolean} 是否成功调用了释放
 | 
						||
   */
 | 
						||
  function disable(uri) {
 | 
						||
    if (!uri) {
 | 
						||
      return false
 | 
						||
    }
 | 
						||
 | 
						||
    if (Array.isArray(uri)) {
 | 
						||
      const arrUri = uri
 | 
						||
      for (let i = 0; i < widgetsdata.length; i++) {
 | 
						||
        const item = widgetsdata[i]
 | 
						||
 | 
						||
        for (let j = 0; j < arrUri.length; j++) {
 | 
						||
          const uri = arrUri[j]
 | 
						||
          if (item._class && (uri === item.uri || uri === item.id)) {
 | 
						||
            item._class.disableBase()
 | 
						||
            arrUri.splice(j, 1)
 | 
						||
            break
 | 
						||
          }
 | 
						||
        }
 | 
						||
      }
 | 
						||
    } else {
 | 
						||
      if (typeof uri === "object") {
 | 
						||
        uri = uri.uri
 | 
						||
      }
 | 
						||
      for (let i = 0; i < widgetsdata.length; i++) {
 | 
						||
        const item = widgetsdata[i]
 | 
						||
 | 
						||
        if (item._class && (uri === item.uri || uri === item.id)) {
 | 
						||
          item._class.disableBase()
 | 
						||
          return true
 | 
						||
        }
 | 
						||
      }
 | 
						||
    }
 | 
						||
    return false
 | 
						||
  }
 | 
						||
 | 
						||
  /**
 | 
						||
   * 关闭释放所有widget
 | 
						||
   *
 | 
						||
   * @export
 | 
						||
   * @param {string|boolean} [nodisable] 传string时 指定不释放的widget的uri或id ,传true值强制释放所有widget(默认autoDisable为false的widet不会释放)
 | 
						||
   * @param {string} [group] 指定强制释放的group名(默认autoDisable为false的widet不会释放),传入group值后会强制释放所有同group组的widget
 | 
						||
   * @return {void}  无
 | 
						||
   */
 | 
						||
  function disableAll(nodisable, group) {
 | 
						||
    for (let i = 0; i < widgetsdata.length; i++) {
 | 
						||
      const item = widgetsdata[i]
 | 
						||
 | 
						||
      if (group && item.group === group) {
 | 
						||
        // 同组别的全部释放
 | 
						||
      } else {
 | 
						||
        if (nodisable !== true && !item.autoDisable) {
 | 
						||
          continue
 | 
						||
        }
 | 
						||
      }
 | 
						||
 | 
						||
      // 指定不释放的跳过
 | 
						||
      if (nodisable && (nodisable === item.uri || nodisable === item.id)) {
 | 
						||
        continue
 | 
						||
      }
 | 
						||
 | 
						||
      if (item._class) {
 | 
						||
        item._class.disableBase() // BaseWidget: disableBase
 | 
						||
      }
 | 
						||
    }
 | 
						||
  }
 | 
						||
 | 
						||
  /**
 | 
						||
   * 关闭释放同组widget
 | 
						||
   *
 | 
						||
   * @param {string} group 指定强制释放的group名
 | 
						||
   * @param {string} [nodisable]  指定不释放的widget的uri或id
 | 
						||
   * @return {void}  无
 | 
						||
   */
 | 
						||
  function disableGroup(group, nodisable) {
 | 
						||
    if (!group) {
 | 
						||
      return
 | 
						||
    }
 | 
						||
 | 
						||
    for (let i = 0; i < widgetsdata.length; i++) {
 | 
						||
      const item = widgetsdata[i]
 | 
						||
      if (item.group === group) {
 | 
						||
        // 指定不释放的跳过
 | 
						||
        if (nodisable && (nodisable === item.uri || nodisable === item.id)) {
 | 
						||
          continue
 | 
						||
        }
 | 
						||
        if (item._class) {
 | 
						||
          item._class.disableBase() /// /BaseWidget: disableBase
 | 
						||
        }
 | 
						||
      }
 | 
						||
    }
 | 
						||
  }
 | 
						||
 | 
						||
  /**
 | 
						||
   * 遍历所有widget
 | 
						||
   * @param {Function} method 回调方法
 | 
						||
   * @return {void}  无
 | 
						||
   */
 | 
						||
  function eachWidget(method) {
 | 
						||
    for (let i = 0; i < widgetsdata.length; i++) {
 | 
						||
      const item = widgetsdata[i]
 | 
						||
      method(item)
 | 
						||
    }
 | 
						||
  }
 | 
						||
 | 
						||
  const _arrLoadWidget = []
 | 
						||
  let loadItem
 | 
						||
  let isloading
 | 
						||
  function loadWidgetJs() {
 | 
						||
    if (_arrLoadWidget.length === 0) {
 | 
						||
      return
 | 
						||
    }
 | 
						||
 | 
						||
    if (isloading) {
 | 
						||
      setTimeout(loadWidgetJs, 500)
 | 
						||
      return
 | 
						||
    }
 | 
						||
    isloading = true
 | 
						||
 | 
						||
    loadItem = _arrLoadWidget[0]
 | 
						||
    loadItem.isloading = true
 | 
						||
    let _uri = loadItem.uri
 | 
						||
    if (cacheVersion) {
 | 
						||
      if (_uri.indexOf("?") === -1) {
 | 
						||
        _uri += "?cache=" + cacheVersion
 | 
						||
      } else {
 | 
						||
        _uri += "&cache=" + cacheVersion
 | 
						||
      }
 | 
						||
    }
 | 
						||
 | 
						||
    if (window.NProgress) {
 | 
						||
      window.NProgress.start()
 | 
						||
    }
 | 
						||
 | 
						||
    fire(WidgetEventType.loadBefore, {
 | 
						||
      sourceTarget: loadItem
 | 
						||
    })
 | 
						||
 | 
						||
    Loader.async([basePath + _uri], function () {
 | 
						||
      isloading = false
 | 
						||
      loadItem.isloading = false
 | 
						||
 | 
						||
      if (window.NProgress) {
 | 
						||
        window.NProgress.done(true)
 | 
						||
      }
 | 
						||
 | 
						||
      _arrLoadWidget.shift()
 | 
						||
      loadWidgetJs()
 | 
						||
    })
 | 
						||
  }
 | 
						||
 | 
						||
  /**
 | 
						||
   * 绑定类到当前对应js的widget中。
 | 
						||
   *
 | 
						||
   * @param {BaseWidget} _class 定义的BaseWidget子类
 | 
						||
   * @return {object} 实例化后的对象
 | 
						||
   */
 | 
						||
  function bindClass(_class) {
 | 
						||
    fire(WidgetEventType.load, {
 | 
						||
      sourceTarget: _class
 | 
						||
    })
 | 
						||
 | 
						||
    if (!loadItem) {
 | 
						||
      const _jspath = getThisJSPath()
 | 
						||
      for (let i = 0; i < widgetsdata.length; i++) {
 | 
						||
        const item = widgetsdata[i]
 | 
						||
        if (_jspath.endsWith(item.uri)) {
 | 
						||
          item.isloading = false
 | 
						||
          item._class = new _class(thismap, item)
 | 
						||
          item._class.activateBase() // BaseWidget: activateBase
 | 
						||
          return item._class
 | 
						||
        }
 | 
						||
      }
 | 
						||
    } else {
 | 
						||
      loadItem.isloading = false
 | 
						||
      loadItem._class = new _class(thismap, loadItem)
 | 
						||
      loadItem._class.activateBase() // BaseWidget: activateBase
 | 
						||
      return loadItem._class
 | 
						||
    }
 | 
						||
  }
 | 
						||
 | 
						||
  function getThisJSPath() {
 | 
						||
    let jsPath
 | 
						||
    const js = document.scripts
 | 
						||
    for (let i = js.length - 1; i >= 0; i--) {
 | 
						||
      jsPath = js[i].src
 | 
						||
      if (!jsPath) {
 | 
						||
        continue
 | 
						||
      }
 | 
						||
      if (jsPath.indexOf("widgets") === -1) {
 | 
						||
        continue
 | 
						||
      }
 | 
						||
      // jsPath = jsPath.substring(0, jsPath.lastIndexOf("/") + 1);
 | 
						||
      return jsPath
 | 
						||
    }
 | 
						||
    return ""
 | 
						||
  }
 | 
						||
 | 
						||
  // 获取路径
 | 
						||
  function getFilePath(file) {
 | 
						||
    const pos = file.lastIndexOf("/")
 | 
						||
    return file.substring(0, pos + 1)
 | 
						||
  }
 | 
						||
 | 
						||
  /**
 | 
						||
   * 移除Widget测试栏(当有开启debugger时)
 | 
						||
   * @return {void}  无
 | 
						||
   */
 | 
						||
  function removeDebugeBar() {
 | 
						||
    jQuery("#widget-testbar").remove()
 | 
						||
  }
 | 
						||
 | 
						||
  /**
 | 
						||
   * 获取配置的version配置参数,用于附加清除浏览器缓存
 | 
						||
   * @return {string} 配置的version参数
 | 
						||
   */
 | 
						||
  function getCacheVersion() {
 | 
						||
    return cacheVersion
 | 
						||
  }
 | 
						||
 | 
						||
  /**
 | 
						||
   * 获取init方法传入的主目录配置参数
 | 
						||
   * @return {string} 主目录配置参数
 | 
						||
   */
 | 
						||
  function getBasePath() {
 | 
						||
    return basePath
 | 
						||
  }
 | 
						||
 | 
						||
  /**
 | 
						||
   * 销毁对象
 | 
						||
   * @return {void}  无
 | 
						||
   */
 | 
						||
  function destroy() {
 | 
						||
    for (let i = 0; i < widgetsdata.length; i++) {
 | 
						||
      const item = widgetsdata[i]
 | 
						||
 | 
						||
      if (item._class) {
 | 
						||
        item._class.disableBase() // BaseWidget: disableBase
 | 
						||
 | 
						||
        if (item._class.destroy) {
 | 
						||
          item._class.destroy()
 | 
						||
        }
 | 
						||
        delete item._class
 | 
						||
      }
 | 
						||
    }
 | 
						||
 | 
						||
    thismap = null
 | 
						||
  }
 | 
						||
 | 
						||
  // 事件相关
 | 
						||
  const eventTarget = new mars3d.BaseClass()
 | 
						||
 | 
						||
  /**
 | 
						||
   * 绑定指定类型事件监听器
 | 
						||
   *
 | 
						||
   * @param {WidgetEventType|WidgetEventType[]} types 事件类型
 | 
						||
   * @param {Function} [fn] 绑定的监听器回调方法
 | 
						||
   * @param {object} [context]  侦听器的上下文(this关键字将指向的对象)。
 | 
						||
   * @return {void}  无
 | 
						||
   */
 | 
						||
  function on(types, fn, context) {
 | 
						||
    return eventTarget.on(types, fn, context)
 | 
						||
  }
 | 
						||
 | 
						||
  /**
 | 
						||
   * 解除绑定指定类型事件监听器
 | 
						||
   *
 | 
						||
   * @param {WidgetEventType|WidgetEventType[]} types 事件类型
 | 
						||
   * @param {Function} [fn] 绑定的监听器回调方法
 | 
						||
   * @param {object} [context]  侦听器的上下文(this关键字将指向的对象)。
 | 
						||
   * @return {void}  无
 | 
						||
   */
 | 
						||
  function off(types, fn, context) {
 | 
						||
    return eventTarget.off(types, fn, context)
 | 
						||
  }
 | 
						||
 | 
						||
  /**
 | 
						||
   * 触发指定类型的事件。
 | 
						||
   *
 | 
						||
   * @param {WidgetEventType} type 事件类型
 | 
						||
   * @param {object} data 传输的数据或对象,可在事件回调方法中event对象中获取进行使用
 | 
						||
   * @param {BaseClass|object} [propagate] 将事件传播给父类 (用addEventParent设置)
 | 
						||
   * @return {void}  无
 | 
						||
   */
 | 
						||
  function fire(type, data, propagate) {
 | 
						||
    return eventTarget.fire(type, data, propagate)
 | 
						||
  }
 | 
						||
 | 
						||
  /**
 | 
						||
   * 绑定一次性执行的指定类型事件监听器
 | 
						||
   * 与on类似,监听器只会被触发一次,然后被删除。
 | 
						||
   *
 | 
						||
   * @param {WidgetEventType|WidgetEventType[]} types 事件类型
 | 
						||
   * @param {Function} [fn] 绑定的监听器回调方法
 | 
						||
   * @param {object} [context]  侦听器的上下文(this关键字将指向的对象)。
 | 
						||
   * @return {void}  无
 | 
						||
   */
 | 
						||
  function once(types, fn, context) {
 | 
						||
    return eventTarget.once(types, fn, context)
 | 
						||
  }
 | 
						||
 | 
						||
  /**
 | 
						||
   * 是否有绑定指定的事件
 | 
						||
   *
 | 
						||
   * @param {WidgetEventType} type 事件类型
 | 
						||
   * @param {BaseClass} [propagate] 是否判断指定的父类 (用addEventParent设置的)
 | 
						||
   * @return {boolean} 是否存在
 | 
						||
   */
 | 
						||
  function listens(type, propagate) {
 | 
						||
    return eventTarget.listens(type, propagate)
 | 
						||
  }
 | 
						||
 | 
						||
  let _resources_cache = []
 | 
						||
 | 
						||
  /**
 | 
						||
   * widget 配置参数
 | 
						||
   *
 | 
						||
   * @typedef {object} BaseWidget.widgetOptions
 | 
						||
   *
 | 
						||
   * @property {string} name 必须,中文名称,用于标识和弹窗标题。
 | 
						||
   * @property {string} uri 必须,JS文件路径,路径是相对于widgets目录的路径。如:"widgets/bookmark/widget.js"
 | 
						||
   * @property {string} [id] 定义该插件的唯一标识,方便后续判断。
 | 
						||
   * @property {boolean} [autoDisable=true] 激活其他新插件时,是否自动释放本插件
 | 
						||
   * @property {boolean} [disableOther=true] 激活本插件时,是否释放其它已激活的插件
 | 
						||
   * @property {string} [group] 配置group后,同group下的widget互斥,打开任意一个会自动释放其他的
 | 
						||
   * @property {object} [windowOptions] 存在弹窗的插件的弹窗相关参数配置,更多参数请参考 [layer弹窗API]{@link https://layui.gitee.io/v2/docs/modules/layer.html} 包括:
 | 
						||
   * @property {number|string} [windowOptions.width] 窗口宽度,可以是 像素数字(像素值) 或者 字符串(屏幕宽度百分比),示例:200 或 "20%"
 | 
						||
   * @property {number|string} [windowOptions.height] 窗口高度,可以是 像素数字(像素值) 或者 字符串(屏幕高度百分比),示例:600 或 "50%"
 | 
						||
   * @property {string|object} [windowOptions.position='auto'] 窗口所在位置坐标,配置字符串可选值:auto垂直水平居中,t顶部,b底部,r右边缘,l左边缘,lt左上角,lb左下角,rt右上角,rb右下角;也可以配置对象:
 | 
						||
   * @property {number|string} [windowOptions.position.top] 位置css的top值,可以是 像素数字(像素值) 或者 字符串(屏幕高度百分比),示例:10 或 "5%"
 | 
						||
   * @property {number|string} [windowOptions.position.bottom] 位置css的top值,可以是 像素数字(像素值) 或者 字符串(屏幕高度百分比),示例:10 或 "5%"
 | 
						||
   * @property {number|string} [windowOptions.position.left] 位置css的top值,可以是 像素数字(像素值) 或者 字符串(屏幕宽度百分比),示例:10 或 "5%"
 | 
						||
   * @property {number|string} [windowOptions.position.right] 位置css的top值,可以是 像素数字(像素值) 或者 字符串(屏幕宽度百分比),示例:10 或 "5%"
 | 
						||
   * @property {number} [windowOptions.minHeight] 限定的窗口最小高度(像素值),默认不限制
 | 
						||
   * @property {number} [windowOptions.maxHeight] 限定的窗口最大高度(像素值),默认不限制
 | 
						||
   * @property {number} [windowOptions.minWidth] 限定的窗口最小宽度(像素值),默认不限制
 | 
						||
   * @property {number} [windowOptions.maxWidth] 限定的窗口最大宽度(像素值),默认不限制
 | 
						||
   *
 | 
						||
   * @property {boolean} [windowOptions.maxmin=true] 是否可以在弹层右下角拖动来拉伸尺寸
 | 
						||
   * @property {number|Array} [windowOptions.shade=0] 遮罩,默认为0不显示,可配置数字0.3透明度的黑色背景('#000'),其他颜色,可以shade: [0.8, '#393D49']
 | 
						||
   * @property {boolean} [windowOptions.shadeClose=false] 当shade是存在的,点击弹层外区域后是否关闭弹窗。
 | 
						||
   * @property {number} [windowOptions.closeBtn=1] 当为0时,不显示关闭按钮,配置1和2来展示两种风格的关闭按钮
 | 
						||
   * @property {number} [windowOptions.noTitle=false] 是否不显示标题,为true是不显示标题
 | 
						||
   * @property {boolean} [windowOptions.show=true] 激活后是否显示弹窗,false时激活后自动隐藏弹窗。
 | 
						||
   *
 | 
						||
   * @property {boolean} [openAtStart=false] 打开系统后是否自动启动本插件
 | 
						||
   * @property {string} [style] 添加到widget的view中的class样式名
 | 
						||
   * @property {object} [css] 添加到widget的css值
 | 
						||
   * @property {*} [多个参数] 传入数据等,定义的任意参数在widget内部方法中都可以通过this.config获取到
 | 
						||
   */
 | 
						||
 | 
						||
  /**
 | 
						||
 * 原生JS技术栈下,widget基础类,
 | 
						||
 * 需要继承后使用,不用手动实例化,框架内部自动实例化及相关处理。
 | 
						||
 *
 | 
						||
 * @param {Map} map 地图对象
 | 
						||
 * @param {BaseWidget.widgetOptions} options 配置参数
 | 
						||
 * @class BaseWidget
 | 
						||
 * @extends {BaseClass}
 | 
						||
 * @see [支持的事件类型]{@link WidgetEventType}
 | 
						||
 | 
						||
 * @example
 | 
						||
//使用示例
 | 
						||
class MyWidget extends es5widget.BaseWidget {
 | 
						||
  //外部资源配置
 | 
						||
  get resources() {
 | 
						||
    return [
 | 
						||
      'js/test.js', //当前同目录下
 | 
						||
      './lib/dom2img/dom-to-image.js', //主页面相同目录下
 | 
						||
    ]
 | 
						||
  }
 | 
						||
  //弹窗配置
 | 
						||
  get view() {
 | 
						||
    return {
 | 
						||
      type: 'window',
 | 
						||
      url: 'view.html',
 | 
						||
      windowOptions: {  width: 250 },
 | 
						||
    }
 | 
						||
  }
 | 
						||
  //初始化[仅执行1次]
 | 
						||
  create() {}
 | 
						||
  //每个窗口创建完成后调用
 | 
						||
  winCreateOK(opt, result) {
 | 
						||
    this.viewWindow = result
 | 
						||
  }
 | 
						||
  //打开激活
 | 
						||
  activate() {}
 | 
						||
  //关闭释放
 | 
						||
  disable() {
 | 
						||
    this.viewWindow = null
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
//注册到widget管理器中。
 | 
						||
es5widget.bindClass(MyWidget)
 | 
						||
 */
 | 
						||
  class BaseWidget extends mars3d.BaseClass {
 | 
						||
    constructor(map, options) {
 | 
						||
      super(options)
 | 
						||
 | 
						||
      /**
 | 
						||
       *  获取当前地图
 | 
						||
       * @type {Map}
 | 
						||
       * @readonly
 | 
						||
       */
 | 
						||
      this.map = map
 | 
						||
 | 
						||
      /**
 | 
						||
       *  获取当前配置参数
 | 
						||
       * @type {BaseWidget.widgetOptions}
 | 
						||
       * @readonly
 | 
						||
       */
 | 
						||
      this.options = options // 配置的config信息
 | 
						||
 | 
						||
      /**
 | 
						||
       *  获取当前配置参数,别名,同options
 | 
						||
       * @type {BaseWidget.widgetOptions}
 | 
						||
       * @readonly
 | 
						||
       */
 | 
						||
      this.config = options
 | 
						||
 | 
						||
      /**
 | 
						||
       *  获取当前widget的目录路径
 | 
						||
       * @type {string}
 | 
						||
       * @readonly
 | 
						||
       */
 | 
						||
      this.path = options.path || "" // 当前widget目录相对路径
 | 
						||
 | 
						||
      /**
 | 
						||
       *  是否激活状态
 | 
						||
       * @type {boolean}
 | 
						||
       * @readonly
 | 
						||
       */
 | 
						||
      this.isActivate = false
 | 
						||
 | 
						||
      /**
 | 
						||
       *  是否已创建
 | 
						||
       * @type {boolean}
 | 
						||
       * @readonly
 | 
						||
       */
 | 
						||
      this.isCreate = false
 | 
						||
 | 
						||
      this._viewcreate_allcount = 0
 | 
						||
      this._viewcreate_okcount = 0
 | 
						||
      this._viewConfig = this.view
 | 
						||
 | 
						||
      this.init()
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * 该模块依赖的外部js、css资源文件,会在实例化之前加入的页面中。
 | 
						||
     * 默认引用是当前widget所在同path目录的资源,
 | 
						||
     * 相当于html主页面的资源 或 外部资源 请 以 “/” 或 “.” 或 “http” 开始的url
 | 
						||
     * @type {string[]}
 | 
						||
     * @readonly
 | 
						||
     * @abstract
 | 
						||
     */
 | 
						||
    get resources() {
 | 
						||
      return null
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * 定义关联的view弹窗或页面配置信息,目前支持3种类型,
 | 
						||
     * (1)type:'window',iframe模式弹窗 ,参考_example示例, 独立的html子页面,比较自由,简单粗暴、无任何限制;可以每个页面用不同的UI和第三方插件不用考虑冲突问题;任何水平的开发人员均容易快速开发。
 | 
						||
     * (2)type:'divwindow',div元素模式弹窗 参考_example_divwin示例,可直接互相访问,这种模式弊端是易引起模块间id命名冲突,在css和html中命名时需注意。
 | 
						||
     * (3)type:'append',任意html元素 参考_example_append示例,任意div节点,比较自由。
 | 
						||
     * 为空时表示当前模块无关联的view页面,
 | 
						||
     * 其中url地址规则,参考resources说明
 | 
						||
     * @type {object|object[]}
 | 
						||
     * @readonly
 | 
						||
     * @abstract
 | 
						||
     */
 | 
						||
    get view() {
 | 
						||
      return null
 | 
						||
    }
 | 
						||
 | 
						||
    //= =============激活插件=================
 | 
						||
    /**
 | 
						||
     * 激活widget,同 es5widget.activate方法
 | 
						||
     * @return {void}  无
 | 
						||
     */
 | 
						||
    activateBase() {
 | 
						||
      const that = this
 | 
						||
 | 
						||
      if (this.isActivate) {
 | 
						||
        // 已激活状态时跳出
 | 
						||
        this.eachView(function (viewopt) {
 | 
						||
          if (viewopt._dom) {
 | 
						||
            // 将层置顶
 | 
						||
            jQuery(".layui-layer").each(function () {
 | 
						||
              jQuery(this).css("z-index", 19891000)
 | 
						||
            })
 | 
						||
            jQuery(viewopt._dom).css("z-index", 19891014)
 | 
						||
          }
 | 
						||
        })
 | 
						||
        return
 | 
						||
      }
 | 
						||
 | 
						||
      eventTarget.fire(WidgetEventType.beforeActivate, {
 | 
						||
        sourceTarget: this
 | 
						||
      })
 | 
						||
      this.beforeActivate()
 | 
						||
      this.isActivate = true
 | 
						||
 | 
						||
      if (!this.isCreate) {
 | 
						||
        eventTarget.fire(WidgetEventType.beforeCreate, {
 | 
						||
          sourceTarget: this
 | 
						||
        })
 | 
						||
 | 
						||
        // 首次进行创建
 | 
						||
        if (this.resources && this.resources.length > 0) {
 | 
						||
          const resources = []
 | 
						||
 | 
						||
          for (let i = 0; i < this.resources.length; i++) {
 | 
						||
            let _resource = this.resources[i]
 | 
						||
            _resource = this._getUrl(_resource)
 | 
						||
 | 
						||
            if (_resources_cache.indexOf(_resource) !== -1) {
 | 
						||
              continue
 | 
						||
            } // 不加重复资源
 | 
						||
 | 
						||
            resources.push(_resource)
 | 
						||
          }
 | 
						||
          _resources_cache = _resources_cache.concat(resources) // 不加重复资源
 | 
						||
 | 
						||
          Loader.async(resources, function () {
 | 
						||
            const result = that.create(function () {
 | 
						||
              that._createWidgetView()
 | 
						||
              that.isCreate = true
 | 
						||
            })
 | 
						||
            eventTarget.fire(WidgetEventType.created, {
 | 
						||
              sourceTarget: that
 | 
						||
            })
 | 
						||
 | 
						||
            if (result) {
 | 
						||
              return
 | 
						||
            }
 | 
						||
            if (that.options.createAtStart) {
 | 
						||
              that.options.createAtStart = false
 | 
						||
              that.isActivate = false
 | 
						||
              that.isCreate = true
 | 
						||
              return
 | 
						||
            }
 | 
						||
            that._createWidgetView()
 | 
						||
            that.isCreate = true
 | 
						||
          })
 | 
						||
          return
 | 
						||
        } else {
 | 
						||
          const result = this.create(function () {
 | 
						||
            that._createWidgetView()
 | 
						||
            this.isCreate = true
 | 
						||
          })
 | 
						||
          eventTarget.fire(WidgetEventType.created, {
 | 
						||
            sourceTarget: this
 | 
						||
          })
 | 
						||
 | 
						||
          if (result) {
 | 
						||
            return
 | 
						||
          }
 | 
						||
          if (that.options.createAtStart) {
 | 
						||
            that.options.createAtStart = false
 | 
						||
            that.isActivate = false
 | 
						||
            that.isCreate = true
 | 
						||
            return
 | 
						||
          }
 | 
						||
        }
 | 
						||
        this.isCreate = true
 | 
						||
      }
 | 
						||
      this._createWidgetView()
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * 构造方法完成后的钩子方法,子类继承后按需使用
 | 
						||
     * @return {void}  无
 | 
						||
     * @abstract
 | 
						||
     */
 | 
						||
    init() {}
 | 
						||
 | 
						||
    /**
 | 
						||
     * 模块初始化,仅首次初始化执行1次
 | 
						||
     * @param {Function} [endfun] 当create内存在异步时,可以异步后调用下endfun
 | 
						||
     * @return {void}  无
 | 
						||
     * @abstract
 | 
						||
     */
 | 
						||
    create() {}
 | 
						||
 | 
						||
    // 创建插件的view
 | 
						||
    _createWidgetView() {
 | 
						||
      const viewopt = this._viewConfig
 | 
						||
      if (viewopt === undefined || viewopt == null) {
 | 
						||
        this._startActivate()
 | 
						||
      } else if (Array.isArray(viewopt)) {
 | 
						||
        this._viewcreate_allcount = viewopt.length
 | 
						||
        this._viewcreate_okcount = 0
 | 
						||
 | 
						||
        for (let i = 0; i < viewopt.length; i++) {
 | 
						||
          this.createItemView(viewopt[i])
 | 
						||
        }
 | 
						||
      } else {
 | 
						||
        this._viewcreate_allcount = 1
 | 
						||
        this._viewcreate_okcount = 0
 | 
						||
        this.createItemView(viewopt)
 | 
						||
      }
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * 遍历所有view配置
 | 
						||
     *
 | 
						||
     * @param {Function} callback 回调方法
 | 
						||
     * @param {number} [index] 当有多个view时,可以指定单个操作的view的index
 | 
						||
     * @return {*} callback执行的返回结果
 | 
						||
     */
 | 
						||
    eachView(callback, index) {
 | 
						||
      const viewopt = this._viewConfig
 | 
						||
      if (viewopt === undefined || viewopt == null) {
 | 
						||
        return false
 | 
						||
      } else if (Array.isArray(viewopt)) {
 | 
						||
        let hascal = false
 | 
						||
        if (index != null) {
 | 
						||
          return callback(viewopt[index])
 | 
						||
        }
 | 
						||
        for (let i = 0; i < viewopt.length; i++) {
 | 
						||
          hascal = callback(viewopt[i])
 | 
						||
        }
 | 
						||
        return hascal
 | 
						||
      } else {
 | 
						||
        return callback(viewopt)
 | 
						||
      }
 | 
						||
    }
 | 
						||
 | 
						||
    createItemView(viewopt) {
 | 
						||
      const that = this
 | 
						||
      switch (viewopt.type) {
 | 
						||
        case "divwindow":
 | 
						||
          this._openDivWindow(viewopt)
 | 
						||
          break
 | 
						||
        case "append":
 | 
						||
          that.getHtml(this._getUrl(viewopt.url), function (html) {
 | 
						||
            that._appendView(viewopt, html)
 | 
						||
          })
 | 
						||
          break
 | 
						||
        case "custom": // 自定义
 | 
						||
          viewopt.open(
 | 
						||
            this._getUrl(viewopt.url),
 | 
						||
            function (html) {
 | 
						||
              that.winCreateOK(viewopt, html)
 | 
						||
              eventTarget.fire(WidgetEventType.openView, {
 | 
						||
                sourceTarget: that,
 | 
						||
                view: viewopt,
 | 
						||
                dom: html
 | 
						||
              })
 | 
						||
              that._viewcreate_okcount++
 | 
						||
              if (that._viewcreate_okcount >= that._viewcreate_allcount) {
 | 
						||
                that._startActivate(html)
 | 
						||
              }
 | 
						||
            },
 | 
						||
            this
 | 
						||
          )
 | 
						||
          break
 | 
						||
        case "window":
 | 
						||
        default:
 | 
						||
          this._openWindow(viewopt)
 | 
						||
          break
 | 
						||
      }
 | 
						||
    }
 | 
						||
 | 
						||
    //= =============layer弹窗=================
 | 
						||
    _openWindow(viewopt) {
 | 
						||
      const view_url = this._getUrl(viewopt.url)
 | 
						||
 | 
						||
      const opts = {
 | 
						||
        type: 2,
 | 
						||
        content: [view_url, "no"],
 | 
						||
        success: (layero, index) => {
 | 
						||
          if (!this.isActivate) {
 | 
						||
            layer.close(index)
 | 
						||
            return
 | 
						||
          }
 | 
						||
          if (viewopt._layerIdx !== index) {
 | 
						||
            layer.close(viewopt._layerIdx)
 | 
						||
            viewopt._layerIdx = index
 | 
						||
          }
 | 
						||
 | 
						||
          viewopt._layerOpening = false
 | 
						||
          viewopt._dom = layero
 | 
						||
 | 
						||
          // 得到iframe页的窗口对象,执行iframe页的方法:viewWindow.method();
 | 
						||
          const viewWindow = window[layero.find("iframe")[0].name]
 | 
						||
 | 
						||
          // 绑定常用对象到子页面,方便直接使用
 | 
						||
          viewWindow.map = this.map
 | 
						||
          viewWindow.mars3d = mars3d
 | 
						||
          viewWindow.Cesium = mars3d.Cesium
 | 
						||
          viewWindow.es5widget = window.es5widget
 | 
						||
 | 
						||
          // 设置css
 | 
						||
          if (this.options.css) {
 | 
						||
            jQuery("#layui-layer" + viewopt._layerIdx).css(this.options.css)
 | 
						||
          }
 | 
						||
 | 
						||
          // 隐藏弹窗
 | 
						||
          if (viewopt.windowOptions.hasOwnProperty("show") && !viewopt.windowOptions.show) {
 | 
						||
            jQuery(layero).hide()
 | 
						||
          }
 | 
						||
 | 
						||
          layer.setTop(layero)
 | 
						||
 | 
						||
          this.winCreateOK(viewopt, viewWindow)
 | 
						||
          eventTarget.fire(WidgetEventType.openView, {
 | 
						||
            sourceTarget: this,
 | 
						||
            view: viewopt,
 | 
						||
            dom: layero
 | 
						||
          })
 | 
						||
 | 
						||
          this._viewcreate_okcount++
 | 
						||
          if (this._viewcreate_okcount >= this._viewcreate_allcount) {
 | 
						||
            this._startActivate(layero)
 | 
						||
          }
 | 
						||
 | 
						||
          // 通知页面,页面需要定义initWidgetView方法
 | 
						||
          if (viewWindow && viewWindow.initWidgetView) {
 | 
						||
            if (this.config?.style) {
 | 
						||
              jQuery(viewWindow.document.body).addClass(this.config.style)
 | 
						||
            }
 | 
						||
 | 
						||
            viewWindow.initWidgetView(this)
 | 
						||
          } else {
 | 
						||
            mars3d.Log.logError(view_url + "页面没有定义function initWidgetView(widget)方法,无法初始化widget页面!")
 | 
						||
          }
 | 
						||
        }
 | 
						||
      }
 | 
						||
      if (viewopt._layerIdx && viewopt._layerIdx > 0) {
 | 
						||
        layer.close(viewopt._layerIdx)
 | 
						||
        viewopt._layerIdx = -1
 | 
						||
      }
 | 
						||
 | 
						||
      viewopt._layerOpening = true
 | 
						||
      viewopt._layerIdx = layer.open(this._getWinOpt(viewopt, opts))
 | 
						||
    }
 | 
						||
 | 
						||
    _openDivWindow(viewopt) {
 | 
						||
      const view_url = this._getUrl(viewopt.url)
 | 
						||
      // div弹窗
 | 
						||
      this.getHtml(view_url, (data) => {
 | 
						||
        const opts = {
 | 
						||
          type: 1,
 | 
						||
          content: data,
 | 
						||
          success: (layero, index) => {
 | 
						||
            if (!this.isActivate) {
 | 
						||
              layer.close(index)
 | 
						||
              return
 | 
						||
            }
 | 
						||
            if (viewopt._layerIdx !== index) {
 | 
						||
              layer.close(viewopt._layerIdx)
 | 
						||
              viewopt._layerIdx = index
 | 
						||
            }
 | 
						||
 | 
						||
            viewopt._layerOpening = false
 | 
						||
            viewopt._dom = layero
 | 
						||
 | 
						||
            // 隐藏弹窗
 | 
						||
            if (viewopt.windowOptions.hasOwnProperty("show") && !viewopt.windowOptions.show) {
 | 
						||
              jQuery(layero).hide()
 | 
						||
            }
 | 
						||
 | 
						||
            layer.setTop(layero)
 | 
						||
            this.winCreateOK(viewopt, layero)
 | 
						||
            eventTarget.fire(WidgetEventType.openView, {
 | 
						||
              sourceTarget: this,
 | 
						||
              view: viewopt,
 | 
						||
              dom: layero
 | 
						||
            })
 | 
						||
 | 
						||
            this._viewcreate_okcount++
 | 
						||
            if (this._viewcreate_okcount >= this._viewcreate_allcount) {
 | 
						||
              this._startActivate(layero)
 | 
						||
            }
 | 
						||
          }
 | 
						||
        }
 | 
						||
        viewopt._layerOpening = true
 | 
						||
        viewopt._layerIdx = layer.open(this._getWinOpt(viewopt, opts))
 | 
						||
      })
 | 
						||
    }
 | 
						||
 | 
						||
    _getUrl(url) {
 | 
						||
      url = this.addCacheVersion(url)
 | 
						||
 | 
						||
      if (url.startsWith("/") || url.startsWith(".") || url.startsWith("http")) {
 | 
						||
        return url
 | 
						||
      } else {
 | 
						||
        return this.path + url
 | 
						||
      }
 | 
						||
    }
 | 
						||
 | 
						||
    _getWinOpt(viewopt, opts) {
 | 
						||
      // 优先使用cofig中配置,覆盖js中的定义
 | 
						||
      const def = getDefWindowOptions()
 | 
						||
 | 
						||
      const windowOptions = { ...def, ...viewopt.windowOptions, ...this.options.windowOptions }
 | 
						||
      viewopt.windowOptions = windowOptions // 赋值
 | 
						||
 | 
						||
      const that = this
 | 
						||
      const _size = this._getWinSize(windowOptions)
 | 
						||
 | 
						||
      let title = false
 | 
						||
      if (!windowOptions.noTitle) {
 | 
						||
        title = this.options.name || " "
 | 
						||
        if (this.options.icon) {
 | 
						||
          title = '<i class="' + this.options.icon + '" ></i> ' + title
 | 
						||
        }
 | 
						||
      }
 | 
						||
 | 
						||
      // 默认值
 | 
						||
      const defOpts = {
 | 
						||
        title: title,
 | 
						||
        area: _size.area,
 | 
						||
        offset: _size.offset,
 | 
						||
        shade: 0,
 | 
						||
        maxmin: false,
 | 
						||
        beforeEnd: function () {
 | 
						||
          that.beforeDisable()
 | 
						||
        },
 | 
						||
        end: function () {
 | 
						||
          // 销毁后触发的回调
 | 
						||
          viewopt._layerIdx = -1
 | 
						||
          viewopt._dom = null
 | 
						||
          that.disableBase()
 | 
						||
        },
 | 
						||
        full: function (dom) {
 | 
						||
          // 最大化后触发的回调
 | 
						||
          that.winFull(dom)
 | 
						||
        },
 | 
						||
        min: function (dom) {
 | 
						||
          // 最小化后触发的回调
 | 
						||
          that.winMin(dom)
 | 
						||
        },
 | 
						||
        restore: function (dom) {
 | 
						||
          // 还原 后触发的回调
 | 
						||
          that.winRestore(dom)
 | 
						||
        }
 | 
						||
      }
 | 
						||
      return { ...defOpts, ...windowOptions, ...opts }
 | 
						||
    }
 | 
						||
 | 
						||
    // 计算弹窗大小和位置
 | 
						||
    _getWinSize(windowOptions) {
 | 
						||
      // 获取高宽
 | 
						||
      let _width = this.bfb2Number(windowOptions.width, document.documentElement.clientWidth, windowOptions)
 | 
						||
      let _height = this.bfb2Number(windowOptions.height, document.documentElement.clientHeight, windowOptions)
 | 
						||
 | 
						||
      // 计算位置offset
 | 
						||
      let offset = ""
 | 
						||
      const position = windowOptions.position
 | 
						||
      if (position) {
 | 
						||
        if (typeof position === "string") {
 | 
						||
          // t顶部,b底部,r右边缘,l左边缘,lt左上角,lb左下角,rt右上角,rb右下角
 | 
						||
          offset = position
 | 
						||
        } else if (typeof position === "object") {
 | 
						||
          let _top
 | 
						||
          let _left
 | 
						||
 | 
						||
          if (position.hasOwnProperty("top") && position.top != null) {
 | 
						||
            _top = this.bfb2Number(position.top, document.documentElement.clientHeight, windowOptions)
 | 
						||
          }
 | 
						||
          if (position.hasOwnProperty("bottom") && position.bottom != null) {
 | 
						||
            windowOptions._hasresize = true
 | 
						||
 | 
						||
            const _bottom = this.bfb2Number(position.bottom, document.documentElement.clientHeight, windowOptions)
 | 
						||
 | 
						||
            if (_top != null) {
 | 
						||
              _height = document.documentElement.clientHeight - _top - _bottom
 | 
						||
            } else {
 | 
						||
              _top = document.documentElement.clientHeight - _height - _bottom
 | 
						||
            }
 | 
						||
          }
 | 
						||
 | 
						||
          if (position.hasOwnProperty("left") && position.left != null) {
 | 
						||
            _left = this.bfb2Number(position.left, document.documentElement.clientWidth, windowOptions)
 | 
						||
          }
 | 
						||
          if (position.hasOwnProperty("right") && position.right != null) {
 | 
						||
            windowOptions._hasresize = true
 | 
						||
            const _right = this.bfb2Number(position.right, document.documentElement.clientWidth, windowOptions)
 | 
						||
 | 
						||
            if (_left != null) {
 | 
						||
              _width = document.documentElement.clientWidth - _left - _right
 | 
						||
            } else {
 | 
						||
              _left = document.documentElement.clientWidth - _width - _right
 | 
						||
            }
 | 
						||
          }
 | 
						||
 | 
						||
          if (_top == null || _top === undefined) {
 | 
						||
            _top = (document.documentElement.clientHeight - _height) / 2
 | 
						||
          }
 | 
						||
          if (_left == null || _left === undefined) {
 | 
						||
            _left = (document.documentElement.clientWidth - _width) / 2
 | 
						||
          }
 | 
						||
 | 
						||
          offset = [_top + "px", _left + "px"]
 | 
						||
        }
 | 
						||
      }
 | 
						||
 | 
						||
      // 最大最小高度判断
 | 
						||
      if (windowOptions.hasOwnProperty("minHeight") && _height < windowOptions.minHeight) {
 | 
						||
        windowOptions._hasresize = true
 | 
						||
        _height = windowOptions.minHeight
 | 
						||
      }
 | 
						||
      if (windowOptions.hasOwnProperty("maxHeight") && _height > windowOptions.maxHeight) {
 | 
						||
        windowOptions._hasresize = true
 | 
						||
        _height = windowOptions.maxHeight
 | 
						||
      }
 | 
						||
 | 
						||
      // 最大最小宽度判断
 | 
						||
      if (windowOptions.hasOwnProperty("minWidth") && _width < windowOptions.minWidth) {
 | 
						||
        windowOptions._hasresize = true
 | 
						||
        _width = windowOptions.minWidth
 | 
						||
      }
 | 
						||
      if (windowOptions.hasOwnProperty("maxWidth") && _width > windowOptions.maxWidth) {
 | 
						||
        windowOptions._hasresize = true
 | 
						||
        _width = windowOptions.maxWidth
 | 
						||
      }
 | 
						||
 | 
						||
      let area
 | 
						||
      if (_width && _height) {
 | 
						||
        area = [_width + "px", _height + "px"]
 | 
						||
      } else {
 | 
						||
        area = _width + "px"
 | 
						||
      }
 | 
						||
 | 
						||
      return { area: area, offset: offset }
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * 更新窗口大小或位置,改变了主页面尺寸后需要调用(内部已自动调用)。
 | 
						||
     * @return {void}  无
 | 
						||
     */
 | 
						||
    indexResize() {
 | 
						||
      if (!this.isActivate) {
 | 
						||
        return
 | 
						||
      }
 | 
						||
 | 
						||
      const that = this
 | 
						||
      this.eachView(function (viewopt) {
 | 
						||
        if (!viewopt._layerIdx || viewopt._layerIdx === -1 || !viewopt.windowOptions || !viewopt.windowOptions._hasresize) {
 | 
						||
          return
 | 
						||
        }
 | 
						||
        const tag = viewopt._dom.attr("maxmin")
 | 
						||
        if (tag === "min") {
 | 
						||
          return
 | 
						||
        }
 | 
						||
        if (tag === "full") {
 | 
						||
          layer.full(viewopt._layerIdx, viewopt)
 | 
						||
          return
 | 
						||
        }
 | 
						||
 | 
						||
        const _size = that._getWinSize(viewopt.windowOptions)
 | 
						||
 | 
						||
        const _style = {}
 | 
						||
        if (Array.isArray(_size.area)) {
 | 
						||
          if (_size.area[0]) {
 | 
						||
            _style.width = _size.area[0]
 | 
						||
          }
 | 
						||
          if (_size.area[1]) {
 | 
						||
            _style.height = _size.area[1]
 | 
						||
          }
 | 
						||
        }
 | 
						||
 | 
						||
        if (Array.isArray(_size.offset)) {
 | 
						||
          if (_size.offset[1]) {
 | 
						||
            _style.top = _size.offset[0]
 | 
						||
          }
 | 
						||
          if (_size.offset[1]) {
 | 
						||
            _style.left = _size.offset[1]
 | 
						||
          }
 | 
						||
        }
 | 
						||
        jQuery(viewopt._dom).attr("myTopLeft", true)
 | 
						||
        layer.style(viewopt._layerIdx, _style)
 | 
						||
 | 
						||
        if (viewopt.type === "divwindow") {
 | 
						||
          layer.iframeAuto(viewopt._layerIdx)
 | 
						||
        }
 | 
						||
      })
 | 
						||
    }
 | 
						||
 | 
						||
    //= =============直接添加dom节点=================
 | 
						||
    _appendView(viewopt, html) {
 | 
						||
      viewopt._dom = jQuery(html).appendTo(viewopt.parent || "body")
 | 
						||
 | 
						||
      // 设置css
 | 
						||
      if (this.options.css) {
 | 
						||
        jQuery(viewopt._dom).css(this.options.css)
 | 
						||
      }
 | 
						||
 | 
						||
      this.winCreateOK(viewopt, html)
 | 
						||
 | 
						||
      this._viewcreate_okcount++
 | 
						||
      if (this._viewcreate_okcount >= this._viewcreate_allcount) {
 | 
						||
        this._startActivate(html)
 | 
						||
      }
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * 每个view窗口或页面创建完成后调用的钩子方法
 | 
						||
     *
 | 
						||
     * @param {object} opt 对应的view配置
 | 
						||
     * @param {object|string} result 得到iframe页的窗口对象 或 view的html内容
 | 
						||
     * @return {void}  无
 | 
						||
     * @abstract
 | 
						||
     */
 | 
						||
    winCreateOK(opt, result) {}
 | 
						||
 | 
						||
    /**
 | 
						||
     * 窗口最大化后触发后 的钩子方法
 | 
						||
     * @return {void}  无
 | 
						||
     * @abstract
 | 
						||
     */
 | 
						||
    winFull() {}
 | 
						||
 | 
						||
    /**
 | 
						||
     * 窗口最小化后触发 的钩子方法
 | 
						||
     * @return {void}  无
 | 
						||
     * @abstract
 | 
						||
     */
 | 
						||
    winMin() {}
 | 
						||
 | 
						||
    /**
 | 
						||
     * 最小化窗口
 | 
						||
     * @return {void}  无
 | 
						||
     */
 | 
						||
    minView() {
 | 
						||
      this.eachView(function (viewopt) {
 | 
						||
        if (viewopt._layerIdx) {
 | 
						||
          layer.min(viewopt._layerIdx, viewopt)
 | 
						||
        }
 | 
						||
      })
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * 还原窗口
 | 
						||
     * @return {void}  无
 | 
						||
     */
 | 
						||
    restoreView() {
 | 
						||
      this.eachView(function (viewopt) {
 | 
						||
        if (viewopt._layerIdx) {
 | 
						||
          layer.restore(viewopt._layerIdx)
 | 
						||
        }
 | 
						||
      })
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * 最大化窗口
 | 
						||
     * @return {void}  无
 | 
						||
     */
 | 
						||
    fullView() {
 | 
						||
      this.eachView(function (viewopt) {
 | 
						||
        if (viewopt._layerIdx) {
 | 
						||
          layer.full(viewopt._layerIdx, viewopt)
 | 
						||
        }
 | 
						||
      })
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * 窗口还原后触发 的钩子方法
 | 
						||
     * @return {void}  无
 | 
						||
     * @abstract
 | 
						||
     */
 | 
						||
    winRestore() {}
 | 
						||
 | 
						||
    _startActivate(layero) {
 | 
						||
      this.activate(layero)
 | 
						||
      eventTarget.fire(WidgetEventType.activated, {
 | 
						||
        sourceTarget: this
 | 
						||
      })
 | 
						||
 | 
						||
      if (this.options.success) {
 | 
						||
        this.options.success(this)
 | 
						||
        delete this.options.success // 一次性的
 | 
						||
      }
 | 
						||
      if (!this.isActivate) {
 | 
						||
        // 窗口打开中没加载完成时,被释放
 | 
						||
        this.disableBase()
 | 
						||
      }
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * 激活模块之前 的钩子方法
 | 
						||
     * @return {void}  无
 | 
						||
     * @abstract
 | 
						||
     */
 | 
						||
    beforeActivate() {}
 | 
						||
 | 
						||
    /**
 | 
						||
     * 激活模块【类内部实现方法】
 | 
						||
     * @return {void}  无
 | 
						||
     * @abstract
 | 
						||
     */
 | 
						||
    activate() {}
 | 
						||
 | 
						||
    //= =============释放插件=================
 | 
						||
 | 
						||
    /**
 | 
						||
     * 释放插件,同 es5widget.disable方法
 | 
						||
     * @return {void}  无
 | 
						||
     */
 | 
						||
    disableBase() {
 | 
						||
      if (!this.isActivate) {
 | 
						||
        return
 | 
						||
      }
 | 
						||
      this.isActivate = false
 | 
						||
 | 
						||
      this.beforeDisable()
 | 
						||
      eventTarget.fire(WidgetEventType.beforeDisable, {
 | 
						||
        sourceTarget: this
 | 
						||
      })
 | 
						||
 | 
						||
      // 关闭所有窗口
 | 
						||
      this.eachView(function (viewopt) {
 | 
						||
        if (viewopt._layerIdx && viewopt._layerIdx > 0) {
 | 
						||
          layer.close(viewopt._layerIdx)
 | 
						||
 | 
						||
          if (viewopt._layerOpening) {
 | 
						||
            // 窗口还在加载中,success方法中去关闭
 | 
						||
          } else {
 | 
						||
            viewopt._layerIdx = -1
 | 
						||
          }
 | 
						||
          return true
 | 
						||
        } else {
 | 
						||
          if (viewopt.type === "append" && viewopt._dom) {
 | 
						||
            viewopt._dom.remove()
 | 
						||
            viewopt._dom = null
 | 
						||
          }
 | 
						||
          if (viewopt.type === "custom" && viewopt.close) {
 | 
						||
            viewopt.close()
 | 
						||
          }
 | 
						||
          return false
 | 
						||
        }
 | 
						||
      })
 | 
						||
 | 
						||
      this.disable()
 | 
						||
 | 
						||
      // 还原配置为初始状态
 | 
						||
      if (this.options.autoReset) {
 | 
						||
        this.resetConfig()
 | 
						||
      }
 | 
						||
      eventTarget.fire(WidgetEventType.disabled, {
 | 
						||
        sourceTarget: this
 | 
						||
      })
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * 释放模块前
 | 
						||
     * @return {void}  无
 | 
						||
     * @abstract
 | 
						||
     */
 | 
						||
    beforeDisable() {}
 | 
						||
 | 
						||
    /**
 | 
						||
     * 释放模块【类内部实现方法】
 | 
						||
     * @return {void}  无
 | 
						||
     * @abstract
 | 
						||
     */
 | 
						||
    disable() {}
 | 
						||
 | 
						||
    //= =============其他方法=================
 | 
						||
    bfb2Number(str, allnum, windowOptions) {
 | 
						||
      if (typeof str === "string" && str.indexOf("%") !== -1) {
 | 
						||
        windowOptions._hasresize = true
 | 
						||
 | 
						||
        return (allnum * Number(str.replace("%", ""))) / 100
 | 
						||
      }
 | 
						||
      return str
 | 
						||
    }
 | 
						||
 | 
						||
    addCacheVersion(_resource) {
 | 
						||
      if (!_resource) {
 | 
						||
        return _resource
 | 
						||
      }
 | 
						||
 | 
						||
      const cacheVersion = getCacheVersion()
 | 
						||
      if (cacheVersion) {
 | 
						||
        if (_resource.indexOf("?") === -1) {
 | 
						||
          _resource += "?cache=" + cacheVersion
 | 
						||
        } else if (_resource.indexOf("cache=" + cacheVersion) === -1) {
 | 
						||
          _resource += "&cache=" + cacheVersion
 | 
						||
        }
 | 
						||
      }
 | 
						||
      return _resource
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * 还原配置为初始状态
 | 
						||
     * @return {void}  无
 | 
						||
     */
 | 
						||
    resetConfig() {
 | 
						||
      if (this.options._firstConfigBak) {
 | 
						||
        const _backData = this.options._firstConfigBak
 | 
						||
        for (const aa in _backData) {
 | 
						||
          if (aa === "uri") {
 | 
						||
            continue
 | 
						||
          }
 | 
						||
          this.options[aa] = _backData[aa]
 | 
						||
        }
 | 
						||
      }
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * 设置view弹窗的显示和隐藏,基于修改css实现
 | 
						||
     *
 | 
						||
     * @param {boolean} show 是否显示
 | 
						||
     * @param {number} [index] 当有多个view时,可以指定单个操作的view的index
 | 
						||
     * @return {void}  无
 | 
						||
     */
 | 
						||
    setViewShow(show, index) {
 | 
						||
      this.eachView(function (viewopt) {
 | 
						||
        if (viewopt._layerIdx && viewopt._layerIdx > 0) {
 | 
						||
          if (show) {
 | 
						||
            jQuery("#layui-layer" + viewopt._layerIdx).show()
 | 
						||
          } else {
 | 
						||
            jQuery("#layui-layer" + viewopt._layerIdx).hide()
 | 
						||
          }
 | 
						||
        } else if (viewopt.type === "append" && viewopt._dom) {
 | 
						||
          if (show) {
 | 
						||
            jQuery(viewopt._dom).show()
 | 
						||
          } else {
 | 
						||
            jQuery(viewopt._dom).hide()
 | 
						||
          }
 | 
						||
        }
 | 
						||
      }, index)
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * 设置view弹窗的css
 | 
						||
     *
 | 
						||
     * @param {object} style css值
 | 
						||
     * @param {number} [index] 当有多个view时,可以指定单个操作的view的index
 | 
						||
     * @return {void}  无
 | 
						||
     */
 | 
						||
    setViewCss(style, index) {
 | 
						||
      this.eachView(function (viewopt) {
 | 
						||
        if (viewopt._layerIdx != null && viewopt._layerIdx > 0) {
 | 
						||
          layer.style(viewopt._layerIdx, style)
 | 
						||
        } else if (viewopt.type === "append" && viewopt._dom) {
 | 
						||
          jQuery(viewopt._dom).css(style)
 | 
						||
        }
 | 
						||
      }, index)
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * 设置view弹窗的标题
 | 
						||
     *
 | 
						||
     * @param {string} title css值
 | 
						||
     * @param {number} [index] 当有多个view时,可以指定单个操作的view的index
 | 
						||
     * @return {void}  无
 | 
						||
     */
 | 
						||
    setTitle(title, index) {
 | 
						||
      this.eachView(function (viewopt) {
 | 
						||
        if (viewopt._dom) {
 | 
						||
          viewopt._dom.find(".layui-layer-title").html(title)
 | 
						||
        }
 | 
						||
      }, index)
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * 读取html页面的内容
 | 
						||
     *
 | 
						||
     * @param {string} url html页面的url
 | 
						||
     * @param {Function} callback 读取完成后的回调方法
 | 
						||
     * @return {void}  无
 | 
						||
     */
 | 
						||
    getHtml(url, callback) {
 | 
						||
      jQuery.ajax({
 | 
						||
        url: url,
 | 
						||
        type: "GET",
 | 
						||
        dataType: "html",
 | 
						||
        timeout: 0, // 永不超时
 | 
						||
        success: function (data) {
 | 
						||
          callback(data)
 | 
						||
        }
 | 
						||
      })
 | 
						||
    }
 | 
						||
  }
 | 
						||
 | 
						||
  //对外接口
 | 
						||
  window.es5widget = {
 | 
						||
    BaseWidget: BaseWidget,
 | 
						||
    EventType: WidgetEventType,
 | 
						||
    WidgetEventType: WidgetEventType,
 | 
						||
    eventTarget,
 | 
						||
    activate,
 | 
						||
    bindClass,
 | 
						||
    destroy,
 | 
						||
    disable,
 | 
						||
    disableAll,
 | 
						||
    disableGroup,
 | 
						||
    eachWidget,
 | 
						||
    fire,
 | 
						||
    getBasePath,
 | 
						||
    getCacheVersion,
 | 
						||
    getClass,
 | 
						||
    getDefWindowOptions,
 | 
						||
    getWidget,
 | 
						||
    init,
 | 
						||
    isActivate,
 | 
						||
    listens,
 | 
						||
    off,
 | 
						||
    on,
 | 
						||
    once,
 | 
						||
    removeDebugeBar,
 | 
						||
    setViewShow
 | 
						||
  }
 | 
						||
})()
 |