JustOff/github-wc-polyfill

"Copy the full SHA" no longer works...

Vangelis66 opened this issue ยท 5 comments

Platform: (forked) UXP
Browser: (latest) Serpent 52.9.0 (2022-02-25) (32-bit)
Extension version: 1.2.14b2
Browser profile: Fresh (with default settings), with only this extension installed

STR:

  1. Visit/load e.g. :

https://github.com/JustOff/github-wc-polyfill/commits/master

  1. Move cursor to the "Copy the full SHA" button of top commit,

CopySHA

, click button

  1. Expected behaviour: Full (40 chars) commit HASH copied to the clipboard (with a visual indication of a successful copy action)

  2. Actual result: Clipboard is empty (or contains whatever string was put there, via whatever, immediately previous, copy action)...

  3. In contrast, on a Chromium-based browser sanctioned by GitHub, this is the visual result of clicking the button in question:

CopySHA2

and the clipboard becomes populated with 1291c0573ddaa116c48386110ffe5c6a4fe751a3 ...
Nothing I could spot stands out in Web/Error Console... ๐Ÿ˜ž

dirkf commented

Confirm in SM 2.5.10.2.

EventTarget.addEventListener failed on Custom Elements polyfill. It's working in current page. ๐Ÿ˜• Maybe click events have been intercepted by button tag.

This code is working. click events triggered by parent button.

(function () {
  function addEventListener (type, listener, options) {
    const target = this, parent = target.parentNode,
          ael = EventTarget.prototype.addEventListener;
    ael.call(target, type, listener, options);
    // Limit applied scope, or break other functions
    if (!(type === "click" && parent.localName === "button")) return;
    if (!triggerMap.has(target))
      triggerMap.set(target, function () {target.dispatchEvent(new Event("click"))});
    ael.call(parent, type, triggerMap.get(target), options);
  }
  function removeEventListener (type, listener, options) {
    const target = this, parent = target.parentNode,
          rel = EventTarget.prototype.removeEventListener;
    rel.call(target, type, listener, options);
    if (!(type === "click" && parent.localName === "button")) return;
    rel.call(parent, type, triggerMap.get(target), options);
  }
  const oldCED = customElements.define, triggerMap = new Map();
  customElements.define = function (name, cls) {
    cls.prototype.addEventListener = addEventListener;
    cls.prototype.removeEventListener = removeEventListener;
    oldCED.call(customElements, name, cls);
  };
}());

I tested the latest snapshot, c2f2c72, of your fork and it does address successfully this issue, thanks ๐Ÿ‘ , but...
Can you please submit a proper PR for this here, that can cleanly apply on top of master branch (or a "patch" on top of latest beta, 1.2.14b2) ?
(FWIW, you were kindly invited to do the same for another of your "fixes", but so far you seem reluctant to indulge... ).
Using a UXP-based browser myself, I have the "luxury" of being able to try your own fork, but this original extension does also cater to SeaMonkey users, which are NOT covered, AFAICS, by your fork...

Kindest regards ๐Ÿ˜„

I will tell you how to patch github-wc-polyfill, so I spend some time on writing digest tool.

Click here to expand and see tool's UI

digest tool

First, copy this html tool to your disk, named e.g. digest.html, then load it with your browser.

Click here to expand and copy
<!DOCTYPE html>
<html lang="en-us">
<head>
<title>Get strings digest integrity</title>
<style>
body > div {
  width: 800px;
  display: block;
  margin: 10px auto;
}
.integrity {
  display: inline-block;
  background: #E0E0E0;
  width: 600px;
  text-align: center;
}
button {
  background: #C0E0FF;
}
</style>
<script>
trimComment = false;
trimWhitespace = true;
shaVer = "256";  // [1, 256, 384, 512]
algorithm = `SHA-${shaVer}`;
async function digest(text) {
  if (!text) {
    integrity.textContent = "-";
    return;
  }
  let data = new TextEncoder().encode(text),
  hashBuffer = await crypto.subtle.digest(algorithm, data),
  hashArray = Array.from(new Uint8Array(hashBuffer)),
  hash = btoa(String.fromCharCode(...hashArray));
  console.log(hash);
  integrity.textContent = `sha${shaVer}-${hash}`;
}
function escape1(text) {
  // escape special replacement patterns
  return text.replace(/\$([$&'1-9])/g, "$\\$1")
             .replace(/\r\n?/g, "\n");         // unify line ending
}
function escape2(text) {
  return text.replace(/`|\\/g, "\\$&")         // escape [`] [\]
             .replace(/\$\{/g, "\\${");        // escape place holder
             
}
function wrap(text) {
  text = escape1(text);
  if (trimComment)
    text = text.replace(/\/\*.+?\*\//sg, "")   // range comment
               .replace(/\s*\/\/.*/g, "");     // standalone comment
  if (trimWhitespace)
    text = text.replace(/^\s*\n/g, "")         // head white
               .replace(/\n\s*(\n|$)/g, "\n")  // empty line
               .replace(/\s*(?=\n|$)/g, "");   // tail white
  text = text.replace(/^\s*$/g, "");           // empty text
  wrapped.textContent = "`" + escape2(text) + "`";
  return text;
}
async function deal(e) {
  let text = wrap(e.target.value);
  await digest(text);
}
function clipboardCopy(node) {
  let selection = getSelection(),
      range = document.createRange();
  selection.removeAllRanges();
  range.selectNodeContents(node);
  selection.addRange(range);
  document.execCommand("copy");
  selection.removeAllRanges();
}
</script>
</head>
<body>
<div>
  <h3>Input Strings</h3>
  <textarea id="inputstings" rows="20" cols="90" oninput="deal(event)"></textarea>
</div>
<div>
  <h3>Output Digest Integrity</h3>
  <div class="integrity"><b id="integrity">-</b></div>
  <button onclick="clipboardCopy(integrity)">copy integrity</button>
</div>
<div>
  <h3>Output Wrapped Strings</h3>
  <textarea id="wrapped" rows="20" cols="90" disabled="disabled"></textarea>
  <button onclick="clipboardCopy(wrapped)">copy wrapped strings</button>
</div>
<script>
inputstings.dispatchEvent(new Event("input"));
</script>
</body>
</html>

Paste the script who will be injected, into input text area, then you can click buttons to copy the following needed values.

+++const pfFollowUp = WRAPPED STRINGS;
+++const hashFollowUp = "'DIGEST INTEGRITY'";

Add hashFollowUp digest integrity.

---              csp = csp.replace(/script-src /g, "script-src " + hashBase + " ");
+++              csp = csp.replace(/script-src /g, "script-src " + hashBase + " " + hashFollowUp + " ");

Inject pfFollowUp at first position, in result it's the last.

      if (this.site == "github") {
+++        data = data.replace("<head>", "<head><script>" + pfFollowUp + "</script>");

Remove unnecessary e.g.

---        data = data.replace(/<script.+chunk-index2-[a-z0-9]+\.js"><\/script>/, "......");

it already works for me (Serpent52 + 1.2.15b1)


it's OK (Serpent52 + 1.2.15b3)