メディア再生窓生成

    @@ -1,11 +1,15 @@ /* * @title メディア再生窓生成 - * @description マルチメディア要素へのリンクにhoverすると<audio>や<video>なウィンドウをポップアップしてくれるようにする + * @description マルチメディア要素へのリンクのクリックイベントに<audio>や<video>なウィンドウをポップアップする機能をオーバーライドする * @include http://* * @license NYSL */ +// 本当は子要素の大きさに合わせて(ブラウザごとに<audio>や<video>のコントローラの大きさが異なるので)ウィンドウの大きさを変えたいけど +// やり方が分からないので、エロい人教えろください + + (function(){ var checked = []; // 同じURLに複数回リクエストを送るのを防ぐためのリストを格納 var timeout = 30 * 1000; // タイムアウトになるまでの時間(単位:ms) @@ -55,7 +59,7 @@ if (url.indexOf("http") === 0) { - url = url.indexOf("#") + 1 ? url.split("#")[0] : url; // URLに # を含む場合は除去 + url = url.split("#")[0]; // URLに # を含む場合は除去 if (checked.every(function(li){ return url !== li })) { // 全てとアンマッチなら true checked.push(url); @@ -110,7 +114,7 @@ var rect = element.getBoundingClientRect(); popup.resizeTo(rect.width + 80, rect.height + 200); - function close() { // 再生中のメディアがゼロのとき、子ウィンドウを閉じる + function close() { // ポップアップ内のメディアがゼロのとき、子ウィンドウを閉じる doc.querySelectorAll( allowList.join(",") ).length === 0 ? popup.close() : 0; }
  • /*
     * @title メディア再生窓生成
     * @description マルチメディア要素へのリンクのクリックイベントに<audio>や<video>なウィンドウをポップアップする機能をオーバーライドする
     * @include http://*
     * @license NYSL
     */
    
    
    // 本当は子要素の大きさに合わせて(ブラウザごとに<audio>や<video>のコントローラの大きさが異なるので)ウィンドウの大きさを変えたいけど
    // やり方が分からないので、エロい人教えろください
    
    
    (function(){
      var checked = [];        // 同じURLに複数回リクエストを送るのを防ぐためのリストを格納
      var timeout = 30 * 1000; // タイムアウトになるまでの時間(単位:ms)
      
      var allowList = ["audio", "video"];
    
      if (!HTMLAnchorElement.prototype.addPopup) { // addPopupメソッドをA要素に追加
    
        Object.defineProperty(HTMLAnchorElement.prototype, "addPopup", {
          value: function(url){
            var self = this;
    
            var xhr = new XMLHttpRequest(); // HEADリクエストを送る
            xhr.open("HEAD", url, true);
            xhr.onreadystatechange = function(){
              if (xhr.readyState === 4) {
                console.log(xhr.status + " : " + url);
    
                if (xhr.status !== 200) return;
    
                var header = xhr.getResponseHeader("Content-Type");
                var type   = header.split("/")[0];
    
                if (allowList.some(function(v){ return v === type })) { // いずれかにヒットすれば true
                  console.log(header + " - OK");
                  addPopupItem(self, type);
                }
              }
            };
            xhr.send(null);
    
            window.setTimeout(function(){ // 一定時間でタイムアウト
              xhr.abort();
            }, timeout);
          }
        });
      }
      else {
        return false;
      }
    
      var elems = document.getElementsByTagName("a");
      elems = Array.prototype.slice.call(elems); // A要素を全て抽出
    
      for (var i in elems) {
        var url = elems[i].href;
    
        if (url.indexOf("http") === 0) {
    
          url = url.split("#")[0]; // URLに # を含む場合は除去
    
          if (checked.every(function(li){ return url !== li })) { // 全てとアンマッチなら true
            checked.push(url);
            elems[i].addPopup(url);
          }
        }
      }
    
      function addPopupItem(target, mediaType) { // ポップアップを生成
        target.onclick = function(evt){
          if (evt.ctrlKey && evt.altKey) {
            return true; // Ctrl+Alt を押しながらクリックすれば普段のクリックと同じ効果
          }
          else {
            openPopup();
            return false;
          }
        };
    
        function openPopup() {
          var popup = window.open("", "media-popup", "menubar=no,toolbar=no,location=no,status=no,scrollbars=yes");
          var doc   = popup.document;
    
          var style = doc.createElement("style");
          doc.querySelector("head").appendChild(style);
          var s = style.sheet, i = 0;
          [
            "body {"
            + "margin: 0;"
            + "padding: 0;"
            + "}",
            "audio {"
            + "display: block;"
            + "margin: auto;"
            + "}"
          ].forEach(function(value){
            s.insertRule(value, i++);
          });
    
          var element; // 殻の中身を定義
    
          element = doc.createElement(mediaType);
          element.setAttribute("src", target.href);
          element.setAttribute("autoplay", "autoplay");
          element.setAttribute("controls", "controls");
          element.addEventListener("ended", function(){ // 終端まで移動したら自らを削除する
            this.parentElement.removeChild(this);
            close();
          }, false);
    
          doc.body.appendChild(element);
          var rect = element.getBoundingClientRect();
          popup.resizeTo(rect.width + 80, rect.height + 200);
    
          function close() { // ポップアップ内のメディアがゼロのとき、子ウィンドウを閉じる
            doc.querySelectorAll( allowList.join(",") ).length === 0
            ? popup.close() : 0;
          }
        }
      }
    
    })();
    
  • Permalink
    このページへの個別リンクです。
    RAW
    書かれたコードへの直接のリンクです。
    Packed
    文字列が圧縮された書かれたコードへのリンクです。
    Userscript
    Greasemonkey 等で利用する場合の .user.js へのリンクです。
    Loader
    @require やソースコードが長い場合に多段ロードする Loader コミのコードへのリンクです。
    Metadata
    コード中にコメントで @xxx と書かれたメタデータの JSON です。

History

  1. 2013/04/28 18:17:21 - 2013-04-28
  2. 2013/04/27 14:07:33 - 2013-04-27
  3. 2013/04/27 03:49:45 - 2013-04-27
  4. 2013/04/27 02:47:19 - 2013-04-27
  5. 2013/04/27 02:44:48 - 2013-04-27
  6. 2013/04/27 02:43:38 - 2013-04-27
  7. 2013/04/26 17:28:58 - 2013-04-26
  8. 2013/04/23 02:15:08 - 2013-04-23
  9. 2013/04/22 10:27:13 - 2013-04-22
  10. 2013/04/22 10:01:50 - 2013-04-22
  11. 2013/04/22 09:50:14 - 2013-04-22