Fossil Forum

Forum
Login

Copy Button causes scrolling with IE

(1) By florian.balmer on 2019-06-11 17:18:04 [link]

Starting with check-in [5f0479d097], clicking the copy button now causes scrolling of the current page to the bottom with IE.

Is it an option to restore the previous version of the copyTextToClipboard() function, which worked fine with IE?

(2) By drh on 2019-06-11 17:34:19 [link] in reply to 1

What is the minimum amount of code that must be added back in in order to get the copyTextToClipboard() function working again on IE?

(3) By florian.balmer on 2019-06-11 21:08:44 [link] in reply to 2

I'll try to figure this out, hopefully tomorrow, and post back here.

There's probably various definitions of "work", here, i.e. "just work", or "work with as little side effects and visual artifacts as possible". The initial version even worked with accessibility settings enabled ("caret browsing" for screen readers).

(5) By florian.balmer on 2019-06-12 07:59:11 and edited on 2019-06-12 08:04:56 [link] in reply to 2

My initial strategy was to avoid IE-specific code, hence the extensive styling.

After reading the articles linked from this wiki page again, it seems that adding two lines of IE-specific code would produce the least amount of extra code.

Moreover, if style.position is set to 'fixed', there's no need to set style.left, so one more line can be squeezed, and some comments in the linked articles state that this would also work better with Edge.

Another good idea from the linked articles is to cleanup the temporary <textarea> element even in case of an error (for example, a security exception, if the browser is configured to block clipboard access).

function copyTextToClipboard(text){
  if( window.clipboardData && window.clipboardData.setData ){
    clipboardData.setData('Text',text);
  }else{
    var x = document.createElement("textarea");
    x.style.position = 'fixed';
    x.value = text;
    document.body.appendChild(x);
    x.select();
    try{
      document.execCommand('copy');
    }catch(err){
    }finally{
      document.body.removeChild(x);
    }
  }
}

By the way, did you try the simplified mousemove handler for the tooltips? It works more uniformly, improves tooltip positions for longer dwell timeouts, and the code is easier to read and maintain.

(6) By florian.balmer on 2019-06-12 12:55:27 [link] in reply to 2

Following HTML page can be used to test the suggested modifications to the copyTextToClipboard() function: the temporary <textarea> is left in place for 5 seconds, so that the visual and scrolling effects can be examined.

With style.position='fixed' it is never visible in Edge, Chrome, and Firefox (and never created in IE), and has no effect on the scrolling position.

However, with style.position='absolute' and style.left='-9999px', the scrolling position is changed for Edge and Firefox.

So I'd like to suggest to change the function to the code pasted above.

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
</head>
<body>
  <p style="white-space: nowrap;">
  Horizontal. Horizontal. Horizontal. Horizontal. Horizontal. Horizontal.
  Horizontal. Horizontal. Horizontal. Horizontal. Horizontal. Horizontal.
  </p>
  <p>Vertical.</p><p>Vertical.</p><p>Vertical.</p><p>Vertical.</p>
  <p>Vertical.</p><p>Vertical.</p><p>Vertical.</p><p>Vertical.</p>
  <p>Vertical.</p><p>Vertical.</p><p>Vertical.</p><p>Vertical.</p>
  <p>Vertical.</p><p>Vertical.</p><p>Vertical.</p><p>Vertical.</p>
  <p>Vertical.</p><p>Vertical.</p><p>Vertical.</p><p>Vertical.</p>
  <p>Vertical.</p><p>Vertical.</p><p>Vertical.</p><p>Vertical.</p>
  <p>Vertical.</p><p>Vertical.</p><p>Vertical.</p><p>Vertical.</p>
  <p>Vertical.</p><p>Vertical.</p><p>Vertical.</p><p>Vertical.</p>
  <script>
  function copyTextToClipboard(text){
    if( window.clipboardData && window.clipboardData.setData ){
      clipboardData.setData('Text',text);
    }else{
      var x = document.createElement("textarea");
      x.style.position = 'fixed';
      //x.style.position = 'absolute';
      //x.style.left = '-9999px';
      x.value = text;
      document.body.appendChild(x);
      x.select();
      try{
        document.execCommand('copy');
      }catch(err){
      }finally{
        setTimeout(function(){
          document.body.removeChild(document.body.lastChild);
        },5000);
      }
    }
  }
  document.body.onclick = function(){
    copyTextToClipboard("sample");
  };
  </script>
</body>
</html>