.gitignore added
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / tools@v0.1.0 / godoc / static / playground.js
diff --git a/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/tools@v0.1.0/godoc/static/playground.js b/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/tools@v0.1.0/godoc/static/playground.js
new file mode 100644 (file)
index 0000000..f5278a0
--- /dev/null
@@ -0,0 +1,593 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+/*
+In the absence of any formal way to specify interfaces in JavaScript,
+here's a skeleton implementation of a playground transport.
+
+        function Transport() {
+                // Set up any transport state (eg, make a websocket connection).
+                return {
+                        Run: function(body, output, options) {
+                                // Compile and run the program 'body' with 'options'.
+                               // Call the 'output' callback to display program output.
+                                return {
+                                        Kill: function() {
+                                                // Kill the running program.
+                                        }
+                                };
+                        }
+                };
+        }
+
+       // The output callback is called multiple times, and each time it is
+       // passed an object of this form.
+        var write = {
+                Kind: 'string', // 'start', 'stdout', 'stderr', 'end'
+                Body: 'string'  // content of write or end status message
+        }
+
+       // The first call must be of Kind 'start' with no body.
+       // Subsequent calls may be of Kind 'stdout' or 'stderr'
+       // and must have a non-null Body string.
+       // The final call should be of Kind 'end' with an optional
+       // Body string, signifying a failure ("killed", for example).
+
+       // The output callback must be of this form.
+       // See PlaygroundOutput (below) for an implementation.
+        function outputCallback(write) {
+        }
+*/
+
+// HTTPTransport is the default transport.
+// enableVet enables running vet if a program was compiled and ran successfully.
+// If vet returned any errors, display them before the output of a program.
+function HTTPTransport(enableVet) {
+  'use strict';
+
+  function playback(output, data) {
+    // Backwards compatibility: default values do not affect the output.
+    var events = data.Events || [];
+    var errors = data.Errors || '';
+    var status = data.Status || 0;
+    var isTest = data.IsTest || false;
+    var testsFailed = data.TestsFailed || 0;
+
+    var timeout;
+    output({ Kind: 'start' });
+    function next() {
+      if (!events || events.length === 0) {
+        if (isTest) {
+          if (testsFailed > 0) {
+            output({
+              Kind: 'system',
+              Body:
+                '\n' +
+                testsFailed +
+                ' test' +
+                (testsFailed > 1 ? 's' : '') +
+                ' failed.',
+            });
+          } else {
+            output({ Kind: 'system', Body: '\nAll tests passed.' });
+          }
+        } else {
+          if (status > 0) {
+            output({ Kind: 'end', Body: 'status ' + status + '.' });
+          } else {
+            if (errors !== '') {
+              // errors are displayed only in the case of timeout.
+              output({ Kind: 'end', Body: errors + '.' });
+            } else {
+              output({ Kind: 'end' });
+            }
+          }
+        }
+        return;
+      }
+      var e = events.shift();
+      if (e.Delay === 0) {
+        output({ Kind: e.Kind, Body: e.Message });
+        next();
+        return;
+      }
+      timeout = setTimeout(function() {
+        output({ Kind: e.Kind, Body: e.Message });
+        next();
+      }, e.Delay / 1000000);
+    }
+    next();
+    return {
+      Stop: function() {
+        clearTimeout(timeout);
+      },
+    };
+  }
+
+  function error(output, msg) {
+    output({ Kind: 'start' });
+    output({ Kind: 'stderr', Body: msg });
+    output({ Kind: 'end' });
+  }
+
+  function buildFailed(output, msg) {
+    output({ Kind: 'start' });
+    output({ Kind: 'stderr', Body: msg });
+    output({ Kind: 'system', Body: '\nGo build failed.' });
+  }
+
+  var seq = 0;
+  return {
+    Run: function(body, output, options) {
+      seq++;
+      var cur = seq;
+      var playing;
+      $.ajax('/compile', {
+        type: 'POST',
+        data: { version: 2, body: body, withVet: enableVet },
+        dataType: 'json',
+        success: function(data) {
+          if (seq != cur) return;
+          if (!data) return;
+          if (playing != null) playing.Stop();
+          if (data.Errors) {
+            if (data.Errors === 'process took too long') {
+              // Playback the output that was captured before the timeout.
+              playing = playback(output, data);
+            } else {
+              buildFailed(output, data.Errors);
+            }
+            return;
+          }
+          if (!data.Events) {
+            data.Events = [];
+          }
+          if (data.VetErrors) {
+            // Inject errors from the vet as the first events in the output.
+            data.Events.unshift({
+              Message: 'Go vet exited.\n\n',
+              Kind: 'system',
+              Delay: 0,
+            });
+            data.Events.unshift({
+              Message: data.VetErrors,
+              Kind: 'stderr',
+              Delay: 0,
+            });
+          }
+
+          if (!enableVet || data.VetOK || data.VetErrors) {
+            playing = playback(output, data);
+            return;
+          }
+
+          // In case the server support doesn't support
+          // compile+vet in same request signaled by the
+          // 'withVet' parameter above, also try the old way.
+          // TODO: remove this when it falls out of use.
+          // It is 2019-05-13 now.
+          $.ajax('/vet', {
+            data: { body: body },
+            type: 'POST',
+            dataType: 'json',
+            success: function(dataVet) {
+              if (dataVet.Errors) {
+                // inject errors from the vet as the first events in the output
+                data.Events.unshift({
+                  Message: 'Go vet exited.\n\n',
+                  Kind: 'system',
+                  Delay: 0,
+                });
+                data.Events.unshift({
+                  Message: dataVet.Errors,
+                  Kind: 'stderr',
+                  Delay: 0,
+                });
+              }
+              playing = playback(output, data);
+            },
+            error: function() {
+              playing = playback(output, data);
+            },
+          });
+        },
+        error: function() {
+          error(output, 'Error communicating with remote server.');
+        },
+      });
+      return {
+        Kill: function() {
+          if (playing != null) playing.Stop();
+          output({ Kind: 'end', Body: 'killed' });
+        },
+      };
+    },
+  };
+}
+
+function SocketTransport() {
+  'use strict';
+
+  var id = 0;
+  var outputs = {};
+  var started = {};
+  var websocket;
+  if (window.location.protocol == 'http:') {
+    websocket = new WebSocket('ws://' + window.location.host + '/socket');
+  } else if (window.location.protocol == 'https:') {
+    websocket = new WebSocket('wss://' + window.location.host + '/socket');
+  }
+
+  websocket.onclose = function() {
+    console.log('websocket connection closed');
+  };
+
+  websocket.onmessage = function(e) {
+    var m = JSON.parse(e.data);
+    var output = outputs[m.Id];
+    if (output === null) return;
+    if (!started[m.Id]) {
+      output({ Kind: 'start' });
+      started[m.Id] = true;
+    }
+    output({ Kind: m.Kind, Body: m.Body });
+  };
+
+  function send(m) {
+    websocket.send(JSON.stringify(m));
+  }
+
+  return {
+    Run: function(body, output, options) {
+      var thisID = id + '';
+      id++;
+      outputs[thisID] = output;
+      send({ Id: thisID, Kind: 'run', Body: body, Options: options });
+      return {
+        Kill: function() {
+          send({ Id: thisID, Kind: 'kill' });
+        },
+      };
+    },
+  };
+}
+
+function PlaygroundOutput(el) {
+  'use strict';
+
+  return function(write) {
+    if (write.Kind == 'start') {
+      el.innerHTML = '';
+      return;
+    }
+
+    var cl = 'system';
+    if (write.Kind == 'stdout' || write.Kind == 'stderr') cl = write.Kind;
+
+    var m = write.Body;
+    if (write.Kind == 'end') {
+      m = '\nProgram exited' + (m ? ': ' + m : '.');
+    }
+
+    if (m.indexOf('IMAGE:') === 0) {
+      // TODO(adg): buffer all writes before creating image
+      var url = 'data:image/png;base64,' + m.substr(6);
+      var img = document.createElement('img');
+      img.src = url;
+      el.appendChild(img);
+      return;
+    }
+
+    // ^L clears the screen.
+    var s = m.split('\x0c');
+    if (s.length > 1) {
+      el.innerHTML = '';
+      m = s.pop();
+    }
+
+    m = m.replace(/&/g, '&');
+    m = m.replace(/</g, '&lt;');
+    m = m.replace(/>/g, '&gt;');
+
+    var needScroll = el.scrollTop + el.offsetHeight == el.scrollHeight;
+
+    var span = document.createElement('span');
+    span.className = cl;
+    span.innerHTML = m;
+    el.appendChild(span);
+
+    if (needScroll) el.scrollTop = el.scrollHeight - el.offsetHeight;
+  };
+}
+
+(function() {
+  function lineHighlight(error) {
+    var regex = /prog.go:([0-9]+)/g;
+    var r = regex.exec(error);
+    while (r) {
+      $('.lines div')
+        .eq(r[1] - 1)
+        .addClass('lineerror');
+      r = regex.exec(error);
+    }
+  }
+  function highlightOutput(wrappedOutput) {
+    return function(write) {
+      if (write.Body) lineHighlight(write.Body);
+      wrappedOutput(write);
+    };
+  }
+  function lineClear() {
+    $('.lineerror').removeClass('lineerror');
+  }
+
+  // opts is an object with these keys
+  //  codeEl - code editor element
+  //  outputEl - program output element
+  //  runEl - run button element
+  //  fmtEl - fmt button element (optional)
+  //  fmtImportEl - fmt "imports" checkbox element (optional)
+  //  shareEl - share button element (optional)
+  //  shareURLEl - share URL text input element (optional)
+  //  shareRedirect - base URL to redirect to on share (optional)
+  //  toysEl - toys select element (optional)
+  //  enableHistory - enable using HTML5 history API (optional)
+  //  transport - playground transport to use (default is HTTPTransport)
+  //  enableShortcuts - whether to enable shortcuts (Ctrl+S/Cmd+S to save) (default is false)
+  //  enableVet - enable running vet and displaying its errors
+  function playground(opts) {
+    var code = $(opts.codeEl);
+    var transport = opts['transport'] || new HTTPTransport(opts['enableVet']);
+    var running;
+
+    // autoindent helpers.
+    function insertTabs(n) {
+      // find the selection start and end
+      var start = code[0].selectionStart;
+      var end = code[0].selectionEnd;
+      // split the textarea content into two, and insert n tabs
+      var v = code[0].value;
+      var u = v.substr(0, start);
+      for (var i = 0; i < n; i++) {
+        u += '\t';
+      }
+      u += v.substr(end);
+      // set revised content
+      code[0].value = u;
+      // reset caret position after inserted tabs
+      code[0].selectionStart = start + n;
+      code[0].selectionEnd = start + n;
+    }
+    function autoindent(el) {
+      var curpos = el.selectionStart;
+      var tabs = 0;
+      while (curpos > 0) {
+        curpos--;
+        if (el.value[curpos] == '\t') {
+          tabs++;
+        } else if (tabs > 0 || el.value[curpos] == '\n') {
+          break;
+        }
+      }
+      setTimeout(function() {
+        insertTabs(tabs);
+      }, 1);
+    }
+
+    // NOTE(cbro): e is a jQuery event, not a DOM event.
+    function handleSaveShortcut(e) {
+      if (e.isDefaultPrevented()) return false;
+      if (!e.metaKey && !e.ctrlKey) return false;
+      if (e.key != 'S' && e.key != 's') return false;
+
+      e.preventDefault();
+
+      // Share and save
+      share(function(url) {
+        window.location.href = url + '.go?download=true';
+      });
+
+      return true;
+    }
+
+    function keyHandler(e) {
+      if (opts.enableShortcuts && handleSaveShortcut(e)) return;
+
+      if (e.keyCode == 9 && !e.ctrlKey) {
+        // tab (but not ctrl-tab)
+        insertTabs(1);
+        e.preventDefault();
+        return false;
+      }
+      if (e.keyCode == 13) {
+        // enter
+        if (e.shiftKey) {
+          // +shift
+          run();
+          e.preventDefault();
+          return false;
+        }
+        if (e.ctrlKey) {
+          // +control
+          fmt();
+          e.preventDefault();
+        } else {
+          autoindent(e.target);
+        }
+      }
+      return true;
+    }
+    code.unbind('keydown').bind('keydown', keyHandler);
+    var outdiv = $(opts.outputEl).empty();
+    var output = $('<pre/>').appendTo(outdiv);
+
+    function body() {
+      return $(opts.codeEl).val();
+    }
+    function setBody(text) {
+      $(opts.codeEl).val(text);
+    }
+    function origin(href) {
+      return ('' + href)
+        .split('/')
+        .slice(0, 3)
+        .join('/');
+    }
+
+    var pushedEmpty = window.location.pathname == '/';
+    function inputChanged() {
+      if (pushedEmpty) {
+        return;
+      }
+      pushedEmpty = true;
+      $(opts.shareURLEl).hide();
+      window.history.pushState(null, '', '/');
+    }
+    function popState(e) {
+      if (e === null) {
+        return;
+      }
+      if (e && e.state && e.state.code) {
+        setBody(e.state.code);
+      }
+    }
+    var rewriteHistory = false;
+    if (
+      window.history &&
+      window.history.pushState &&
+      window.addEventListener &&
+      opts.enableHistory
+    ) {
+      rewriteHistory = true;
+      code[0].addEventListener('input', inputChanged);
+      window.addEventListener('popstate', popState);
+    }
+
+    function setError(error) {
+      if (running) running.Kill();
+      lineClear();
+      lineHighlight(error);
+      output
+        .empty()
+        .addClass('error')
+        .text(error);
+    }
+    function loading() {
+      lineClear();
+      if (running) running.Kill();
+      output.removeClass('error').text('Waiting for remote server...');
+    }
+    function run() {
+      loading();
+      running = transport.Run(
+        body(),
+        highlightOutput(PlaygroundOutput(output[0]))
+      );
+    }
+
+    function fmt() {
+      loading();
+      var data = { body: body() };
+      if ($(opts.fmtImportEl).is(':checked')) {
+        data['imports'] = 'true';
+      }
+      $.ajax('/fmt', {
+        data: data,
+        type: 'POST',
+        dataType: 'json',
+        success: function(data) {
+          if (data.Error) {
+            setError(data.Error);
+          } else {
+            setBody(data.Body);
+            setError('');
+          }
+        },
+      });
+    }
+
+    var shareURL; // jQuery element to show the shared URL.
+    var sharing = false; // true if there is a pending request.
+    var shareCallbacks = [];
+    function share(opt_callback) {
+      if (opt_callback) shareCallbacks.push(opt_callback);
+
+      if (sharing) return;
+      sharing = true;
+
+      var sharingData = body();
+      $.ajax('/share', {
+        processData: false,
+        data: sharingData,
+        type: 'POST',
+        contentType: 'text/plain; charset=utf-8',
+        complete: function(xhr) {
+          sharing = false;
+          if (xhr.status != 200) {
+            alert('Server error; try again.');
+            return;
+          }
+          if (opts.shareRedirect) {
+            window.location = opts.shareRedirect + xhr.responseText;
+          }
+          var path = '/p/' + xhr.responseText;
+          var url = origin(window.location) + path;
+
+          for (var i = 0; i < shareCallbacks.length; i++) {
+            shareCallbacks[i](url);
+          }
+          shareCallbacks = [];
+
+          if (shareURL) {
+            shareURL
+              .show()
+              .val(url)
+              .focus()
+              .select();
+
+            if (rewriteHistory) {
+              var historyData = { code: sharingData };
+              window.history.pushState(historyData, '', path);
+              pushedEmpty = false;
+            }
+          }
+        },
+      });
+    }
+
+    $(opts.runEl).click(run);
+    $(opts.fmtEl).click(fmt);
+
+    if (
+      opts.shareEl !== null &&
+      (opts.shareURLEl !== null || opts.shareRedirect !== null)
+    ) {
+      if (opts.shareURLEl) {
+        shareURL = $(opts.shareURLEl).hide();
+      }
+      $(opts.shareEl).click(function() {
+        share();
+      });
+    }
+
+    if (opts.toysEl !== null) {
+      $(opts.toysEl).bind('change', function() {
+        var toy = $(this).val();
+        $.ajax('/doc/play/' + toy, {
+          processData: false,
+          type: 'GET',
+          complete: function(xhr) {
+            if (xhr.status != 200) {
+              alert('Server error; try again.');
+              return;
+            }
+            setBody(xhr.responseText);
+          },
+        });
+      });
+    }
+  }
+
+  window.playground = playground;
+})();