<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
	<id>https://ejwiki.org/index.php?action=history&amp;feed=atom&amp;title=MediaWiki%3AUrldecoder.js</id>
	<title>MediaWiki:Urldecoder.js - История изменений</title>
	<link rel="self" type="application/atom+xml" href="https://ejwiki.org/index.php?action=history&amp;feed=atom&amp;title=MediaWiki%3AUrldecoder.js"/>
	<link rel="alternate" type="text/html" href="https://ejwiki.org/index.php?title=MediaWiki:Urldecoder.js&amp;action=history"/>
	<updated>2026-05-16T03:32:08Z</updated>
	<subtitle>История изменений этой страницы в вики</subtitle>
	<generator>MediaWiki 1.42.3</generator>
	<entry>
		<id>https://ejwiki.org/index.php?title=MediaWiki:Urldecoder.js&amp;diff=388338&amp;oldid=prev</id>
		<title>Mliris: 1 версия</title>
		<link rel="alternate" type="text/html" href="https://ejwiki.org/index.php?title=MediaWiki:Urldecoder.js&amp;diff=388338&amp;oldid=prev"/>
		<updated>2010-03-11T07:35:33Z</updated>

		<summary type="html">&lt;p&gt;1 версия&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;ru&quot;&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Предыдущая версия&lt;/td&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Версия от 07:35, 11 марта 2010&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-notice&quot; lang=&quot;ru&quot;&gt;&lt;div class=&quot;mw-diff-empty&quot;&gt;(нет различий)&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</summary>
		<author><name>Mliris</name></author>
	</entry>
	<entry>
		<id>https://ejwiki.org/index.php?title=MediaWiki:Urldecoder.js&amp;diff=25673&amp;oldid=prev</id>
		<title>Ariely: переименовал «MediaWiki:Gadget-urldecoder.js» в «MediaWiki:Urldecoder.js»</title>
		<link rel="alternate" type="text/html" href="https://ejwiki.org/index.php?title=MediaWiki:Urldecoder.js&amp;diff=25673&amp;oldid=prev"/>
		<updated>2010-02-28T08:09:41Z</updated>

		<summary type="html">&lt;p&gt;переименовал «&lt;a href=&quot;/index.php/MediaWiki:Gadget-urldecoder.js&quot; title=&quot;MediaWiki:Gadget-urldecoder.js&quot;&gt;MediaWiki:Gadget-urldecoder.js&lt;/a&gt;» в «&lt;a href=&quot;/index.php/MediaWiki:Urldecoder.js&quot; title=&quot;MediaWiki:Urldecoder.js&quot;&gt;MediaWiki:Urldecoder.js&lt;/a&gt;»&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Новая страница&lt;/b&gt;&lt;/p&gt;&lt;div&gt;//[[ВП:Гаджеты/Упрощение ссылок]]&lt;br /&gt;
