User:Artoria2e5/sandbox-taggeo.js

注意:保存之后,你必须清除浏览器缓存才能看到做出的更改。Google ChromeFirefoxMicrosoft EdgeSafari:按住⇧ Shift键并单击工具栏的“刷新”按钮。参阅Help:绕过浏览器缓存以获取更多帮助。
// <nowiki>
/**
 * Gadget-taggeo.js
 * prototype rewrite of shizhao's thing
 *
 * @author shizhao [[User:Shizhao/taggeo.js]]
 * @author Artoria2e5
 */
/*global mw OO $ wgULS*/
mw.loader.using('oojs-ui').done(function () {
  // 只在条目空间
  if (mw.config.get('wgNamespaceNumber') !== 0)
    return

  // Define the dialog.
  // This API is crazy.
  var GeoDialog = function GeoDialog (config) {
    GeoDialog.super.call(this, config)
  }
  OO.inheritClass(GeoDialog, OO.ui.ProcessDialog)
  GeoDialog.static.title = wgULS('查找坐标', '尋找座標')
  GeoDialog.static.actions = [
    { action: 'help', label: wgULS('帮助', '幫助'), flags: 'primary' },
    { action: 'close', label: '取消', flags: 'safe' }
  ]
  GeoDialog.prototype.getActionProcess = function (action) {
    var dialog = this
    if (action === 'help') {
      return new OO.ui.Process(function () {
        window.open('/wiki/User:Shizhao/taggeo')
      }, this)
    } else if (action === 'close') {
      return new OO.ui.Process(function () {
        dialog.close({ action: action })
      })
    }
    return GeoDialog.super.prototype.getActionProcess.call(this, action)
  }

  var api = new mw.Api()

  function getCoords (title) {
    var ret
    api.get({
      format: 'json',
      action: 'query',
      prop: 'coordinates',
      titles: title, // mw.config.get('wgTitle'),
      coprop: 'type|name|dim|country|region'
    }).done(function (data) {
      ret = data.query.pages[0].coordinates
    })
    return ret
  }

  var taggeo_ui = function taggeo_ui (JSONresults) { // 解析map API
    var gmapsStatus = JSONresults.status
    var results = JSONresults.results
      .slice(0, 10)
      .map(function JQ说要这个格式 (玩意儿) {
        return {
          name: 玩意儿.address_components[0].long_name,
          address: 玩意儿.formatted_address,
          location: 玩意儿.geometry.location,
          type: 玩意儿.types
        }
      })
      // Specify a static title and actions.
	console.log(results)

    // Use the initialize() method to add content to the dialog's $body,
    // to initialize widgets, and to set up event handlers
    var panel, select
    GeoDialog.prototype.initialize = function () {
      GeoDialog.super.prototype.initialize.call(this)
      var menuLayout = new OO.ui.MenuLayout({
        position: 'top'
      })
      panel = new OO.ui.PanelLayout({ $: this.$, padded: true, expanded: true, scrollable: true })
      var menuPanel = new OO.ui.PanelLayout({ $: this.$, padded: true, expanded: true, scrollable: true })
      var contentPanel = new OO.ui.PanelLayout({ $: this.$, padded: true, expanded: true, scrollable: true })
      select = new OO.ui.SelectWidget({
        items: results.map(function 包个选项 (玩意儿) {
          return new OO.ui.OptionWidget(玩意儿, 玩意儿.name)
        })
      }).on('select', function (item) { // 菜单选择行为
        let itemdata = item.getData()
        let contentname = itemdata.name
        let contentaddress = itemdata.address
        let contentlocation = itemdata.location.lat + ', ' + itemdata.location.lng
        // let contentlocationdata = itemdata.location
        let contenttype = itemdata.type.join(', ')
        contentPanel.$element.empty() // 每次重置内容面板
        // 当前页面坐标
        var fieldset = new OO.ui.FieldsetLayout({
          label: '坐标编辑'
        })
        var coordinatesdata = getCoords(mw.config.get('wgTitle'))
        // 页面有坐标的情况
        if (coordinatesdata.length == 1) {
          fieldset.setLabel(new OO.ui.HtmlSnippet('坐标编辑<span style="color:red;"><b><big>(当前页面已有坐标信息,请手工修改)</big></b></span>'))
          fieldset.setIcon('alert')
          fieldset.setIconTitle('当前页面已有坐标信息,请手工修改')
          $('.oo-ui-menuLayout-content').css('color', 'gray')
        } else if (coordinatesdata.length > 1) {
          fieldset.setLabel(new OO.ui.HtmlSnippet('坐标编辑<span style="color:red;"><b><big>(当前页面有多个坐标信息,脚本无法确认)</big></b></span>'))
          fieldset.setIcon('alert')
          fieldset.setIconTitle('当前页面有多个坐标信息,不能编辑')
          $('.oo-ui-menuLayout-content').css('color', 'gray')
        }

        // Add an action field layout:
        var namelabel = new OO.ui.LabelWidget({
          label: $('<b>名称</b>:<code>' + contentname + '</code>')
        })
        var addresslabel = new OO.ui.LabelWidget({
          label: $('<b>地址</b>:<code>' + contentaddress + '</code>')
        })
        var TextInputcoord = new OO.ui.TextInputWidget({
          value: contentlocation,
          required: true,
          label: '坐标',
          validate: 'non-empty',
          labelPosition: 'before',
          indicatorTitle: '必填'
        })
        var typelabel = new OO.ui.LabelWidget({
          label: $('<b>找到的坐标类型</b>:<code>' + contenttype + '</code>')
        })
        var dropDowntype = new OO.ui.DropdownWidget({
          label: '选择下列一个坐标类型',
          // The menu is composed within the DropdownWidget
          menu: {
            // make this a list and a dict
            items: [
              new OO.ui.MenuOptionWidget({
                data: 'country',
                label: 'country(国家)'
              }),
              new OO.ui.MenuOptionWidget({
                data: 'adm1st',
                label: 'adm1st(国家一级行政区,如州、省等)'
              }),
              new OO.ui.MenuOptionWidget({
                data: 'adm2nd',
                label: 'adm2nd(国家二级行政区)'
              }),
              new OO.ui.MenuOptionWidget({
                data: 'adm3rd',
                label: 'adm3rd(国家三级行政区)'
              }),
              new OO.ui.MenuOptionWidget({
                data: 'city',
                label: 'city(市镇、村庄等)'
              }),
              new OO.ui.MenuOptionWidget({
                data: 'airport',
                label: 'airport(机场、航空基地)'
              }),
              new OO.ui.MenuOptionWidget({
                data: 'mountain',
                label: 'mountain(山峰、山脉、丘陵、暗礁等)'
              }),
              new OO.ui.MenuOptionWidget({
                data: 'isle',
                label: 'isle(岛屿)'
              }),
              new OO.ui.MenuOptionWidget({
                data: 'waterbody',
                label: 'waterbody(海湾、湖泊、水库、河口、瀑布等)'
              }),
              new OO.ui.MenuOptionWidget({
                data: 'forest',
                label: 'forest(森林和林地)'
              }),
              new OO.ui.MenuOptionWidget({
                data: 'river',
                label: 'river(河流、水渠、溪流等)'
              }),
              new OO.ui.MenuOptionWidget({
                data: 'glacier',
                label: 'glacier(冰川、冰冠)'
              }),
              new OO.ui.MenuOptionWidget({
                data: 'event',
                label: 'event(在特定地点发生的活动、事件、战争、灾害、事故等)'
              }),
              new OO.ui.MenuOptionWidget({
                data: 'edu',
                label: 'edu(各种教育机构)'
              }),
              new OO.ui.MenuOptionWidget({
                data: 'pass',
                label: 'pass(山口)'
              }),
              new OO.ui.MenuOptionWidget({
                data: 'railwaystation',
                label: 'railwaystation(各种车站)'
              }),
              new OO.ui.MenuOptionWidget({
                data: 'landmark',
                label: 'landmark(各种地标、建筑物、自然文化景观、旅游景点等)'
              }),
              new OO.ui.MenuOptionWidget({
                data: 'satellite',
                label: 'satellite(地球同步卫星)'
              }),
              new OO.ui.MenuOptionWidget({
                data: '',
                label: '不选择'
              })
            ]
          }
        })
        var TextInputregion = new OO.ui.TextInputWidget({
          placeholder: '设置一个地区代码(可选)',
          label: 'region:',
          labelPosition: 'before'
        })
        var TextInputdim = new OO.ui.TextInputWidget({
          placeholder: '地图覆盖范围(可选)',
          label: 'dim:',
          labelPosition: 'before'
        })
        var TextInputnotes = new OO.ui.TextInputWidget({
          placeholder: '<ref>...</ref>',
          label: 'notes=',
          multiline: true,
          autosize: true,
          maxRows: 3,
          labelPosition: 'before'
        })
        var previewbutton = new OO.ui.ButtonWidget({
          label: '预览',
          flags: [ 'safe'],
          icon: 'code',
          title: '点击按钮,预览{{Coord}}模板代码'
        })
        var gmapsbutton = new OO.ui.ButtonWidget({
          label: '地图',
          flags: [ 'safe', 'progressive' ],
          icon: 'window',
          title: '在新窗口中打开Google地图查看位置信息',
          href: '//maps.google.com/maps?ll=' + TextInputcoord.getValue() + '&q=' + TextInputcoord.getValue() + '&t=m&z=18',
          target: '_blank'
        })

        var editbutton = new OO.ui.ButtonWidget({
          label: '编辑',
          flags: [ 'safe', 'progressive' ],
          icon: 'add',
          title: '在新窗口中编辑本条目',
          href: '/w/index.php?title=' + mw.config.get('wgTitle') + '&action=edit',
          target: '_blank'
        })
        if (coordinatesdata.length > 0) {
          editbutton.setFlags([ 'primary', 'progressive' ])
        }

        var savebutton = new OO.ui.ButtonWidget({
          label: '保存',
          flags: [ 'primary', 'constructive' ],
          title: '点击按钮,直接保存坐标信息到本条目中'
        })
        if (coordinatesdata.length > 0) {
          savebutton.setDisabled(true)
          savebutton.setTitle('当前页面已有坐标信息,不能直接保存')
        }

        var buttonGroup = new OO.ui.ButtonGroupWidget({
          items: [previewbutton, gmapsbutton, editbutton, savebutton]
        })

        let TextInputcoordnotices = []
        let dropDowntypenotices = []
        let TextInputregionnotices = []
        let TextInputdimnotices = []
        // 显示当前页坐标信息
        if (coordinatesdata.length == 1) {
          TextInputcoordnotices.push(new OO.ui.HtmlSnippet('<small>当前页面的坐标值是:<code>' + coordinatesdata[0].lat + ',' + coordinatesdata[0].lon + '</code></small>'))
          if (coordinatesdata[0].type) {
            dropDowntypenotices.push(new OO.ui.HtmlSnippet('<small>当前页面坐标的<code>type</code>值是:<code>' + coordinatesdata[0].type + '</code></small>'))
          }

          if (coordinatesdata[0].country) {
            TextInputregionnotices = [new OO.ui.HtmlSnippet('<small>当前页面坐标的<code>region</code>值是:<code>' + coordinatesdata[0].country + '</code></small>')]
            if (coordinatesdata[0].region) {
              TextInputregionnotices = [new OO.ui.HtmlSnippet('<small>当前页面坐标的<code>region</code>值是:<code>' + coordinatesdata[0].country + '-' + coordinatesdata[0].region + '</code></small>')]
            }
          }

          if (coordinatesdata[0].dim) {
            TextInputdimnotices = [new OO.ui.HtmlSnippet('<small>当前页面坐标的<code>dim</code>值是:<code>' + coordinatesdata[0].dim + '</code></small>')]
          }
        }
        
        fieldset.addItems([
          new OO.ui.FieldLayout(namelabel, {
            align: 'left'
          }),
          new OO.ui.FieldLayout(addresslabel, {
            align: 'left'
          }),
          new OO.ui.FieldLayout(
            TextInputcoord,
            {notices: TextInputcoordnotices}
          ),
          new OO.ui.FieldLayout(typelabel, {
            align: 'left'
          }),
          new OO.ui.FieldLayout(
            dropDowntype,
            {
              notices: dropDowntypenotices,
              help: new OO.ui.HtmlSnippet('关于坐标类型,请参考<a href="/wiki/User:Shizhao/taggeo">说明文档</a>。')
            }
          ),
          new OO.ui.FieldLayout(
            TextInputregion,
            {
              notices: TextInputregionnotices,
              help: new OO.ui.HtmlSnippet('地区代码,使用<a href="/wiki/ISO_3166-2">ISO 3166-2</a>和<a href="/wiki/ISO_3166-1_alpha-2">ISO 3166-1 alpha-2</a>。')
            }
          ),
          new OO.ui.FieldLayout(
            TextInputdim,
            {
              notices: TextInputdimnotices,
              help: new OO.ui.HtmlSnippet('dim是一个整数,<code>dim = scale / 10</code>')
            }
          ),
          new OO.ui.FieldLayout(
            TextInputnotes
          ),
          new OO.ui.FieldLayout(
            buttonGroup
          )
        ])

        menuLayout.$content.append(
          contentPanel.$element.append(fieldset.$element)
        )
        menuLayout.$content.append(
          contentPanel.$element.append('<div id="geotag-preview"></div>') // 设置预览位置
        )
        // {{Coord}}模板内容
        function Coord () {
          var coordparameter = '|'
          var templatecoord = ''
          try {
            if (dropDowntype.getMenu().getSelectedItem().getData() !== '') {
              coordparameter = coordparameter + 'type:' + dropDowntype.getMenu().getSelectedItem().getData() + '_'
            }
          } catch (err) {
            window.console.error(err)
          }
          if (TextInputregion.getValue()) {
            coordparameter = coordparameter + 'region:' + TextInputregion.getValue() + '_'
          }
          if (TextInputdim.getValue()) {
            coordparameter = coordparameter + 'dim:' + TextInputdim.getValue() + '_'
          }
          coordparameter = coordparameter + 'source:GoogleMaps'
          if (TextInputnotes.getValue()) {
            templatecoord = '{{Coord|' + TextInputcoord.getValue().split(',').join('|') + coordparameter + '|display=title|notes=' + TextInputnotes.getValue() + '}}'
          } else {
            templatecoord = '{{Coord|' + TextInputcoord.getValue().split(',').join('|') + coordparameter + '|display=title}}'
          }
          return templatecoord
        }

        previewbutton.on('click', function () {
          let wikitext = '<p><b>Wikicode预览:</b></p><p><code>' + Coord() + '</code></p>'
          $('div#geotag-preview').html(wikitext)
        })

        savebutton.on('click', function () {
          // 点击编辑页面
          let CoordDatas = Coord()
          api.postWithToken('edit', {
            action: 'edit',
            title: mw.config.get('wgPageName'),
            summary: '通过[[User:Shizhao/taggeo|脚本]]添加坐标信息',
            tags: 'TagGeo',
            prependtext: CoordDatas + '\n',
            contentformat: 'text/x-wiki',
            contentmodel: 'wikitext'
          }).done(function (/*result, jqXHR*/) {
            mw.log('Saved successfully')
            location.reload()
          }).fail(function (code, result) {
            if (code === 'http') {
              mw.log('HTTP error: ' + result.textStatus) // result.xhr contains the jqXHR object
              mw.notify('HTTP错误: ' + result.textStatus)
            } else if (code === 'ok-but-empty') {
              mw.log('服务器未响应')
              mw.notify('服务器未响应')
            } else {
              mw.log('API error: ' + code)
              mw.notify('API错误: ' + code)
            }
          }) // 保存按钮点击事件结束
        }) // 当前页面坐标.done结束
      }) // 菜单选择事件结束

      menuLayout.$menu.append(
        menuPanel.$element.append('<b>请选择下列地点:</b>', select.$element)
      )
      menuLayout.$content.append(
        contentPanel.$element.append('<p><big><b><--</b> 点击左侧地名显示详情</p></big>')
      )
      
      // google API状态
      if (gmapsStatus !== 'OK') {
        contentPanel.$element.empty()
        let alertIcon = new OO.ui.IconWidget({ icon: 'alert' })
        let iconLabel = '<p><big><b>API请求出错,原因是:</b></big><br><code>' + gmapsStatus + '</code></p>'
        
        switch (gmapsStatus) {
          case "ZERO_RESULTS":
            iconLabel = '<p><big><b>未找到<code>' + mw.config.get('wgTitle') + '</code>的坐标信息。</b></big></p>'
            break
          case 'OVER_QUERY_LIMIT':
            iconLabel = '<p><big><b>API请求数已经超过配额限制,请稍后再试!</b></big></p>'
            break
        }

        menuLayout.$content.append(
          contentPanel.$element.append(
            alertIcon.$element,
            new OO.ui.LabelWidget({ label: $(iconLabel) }).$element
          )
        )
      } // API状态结束

      panel.$element.append(menuLayout.$element)
      this.$body.append(panel.$element)
    } // initialize() method to add content to the dialog Done!

    // Get dialog height.
    GeoDialog.prototype.getBodyHeight = function () {
      return (select.$element.outerHeight(true) + panel.$element.outerHeight(true)) * 4
    }

    // Use the getActionProcess() method to specify a process to handle the
    // actions (for the 'save' action, in this example).


    // Create and append the window manager.
    var windowManager = new OO.ui.WindowManager()
    $('body').append(windowManager.$element)

    // Create a new dialog window.
    var geoDialog = new GeoDialog({
      size: 'larger',
      id: 'geodialog',
    })

    // Add windows to window manager using the addWindows() method.
    windowManager.addWindows({ geoProcessDialog: geoDialog })

    // Open the window.
    windowManager.openWindow('geoProcessDialog')
  }

  var taggeo_main = function taggeo_main () {
    var gmapAPIurl = 'https://maps.googleapis.com/maps/api/geocode/json?'
    $.ajax({ // google map API 请求
      url: gmapAPIurl,
      data: {
        address: mw.config.get('wgTitle')
      },
      xhrFields: {
        //  withCredentials: true
      },
      dataType: 'json'
    }).done(taggeo_ui) // map API done
  }

  // Create portlet link
  var portletLink = mw.util.addPortletLink('p-views', '#', 'TagGeo', 'ca-taggeo', '寻找本页的地理坐标')

  // 点击事件
  $(portletLink).click(function (e) {
    e.preventDefault()
    taggeo_main()
  }) // ca-taggeo click done
})
// </nowiki>