T/U box Fork

    @@ -36,16 +36,25 @@ return e; }; - // https://gist.github.com/noromanba/d730ccf3ae5e6916cd60 - const canonical_base = - (document.querySelector('head meta[property="og:url"][content]') || {}).content || - (document.querySelector('head link[rel="canonical"][href]') || {}).href || - ''; - const prefix = - (canonical_base.startsWith('/') && location.origin) || - (!canonical_base.match(/^[a-z]+:/) && location.protocol + '//') || /* :/ */ - ''; - const canonical = canonical_base ? prefix + canonical_base + location.hash : null; + const canonical = (() => { + const canonical_base = + (document.querySelector('head meta[property="og:url"][content]') || {}).content || + (document.querySelector('head link[rel="canonical"][href]') || {}).href || + ''; + + if (!canonical_base) return null; + + const prefix = + (canonical_base.startsWith('/') && location.origin) || + (!canonical_base.match(/^[a-z]+:/) && location.protocol + '//') || /* :/ */ + ''; + + const urlobj = new URL(prefix + canonical_base); + urlobj.hash = location.hash; + + return urlobj.href; + })(); + const title = document.title; const canonical_whitelist = /\.amazon\./;
  • /*
     * @title T/U box
     * @description w/ "{title} {url}" format. easy copyable title/url box; click to copy, double-click outer to close
     * @include http://*
     * @include https://*
     * @contributor	pacochi	http://let.hatelabo.jp/pacochi/let/hJme3OvVzN41
     * @contributor noromanba http://let.hatelabo.jp/noromanba/let/hJme3Pyylqos
     * @license MIT License	https://opensource.org/licenses/MIT
     * @javascript_url
     */
    
    /* modifications
    
    * Show confirm dialog for doubtful URL
     (location.pushState/replace will cause mismatch between meta URLs and current URL)
    * URL cleanup for some sites
    * Fix copy format
    * Hover cursor on inputs to show preview (i.e. title attribute)
    * Add Title+URL format
    * Append location.hash
    * Avoid to use array for querySelector (for cloudflare rocket.js)
    * Close on click anywhere
    * Add support of og:url with absolute path and protocol-less URL
    * Add support of Web Share API (Chromium and "Experimental Web Platform features" flag may be required. only on https page)
    * More styles
    
    */
    
    (() => {
      'use strict';
      
      const tag = (name, props = {}, children = []) => {
        const e = Object.assign(document.createElement(name), props);
        if (typeof props.style === "object") Object.assign(e.style, props.style);
        (children.forEach ? children : [children]).forEach(c => e.appendChild(c));
        return e;
      };
    
      const canonical = (() => {
        const canonical_base = 
              (document.querySelector('head meta[property="og:url"][content]') || {}).content ||
              (document.querySelector('head link[rel="canonical"][href]') || {}).href ||
              '';
        
        if (!canonical_base) return null;
        
        const prefix = 
              (canonical_base.startsWith('/') && location.origin) ||
              (!canonical_base.match(/^[a-z]+:/) && location.protocol + '//') || /* :/ */
              '';
        
        const urlobj = new URL(prefix + canonical_base);
        urlobj.hash = location.hash;
        
        return urlobj.href;
      })();
      
      const title = document.title;
    
      const canonical_whitelist = /\.amazon\./;
      const canonical_blacklist = /[\.\/]github\.com/;
      
      let url =
            (!canonical && location.href) ||
            (new URL(canonical).pathname === location.pathname && canonical) ||
            (canonical_whitelist.test(location.href) && canonical) ||
            (canonical_blacklist.test(location.href) && location.href) ||
            (confirm(`次のURLがmetaタグから見つかりましたが、現在のpathと異なります。\nキャンセルを押すとlocation.hrefを使用します。\n${canonical}`) && canonical) ||
            location.href;
      
      const filters = {
        // tbm: mode, tbs: options
        [/www\.google\.[a-z\.]+\/search/]: { allowed_params: /^(q|tbm|tbs|start)$/ },
        [/(amazon\.[a-z\.]+)\/([^\/]+\/)?dp/]: { replace: '$1/dp', allowed_params: /^$/ },
        // 単純な検索は search-alias, field-.+ で、そこから設定していくと rh になるっぽい。
        // url は search-alias 等を含んでいることがあり、展開してしまってもよさそうではあるが…。
        // あとcanonicalだとrhに正規化されてる気がする。
        [/(amazon\.[a-z\.]+)\/([^\/]+?\/)?(s|gp\/search)(\/[^\?]*)?\?/]: { replace: '$1/s?', allowed_params: /^(url|search-alias|field-.+|rh|sort|page)$/ }
      };
    
      for (const [name, action] of Object.entries(filters)) {
          const regex = new RegExp(name.substr(1, name.length - 2));
          if (!regex.test(url)) continue;
    
          if (action.replace)
            url = url.replace(regex, action.replace);
    
          const urlobj = new URL(url);
          if (action.allowed_params) {
            [...urlobj.searchParams.keys()]
            .filter(k => !action.allowed_params.test(k))
            .forEach(k => urlobj.searchParams.delete(k));
          }
          url = urlobj.toString();
      }
    
      const box = document.body.appendChild(tag('div', {
        id: 'copy-buttons',
        style: `
    border: 1em solid white;
    outline: 1px solid silver;
    padding: 0.2em 0.5em;
    background: silver;
    position: fixed;
    top: 0;
    left: 0;
    z-index: ${Number.MAX_SAFE_INTEGER || Number.MAX_VALUE};
    `,
      }));
      const onClose = e => {
        box.parentNode.removeChild(box);
        document.removeEventListener('click', onClose);
        e.stopPropagation();
      };
      
      box.addEventListener('click', e => e.stopPropagation());
      box.addEventListener('dblclick', onClose);
      document.addEventListener('click', onClose);
      
      [
        { label: 'URL', value: url },
        { label: 'Title', value: title },
        { label: 'Title + URL', value: title + ' ' + url },
        { label: 'Hatena', value: `[${url}:title=${title}]` },
        { label: 'Markdown', value: `[${title}](${url})` },
        navigator.share && { label: 'Web Share', value: `Share!`, onclick: () => navigator.share({ title, url }) },
      ].filter(x => x).forEach(({label, value, onclick}) => {
        box.appendChild(tag('label', {
          style: `display: block; color: black; text-align: left;`,
        }, [
          tag('span', {
            style: `display: inline-block; width: 8em;`,
            textContent: `${label}: `
          }),
          !onclick ?
          tag('input', {
            style: `
    color: black;
    background-color: #ddd;
    border: none;
    border-bottom: 1px solid gray;
    padding: 0.2em;
    margin: 0.3em 0;
    width: 15em;`,
            value,
            title: value,
            onclick: e => {
              e.target.select();
              document.execCommand('copy');
              e.stopPropagation();
            }
          }) :
          tag('input', {
            type: 'button',
            style: `margin: 0.3em 0; `,
            onclick,
            value
          })
        ]));
      });
    })();
    
  • Permalink
    このページへの個別リンクです。
    RAW
    書かれたコードへの直接のリンクです。
    Packed
    文字列が圧縮された書かれたコードへのリンクです。
    Userscript
    Greasemonkey 等で利用する場合の .user.js へのリンクです。
    Loader
    @require やソースコードが長い場合に多段ロードする Loader コミのコードへのリンクです。
    Metadata
    コード中にコメントで @xxx と書かれたメタデータの JSON です。