2013-08-26 119 views
2

我已经写了的Greasemonkey(火狐)一UserScript和我在开发者控制台测试它与Chrome的Tampermonkey兼容性,并且得到错误:Tampermonkey的GM_xmlhttpRequest没有实现'context'属性?

Uncaught TypeError: Cannot read property 'profile_url' of undefined 
Uncaught TypeError: Cannot read property 'encoded_name' of undefined 

的错误似乎引用onreadystatechanged回调GM_xmlhttpRequest这是这样调用:

var flairs = document.querySelectorAll('span.flair'); 
var steam_re = /(?:(?:https?:\/\/)?www\.)?(?:steam|pc)(?:community\.com\/?(?:(id|profiles)\/?)?|[\s\-_]*id)?[\/:\s\|]*(.{2,}?)(?:[\/|:\-\[(] ?(?:\/?(?:ghost|enforcer|tech|mm|master))+[\[)]?)?$/i 

function get_text(e) { return e.innerText || e.textContent; } 

function set_text(e, t) { 
    if (e.innerText) 
     e.innerText = t; 
    else 
     e.textContent = t; 
} 

var parser = new DOMParser(); 

for (var i = 0; i < flairs.length; i++) { 
    var text = get_text(flairs[i]); 
    var match = steam_re.exec(text); 
    if (match == null || match.length < 3) 
     continue; 
    var type = match[1] || 'id'; 
    var name = encodeURIComponent(match[2]); 
    var url = 'http://steamcommunity.com/' + type + '/' + name; 
    var xml_url = url + '?xml=1'; 
    GM_xmlhttpRequest({ 
     method: 'GET', 
     url: xml_url, // Link to a steam profile with ?xml=1 added 
     accept: 'text/xml', 
     context: { 
      flair_index: i, 
      flair_text: text, // textContent of span element 
      encoded_name: name, 
      profile_url: url, // Link to steam profile 
      query_url: xml_url 
     }, 
     onreadystatechange: function(response) { 
      if (response.readyState != 4) 
       return; 
      // Attempt to fall back to alternate forms of context, 
      // none of which works. response.context works on Firefox/Greasemonkey. 
      var context = response.context || this.context || context; 
      var doc = parser.parseFromString(response.responseText, 'text/xml'); 
      var validProfile = doc.documentElement.nodeName == 'profile'; 
      var a = document.createElement('a'); 
      a.href = validProfile ? 
       context.profile_url : // TypeError here, context is undefined 
       ('http://steamcommunity.com/actions/SearchFriends?K=' + context.encoded_name); 
      a.className += (validProfile ? 'steam-profile-link' : 'steam-profile-search-link'); 
      var a_text = document.createTextNode(context.flair_text); 
      a.appendChild(a_text); 
      set_text(flairs[context.flair_index], ''); 
      flairs[context.flair_index].appendChild(a); 
     } 
    }); 
} 

此功能也称为细,并调用回调函数,但一旦我尝试访问它里面的context变种,它是不确定的。

这一切都按预期在Firefox中运行。它所做的是遍历具有“flair”类的span元素,并使用正则表达式检查它们是否包含Steam用户名,如果是,则使其成为SteamCommunity页面的链接。 (全文来源于github)。该脚本在/r/PaydayTheHeistOnline上运行。

我已经测试了使用在函数外部定义的数组来存储数据,而不是使用传递给xmlhttpRequest的上下文属性,但我得到了完全相同的错误。

回答

2

更新:
Tampermonkey现在报告,此功能(目前处于测试阶段)固定为3.8.4116版本。请参阅:


年长/通用解决方法:
The context property is a relatively new feature of GM_xmlhttpRequest(), in Firefox。我怀疑它是否已经在Tampermonkey中实现了;见Tampermonkey's docs for GM_xmlhttpRequest()

同时,这种事情的尝试和真正的方法是使用closure

GM_xmlhttpRequest()呼叫改变的东西

(function (flair_index, flair_text, encoded_name, profile_url, query_url) { 
    GM_xmlhttpRequest ({ 
     method: 'GET', 
     url: xml_url, // Link to a steam profile with ?xml=1 added 
     accept: 'text/xml', 
     onreadystatechange: function (response) { 
      if (response.readyState != 4) 
       return; 

      var doc = parser.parseFromString (response.responseText, 'text/xml'); 
      var validProfile = doc.documentElement.nodeName == 'profile'; 
      var a = document.createElement ('a'); 
      a.href = validProfile ? 
       profile_url : 
       ('http://steamcommunity.com/actions/SearchFriends?K=' + encoded_name); 
      a.className += (validProfile ? 'steam-profile-link' : 'steam-profile-search-link'); 
      var a_text = document.createTextNode (flair_text); 
      a.appendChild (a_text); 
      set_text (flairs[flair_index], ''); 
      flairs[flair_index].appendChild (a); 
     } 
    }); 
}) (
    i, 
    text, // textContent of span element 
    name, 
    url, // Link to steam profile 
    xml_url 
); 
+0

这工作完全,谢谢!我将不得不阅读关闭和范围。 – Sharparam

+0

不客气。乐意效劳。 –