diff --git a/app/components/client/playground-scripts.js b/app/components/client/playground-scripts.js index 4fab7d3..1fd78f5 100644 --- a/app/components/client/playground-scripts.js +++ b/app/components/client/playground-scripts.js @@ -8,6 +8,7 @@ initializePlayground(); if (window.location.href.search && window.location.href.split("?url=")[1]) { // pre-fill example one if search parameter exists const searchParameter = window.location.href.split("?url=")[1]; + fetchMetadata(1, searchParameter); } @@ -102,7 +103,7 @@ function detectLanguageAndUpdate() { // eslint-disable-line function debounce(func, wait, immediate) { let timeout; - return function () { + return function() { const context = this; const args = arguments; @@ -112,6 +113,7 @@ function debounce(func, wait, immediate) { }; const callNow = immediate && !timeout; + clearTimeout(timeout); timeout = setTimeout(later, wait); @@ -126,7 +128,7 @@ function initializePlayground() { document.querySelector(".playground__navigation__example:nth-child(1)").classList.add("active"); send(JSON.stringify({ - "message": "landed on playground" + message: "landed on playground" })); setTimeout(() => { @@ -142,10 +144,10 @@ function fetchMetadata(exampleNumber, data) { switch(exampleNumber) { case 1: send(JSON.stringify({ - "claim": data, - "message": "fetch metadata", - "method": "resolve", - "example": exampleNumber + claim: data, + message: "fetch metadata", + method: "resolve", + example: exampleNumber })); document.getElementById("fetch-claim-uri").value = data; @@ -165,10 +167,10 @@ curl --header "Content-Type: application/json" case 2: send(JSON.stringify({ - "data": data, - "message": "fetch metadata", - "method": "publish", - "example": exampleNumber + data: data, + message: "fetch metadata", + method: "publish", + example: exampleNumber })); document.getElementById("playground-results").innerHTML = ` @@ -186,10 +188,10 @@ curl --header "Content-Type: application/json" case 3: send(JSON.stringify({ - "claim": data, - "message": "fetch metadata", - "method": "wallet_send", - "example": exampleNumber + claim: data, + message: "fetch metadata", + method: "wallet_send", + example: exampleNumber })); document.getElementById("fetch-claim-uri").value = data; @@ -269,7 +271,7 @@ const handleExamples = debounce(event => { document.getElementById("playground-results").removeAttribute("style"); send(JSON.stringify({ - "message": `request for ${data.action}` + message: `request for ${data.action}` })); break; @@ -295,7 +297,7 @@ const handleExamples = debounce(event => { document.getElementById("playground-results").removeAttribute("style"); send(JSON.stringify({ - "message": `request for ${data.action}` + message: `request for ${data.action}` })); break; @@ -324,7 +326,7 @@ const handleExamples = debounce(event => { document.getElementById("playground-results").removeAttribute("style"); send(JSON.stringify({ - "message": `request for ${data.action}` + message: `request for ${data.action}` })); break; diff --git a/app/components/head.js b/app/components/head.js index 307021a..655dbd8 100644 --- a/app/components/head.js +++ b/app/components/head.js @@ -77,6 +77,6 @@ export default (state, emit) => { // H E L P E R -String.prototype.capitalize = function () { +String.prototype.capitalize = function() { return this.charAt(0).toUpperCase() + this.slice(1); }; diff --git a/app/dist/scripts/app.js b/app/dist/scripts/app.js index 2572e85..3a75921 100755 --- a/app/dist/scripts/app.js +++ b/app/dist/scripts/app.js @@ -29,7 +29,7 @@ if ( // Toggle beta message localStorage.getItem("hide lbry alert") === "true" // cannot set Booleans for some reason ) document.querySelector("#alert-beta").style.display = "none"; -document.querySelector("#close-alert").onclick = function () { +document.querySelector("#close-alert").onclick = function() { localStorage.setItem("hide lbry alert", true); document.querySelector("#alert-beta").style.display = "none"; }; @@ -60,11 +60,12 @@ document.querySelectorAll("a[href^='#']").forEach(anchor => { // Newsletter document.querySelector("[data-action='subscribe to newsletter']").onclick = () => { const email = document.getElementById("emailAddress").value; + if (!validateEmail(email)) return; send(JSON.stringify({ - "email": email, - "message": "subscribe" + email: email, + message: "subscribe" })); }; @@ -88,5 +89,6 @@ function scrollToElementOnLoad() { function validateEmail(email) { const emailRegex = /^(([^<>()[\].,;:\s@"]+(\.[^<>()[\].,;:\s@"]+)*)|(".+"))@(([^<>()[\].,;:\s@"]+\.)+[^<>()[\\.,;:\s@"]{2,})$/i; + return emailRegex.test(String(email)); } diff --git a/app/dist/scripts/plugins/jets.js b/app/dist/scripts/plugins/jets.js index 4413390..04e12d4 100644 --- a/app/dist/scripts/plugins/jets.js +++ b/app/dist/scripts/plugins/jets.js @@ -1,14 +1,14 @@ /* global define */ -/*! Jets.js - v0.14.1 - 2018-06-22 +/* ! Jets.js - v0.14.1 - 2018-06-22 * http://NeXTs.github.com/Jets.js/ * Copyright (c) 2015 Denis Lukov; Refactored 2018 Paul Anthony Webb; Licensed MIT */ -(function (root, definition) { +(function(root, definition) { if (typeof module !== "undefined") module.exports = definition(); else if (typeof define === "function" && typeof define.amd === "object") define(definition); else root["Jets"] = definition(); -}(this, function () { +}(this, function() { "use strict"; function Jets(opts) { @@ -21,6 +21,7 @@ }; const self = this; + self.options = {}; [ @@ -58,23 +59,23 @@ self.search = (search_query, optional_column) => { const new_search_query = self.options.callSearchManually && - typeof search_query !== "undefined" - ? search_query - : self.search_tag - ? self.search_tag.value - : ""; + typeof search_query !== "undefined" ? + search_query : + self.search_tag ? + self.search_tag.value : + ""; if (last_search_query === (last_search_query = new_search_query)) return; (0, self._applyCSS(last_search_query, optional_column)); self.options.didSearch && self.options.didSearch(last_search_query); }; - self._onSearch = function (event) { + self._onSearch = function(event) { if (event.type === "keydown") return setTimeout(self.search, 0); self.search(); }; - self.destroy = function () { + self.destroy = function() { if (!self.options.callSearchManually) self._processEventListeners("remove"); self._destroy(); }; @@ -88,17 +89,17 @@ Jets.prototype = { constructor: Jets, - _processEventListeners: function (action) { + _processEventListeners: function(action) { [ "change", "input", "keydown" - ].forEach(function (event_type) { + ].forEach(function(event_type) { this.search_tag[action + "EventListener"](event_type, this._onSearch); }.bind(this)); }, - _applyCSS: function (search_query, optional_column) { + _applyCSS: function(search_query, optional_column) { const options = this.options; const search_phrase = this.replaceDiacritics( @@ -108,9 +109,9 @@ .replace(/\s\s+/g, " ") ).replace(/\\/g, "\\\\"); - const words = options.searchSelectorMode - ? search_phrase.split(" ").filter((item, pos, arr) => arr.indexOf(item) === pos) - : [search_phrase]; + const words = options.searchSelectorMode ? + search_phrase.split(" ").filter((item, pos, arr) => arr.indexOf(item) === pos) : + [search_phrase]; const is_strict_selector = options.searchSelectorMode === "AND"; const selectors = new Array(words.length); @@ -134,27 +135,30 @@ this.styleTag.innerHTML = search_phrase.length ? css_rule : ""; }, - _addStyleTag: function () { + _addStyleTag: function() { this.styleTag = document.createElement("style"); document.head.appendChild(this.styleTag); }, - _getText: function (tag) { + _getText: function(tag) { return tag && (tag.textContent || tag.innerText) || ""; }, - _sanitize: function (text) { - return this.replaceDiacritics(text).trim().replace(/\s+/g, " ").toLowerCase(); + _sanitize: function(text) { + return this.replaceDiacritics(text).trim() + .replace(/\s+/g, " ") + .toLowerCase(); }, - _getContentTags: function (query) { + _getContentTags: function(query) { return Array.prototype.slice.call(this.content_tag).reduce((all, elem) => { return all.concat(Array.prototype.slice.call(elem.querySelectorAll(query || ":scope > *"))); }, []); }, - _handleSpecificColumns: function (tag, set) { + _handleSpecificColumns: function(tag, set) { const self = this; + if (!self.options.searchInSpecificColumn) return; Array.prototype.slice.call(tag.children).map((children, i) => { @@ -168,7 +172,7 @@ }); }, - _setJets: function (query, force) { + _setJets: function(query, force) { const self = this; const tags = self._getContentTags(force ? "" : query); let text; @@ -176,19 +180,19 @@ for (const tag of tags) { if (tag.hasAttribute("data-jets") && !force) continue; - text = this.options.manualContentHandling - ? this.options.manualContentHandling(tag) - : self.options.columns && - self.options.columns.length - ? self.options.columns.map(column => self._getText(tag.children[column])).join(" ") - : self._getText(tag); + text = this.options.manualContentHandling ? + this.options.manualContentHandling(tag) : + self.options.columns && + self.options.columns.length ? + self.options.columns.map(column => self._getText(tag.children[column])).join(" ") : + self._getText(tag); tag.setAttribute("data-jets", self._sanitize(text)); self._handleSpecificColumns(tag, "set"); } }, - replaceDiacritics: function (text) { + replaceDiacritics: function(text) { const diacritics = this.options.diacriticsMap; for (const letter in diacritics) if (diacritics.hasOwnProperty(letter)) { @@ -200,11 +204,11 @@ return text; }, - update: function (force) { + update: function(force) { this._setJets(":scope > :not([data-jets])", force); }, - _destroy: function () { + _destroy: function() { this.styleTag.parentNode && document.head.removeChild(this.styleTag); const tags = this._getContentTags(); @@ -217,20 +221,22 @@ // :scope polyfill // https://stackoverflow.com/a/17989803/1221082 - ;(function (doc, proto) { + ;(function(doc, proto) { try { doc.querySelector(":scope body"); } catch (err) { ["querySelector", "querySelectorAll"].forEach(method => { const nativ = proto[method]; - proto[method] = function (selectors) { + proto[method] = function(selectors) { if (/(^|,)\s*:scope/.test(selectors)) { const id = this.getAttribute("id"); + this.id = "ID_" + Date.now(); selectors = selectors.replace(/((^|,)\s*):scope/g, "$1#" + this.getAttribute("id")); const result = doc[method](selectors); + this.id = id; return result; diff --git a/app/helpers/fetch-metadata.js b/app/helpers/fetch-metadata.js index 7324393..4de22bc 100644 --- a/app/helpers/fetch-metadata.js +++ b/app/helpers/fetch-metadata.js @@ -44,9 +44,9 @@ module.exports = exports = (data, socket) => { let apiRequestMethod = ""; if (allowedMethods.indexOf(resolveMethod) < 0) return socket.send(JSON.stringify({ - "details": "Unallowed resolve method for tutorial", - "message": "notification", - "type": "error" + details: "Unallowed resolve method for tutorial", + message: "notification", + type: "error" })); @@ -73,9 +73,9 @@ module.exports = exports = (data, socket) => { return uploadImage(body.file_path).then(uploadResponse => { if (!uploadResponse.status || uploadResponse.status !== "ok") { socket.send(JSON.stringify({ - "details": "Image upload failed", - "message": "notification", - "type": "error" + details: "Image upload failed", + message: "notification", + type: "error" })); if (process.env.NODE_ENV !== "development") { @@ -94,9 +94,9 @@ module.exports = exports = (data, socket) => { return publishMeme(body).then(publishResponse => { if (publishResponse.error) { socket.send(JSON.stringify({ - "details": "Meme publish failed", - "message": "notification", - "type": "error" + details: "Meme publish failed", + message: "notification", + type: "error" })); if (process.env.NODE_ENV !== "development") { @@ -126,14 +126,14 @@ module.exports = exports = (data, socket) => { `; return socket.send(JSON.stringify({ - "example": data.example, - "html": raw(` + example: data.example, + html: raw(`

Response

${explorerNotice}
${renderedCode}
`), - "message": "show result", - "selector": `#example${data.example}-result` + message: "show result", + selector: `#example${data.example}-result` })); }); }); @@ -160,13 +160,13 @@ module.exports = exports = (data, socket) => { if (!approvedIds.includes(claimAddress)) { return socket.send(JSON.stringify({ - "example": data.example, - "html": raw(` + example: data.example, + html: raw(`

Response

Tipping creators not in the whitelist for this example is not allowed.
`), - "message": "show result", - "selector": `#example${data.example}-result` + message: "show result", + selector: `#example${data.example}-result` })); } @@ -227,14 +227,14 @@ module.exports = exports = (data, socket) => { ); return socket.send(JSON.stringify({ - "example": data.example, - "html": raw(` + example: data.example, + html: raw(`

Response

${explorerNotice}
${renderedCode}
`), - "message": "show result", - "selector": `#example${data.example}-result` + message: "show result", + selector: `#example${data.example}-result` })); } diff --git a/app/helpers/github.js b/app/helpers/github.js index 9f0cf8d..05d1b7b 100644 --- a/app/helpers/github.js +++ b/app/helpers/github.js @@ -280,7 +280,10 @@ function generateGitHubFeed(displayGitHubFeed) { displayGitHubFeed(`

GitHub

-
Last updated: ${new Date().format("YYYY-MM-DD").replace(/-/g, "·")} at ${new Date().add(-4, "hours").format("UTC:H:mm:ss A").toLowerCase()} EST
+
Last updated: ${new Date().format("YYYY-MM-DD") + .replace(/-/g, "·")} at ${new Date().add(-4, "hours") + .format("UTC:H:mm:ss A") + .toLowerCase()} EST
${renderedEvents.join("")} `); @@ -336,13 +339,14 @@ function updateGithubFeed() { else callback(); }); }, () => client.zremrangebyrank("events", 0, -51)); // Keep the latest 50 events - }).catch(err => { - logSlackError( - "\n" + + }) + .catch(err => { + logSlackError( + "\n" + "> *GITHUB FEED ERROR:* ```" + JSON.parse(JSON.stringify(err)) + "```" + "\n" + "> _Cause: GitHub feed refresh_\n" - ); - }); + ); + }); } diff --git a/app/helpers/random-string.js b/app/helpers/random-string.js index 0762092..4ed3bcc 100644 --- a/app/helpers/random-string.js +++ b/app/helpers/random-string.js @@ -12,5 +12,6 @@ const crypto = require("crypto"); module.exports = exports = len => { if (!Number.isFinite(len)) throw new TypeError("Expected a finite number"); - return crypto.randomBytes(Math.ceil(len / 2)).toString("hex").slice(0, len); + return crypto.randomBytes(Math.ceil(len / 2)).toString("hex") + .slice(0, len); }; diff --git a/app/modules/markdown-it-sup.js b/app/modules/markdown-it-sup.js index 7973b36..5835136 100644 --- a/app/modules/markdown-it-sup.js +++ b/app/modules/markdown-it-sup.js @@ -59,6 +59,7 @@ function superscript(state, silent) { if (content.match(regexForIds)) { const theLink = supText.match(regexForIds)[0].replace("(#", "").replace(")", ""); + token.attrPush([ "id", theLink ]); } @@ -66,6 +67,7 @@ function superscript(state, silent) { if (content.match(regexForIds)) { const theText = supText.match(regexForTextBeforeLink)[0]; + token.content = theText; } else token.content = supText; diff --git a/app/sockets.js b/app/sockets.js index 2ba496b..a4c3874 100644 --- a/app/sockets.js +++ b/app/sockets.js @@ -29,9 +29,9 @@ module.exports = exports = (socket, action) => { case (action.message === "landed on homepage"): generateGitHubFeed(result => { socket.send(JSON.stringify({ - "html": result, - "message": "updated html", - "selector": "#github-feed" + html: result, + message: "updated html", + selector: "#github-feed" })); }); break; @@ -39,9 +39,9 @@ module.exports = exports = (socket, action) => { case (action.message === "landed on playground"): generateContent(1, result => { socket.send(JSON.stringify({ - "html": result, - "message": "updated html", - "selector": "#playground-loader" + html: result, + message: "updated html", + selector: "#playground-loader" })); }); break; @@ -49,9 +49,9 @@ module.exports = exports = (socket, action) => { case (action.message === "request for playground, example 1"): generateContent(1, result => { socket.send(JSON.stringify({ - "html": result, - "message": "updated html", - "selector": "#playground-loader" + html: result, + message: "updated html", + selector: "#playground-loader" })); }); break; @@ -63,9 +63,9 @@ module.exports = exports = (socket, action) => { case (action.message === "request for playground, example 3"): generateContent(3, result => { socket.send(JSON.stringify({ - "html": result, - "message": "updated html", - "selector": "#playground-loader" + html: result, + message: "updated html", + selector: "#playground-loader" })); }); break; @@ -291,10 +291,10 @@ function generateMemeCreator(socket) { `; return socket.send(JSON.stringify({ - "example": 2, - "html": memeCreator, - "message": "updated html", - "selector": "#playground-loader" + example: 2, + html: memeCreator, + message: "updated html", + selector: "#playground-loader" })); } @@ -315,9 +315,9 @@ function newsletterSubscribe(data, socket) { const email = data.email; if (!validateEmail(email)) return socket.send(JSON.stringify({ - "html": "Your email is invalid", - "message": "updated html", - "selector": "#emailMessage" + html: "Your email is invalid", + message: "updated html", + selector: "#emailMessage" })); return new Promise((resolve, reject) => { @@ -333,9 +333,9 @@ function newsletterSubscribe(data, socket) { ); return resolve(socket.send(JSON.stringify({ - "html": "Something is terribly wrong", - "message": "updated html", - "selector": "#emailMessage" + html: "Something is terribly wrong", + message: "updated html", + selector: "#emailMessage" }))); } @@ -349,36 +349,38 @@ function newsletterSubscribe(data, socket) { ); return reject(socket.send(JSON.stringify({ - "html": body.error, - "message": "updated html", - "selector": "#emailMessage" + html: body.error, + message: "updated html", + selector: "#emailMessage" }))); } return resolve(socket.send(JSON.stringify({ - "html": "Thank you! Please confirm subscription in your inbox.", - "message": "updated html", - "selector": "#emailMessage" + html: "Thank you! Please confirm subscription in your inbox.", + message: "updated html", + selector: "#emailMessage" }))); - }).catch(welp => { - if (welp.statusCode === 409) { - logSlackError( - "\n" + + }) + .catch(welp => { + if (welp.statusCode === 409) { + logSlackError( + "\n" + "> *NEWSLETTER ERROR:* ```" + JSON.parse(JSON.stringify(welp.error)) + "```" + "\n" + `> _Cause: ${email} interacted with the form_\n` - ); + ); - return resolve(socket.send(JSON.stringify({ - "html": "You have already subscribed!", - "message": "updated html", - "selector": "#emailMessage" - }))); - } - }); + return resolve(socket.send(JSON.stringify({ + html: "You have already subscribed!", + message: "updated html", + selector: "#emailMessage" + }))); + } + }); }); } function validateEmail(email) { const emailRegex = /^(([^<>()[\].,;:\s@"]+(\.[^<>()[\].,;:\s@"]+)*)|(".+"))@(([^<>()[\].,;:\s@"]+\.)+[^<>()[\\.,;:\s@"]{2,})$/i; + return emailRegex.test(String(email)); } diff --git a/app/views/api.js b/app/views/api.js index 41b3171..23ae3e6 100644 --- a/app/views/api.js +++ b/app/views/api.js @@ -51,10 +51,11 @@ module.exports = exports = state => parseApiFile(state.params.wildcard).then(res `; -}).catch(() => { - const redirectUrl = redirects[state.href]; +}) + .catch(() => { + const redirectUrl = redirects[state.href]; - return asyncHtml` + return asyncHtml`