User:Artoria2e5/sandbox-taggeo.js
外观
注意:保存之后,你必须清除浏览器缓存才能看到做出的更改。Google Chrome、Firefox、Microsoft Edge及Safari:按住⇧ 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>