![刷新 刷新](/images/thumb/b/b0/OOjs_UI_icon_reload-progressive.svg/55px-OOjs_UI_icon_reload-progressive.svg.png)
请注意:更新本页面后,您可能需要清除浏览器缓存才能看到所作变更的影响。
Google Chrome、Microsoft Edge、Mozilla Firefox、Safari:按住⇧ Shift,同时单击“刷新”。
Google Chrome、Microsoft Edge、Mozilla Firefox、Safari:按住⇧ Shift,同时单击“刷新”。
![Cc.logo.circle.svg](/images/thumb/5/5d/CC_Logo.svg/40px-CC_Logo.svg.png)
![署名 署名](/images/thumb/1/11/Cc-by_new_white.svg/24px-Cc-by_new_white.svg.png)
![相同方式共享 相同方式共享](/images/thumb/d/df/Cc-sa_white.svg/24px-Cc-sa_white.svg.png)
本文件采用知识共享署名-相同方式共享 4.0 国际(CC BY-SA 4.0)许可协议授权。
- 您可以自由地:
- 分享 – 在任何媒介以任何形式复制、发行本作品
- 演绎 – 修改、转换或以本作品为基础进行创作
- 惟须遵守下列条件:
- 署名 – 您必须给出适当的署名(标明原作者),提供指向本许可协议的链接,同时标明是否(对原始作品)作了修改。您可以用任何合理的方式来署名,但是不得以任何方式暗示许可人为您或您的使用背书(即诱导原作者在不了解协议情况下给你授权)。
- 相同方式共享 – 如果您再混合、转换或者基于本作品进行创作,您必须基于与原先许可协议相同或相兼容的许可协议分发您贡献的作品。
"use strict";
/* <nowiki> */
/**
* SPDX-License-Identifier: GPL-2.0-or-later
* _addText: '{{Gadget Header|license=GPLv2+}}'
*
* @source <github.com/wikimedia/mediawiki-extensions-CentralNotice/blob/5ac5d25f1a6ed1fa5b35bdc6f0eca209bad4cb91/resources/subscribing/ext.centralNotice.geoIP.js>
* @dependency mediawiki.storage
*/
(function ($, mw) {
if (window.Geo) {
return;
}
var cName = "GeoIP";
var geoPromise;
/**
* Parse geo data in cValue and return an object with properties from
* the fields therein. Returns null if the value couldn't be parsed or
* doesn't contain location data.
*
* The storage item will look like one of the following:
* - "CN-SH-Shanghai"
* - "CN-SH-"
* - "CN--"
* - "--"
*
* @param {string} cValue
* @return {?Object}
*/
var parseCValue = function parseCValue(cValue) {
// TODO Verify that these Regexes are optimal. (Why no anchors? Why the
// semicolon in the last group?)
// Parse storage item
var matches = cValue.match(/([^-]*)-([^-]*)-([^-]*)/);
// No matches...? Boo, no data.
if (!matches) {
return null;
}
// There was no info found if there's no country field, or if it's
// empty
if (typeof matches[1] !== "string" || matches[1].length === 0) {
return null;
}
// Return a juicy Geo object
return {
country: matches[1],
region: matches[2],
city: matches[3]
};
};
/**
* Request geo data and store it in the local storage
*
* @param {Object} geo
*/
var storeGeoInStorage = function storeGeoInStorage() {
$.ajax({
url: "https://geo.qiuwen.net.cn"
}).done(function (data) {
var parts = [data.country || "", data.region || "", data.city || ""];
var cValue = parts.join("-");
mw.storage.set(cName, cValue, 3600); // 1 hour
// Return Geo object
return parseCValue(cValue);
});
};
/**
* Public geoIP object
*/
mw.geoIP = {
/**
* Don't call this function! It is only exposed for tests.
*
* Set a promise that resolves with geo. First try to get data from the
* GeoIP storage. If that fails, and if a background lookup callback
* module is configured, try the background lookup.
*
* @private
*/
makeGeoWithPromise: function makeGeoWithPromise() {
var cValue = mw.storage.get(cName);
var geo;
// Were we able to read the storage?
if (!cValue) {
geo = storeGeoInStorage();
} else {
geo = parseCValue(cValue);
}
// All good? Resolve with geo and get outta here.
if (geo) {
geoPromise = $.Deferred().resolve(geo).promise();
return;
}
geoPromise = $.Deferred().reject().promise();
},
/**
* Returns a promise that resolves with geo when it's available. While
* it's usually available right away, it may not be if a background
* call is performed.
*
* @return {jQuery.Promise}
*/
getPromise: function getPromise() {
return geoPromise;
}
};
mw.geoIP.makeGeoWithPromise();
geoPromise.done(function (geo) {
window.Geo = geo;
});
})(jQuery, mediaWiki);
/* </nowiki> */