Commit 28489698619a5ccc249a1ef386316523f67fe666

Michael Schmidt 2019-01-22T01:17:50

Cleanup JSONP highlight code (#1674) Document, refactor and format the JSONP Highlighting plugin.

diff --git a/plugins/jsonp-highlight/prism-jsonp-highlight.js b/plugins/jsonp-highlight/prism-jsonp-highlight.js
index 4ce5ca5..14ac205 100644
--- a/plugins/jsonp-highlight/prism-jsonp-highlight.js
+++ b/plugins/jsonp-highlight/prism-jsonp-highlight.js
@@ -1,44 +1,67 @@
-(function() {
-	if ( !self.Prism || !self.document || !document.querySelectorAll || ![].filter) return;
+(function () {
+	if (!self.Prism || !self.document || !document.querySelectorAll || ![].filter) return;
 
+	/**
+	 * The list of adapter which will be used if `data-adapter` is not specified.
+	 *
+	 * @type {Array.<(response: any, pre?: HTMLPreElement) => string>}
+	 */
 	var adapters = [];
+
+	/**
+	 * Adds a new function to the list of adapters.
+	 *
+	 * If the given adapter is already registered or not a function, nothing will happen.
+	 *
+	 * @param {(response: any, pre?: HTMLPreElement) => string} adapter The adapter to be registered.
+	 */
 	function registerAdapter(adapter) {
 		if (typeof adapter === "function" && !getAdapter(adapter)) {
 			adapters.push(adapter);
 		}
 	}
+	/**
+	 * Returns the given adapter itself, if registered, or a registered adapter with the given function name.
+	 *
+	 * If no fitting adapter is registered, `null` will be returned.
+	 *
+	 * @param {string|Function} adapter The adapter itself or the function name of an adapter.
+	 * @returns {(response: any, pre?: HTMLPreElement) => string} A registered adapter or `null`.
+	 */
 	function getAdapter(adapter) {
 		if (typeof adapter === "function") {
-			return adapters.filter(function(fn) { return fn.valueOf() === adapter.valueOf()})[0];
+			return adapters.filter(function (fn) { return fn.valueOf() === adapter.valueOf(); })[0];
 		}
 		else if (typeof adapter === "string" && adapter.length > 0) {
-			return adapters.filter(function(fn) { return fn.name === adapter})[0];
+			return adapters.filter(function (fn) { return fn.name === adapter; })[0];
 		}
 		return null;
 	}
+	/**
+	 * Remove the given adapter or the first registered adapter with the given function name from the list of
+	 * registered adapters.
+	 *
+	 * @param {string|Function} adapter The adapter itself or the function name of an adapter.
+	 */
 	function removeAdapter(adapter) {
-		if (typeof adapter === "string")
+		if (typeof adapter === "string") {
 			adapter = getAdapter(adapter);
+		}
 		if (typeof adapter === "function") {
 			var index = adapters.indexOf(adapter);
-			if (index >=0) {
-				adapters.splice(index,1);
+			if (index >= 0) {
+				adapters.splice(index, 1);
 			}
 		}
 	}
 
-	Prism.plugins.jsonphighlight = {
-		registerAdapter: registerAdapter,
-		removeAdapter: removeAdapter,
-		highlight: highlight
-	};
 	registerAdapter(function github(rsp, el) {
-		if ( rsp && rsp.meta && rsp.data ) {
-			if ( rsp.meta.status && rsp.meta.status >= 400 ) {
-				return "Error: " + ( rsp.data.message || rsp.meta.status );
+		if (rsp && rsp.meta && rsp.data) {
+			if (rsp.meta.status && rsp.meta.status >= 400) {
+				return "Error: " + (rsp.data.message || rsp.meta.status);
 			}
-			else if ( typeof(rsp.data.content) === "string" ) {
-				return typeof(atob) === "function"
+			else if (typeof (rsp.data.content) === "string") {
+				return typeof (atob) === "function"
 					? atob(rsp.data.content.replace(/\s/g, ""))
 					: "Your browser cannot decode base64";
 			}
@@ -46,91 +69,99 @@
 		return null;
 	});
 	registerAdapter(function gist(rsp, el) {
-		if ( rsp && rsp.meta && rsp.data && rsp.data.files ) {
-			if ( rsp.meta.status && rsp.meta.status >= 400 ) {
-				return "Error: " + ( rsp.data.message || rsp.meta.status );
+		if (rsp && rsp.meta && rsp.data && rsp.data.files) {
+			if (rsp.meta.status && rsp.meta.status >= 400) {
+				return "Error: " + (rsp.data.message || rsp.meta.status);
 			}
-			else {
-				var filename = el.getAttribute("data-filename");
-				if (filename == null) {
-					// Maybe in the future we can somehow render all files
-					// But the standard <script> include for gists does that nicely already,
-					// so that might be getting beyond the scope of this plugin
-					for (var key in rsp.data.files) {
-						if (rsp.data.files.hasOwnProperty(key)) {
-							filename = key;
-							break;
-						}
+
+			var files = rsp.data.files;
+			var filename = el.getAttribute("data-filename");
+			if (filename == null) {
+				// Maybe in the future we can somehow render all files
+				// But the standard <script> include for gists does that nicely already,
+				// so that might be getting beyond the scope of this plugin
+				for (var key in files) {
+					if (files.hasOwnProperty(key)) {
+						filename = key;
+						break;
 					}
 				}
-				if (rsp.data.files[filename] !== undefined) {
-					return rsp.data.files[filename].content;
-				}
-				else {
-					return "Error: unknown or missing gist file " + filename;
-				}
 			}
+
+			if (files[filename] !== undefined) {
+				return files[filename].content;
+			}
+			return "Error: unknown or missing gist file " + filename;
 		}
 		return null;
 	});
 	registerAdapter(function bitbucket(rsp, el) {
-		return rsp && rsp.node && typeof(rsp.data) === "string"
-			? rsp.data
-			: null;
+		if (rsp && rsp.node && typeof (rsp.data) === "string") {
+			return rsp.data;
+		}
+		return null;
 	});
 
 	var jsonpcb = 0,
-	    loadstr = "Loading…";
+		loadMsg = "Loading\u2026";
 
+	/**
+	 * Highlights all `pre` elements with an `data-jsonp` by requesting the specified JSON and using the specified adapter
+	 * or a registered adapter to extract the code to highlight from the response. The highlighted code will be inserted
+	 * into the `pre` element.
+	 */
 	function highlight() {
-		Array.prototype.slice.call(document.querySelectorAll("pre[data-jsonp]")).forEach(function(pre) {
+		Array.prototype.slice.call(document.querySelectorAll("pre[data-jsonp]")).forEach(function (pre) {
 			pre.textContent = "";
 
 			var code = document.createElement("code");
-			code.textContent = loadstr;
+			code.textContent = loadMsg;
 			pre.appendChild(code);
 
-			var adapterfn = pre.getAttribute("data-adapter");
+			var adapterName = pre.getAttribute("data-adapter");
 			var adapter = null;
-			if ( adapterfn ) {
-				if ( typeof(window[adapterfn]) === "function" ) {
-					adapter = window[adapterfn];
+			if (adapterName) {
+				if (typeof window[adapterName] === "function") {
+					adapter = window[adapterName];
 				}
 				else {
-					code.textContent = "JSONP adapter function '" + adapterfn + "' doesn't exist";
+					code.textContent = "JSONP adapter function '" + adapterName + "' doesn't exist";
 					return;
 				}
 			}
 
-			var cb = "prismjsonp" + ( jsonpcb++ );
-			
+			var cb = "prismjsonp" + jsonpcb++;
+
 			var uri = document.createElement("a");
 			var src = uri.href = pre.getAttribute("data-jsonp");
-			uri.href += ( uri.search ? "&" : "?" ) + ( pre.getAttribute("data-callback") || "callback" ) + "=" + cb;
+			uri.href += (uri.search ? "&" : "?") + (pre.getAttribute("data-callback") || "callback") + "=" + cb;
 
-			var timeout = setTimeout(function() {
+			var timeout = setTimeout(function () {
 				// we could clean up window[cb], but if the request finally succeeds, keeping it around is a good thing
-				if ( code.textContent === loadstr )
+				if (code.textContent === loadMsg) {
 					code.textContent = "Timeout loading '" + src + "'";
+				}
 			}, 5000);
-			
+
 			var script = document.createElement("script");
 			script.src = uri.href;
 
-			window[cb] = function(rsp) {
+			window[cb] = function (rsp) {
 				document.head.removeChild(script);
 				clearTimeout(timeout);
 				delete window[cb];
 
 				var data = "";
-				
-				if ( adapter ) {
+
+				if (adapter) {
 					data = adapter(rsp, pre);
 				}
 				else {
-					for ( var p in adapters ) {
+					for (var p in adapters) {
 						data = adapters[p](rsp, pre);
-						if ( data !== null ) break;
+						if (data !== null) {
+							break;
+						}
 					}
 				}
 
@@ -147,5 +178,11 @@
 		});
 	}
 
+	Prism.plugins.jsonphighlight = {
+		registerAdapter: registerAdapter,
+		removeAdapter: removeAdapter,
+		highlight: highlight
+	};
+
 	highlight();
 })();
\ No newline at end of file
diff --git a/plugins/jsonp-highlight/prism-jsonp-highlight.min.js b/plugins/jsonp-highlight/prism-jsonp-highlight.min.js
index ae910af..ba49d4d 100644
--- a/plugins/jsonp-highlight/prism-jsonp-highlight.min.js
+++ b/plugins/jsonp-highlight/prism-jsonp-highlight.min.js
@@ -1 +1 @@
-!function(){function t(t){"function"!=typeof t||e(t)||r.push(t)}function e(t){return"function"==typeof t?r.filter(function(e){return e.valueOf()===t.valueOf()})[0]:"string"==typeof t&&t.length>0?r.filter(function(e){return e.name===t})[0]:null}function n(t){if("string"==typeof t&&(t=e(t)),"function"==typeof t){var n=r.indexOf(t);n>=0&&r.splice(n,1)}}function a(){Array.prototype.slice.call(document.querySelectorAll("pre[data-jsonp]")).forEach(function(t){t.textContent="";var e=document.createElement("code");e.textContent=i,t.appendChild(e);var n=t.getAttribute("data-adapter"),a=null;if(n){if("function"!=typeof window[n])return e.textContent="JSONP adapter function '"+n+"' doesn't exist",void 0;a=window[n]}var u="prismjsonp"+o++,f=document.createElement("a"),l=f.href=t.getAttribute("data-jsonp");f.href+=(f.search?"&":"?")+(t.getAttribute("data-callback")||"callback")+"="+u;var s=setTimeout(function(){e.textContent===i&&(e.textContent="Timeout loading '"+l+"'")},5e3),d=document.createElement("script");d.src=f.href,window[u]=function(n){document.head.removeChild(d),clearTimeout(s),delete window[u];var o="";if(a)o=a(n,t);else for(var i in r)if(o=r[i](n,t),null!==o)break;null===o?e.textContent="Cannot parse response (perhaps you need an adapter function?)":(e.textContent=o,Prism.highlightElement(e))},document.head.appendChild(d)})}if(self.Prism&&self.document&&document.querySelectorAll&&[].filter){var r=[];Prism.plugins.jsonphighlight={registerAdapter:t,removeAdapter:n,highlight:a},t(function(t){if(t&&t.meta&&t.data){if(t.meta.status&&t.meta.status>=400)return"Error: "+(t.data.message||t.meta.status);if("string"==typeof t.data.content)return"function"==typeof atob?atob(t.data.content.replace(/\s/g,"")):"Your browser cannot decode base64"}return null}),t(function(t,e){if(t&&t.meta&&t.data&&t.data.files){if(t.meta.status&&t.meta.status>=400)return"Error: "+(t.data.message||t.meta.status);var n=e.getAttribute("data-filename");if(null==n)for(var a in t.data.files)if(t.data.files.hasOwnProperty(a)){n=a;break}return void 0!==t.data.files[n]?t.data.files[n].content:"Error: unknown or missing gist file "+n}return null}),t(function(t){return t&&t.node&&"string"==typeof t.data?t.data:null});var o=0,i="Loading…";a()}}();
\ No newline at end of file
+!function(){function t(t){"function"!=typeof t||e(t)||r.push(t)}function e(t){return"function"==typeof t?r.filter(function(e){return e.valueOf()===t.valueOf()})[0]:"string"==typeof t&&t.length>0?r.filter(function(e){return e.name===t})[0]:null}function n(t){if("string"==typeof t&&(t=e(t)),"function"==typeof t){var n=r.indexOf(t);n>=0&&r.splice(n,1)}}function a(){Array.prototype.slice.call(document.querySelectorAll("pre[data-jsonp]")).forEach(function(t){t.textContent="";var e=document.createElement("code");e.textContent=i,t.appendChild(e);var n=t.getAttribute("data-adapter"),a=null;if(n){if("function"!=typeof window[n])return e.textContent="JSONP adapter function '"+n+"' doesn't exist",void 0;a=window[n]}var u="prismjsonp"+o++,f=document.createElement("a"),l=f.href=t.getAttribute("data-jsonp");f.href+=(f.search?"&":"?")+(t.getAttribute("data-callback")||"callback")+"="+u;var s=setTimeout(function(){e.textContent===i&&(e.textContent="Timeout loading '"+l+"'")},5e3),c=document.createElement("script");c.src=f.href,window[u]=function(n){document.head.removeChild(c),clearTimeout(s),delete window[u];var o="";if(a)o=a(n,t);else for(var i in r)if(o=r[i](n,t),null!==o)break;null===o?e.textContent="Cannot parse response (perhaps you need an adapter function?)":(e.textContent=o,Prism.highlightElement(e))},document.head.appendChild(c)})}if(self.Prism&&self.document&&document.querySelectorAll&&[].filter){var r=[];t(function(t){if(t&&t.meta&&t.data){if(t.meta.status&&t.meta.status>=400)return"Error: "+(t.data.message||t.meta.status);if("string"==typeof t.data.content)return"function"==typeof atob?atob(t.data.content.replace(/\s/g,"")):"Your browser cannot decode base64"}return null}),t(function(t,e){if(t&&t.meta&&t.data&&t.data.files){if(t.meta.status&&t.meta.status>=400)return"Error: "+(t.data.message||t.meta.status);var n=t.data.files,a=e.getAttribute("data-filename");if(null==a)for(var r in n)if(n.hasOwnProperty(r)){a=r;break}return void 0!==n[a]?n[a].content:"Error: unknown or missing gist file "+a}return null}),t(function(t){return t&&t.node&&"string"==typeof t.data?t.data:null});var o=0,i="Loading…";Prism.plugins.jsonphighlight={registerAdapter:t,removeAdapter:n,highlight:a},a()}}();
\ No newline at end of file