Skip to content

Commit

Permalink
First shot at refactoring out common code
Browse files Browse the repository at this point in the history
See #137

When this is actually done, js/zap-common.js
will be moved into a bower module and end up
moving to something like:

bower_components/zap-common/index.js
  • Loading branch information
Shakeel Mohamed committed Jan 20, 2016
1 parent 12d6bf4 commit 150fa2e
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 85 deletions.
1 change: 1 addition & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
<script src="bower_components/jquery/dist/jquery.min.js"></script>
<script src="bower_components/seiyria-bootstrap-slider/dist/bootstrap-slider.min.js"></script>
<script src="bower_components/typeahead.js/dist/typeahead.jquery.min.js"></script>
<script src="js/zap-common.js"></script>
<script src="js/everything.js"></script>
<script src="https://www.youtube.com/iframe_api"></script>
</head>
Expand Down
133 changes: 48 additions & 85 deletions js/everything.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
/*global getParameterByName, getSearchResults, getAutocompleteSuggestions, parseYoutubeVideoID*/

/**
* YouTube iframe API required setup
*/
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -462,81 +463,26 @@ function anchorURLs(text) {
return text.replace(re, "<a href=\"$1\" target=\"_blank\">$1</a>");
}

// 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("<li><h4><a href=?v=" + result.id.videoId + ">" + result.snippet.title + "</a></h4></li>");
});
}).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();
Expand All @@ -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("<li><h4><a href=?v=" + result.id.videoId + ">" + result.snippet.title + "</a></h4></li>");
});
},
function(jqXHR, textStatus, errorThrown) {
var responseText = JSON.parse(jqXHR.error().responseText);
errorMessage.show(responseText.error.errors[0].message);
console.log("Search error", errorThrown);
}
);
}
}

Expand All @@ -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];
}));
Expand All @@ -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()) {
Expand Down
64 changes: 64 additions & 0 deletions js/zap-common.js
Original file line number Diff line number Diff line change
@@ -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 */
1 change: 1 addition & 0 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 + "=([^&#]*)"),
Expand Down

0 comments on commit 150fa2e

Please sign in to comment.