T/U box

    @@ -18,12 +18,21 @@ * Append location.hash * Avoid to use array for querySelector (for cloudflare rocket.js) * Close on click anywhere -* support og:url with absolute path and protocol-less URL +* Add support of og:url with absolute path and protocol-less URL +* Add support od Web Share API +* 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; + }; // https://gist.github.com/noromanba/d730ccf3ae5e6916cd60 const canonical_base = @@ -43,12 +52,13 @@ (confirm(`次のURLがmetaタグから見つかりましたが、現在のpathと異なります。\nキャンセルを押すとlocation.hrefを使用します。\n${canonical}`) && canonical) || location.href; - const box = document.body.appendChild(Object.assign(document.createElement('div'), { + const box = document.body.appendChild(tag('div', { id: 'copy-buttons', style: ` -background-color: white; -border: 1px solid silver; -padding: 1em; +border: 1em solid white; +outline: 1px solid silver; +padding: 0.2em 0.5em; +background: silver; position: fixed; top: 0; left: 0; @@ -65,33 +75,43 @@ box.addEventListener('dblclick', onClose); document.addEventListener('click', onClose); - // TBD alignment [ { label: 'URL', value: url }, { label: 'Title', value: title }, { label: 'Title + URL', value: title + ' ' + url }, - { label: 'HatenaSyntax', value: `[${url}:title=${title}]` }, + { label: 'Hatena', value: `[${url}:title=${title}]` }, { label: 'Markdown', value: `[${title}](${url})` }, - ].forEach(({label, value}) => { - box.appendChild(Object.assign(document.createElement('label'), { - style: ` -display: block; + 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: silver; -text-align: left; -`, - textContent: `${label}: `, - })).appendChild(Object.assign(document.createElement('input'), { - style: ` -color: black; -background-color: silver; -margin: 0.5em; -`, - value, - })).addEventListener('click', e => { - e.target.select(); - document.execCommand('copy'); - e.stopPropagation(); - }); +background-color: #ddd; +border: none; +border-bottom: 1px solid gray; +padding: 0.2em; +margin: 0.3em 0; +width: 15em;`, + value, + onclick: e => { + e.target.select(); + document.execCommand('copy'); + e.stopPropagation(); + } + }) : + tag('button', { + style: `margin: 0.3em 0; `, + onclick, + textContent: value + }) + ])); }); })();
  • /*
     * @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)
    * Fix copy format
    * 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 od Web Share API
    * 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;
      };
    
      // 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 title = document.title;
      
      const url =
            (!canonical && location.href) ||
            (new URL(canonical).pathname === location.pathname && canonical) ||
            (confirm(`次のURLがmetaタグから見つかりましたが、現在のpathと異なります。\nキャンセルを押すとlocation.hrefを使用します。\n${canonical}`) && canonical) ||
            location.href;
    
      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,
            onclick: e => {
              e.target.select();
              document.execCommand('copy');
              e.stopPropagation();
            }
          }) :
          tag('button', {
            style: `margin: 0.3em 0; `,
            onclick,
            textContent: value
          })
        ]));
      });
    })();
    
  • Permalink
    このページへの個別リンクです。
    RAW
    書かれたコードへの直接のリンクです。
    Packed
    文字列が圧縮された書かれたコードへのリンクです。
    Userscript
    Greasemonkey 等で利用する場合の .user.js へのリンクです。
    Loader
    @require やソースコードが長い場合に多段ロードする Loader コミのコードへのリンクです。
    Metadata
    コード中にコメントで @xxx と書かれたメタデータの JSON です。

History

  1. 2022/12/07 00:28:34 - 2022-12-07
  2. 2018/12/25 14:59:51 - 2018-12-25
  3. 2018/08/09 16:09:12 - 2018-08-09
  4. 2018/07/19 16:26:12 - 2018-07-19
  5. 2018/06/03 23:15:58 - 2018-06-03
  6. 2018/03/19 02:34:37 - 2018-03-19
  7. 2018/02/27 10:06:21 - 2018-02-27
  8. 2018/02/27 10:04:04 - 2018-02-27
  9. 2018/02/18 21:29:38 - 2018-02-18
  10. 2018/01/22 01:10:08 - 2018-01-22
  11. 2018/01/22 00:49:28 - 2018-01-22
  12. 2018/01/22 00:34:27 - 2018-01-22
  13. 2018/01/06 20:03:54 - 2018-01-06
  14. 2017/07/09 04:14:17 - 2017-07-09
  15. 2017/07/02 01:00:23 - 2017-07-02
  16. 2017/07/01 21:48:51 - 2017-07-01
  17. 2017/06/29 21:09:02 - 2017-06-29
  18. 2017/06/28 19:18:42 - 2017-06-28
  19. 2017/06/28 18:37:56 - 2017-06-28
  20. 2017/06/27 10:23:22 - 2017-06-27
  21. 2017/06/27 10:20:43 - 2017-06-27
  22. 2017/06/27 10:18:32 - 2017-06-27
  23. 2017/06/26 07:56:10 - 2017-06-26
  24. 2017/06/25 13:30:31 - 2017-06-25
  25. 2017/06/25 13:29:40 - 2017-06-25
  26. 2017/06/25 13:26:52 - 2017-06-25