&lt;br /&gt;
function urlDecoderButton(){&lt;br /&gt;
 var tlb = document.getElementById(&amp;#039;toolbar&amp;#039;)&lt;br /&gt;
 if (!tlb) return&lt;br /&gt;
 var bt = document.createElement(&amp;#039;input&amp;#039;)&lt;br /&gt;
 bt.type = &amp;#039;button&amp;#039;; bt.onclick = urlDecoderRun;  bt.id = &amp;#039;urlDecoder&amp;#039;&lt;br /&gt;
 bt.value = &amp;#039;%%&amp;#039;;  &lt;br /&gt;
 bt.title = &amp;#039;Раскодировать URL перед курсором или все URL в выделенном тексте&amp;#039;&lt;br /&gt;
 bt.style.cssText = &amp;#039;background:#adbede; height:22px; vertical-align:top; padding:0&amp;#039;&lt;br /&gt;
 tlb.appendChild(bt)&lt;br /&gt;
 if (!window.urlDecoderKey) return&lt;br /&gt;
 bt.accessKey = urlDecoderKey&lt;br /&gt;
 bt.title += &amp;#039; [&amp;#039;+urlDecoderKey+&amp;#039;]&amp;#039;&lt;br /&gt;
 updateTooltipAccessKeys([bt])&lt;br /&gt;
}&lt;br /&gt;
if (wgAction==&amp;#039;edit&amp;#039; || wgAction==&amp;#039;submit&amp;#039;) addOnloadHook(urlDecoderButton)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
function urlDecoderRun(){ //main function&lt;br /&gt;
&lt;br /&gt;
var httpRegExp = &amp;#039;(https?:\\/\\/[^\\]\\[\\n\\r&amp;lt;&amp;gt;&amp;quot; ]+)&amp;#039; //  except []&amp;lt;&amp;gt;&amp;quot;&lt;br /&gt;
var beforeCursor = new RegExp(&amp;#039;(\\[{0,2})&amp;#039;+httpRegExp+&amp;#039;( +[^\\]\n]+)?\\]{0,2}$&amp;#039;, &amp;#039;i&amp;#039;) &lt;br /&gt;
var localPrefix = WMPrefixes(unSecure(wgServer+wgScript))&lt;br /&gt;
var newText, linkSize, txtarea = document.editform.wpTextbox1&lt;br /&gt;
var isBeforeCursor = false&lt;br /&gt;
&lt;br /&gt;
if (document.selection) { //IE/Opera&lt;br /&gt;
  var scrollTop = document.documentElement.scrollTop&lt;br /&gt;
  txtarea.focus()&lt;br /&gt;
  range = document.selection.createRange()&lt;br /&gt;
  if (!range.moveStart) return&lt;br /&gt;
  if (range.text){&lt;br /&gt;
    newText = processSelText(range.text)&lt;br /&gt;
  }else { //no selection&lt;br /&gt;
    if (!(rr=range.duplicate())) return&lt;br /&gt;
    rr.moveStart(&amp;#039;character&amp;#039;, - 1500)&lt;br /&gt;
    linkSize = processBeforeCursor(rr.text)&lt;br /&gt;
    if (!linkSize) return&lt;br /&gt;
    range.moveStart(&amp;#039;character&amp;#039;, - linkSize) //select matched&lt;br /&gt;
  }&lt;br /&gt;
  //replace text&lt;br /&gt;
  if (newText != range.text){&lt;br /&gt;
    range.text = newText&lt;br /&gt;
    if (navigator.userAgent.indexOf(&amp;#039;MSIE&amp;#039;) != -1) newText = newText.replace(/\r/g,&amp;#039;&amp;#039;) //for IE: do not count \r&lt;br /&gt;
    range.moveStart(&amp;#039;character&amp;#039;, - newText.length)&lt;br /&gt;
    range.select()&lt;br /&gt;
  }&lt;br /&gt;
  document.documentElement.scrollTop = scrollTop //restore window scroll position&lt;br /&gt;
&lt;br /&gt;
}else if (txtarea.selectionStart || txtarea.selectionStart == &amp;#039;0&amp;#039;) { // Mozilla&lt;br /&gt;
  var scrollTop = txtarea.scrollTop, txt = txtarea.value&lt;br /&gt;
  txtarea.focus()&lt;br /&gt;
  var startPos = txtarea.selectionStart, endPos = txtarea.selectionEnd&lt;br /&gt;
  if (startPos != endPos){&lt;br /&gt;
    newText = processSelText(txt.substring(startPos, endPos))&lt;br /&gt;
  }else{ //no selection&lt;br /&gt;
	linkSize = processBeforeCursor(txt.substring((endPos-1500&amp;gt;0?endPos-1500:0), endPos))&lt;br /&gt;
    if (!linkSize) return&lt;br /&gt;
    startPos = endPos - linkSize //select matched&lt;br /&gt;
  }&lt;br /&gt;
  //replace text&lt;br /&gt;
  if (newText != txt.substring(startPos, endPos)){&lt;br /&gt;
    txtarea.value = txt.substring(0, startPos) + newText +	txt.substring(endPos, txtarea.value.length)&lt;br /&gt;
    txtarea.selectionEnd = startPos + newText.length&lt;br /&gt;
    txtarea.selectionStart = startPos&lt;br /&gt;
  }&lt;br /&gt;
  txtarea.scrollTop = scrollTop&lt;br /&gt;
}//end of main function&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
function processBeforeCursor(str){//finds http:.* in string, returns its length and also newText var&lt;br /&gt;
 isBeforeCursor = true&lt;br /&gt;
 var pos = str.lastIndexOf(&amp;#039;http://&amp;#039;)&lt;br /&gt;
 if (pos == -1) pos = str.lastIndexOf(&amp;#039;https://&amp;#039;)&lt;br /&gt;
 if (pos == -1) return 0&lt;br /&gt;
 if (pos &amp;gt;= 2)  str = str.substring(pos-2) //move left to include leading [s&lt;br /&gt;
 var ma = str.match(beforeCursor) // result: (whole string)&amp;#039; &amp;#039;[&amp;#039;, &amp;#039;http:...&amp;#039;, &amp;#039; name]&amp;#039;&lt;br /&gt;
 if (!ma) return 0&lt;br /&gt;
 if (ma[3]) //link with name: automatically add brackets&lt;br /&gt;
   newText = simplifyMatched(ma[0], &amp;#039;[&amp;#039;, ma[2], ma[3]+&amp;#039;]&amp;#039;)&lt;br /&gt;
 else //just url: add closing bracket only if there is leading bracket&lt;br /&gt;
   newText = simplifyMatched(ma[0], ma[1], ma[2], ma[1]?&amp;#039;]&amp;#039;:&amp;#039;&amp;#039;)&lt;br /&gt;
 return ma[0].length&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function processSelText(txt){&lt;br /&gt;
 txt = txt.replace(RegExp(&amp;#039;(\\[{0,2})&amp;#039; + httpRegExp + &amp;#039;([^\\]\\[\\n\\r]*?\\]\\]?)?&amp;#039;, &amp;#039;ig&amp;#039;),&lt;br /&gt;
  simplifyMatched)&lt;br /&gt;
 if (window.urlDecoderIntLinks) txt = txt.replace(/\[\[[^\]\|\n]+/g, &lt;br /&gt;
  function(lnk){//skip user_talk&lt;br /&gt;
   return /^\[\[user_talk:[^#]+$/i.test(lnk) ? lnk : decodeAnchor(lnk)&lt;br /&gt;
 })&lt;br /&gt;
 return txt&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
function simplifyMatched(str, bracket, url, rest){//arguments: (whole string), &amp;#039;[&amp;#039;, url, &amp;#039; name]&amp;#039;; calls decodeUrl&lt;br /&gt;
 if (!bracket){//no brackets, just url&lt;br /&gt;
   var trail = url.match(RegExp(&amp;#039;[,;\\\\\.:!\\?&amp;#039; //trailing punctuation, per Parser.php&lt;br /&gt;
    + (!/\(/.test(url) ? &amp;#039;\\)&amp;#039; : &amp;#039;&amp;#039;) + &amp;#039;]+$&amp;#039; ))  //trailing no-matching )&lt;br /&gt;
   if (trail) url = url.substring(0, url.length-trail[0].length) //move these out of url&lt;br /&gt;
   return decodeUrl(url) + str.substring(url.length)&lt;br /&gt;
 }else if (rest) //both brackets and possibly name&lt;br /&gt;
   return decodeUrl(url, rest.replace(/\]+$|^ +| +$/g,&amp;#039;&amp;#039;)) //trim ending brackets and spaces in &amp;#039;name]&amp;#039;&lt;br /&gt;
 else return str //probably broken wikicode in selected text&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function decodeUrl(url, name){ //url -&amp;gt; %-decoded -&amp;gt; [[link|name]] (if possible); name is optional&lt;br /&gt;
 url = unSecure(url)&lt;br /&gt;
 if (url.indexOf(&amp;#039;%&amp;#039;) != -1) try { url = decodeURI(url) } catch(e){}  //decode %&lt;br /&gt;
 url = url.replace(/%(3B|2F|2C|3A)/g, decodeURIComponent) //decode ;/,:&lt;br /&gt;
 url = url.replace(/[ &amp;lt;&amp;gt;&amp;quot;\[\]]/g, encodeURIComponent) //&amp;quot; disallowed chars&lt;br /&gt;
 if (isBeforeCursor)&lt;br /&gt;
   for (var n in window.urlDecoderEngNames) //to eng keywords&lt;br /&gt;
     url = url.replace(RegExp(&amp;#039;(title=|wiki\/)(&amp;#039;+urlDecoderEngNames[n]+&amp;#039;:)&amp;#039;), &amp;#039;$1&amp;#039; + n + &amp;#039;:&amp;#039;)&lt;br /&gt;
 var link&lt;br /&gt;
 if (!/(\}\}|\|)$/.test(url)) link = toWikilink(url) //trailing | or }}  can be a part of template, skip to be safe&lt;br /&gt;
 if (!link &amp;amp;&amp;amp; window.urlDecoderCustom&lt;br /&gt;
     &amp;amp;&amp;amp; (link = urlDecoderCustom(url)) &amp;amp;&amp;amp; /^(https?:\/\/|\{\{)/.test(link))&lt;br /&gt;
	  {url = link; link = null} //still external&lt;br /&gt;
 if (link){&lt;br /&gt;
  link = link.replace(/%(3f|26|22)/ig, decodeURIComponent) //decode ?&amp;amp;&amp;quot;&lt;br /&gt;
  if ((wgNamespaceNumber==0 || wgNamespaceNumber==14)&lt;br /&gt;
      &amp;amp;&amp;amp; isBeforeCursor)  &lt;br /&gt;
	  link=link.replace(/^:/,&amp;#039;&amp;#039;) //probably interwiki&lt;br /&gt;
  return &amp;#039;[\[&amp;#039; + link + (name?&amp;#039;|&amp;#039;+name:&amp;#039;&amp;#039;) + &amp;#039;]]&amp;#039;&lt;br /&gt;
 }&lt;br /&gt;
 if (isBeforeCursor || typeof name == &amp;#039;string&amp;#039;)&lt;br /&gt;
   url = url.replace(/&amp;#039;&amp;#039;/g,&amp;#039;%27%27&amp;#039;)//techically &amp;#039;&amp;#039; means the end of URL, but more likely it&amp;#039;s part of it&lt;br /&gt;
 if (typeof name == &amp;#039;string&amp;#039;) return &amp;#039;[&amp;#039; + url + (name?&amp;#039; &amp;#039;+name:&amp;#039;&amp;#039;) + &amp;#039;]&amp;#039; //empty name&lt;br /&gt;
 else return url&lt;br /&gt;
}&lt;br /&gt;
	 &lt;br /&gt;
function toWikilink(url){//url -&amp;gt; wikilink, otherwise null&lt;br /&gt;
 //try bugzilla and user-defined prefixes&lt;br /&gt;
 if (!window.urlDecoderPrefixes) urlDecoderPrefixes = {}&lt;br /&gt;
 urlDecoderPrefixes[&amp;#039;https://bugzilla.wikimedia.org/show_bug.cgi?id=&amp;#039;]=&amp;#039;mediazilla&amp;#039;&lt;br /&gt;
 for (var key in urlDecoderPrefixes)&lt;br /&gt;
   if (url.toLowerCase().indexOf(key)!=-1)&lt;br /&gt;
    return urlDecoderPrefixes[key]+&amp;#039;:&amp;#039;+ url.substring(url.indexOf(key)+key.length)&lt;br /&gt;
 //try WM prefixes&lt;br /&gt;
 var parts = url.substring(7).split(&amp;#039;/&amp;#039;)&lt;br /&gt;
 if (parts[1]!=&amp;#039;wiki&amp;#039; || url.indexOf(&amp;#039;?&amp;#039;)!=-1) return null&lt;br /&gt;
 var linkPrefix = WMPrefixes(url.toLowerCase()), prefixes = &amp;#039;&amp;#039;&lt;br /&gt;
 if (!linkPrefix) return null&lt;br /&gt;
 var title = url.substring(parts[0].length + parts[1].length + 9) //get part after  /wiki/&lt;br /&gt;
 title = decodeAnchor(title)&lt;br /&gt;
 if (linkPrefix[0] &amp;amp;&amp;amp; (linkPrefix[0] != localPrefix[0])) prefixes = linkPrefix[0]&lt;br /&gt;
 if (linkPrefix[1] &amp;amp;&amp;amp; (linkPrefix[1] != localPrefix[1])) prefixes += &amp;#039;:&amp;#039; + linkPrefix[1]&lt;br /&gt;
 if (prefixes || isColonNeeded(title)) prefixes += &amp;#039;:&amp;#039; //dividing colon or cat/file leading colon&lt;br /&gt;
 return prefixes + title&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
function decodeAnchor(link){//simplify internal link: replace %20 and _ then decode anchor&lt;br /&gt;
 link = link.replace(/(_|%20)/g, &amp;#039; &amp;#039;).replace(/^ +| +$/g, &amp;#039;&amp;#039;)&lt;br /&gt;
 var parts = link.split(&amp;#039;#&amp;#039;)&lt;br /&gt;
 if (parts.length != 2) return link //no anchor&lt;br /&gt;
 var anchor = parts[1], hidIdx = -1, hidden = []&lt;br /&gt;
 //decode 4, 3 and 2-byte: http://en.wikipedia.org/wiki/UTF-8&lt;br /&gt;
 anchor = anchor.replace(/\.F[0-4]\.[89AB][\dA-F]\.[89AB][\dA-F]\.[89AB][\dA-F]/g, deChar)&lt;br /&gt;
 anchor = anchor.replace(/\.E[\dA-F]\.[89AB][\dA-F]\.[89AB][\dA-F]/g, deChar)&lt;br /&gt;
 anchor = anchor.replace(/\.[CD][\dA-F]\.[89AB][\dA-F]/g, deChar)&lt;br /&gt;
 anchor = anchor.replace( //hide IPs&lt;br /&gt;
/(?:^|[^0-9A-F\.])(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)/,&lt;br /&gt;
   function(s){ hidden[++hidIdx] = s; return &amp;#039;\x01&amp;#039; + hidIdx + &amp;#039;\x02&amp;#039; }&lt;br /&gt;
 )&lt;br /&gt;
 //decode 1-byte chars: all symbols except  -.:_  and []{} prohibited in links&lt;br /&gt;
 anchor = anchor.replace(/\.[2-7][0-9A-F]/g, function(hhh){&lt;br /&gt;
   var ch = deChar(hhh)&lt;br /&gt;
   if (&amp;#039;!&amp;quot;#$%&amp;amp;\&amp;#039;()*+,/;&amp;lt;=&amp;gt;?@\\^`~&amp;#039;.indexOf(ch) &amp;gt;= 0) return ch; else return hhh&lt;br /&gt;
 })&lt;br /&gt;
 //unhide IPs and return&lt;br /&gt;
 for (var i=hidIdx; i&amp;gt;=0; i--) anchor = anchor.replace(&amp;#039;\x01&amp;#039;+i+&amp;#039;\x02&amp;#039;, hidden[i])&lt;br /&gt;
 if (anchor.indexOf(&amp;quot;&amp;#039;&amp;#039;&amp;quot;) != -1) return link //cannot have double &amp;#039;&amp;#039; in link&lt;br /&gt;
 else return parts[0] + &amp;#039;#&amp;#039; + anchor&lt;br /&gt;
&lt;br /&gt;
 function deChar(ss){ &lt;br /&gt;
  try{ss = decodeURIComponent(ss.replace(/\.([0-9A-F][0-9A-F])/g, &amp;#039;%$1&amp;#039;))} catch(e){}&lt;br /&gt;
  return ss&lt;br /&gt;
 } &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function WMPrefixes(url){  // htp://en.wikipedia.org/wiki/...  -&amp;gt; [ &amp;#039;w&amp;#039;,  &amp;#039;en&amp;#039;]&lt;br /&gt;
 var dd = url.substring(7).split(&amp;#039;/&amp;#039;)[0].split(&amp;#039;.&amp;#039;) // -&amp;gt; [&amp;#039;en&amp;#039;,&amp;#039;wikipedia&amp;#039;,&amp;#039;org&amp;#039;]&lt;br /&gt;
 if (dd.pop() != &amp;#039;org&amp;#039;) return null&lt;br /&gt;
 var proj=&amp;#039;&amp;#039;, lang = &amp;#039;&amp;#039;, part = dd.pop()&lt;br /&gt;
 if (proj = {&amp;#039;mediawiki&amp;#039;:&amp;#039;mw&amp;#039;,&amp;#039;wikimediafoundation&amp;#039;:&amp;#039;foundation&amp;#039;}[part]);&lt;br /&gt;
 else if (proj = {&amp;#039;wikipedia&amp;#039;:&amp;#039;w&amp;#039;,&amp;#039;wikibooks&amp;#039;:&amp;#039;b&amp;#039;,&amp;#039;wikinews&amp;#039;:&amp;#039;n&amp;#039;,&amp;#039;wikiquote&amp;#039;:&amp;#039;q&amp;#039;,&lt;br /&gt;
 &amp;#039;wikisource&amp;#039;:&amp;#039;s&amp;#039;,&amp;#039;wikiversity&amp;#039;:&amp;#039;v&amp;#039;,&amp;#039;wiktionary&amp;#039;:&amp;#039;wikt&amp;#039;}[part]){&lt;br /&gt;
   lang = dd.pop()&lt;br /&gt;
   if (!lang || lang==&amp;#039;www&amp;#039;) lang = &amp;#039;&amp;#039;&lt;br /&gt;
   else if (lang==&amp;#039;test&amp;#039;) {lang=&amp;#039;&amp;#039;; proj=&amp;#039;testwiki&amp;#039;}&lt;br /&gt;
 }else if (part == &amp;#039;wikimedia&amp;#039;){&lt;br /&gt;
   part = dd.pop()&lt;br /&gt;
   if (!part || part==&amp;#039;www&amp;#039;) proj = &amp;#039;foundation&amp;#039;&lt;br /&gt;
   else if (/^(meta|commons|incubator|species|strategy)$/.test(part)) proj = part&lt;br /&gt;
   else return null&lt;br /&gt;
 }else return null&lt;br /&gt;
 return [proj, lang]&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function unSecure(url){&lt;br /&gt;
 return url.replace(/https:\/\/secure\.wikimedia\.org\/(\w+)\/(\w+)\/([^\]\|\n\r ]+)/,&lt;br /&gt;
  &amp;#039;http://$2.$1.org/$3&amp;#039;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function isColonNeeded(pg){&lt;br /&gt;
 return /^(категория|файл|изображение|category|file|image):/i.test(pg)&lt;br /&gt;
}&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Ariely</name></author>
	</entry>
</feed>