|
5 | 5 | <link rel="stylesheet" href="styles.css"> |
6 | 6 | <meta name="robots" content="noindex"> |
7 | 7 | <script type="text/javascript"> |
| 8 | + // URL params are reflected into the page, so they must NEVER reach |
| 9 | + // innerHTML — that would be reflected XSS. Build the DOM with |
| 10 | + // textContent and createElement only. The strings are plain text: |
| 11 | + // mainHeading uses "\n" for line breaks, mainSpan uses "{0}" as |
| 12 | + // the placeholder for the phcode.io link. |
8 | 13 | function applyTranslations() { |
9 | | - const urlSearchParams = new URLSearchParams(window.location.search); |
10 | | - const params = Object.fromEntries(urlSearchParams.entries()); |
11 | | - if(params.mainHeading){ |
12 | | - document.getElementById("mainHeading").innerHTML = decodeURIComponent(params.mainHeading); |
| 14 | + const params = Object.fromEntries( |
| 15 | + new URLSearchParams(window.location.search).entries() |
| 16 | + ); |
| 17 | + if (params.mainHeading) { |
| 18 | + const el = document.getElementById("mainHeading"); |
| 19 | + el.textContent = ""; |
| 20 | + const lines = decodeURIComponent(params.mainHeading).split("\n"); |
| 21 | + lines.forEach(function(line, i) { |
| 22 | + if (i > 0) { |
| 23 | + el.appendChild(document.createElement("br")); |
| 24 | + } |
| 25 | + el.appendChild(document.createTextNode(line)); |
| 26 | + }); |
13 | 27 | } |
14 | | - if(params.mainSpan){ |
15 | | - document.getElementById("mainSpan").innerHTML = decodeURIComponent(params.mainSpan); |
| 28 | + if (params.mainSpan) { |
| 29 | + const el = document.getElementById("mainSpan"); |
| 30 | + el.textContent = ""; |
| 31 | + const parts = decodeURIComponent(params.mainSpan).split("{0}"); |
| 32 | + parts.forEach(function(part, i) { |
| 33 | + if (i > 0) { |
| 34 | + const a = document.createElement("a"); |
| 35 | + a.href = "https://phcode.io"; |
| 36 | + a.style.color = "white"; |
| 37 | + a.textContent = "phcode.io"; |
| 38 | + el.appendChild(a); |
| 39 | + } |
| 40 | + el.appendChild(document.createTextNode(part)); |
| 41 | + }); |
16 | 42 | } |
17 | 43 | } |
18 | 44 | </script> |
|
23 | 49 | <div id="mainDiv"> |
24 | 50 | <img id="logo" src="images/phoenix-logo-broken.svg"/> |
25 | 51 | <div id="MainText" class="safari-text"> |
26 | | - <h2 id="mainHeading">Uh Oh! <br>Your current browser doesn't support live preview.</h2> |
| 52 | + <h2 id="mainHeading">Uh Oh!<br>Your current browser doesn't support live preview.</h2> |
27 | 53 | <span id="mainSpan"> |
28 | | - Get the best live preview experience by downloading our native apps for Windows, Mac, and Linux from <a href="https://phcode.io" style="color: white">phcode.io</a>.<br> |
| 54 | + Get the best live preview experience by downloading our native apps for Windows, Mac, and Linux from <a href="https://phcode.io" style="color: white">phcode.io</a>. |
29 | 55 | </span><br> |
30 | 56 | </div> |
31 | 57 | </div> |
|
0 commit comments