为什么这个greasemonkey代码不能与UTF8字符一起使用?

时间:2011-12-29 03:31:34

标签: javascript twitter greasemonkey

我正试图在Twitter上使用这个greasemonkey脚本。当我单击“RT”时,如果它是英文的话,它会正确地捕获引用的文本,而不是像日语这样的其他语言。如何解决这个问题?

(function () {
// ==UserScript==
// @name           Traditional Twitter RT (re-mixed) FF + Chrome
// @namespace      http://blog.krakenstein.net
// @author         daYOda (Krakenstein)
// @description    Old School RT Functionality for New Twitter, Allows retweeting with Comments
// @version        2.0
// @match          http://twitter.com/*
// @match          https://twitter.com/*
// ==/UserScript==

function c1(q,root){return document.evaluate(q,root?root:document,null,9,null).singleNodeValue;}
function c2(_q,_el){
  var res=[];var el,els=document.evaluate(_q,_el?_el:document,null,XPathResult.UNORDERED_NODE_ITERATOR_TYPE,null);
  while (el=els.iterateNext())res.push(el);return res;
}

const yodUpdate = {
  script_id : 89405,
  script_version : '2.0',
  script_pipeId : '7015d15962d94b26823e801048aae95d',
}

function setValue(key, value) {
  localStorage.setItem(key, value);
  return false;
}

function getValue(key) {
  var val = localStorage.getItem(key);
  return val;
}

function usoUpdate(el) {
  const s_CheckUpdate = 'YodCheckUpdate' + yodUpdate['script_id'];
  var md = parseInt(new Date().getDate());
  var CheckUpdate = parseInt(getValue(s_CheckUpdate));
  var NeedCheckUpdate = false;
  if (CheckUpdate !== md) {
    setValue(s_CheckUpdate, md);
    el = el ? el : document.body;
    if (el) {
      if (!document.getElementById(s_CheckUpdate)) {
        var s_gm = document.createElement('script');
        s_gm.id = s_CheckUpdate;
        s_gm.type = 'text/javascript';
        s_gm.innerHTML = 'function go' + s_CheckUpdate + '(itm){if(itm.value.items.length){return eval(unescape(itm.value.items[0].content).replace(/&lt;/g,\'<\').replace(/&gt;/g,\'>\').replace(/&amp;/g,\'&\'));}}';
        el.appendChild(s_gm);
      }
      var s_gm = document.createElement('script');
      s_gm.type = 'text/javascript';
      var sSrc = 'http://pipes.yahoo.com/pipes/pipe.run?_id=' + yodUpdate['script_pipeId'];
      sSrc += '&_render=json&_callback=go' + s_CheckUpdate;
      sSrc += '&id=' + yodUpdate['script_id'] + '&ver=' + yodUpdate['script_version'];
      //sSrc += '&redir=yes';
      s_gm.src = sSrc;
      el.appendChild(s_gm);

      NeedCheckUpdate = true;
    }
  }
  else {
    setValue(s_CheckUpdate, md);
  }

  return NeedCheckUpdate;
}

// phpjs
function addslashes (str) {
  return (str+'').replace(/[\\"']/g, '\\$&').replace(/\u0000/g, '\\0');
}

function ytrim(s) {
  var str = '';
  if (!(str = s.toString().replace(/[\u0080-\uFFFF]+/g, '').trim())) return str;
  var lines = str.replace(/^\s+|\s+$/g, '').split(/\s*\n\s*/);
  str = lines.join(' ').replace(/[\s]{2,}/, ' ');
  return str;
}

// click
function rt_click (screen_name, content) {
  return function (e) {
    var gmbinder, s_gm = document.createElement('script');
    if (gmbinder = c1('.//script[contains(@id,"gmbinder")]')) {
      document.body.removeChild(gmbinder);
    }
    s_gm.type = 'text/javascript';
    s_gm.id = 'yodgmbinder';
    s_gm.innerHTML = "yodShowTweetBox('" + addslashes(ytrim(screen_name)) + "','" + addslashes(ytrim(content)) + "');";
    document.body.appendChild(s_gm);
  }
}

// inject_button
function inject_button (target, link, text, ico) {
  var img = document.createElement('img');
  img.setAttribute('style', 'margin: 5px 5px 0px;');
  img.setAttribute('src', ico);

  var b = document.createElement('b');
  b.appendChild(document.createTextNode(text));

  // span tag
  var span = document.createElement('span');
  span.appendChild(img);
  span.appendChild(b);

  // a tag
  var a = document.createElement('a');
  //a.setAttribute('href', 'javascript:void(0);');
  a.setAttribute('href', '#');
  if (link._class) a.className = link._class;
  if (link._click) a.addEventListener('click', link._click, false);
  a.appendChild(span);
  target.appendChild(a);
}

// inject_button
function translate_link (yodRTDiv, tt, shortlink) {
  yodRTDiv.innerHTML = tt.innerHTML;
  // collect links
  var links = c2(".//a", yodRTDiv);
  for (i=0; i<links.length; i++) {
    var link = links[i];
    if (longURL = link.getAttribute('data-expanded-url')) {
      var newLink = document.createTextNode(shortlink? link.href : longURL);
      link.parentNode.replaceChild(newLink, link);
    }
  }
  var content = yodRTDiv.innerHTML.replace(/<\/?[^>]+>/g, '').replace(/&lt;/g, '<').replace(/&gt;/g, '>').replace(/&amp;/g, '&');
  yodRTDiv.innerHTML = "";
  return content;
}

// make retweet action
function make_retweet_action (entry) {

  // return if no Slave yodRTDiv
  if (!(yodRTDiv = c1('.//div[contains(@id,"yodRTDiv")]'))) return;

  // return if no Target
  var target;
  if (!(target = c1('.//span[contains(@class,"tweet-actions")]', entry))) return;

  // return if exist
  if (c1('.//a[contains(@class,"yod-old-style-retweet")]', entry)) return;

  // tweet text
  var tt;
  if (!(tt = c1('.//div[contains(@class,"tweet-text")]', entry))) return;

  // screen name
  var hh, screen_name;
  if (multi_tweet = c1('.//div[contains(@class,"stream-item-content")]', entry)) {
    screen_name = multi_tweet.getAttribute('data-screen-name');
  } else { //tweet
    if (tweet = entry) {
      screen_name = tweet.getAttribute('data-screen-name');
    }
  }
  if (!screen_name) return;

  // RT text
  var content = translate_link(yodRTDiv, tt);

  var link = {
    _class: 'yod-old-style-retweet',
    _click: rt_click(screen_name, content)
  };
  var label = 'RT';
  var ico = 'data:image/gif;base64,\
    R0lGODlhDQANAMQdALe3t6urq/z8/GNjY5eXl4ODg7a2tomJicDAwPn5+YaGhpmZmfv7+\
    6enp/39/aOjo+Tk5Lu7u/b29ry8vKmpqaamprCwsJubm6ysrPLy8u/v78HBwf///////w\
    AAAAAAACH5BAEAAB0ALAAAAAANAA0AAAVmYCdqW3VVmyauEZZxcIZF6wTBOAxNnUbBDIL\
    FcjFwMBqEg6PgJGCCCyezCUgOhcEL9uM8GhLAYrPhkBcASePBxWUGhYMksHldBLBn04HQ\
    YDgGF0MEDFwqNjk4OywubjMrIyUnKSshADs=';

  //inject_button (target, link, text, ico)
  inject_button(target, link, label, ico);

  // RT text
  var content = translate_link(yodRTDiv, tt, true);

  // FB Share
  var fbURL, fbTitle = 'Twitter @' + screen_name + ' ; ' + content;

  if (fbURL = c1('.//a[contains(@class,"tweet-timestamp")]', entry)) {
    var fbURL1 = 'http://www.facebook.com/sharer.php?u=' + fbURL.href.replace(/\/#!/, '');

    var link = {
      _click: function(){window.open(fbURL1)}
    };
    var label = 'Share';
    var ico = 'data:image/gif;base64,\
      R0lGODlhDQANANUAANna2+vu9Nvc3WF5rEVintrb3Onp6vv7+/T19c3T0t3e3/39/cbMzOPj\
      5OHi49/g4eXl5vLy8sXMy+fn6PX29urr6+Pl5tfY2cXLy8fOzeXm5tbY2fPz9Pn5+v7+/ubn\
      59ra29zd3vn5+efp6e7u7mB4q/n6+u/w8MbNzO/v8Pj4+MfNzfP09MbMy+rq67jAv+3t7r7E\
      xOvs7N/g4MfNzO7v7+bn6OHi4vb3922EtLnAwP///ztZmP///wAAAAAAACH5BAEAAD0ALAAA\
      AAANAA0AAAZQwJ5uSCzqhLukcrl76XYDnnTKG+yGOyqvlORdn9pA97vQZqVfDlUcCHiHKfP0\
      +5Gjhw5Cbp/b7QkeQwBRWlUUQwIABQIPDRAGFTUsR0aVPUEAOw==';

    inject_button(target, link, label, ico);


    var fbStatus = '@' + ytrim(escape(screen_name)).replace('"', '\"');
    fbStatus += ' ' + ytrim(escape(content)).replace('"', '\"');
    var fbURL2 = 'http://www.facebook.com/dialog/feed?app_id=215093328517543&message=' + fbStatus +'&redirect_uri=http://www.facebook.com/';

    var link = {
      _click: function(){window.open(fbURL2)}
    };
    var label = 'Status';

    inject_button(target, link, label, ico);
  }
}


// make all retweet actions
function make_all() {
  var si = document.getElementsByClassName('stream-item');
  if (si_length = si.length) {
    for (var i = 0; i < si_length; i++) {
      make_retweet_action(si[i]);
    }
  }
  else if (tweet = c1('.//div[contains(@class,"permalink-tweet")]')) {
    make_retweet_action(tweet);
  }

  //code for opening TweetDialog added on the head section, since it doesn't work otherwise
  var s_gm = document.createElement('script');
  s_gm.type = 'text/javascript';
  s_gm.id = 'yodShowTweetBoxHeaderScript';
  s_gm.innerHTML = 'function yodShowTweetBox(s,c){new twttr.widget.TweetDialog({draggable:true,defaultContent:"RT @"+s+" "+c,origin:"yod-Traditional-RT",template:{title:_("ReTweet @"+s+" (The Real Retweet)")}}).open().focus();}';

  var headElm = document.getElementsByTagName('head');
  headElm[0].appendChild(s_gm);

  //create Slave yodRTDiv
  var yodRTDiv = document.createElement('div');
  yodRTDiv.id = 'yodRTDiv';
  yodRTDiv.setAttribute('style', 'display:hidden;overflow:hidden;');
  document.body.appendChild(yodRTDiv);
}

var logged = false;

if (logged = c1('.//a[contains(@id,"new-tweet")]')) {
  // DOM node inserted event
  document.addEventListener('DOMNodeInserted', function (event) {
    var relatedtweets, replies, tweet, cname, elmt = event.target;
    if (!(/DIV/.test(elmt.tagName))) return;
    if (cname = elmt.className) {
      if (/stream-item/.test(cname)) {
        make_retweet_action(elmt);
      }
      else if (/component/.test(cname)) {
        if (tweet = c1('.//div[contains(@class,"permalink-tweet")]'), elmt) {
          make_retweet_action(tweet);
        }
        /*else*/
        if (relatedtweets = c2('.//div[contains(@class,"related-tweets")]/div[contains(@class,"stream-item")]'), elmt) {
          for (i=0; i<relatedtweets.length; i++) {
            make_retweet_action(relatedtweets[i]);
          }
        }
        if (tweet = c1('.//div[contains(@class,"conversation-last-ancestor-tweet")]'), elmt) {
          make_retweet_action(tweet);
        }
        if (tweet = c1('.//div[contains(@class,"details-pane-tweet")]'), elmt) {
          make_retweet_action(tweet);
        }
        if (replies = c2('.//div[contains(@class,"replies")]/div[contains(@class,"stream-item")]'), elmt) {
          for (i=0; i<replies.length; i++) {
            make_retweet_action(replies[i]);
          }
        }
      }
    }
  }, false);

  // make all retweet actions
  make_all();
}

usoUpdate();
})();

1 个答案:

答案 0 :(得分:2)

代码故意剥离非ASCII字符。

问题是ytrim功能。 不要写这样的代码!if()内部的分配,过度内联等)。

ytrim替换为:

function ytrim (s) {
    var str     = s.toString().trim();
    if ( ! str) {
        return str;
    }
    var lines   = str.replace (/^\s+|\s+$/g, '').split (/\s*\n\s*/);
    str         = lines.join (' ').replace (/[\s]{2,}/, ' ');
    return str;
}

它将解决全部或部分问题。