管理画面のプレビューリンクをポップアップ表示するGMクリプト2008年03月29日 05時11分34秒

コメントスパム、多すぎ

またもアサブロがらみのグリモンスクリプトです。

トラバもそうなんだけど、ここ何日かコメントスパムが増えてきた。しかもほぼエロ関係

コメントはいままで即時公開設定だったんだけど、非合法くさいエロサイトへのリンクが載っかってるのはさすがに気まずいっつーか気分悪いので、取り急ぎチェックを経てから公開するように変更したんだけど、いちいちプレビューを開いて確認するのはわりと大変なのでその場で確認してみたいと。

んでソース

前回のグリモンスクリプトよりもちょっと長いかな。

var K = function(x) { return x; }

Object.extend = function(destination, source) {
  for(var key in source) destination[key] = source[key];
  return destination;
}

var $break = {};
var $continue = {};
var Enumerable = {
  each : function(iterator) {
    var i = 0;
    try {
      this._each( function(value) {
        try {
          iterator(value, i++);
        } catch(e) {
          if( e != $continue ) throw e;
        }
      } );
    } catch(e) {
      if( e != $break ) throw e;
    }
  },
  find : function(iterator) {
    var result = null;
    this.each( function(value, index) {
      if( iterator(value, index) ) {
        result = value;
        throw $break;
      }
    } );
    return result;
  },
  findAll : function(iterator) {
    var results = [];
    this.each( function(value, index) {
      if( iterator(value, index) ) results.push( value );
    } );
    return results;
  }
}
Array.prototype._each = function(iterator) {
  for(var i = 0, l = this.length; i < l; i++) iterator(this[i]);
}
Object.extend( Array.prototype, Enumerable );

Array.from = $A = function(list) {
  Object.extend( list, { _each : Array.prototype._each } );
  return Object.extend( list, Enumerable );
}

document.getElementsByClassName = function(className) {
  return $A( (arguments[1] || document).getElementsByTagName("*") ).findAll( function(ele) {
    var classes = ( ele.className || "" ).split(" ");
    return classes.find( function(c) { return c == className; } );
  } );
}

Object.extend( String.prototype, {
  stripTags : function(br) {
    var result = this;
    if( br ) result = result.replace( /<br\s*\/?>/ig, "\n" );
    return result.replace( /<[^>]+\/?>/g, "" );
  },
  toElements : function() {
    var temp = document.createElement("div");
    temp.style.display = "none";
    document.body.appendChild( temp );
    
    temp.innerHTML = this;
    
    var result = $A( temp.childNodes );
    document.body.removeChild( temp );
    
    return result;
  }
} );

var pop = Object.extend( document.createElement("div"), {
  _hover : false,
  id : "popup_element_" + (new Date().valueOf()),
  visible : function() {
    return this.style.display != "none";
  },
  show : function() {
    if( this.visible() ) return;
    
    this.style.display = "";
    this.scrollTop = 0;
    var pos = {
      x : ( arguments[0] + 8 ) || this.clientLeft,
      y : ( arguments[1] + 8 )|| this.clientTop
    };
    this.style.left = pos.x + "px";
    this.style.top = pos.y + "px";
  },
  hide : function() {
    if( this._hover ) return;
    this.style.display = "none";
  }
} );
pop.addEventListener( "mousemove", function(evt) {
  pop._hover = true;
  evt.preventDefault();
}, true );
pop.addEventListener( "mouseout", function(evt) {
  pop._hover = false;
  setTimeout( function() {
    pop.hide();
  }, 1000 );
  evt.preventDefault();
}, true );

Object.extend( pop.style, {
  width : "350px", height : "150px",
  border: "solid 1px silver",
  backgroundColor : "whitesmoke", color : "dimgray",
  padding: "0px", fontSize : "8pt",
  position : "absolute", overflow : "auto",
  opacity : 0.9, display : "none"
} );
document.body.appendChild( pop );

var cache = {};

var handlers = {
  over : function(evt) {
    if( ! evt.target.href || ! /app\?cmd=preview/.test( evt.target.href ) ) return;
    
    var link = evt.target.href;
    if( ! cache[link] ) {
      var xhr = new XMLHttpRequest();
      xhr.open( "get", link, false );
      xhr.send( null );
      
      var container = xhr.responseText.toElements().find( function(node) {
        return node.nodeType == 1 &&
          /div/i.test( node.nodeName ) &&
          node.id == "container";
      } );
      var previews = document.getElementsByClassName("preview", container );
      if( previews ) cache[link] = previews[0].innerHTML;
    }
    pop.innerHTML = cache[link] || "oops !!";
    pop.show( evt.pageX, evt.pageY );
  },
  leave : function(evt) {
    setTimeout( function() {
      pop.hide();
    }, 1000 );
  }
}

$A(document.getElementsByClassName("list")[0].getElementsByTagName("a")).findAll( function(a) {
  return /app\?cmd=preview/.test( a.href );
} ).each( function(a) {
  a.addEventListener( "mousemove", handlers.over, false );
  a.addEventListener( "mouseout", handlers.leave, false );
} );


前半部分は前と一緒でprototype.jsの一部移植。ほんで「var pop = 」のところがリンク先をポップアップ表示させるツールチップにあたるオブジェクトの定義。

んでこのスクリプトを「http://www.asablo.jp/app?cmd=edit_*」で実行させる。そうすると「コメント一覧」「トラックバック一覧」と「記事の編集・削除」のそれぞれの画面のプレビューリンク先にカーソルを乗せてその場で内容を確認できる。こんな感じで。

プレビューリンクからカーソルはずすと勝手に消えるけど、ポップアップ表示してるところにカーソルのせとけばずっと表示されてるので多少はじっくり確認できます。