diff --git a/index.html b/index.html index b45f8c34..54f0192e 100644 --- a/index.html +++ b/index.html @@ -21,6 +21,7 @@ + diff --git a/js/everything.js b/js/everything.js index 8da02c1d..8755b995 100644 --- a/js/everything.js +++ b/js/everything.js @@ -1,3 +1,5 @@ +/*global getParameterByName, getSearchResults, getAutocompleteSuggestions, parseYoutubeVideoID*/ + /** * YouTube iframe API required setup */ @@ -382,6 +384,7 @@ function cleanTime(time) { } function storeTime(time) { + // TODO: this is a bug! calling this function will make shit blow up var videoID = currentVideoID || getCurrentVideoID(); if (window.sessionStorage && videoID) { window.sessionStorage[videoID] = time; @@ -409,17 +412,15 @@ function loadTime() { } } -function getParameterByName(url, name) { - name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]"); - var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"), - results = regex.exec(url); - return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " ")); -} - function getCurrentVideoID() { var v = getParameterByName(window.location.search, "v"); - if (v.length > 0) { - return parseYoutubeVideoID(v); + // If the URL had 2 v parameters, try parsing the second (usually when ?v=someurl&v=xyz) + var vParams = window.location.search.match(/v=\w+/g); + if (vParams && vParams.length > 1) { + v = vParams[vParams.length - 1].replace("v=", ""); + } + else if (v.length > 1) { + return wrapParseYouTubeVideoID(v); } return v; } @@ -462,81 +463,26 @@ function anchorURLs(text) { return text.replace(re, "$1"); } -// TODO: this function can go away, the YouTube API will let you play video by URL -// The url parameter could be the video ID -function parseYoutubeVideoID(url) { - var videoID = currentVideoID; - - // We have already determined the video id - if (videoID && url === videoID) { - return videoID; +function wrapParseYouTubeVideoID(url) { + if (currentVideoID && url === currentVideoID) { + // We have already determined the video id + return currentVideoID; } - var shortUrlDomain = "youtu.be"; - var longUrlDomain = "youtube.com"; - - if (url && url.length > 0) { - // youtube.com format - if (url.indexOf(longUrlDomain) !== -1) { - ga("send", "event", "video ID format", longUrlDomain); - videoID = getParameterByName(url, "v"); - // If the URL had 2 v parameters, try parsing the second (usually when ?v=someurl&v=xyz) - if (videoID === "") { - videoID = getParameterByName(window.location.href.substring(window.location.href.indexOf(url)), "v"); - } - } - // youtu.be format - else if (url.indexOf(shortUrlDomain) !== -1) { - ga("send", "event", "video ID format", shortUrlDomain); - var endPosition = url.indexOf("?") === -1 ? url.length : url.indexOf("?"); - var offset = url.indexOf(shortUrlDomain) + shortUrlDomain.length + 1; // Skip over the slash also - videoID = url.substring(offset, endPosition); - } - // Assume YouTube video ID string - else { - ga("send", "event", "video ID format", "video ID"); - videoID = url; - } - - var slashPos = videoID.indexOf("/"); - // We found a slash in the video ID (ex: real id is ABC123, but saw ABC123/zen) - // So, only keep what's before the slash - if (slashPos !== -1) { - videoID = videoID.substring(0, slashPos); - } - - currentVideoID = videoID; + var info = parseYoutubeVideoID(url); - return videoID; + if (info.id) { + currentVideoID = info.id; + ga("send", "event", "video ID format", info.format); + return info.id; + } + else { + // TODO: analytics + errorMessage.show("Failed to parse the video ID."); } - errorMessage.show("Failed to parse the video ID."); } -function getSearchResults(query) { - $.getJSON("https://www.googleapis.com/youtube/v3/search", { - key: youTubeDataApiKey, - part: "snippet", - q: query, - type: "video" - }, function(data) { - if (data.pageInfo.totalResults === 0) { - errorMessage.show("No results."); - return; - } - //console.log(data); - $("#search-results").show(); - // Clear out results - $("#search-results ul").html(""); - $.each(data.items, function(index, result) { - //console.log(result.id.videoId); - $("#search-results ul").append("
  • " + result.snippet.title + "

  • "); - }); - }).fail(function(jqXHR, textStatus, errorThrown) { - var responseText = JSON.parse(jqXHR.error().responseText); - errorMessage.show(responseText.error.errors[0].message); - console.log("Search error", errorThrown); - }); -} +// TODO: this function can go away, the YouTube API will let you play video by URL $(function() { errorMessage.init(); @@ -550,7 +496,28 @@ $(function() { var currentSearchQuery = getCurrentSearchQuery(); if (currentSearchQuery) { $("#v").attr("value", currentSearchQuery); - getSearchResults(currentSearchQuery); + getSearchResults( + currentSearchQuery, + youTubeDataApiKey, + function(data) { + if (data.pageInfo.totalResults === 0) { + errorMessage.show("No results."); + return; + } + $("#search-results").show(); + // Clear out results + $("#search-results ul").html(""); + // TODO: refactor this to be less wide + $.each(data.items, function(index, result) { + $("#search-results ul").append("
  • " + result.snippet.title + "

  • "); + }); + }, + function(jqXHR, textStatus, errorThrown) { + var responseText = JSON.parse(jqXHR.error().responseText); + errorMessage.show(responseText.error.errors[0].message); + console.log("Search error", errorThrown); + } + ); } } @@ -561,11 +528,7 @@ $(function() { minLength: 1 }, { source: function (query, processSync, processAsync) { - return $.getJSON("https://suggestqueries.google.com/complete/search?callback=?", { - q: query, - client: "youtube", - ds: "yt" - }, function(data) { + getAutocompleteSuggestions(query, function(data) { return processAsync($.map(data[1], function(item) { return item[0]; })); @@ -581,7 +544,7 @@ $(function() { var formValue = $.trim($("#v").val()); if (formValue) { - var videoID = parseYoutubeVideoID(formValue); + var videoID = wrapParseYouTubeVideoID(formValue, true); ga("send", "event", "form submitted", videoID); if (isFileProtocol()) { diff --git a/js/zap-common.js b/js/zap-common.js new file mode 100644 index 00000000..56cb59cb --- /dev/null +++ b/js/zap-common.js @@ -0,0 +1,64 @@ +/*eslint-disable no-unused-vars*/ +function getParameterByName(url, name) { + name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]"); + var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"), + results = regex.exec(url); + return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " ")); +} + +function getSearchResults(query, youTubeDataApiKey, onData, onFail) { + $.getJSON("https://www.googleapis.com/youtube/v3/search", { + key: youTubeDataApiKey, + part: "snippet", + q: query, + type: "video" + }, onData).fail(onFail); +} + +function getAutocompleteSuggestions(query, callback) { + $.getJSON("https://suggestqueries.google.com/complete/search?callback=?", { + q: query, + client: "youtube", + ds: "yt" + }, callback); +} + +// The url parameter could be the video ID +function parseYoutubeVideoID(url) { + var videoInfo = { + format: "other", + id: null + }; + var shortUrlDomain = "youtu.be"; + var longUrlDomain = "youtube.com"; + + if (url && url.length > 0) { + // youtube.com format + if (url.indexOf(longUrlDomain) !== -1) { + videoInfo.format = longUrlDomain; + videoInfo.id = getParameterByName(url, "v"); + } + // youtu.be format + else if (url.indexOf(shortUrlDomain) !== -1) { + videoInfo.format = shortUrlDomain; + var endPosition = url.indexOf("?") === -1 ? url.length : url.indexOf("?"); + var offset = url.indexOf(shortUrlDomain) + shortUrlDomain.length + 1; // Skip over the slash also + videoInfo.id = url.substring(offset, endPosition); + } + // Assume YouTube video ID string + else { + videoInfo.format = "video ID"; + videoInfo.id = url; + } + + var slashPos = videoInfo.id.indexOf("/"); + // We found a slash in the video ID (ex: real id is ABC123, but saw ABC123/zen) + // So, only keep what's before the slash + if (slashPos !== -1) { + videoInfo.id = videoInfo.id.substring(0, slashPos); + } + + return videoInfo; + } +} +/*eslint-enable */ \ No newline at end of file diff --git a/test/index.js b/test/index.js index b5b59422..79f0eb8d 100644 --- a/test/index.js +++ b/test/index.js @@ -10,6 +10,7 @@ const browser = new Browser(); var indexHTMLURL = "file://" + path.join(__dirname, "..", "index.html"); /** Utilities **/ +// TODO: with refactor into a node module, this can go away! function getParameterByName(url, name) { name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]"); var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),