2009/05/10

Google Readerでtombloo

クロスポストに便利なtombloo。2種類のポスト方法があります。

  • コンテキストメニューからポスト
  • ショートカットキーからクイックポスト

一般的なサイトでの挙動はどちらでも大差無いのですが、Google Reader(多分LDRでも?)上だと若干異なります。

前者では現在フォーカスされているエントリーがポスト対象となり、後者ではGoogle Readerのページ自体がポストされてしまいます。後者でもフォーカスされているエントリーをポスト対象として欲しい。

コンテキストメニューの場合、イベント発生元の要素(=マウスポインタが置いてある要素)から遡って親要素からタイトルやリンクを取得している様ですが、ショートカットの場合、マウスの位置が関係ないので親要素の取得が出来ません。

ただ、DOM Inspectorで見る限り、フォーカスのあるエントリーは動的に"current-entry"というIDが振られる様です。なので、ID指定で要素を取得してポストする様に勝手にソース改変。

  1. 158:  var ctx = update({  
  2. 159:   document  : doc,  
  3. 160:   window    : win,  
  4. 161:   title     : doc.title,  
  5. 162:  }, win.location);  
  6. 163:// custom start  
  7. 164:   if(ctx.href.match('//www.google.[^/]+/reader/')) {  
  8. 165:    if(item = $x('id("current-entry")', ctx.document)) {  
  9. 166:     // Google Readerで、かつアクティブなエントリーが取得できた場合  
  10. 167:     // タイトル等を取得  
  11. 168:     var res = {  
  12. 169:      author : ($x('descendant::div[@class="entry-author"]/*[@class="entry-author-name"]/text()', item) || ''),  
  13. 170:      title  : $x('descendant::a[@class="entry-title-link"]/text()', item) || '',  
  14. 171:      feed   : ($x('descendant::a[@class="entry-source-title"]/text()', item) || $x('id("chrome-stream-title")//a/text()')),  
  15. 172:      href   : $x('descendant::a[@class="entry-title-link"]/@href', item).replace(/[?&;](fr?(om)?|track|ref|FM)=(r(ss(all)?|df)|atom)([&;].*)?/,''),  
  16. 173:     };  
  17. 174:       
  18. 175:     // この後ポストフォームで、ctx.titleとctx.hrefが使用される  
  19. 176:     // ので、勝手に書き換える  
  20. 177:     ctx.title = res.feed + (res.title? ' - ' + res.title : '');  
  21. 178:     ctx.href  = res.href;  
  22. 179:     ctx.host  = res.href.match('http://(.*?)/')[1];  
  23. 180:    } else {  
  24. 181:     // Google Readerだが、アクティブなエントリーが無い場合  
  25. 182:     // 何もしない  
  26. 183:    }  
  27. 184:   } else {  
  28. 185:    // Google Reader以外の場合  
  29. 186:    // 何もしない  
  30. 187:   }  
  31. 188:// custom end  
158: var ctx = update({ 159: document : doc, 160: window : win, 161: title : doc.title, 162: }, win.location); 163:// custom start 164: if(ctx.href.match('//www.google.[^/]+/reader/')) { 165: if(item = $x('id("current-entry")', ctx.document)) { 166: // Google Readerで、かつアクティブなエントリーが取得できた場合 167: // タイトル等を取得 168: var res = { 169: author : ($x('descendant::div[@class="entry-author"]/*[@class="entry-author-name"]/text()', item) || ''), 170: title : $x('descendant::a[@class="entry-title-link"]/text()', item) || '', 171: feed : ($x('descendant::a[@class="entry-source-title"]/text()', item) || $x('id("chrome-stream-title")//a/text()')), 172: href : $x('descendant::a[@class="entry-title-link"]/@href', item).replace(/[?&;](fr?(om)?|track|ref|FM)=(r(ss(all)?|df)|atom)([&;].*)?/,''), 173: }; 174: 175: // この後ポストフォームで、ctx.titleとctx.hrefが使用される 176: // ので、勝手に書き換える 177: ctx.title = res.feed + (res.title? ' - ' + res.title : ''); 178: ctx.href = res.href; 179: ctx.host = res.href.match('http://(.*?)/')[1]; 180: } else { 181: // Google Readerだが、アクティブなエントリーが無い場合 182: // 何もしない 183: } 184: } else { 185: // Google Reader以外の場合 186: // 何もしない 187: } 188:// custom end
  1. 1403: // ドキュメントタイトルを取得する  
  2. 1404: var title;  
  3. 1405:// custom start  
  4. 1406: if(typeof(ctx.title) == 'string'){  
  5. 1407:  // ctx.title設定済みの場合、ドキュメントタイトルに優先する  
  6. 1408:  title = ctx.title;  
  7. 1409: } else  
  8. 1410:// custom end  
1403: // ドキュメントタイトルを取得する 1404: var title; 1405:// custom start 1406: if(typeof(ctx.title) == 'string'){ 1407: // ctx.title設定済みの場合、ドキュメントタイトルに優先する 1408: title = ctx.title; 1409: } else 1410:// custom end

いささかスマートさに欠ける方法ですが、とりあえず目的は達成。

残る問題はSBM経由だとタイトルに余計な文字が入ることです。例えばDelicious/networkだとタイトルに"[from {user name}]"というプレフィックスが入ってしまいます。非同期でオリジナルソースページにアクセスしてタイトル取得とか、良くあるプレフィックスリストを作って削除、とかする必要がありそう。