window.VJGreetingApp = function () {
this.label = function () { return "Greeting"; }
this.url = function () { return ""; }
this.sentences = function () {
var text = "";
var d = new Date();
var hours = d.getHours();
if (hours >= 5 && hours < 12) {
text = "Good Morning";
} else if (hours >= 12 && hours < 18) {
text = "Good Afternoon";
} else {
text = "Good Evening";
}
return [ text ];
}
};
window.VJTodayApp = function () {
this.label = function () { return "Today\'s Date"; }
this.url = function () { return "http://www.google.com/search?q=time"; }
this.sentences = function () {
var d = new Date();
var days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
var months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
var year = d.getFullYear() +"";
var dayOfWeek = days[d.getDay()];
var month = months[d.getMonth()];
var day = d.getDate();
var year1 = year.substr(0, 2);
var year2 = year.substr(2, 2);
var text = "Today is "+ dayOfWeek +", "+ month +" "+ day +", "+ year1 +" "+ year2 +".";
return [ text ];
}
this.focusElements = function () {
return [ byId("topstuff") ];
}
};
window.VJWeatherApp = function () {
this.label = function () { return "Weather"; }
this.url = function () { return "http://www.google.com/search?q=weather+forecast"; }
this.sentences = function () {
var error = [ "The current weather could not be determined." ];
var topstuff = byId("topstuff");
if (!topstuff) {
return [ error ];
}
// find the temperature
var allText = topstuff.textContent;
var positionOfPipe = allText.indexOf("|");
if (positionOfPipe < 0) {
return [ error ];
}
var dirtyTemperature = allText.substr(positionOfPipe - 5, 5);
var temperature = parseIntFromString(dirtyTemperature);
var condition;
// find the div with the "Current" word at the beginning
var divs = topstuff.getElementsByTagName("div");
for (var i = 0; i < divs.length; i++) {
var div = divs[i];
if (div.textContent.indexOf("Current") == 0) {
var currentDiv = div;
// we've found the "Current" div, now find the bold tag with the condition
var bDivs = currentDiv.getElementsByTagName("b");
if (bDivs.length > 0) {
condition = bDivs[0].textContent;
}
}
}
if (!condition) {
return [ error ];
}
var text = "The weather is "+ condition + " with a temperature of "+ temperature +" degrees.";
return [ text ];
}
this.focusElements = function () {
return [ byId("topstuff") ];
}
};
window.VJGoodbyeFlickrApp = function () {
this.label = function () { return "Goodbye (Flickr)"; }
this.url = function () {
var d = new Date();
var month = d.getMonth();
var day = d.getDate();
var year = d.getFullYear();
return "http://www.flickr.com/explore/interesting/"+ year +"/"+ month +"/"+ day +"/show/";
}
this.sentences = function () { return [ "That\'s all for now.", "Have a great day!" ]; }
};
window.VJGoodbyeGladiatorApp = function () {
this.label = function () { return "Goodbye (Gladiator)"; }
this.url = function () { return "http://www.youtube.com/watch?v=rNdKBPcVGJI"; }
this.sentences = function () { return [ "That\'s all for now.", "You are a Gladiator." ]; }
};
window.VJGoodbyeDefaultApp = function () {
this.label = function () { return "Goodbye (Default)"; }
this.url = function () { return "http://verbaljuicer.com/"; }
this.sentences = function () { return [
"That\'s all for now.",
"Thanks for trying Verbal Juicer.",
"You can install new sites from the gallery on this page.",
"You can re-order your list and final page by clicking the edit button.",
"You can customize my voice and speed in your computer\'s System Preferences.",
"Have a great day." ]; }
};
window.VJFlickrApp = function () {
this.label = function () { return "Flickr"; }
this.url = function () {
return "http://www.flickr.com/";
}
this.sentences = function () {
// find the number of new messages
var text = "You have no new messages";
var unread = parseIntFromElement(byId("UnreadMessageChunk"));
if (unread >= 0) {
text = "You have "+ unread +" new message"+ ((unread != 1) ? "s" : "");
}
return [ "Flickr.", text ];
}
};
window.VJTwitterApp = function () {
this.label = function () { return "Twitter"; }
this.url = function () {
return "http://twitter.com/";
}
this.delayAfterPageLoads = function () { return 2.5; }
this.sentences = function () {
var text = "";
var text2 = "";
// find the number of new followers
var els = document.getElementsByClassName("new-followers-activity");
if (els[0]) {
var els2 = els[0].getElementsByClassName("user-stat-link");
if (els2[0]) {
var followers = parseIntFromElement(els2[0]);
if (followers >= 0) {
text = "You have "+ followers +" follower"+ ((followers != 1) ? "s" : "");
}
}
}
// find the number of new lists
var els3 = document.getElementsByClassName("lists-activity");
if (els3[0]) {
var els4 = els3[0].getElementsByClassName("user-stat-link");
if (els4[0]) {
var lists = parseIntFromElement(els4[0]);
if (lists >= 0) {
text2 = " and you are on "+ lists +" list"+ ((lists != 1) ? "s" : "");
}
}
}
return [ "Twitter.", text, text2 ];
}
this.focusElements = function () {
return [
document,
document.getElementsByClassName("new-followers-activity")[0],
document.getElementsByClassName("lists-activity")[0]
];
}
};
window.VJTwitterDirectMessagesApp = function () {
this.label = function () { return "Twitter DMs"; }
this.url = function () {
return "http://twitter.com/messages";
}
this.delayAfterPageLoads = function () { return 1.5; }
this.sentences = function () {
var text = "";
// find the number of new direct messages
var directMessages;
var els = document.getElementsByClassName("stream-items");
for (var i in els) {
if (els[i] && els[i].getElementsByClassName) {
var timestamps = els[i].getElementsByClassName("_timestamp");
var k = 0;
for (var j in timestamps) {
if (timestamps[j].innerHTML && (timestamps[j].innerHTML.indexOf("hour") != -1
|| timestamps[j].innerHTML.indexOf("minute") != -1
|| timestamps[j].innerHTML.indexOf("second") != -1)) {
k++;
}
}
directMessages = k;
}
}
if (directMessages >= 0) {
text = "You have "+ directMessages +" direct message"+ ((directMessages != 1) ? "s" : "") +" in the past 24 hours";
}
return [ text ];
}
};
window.VJGoogleNewsApp = function () {
this.label = function () { return "Google News"; }
this.url = function () { return "http://news.google.com/"; }
this.sentences = function () {
var arr = [ "Google News" ];
// find the top headlines
var sectionHeadlines = byId("replaceable-section-headline");
if (!sectionHeadlines) {
arr.push("The headlines could not be determined.");
return arr;
}
var els = sectionHeadlines.getElementsByClassName("blended-wrapper");
for (var i in els) {
var el = els[i];
if (el.getElementsByTagName) {
var h2s = el.getElementsByTagName("h2");
if (h2s.length > 0) {
var spans = h2s[0].getElementsByTagName("span");
if (spans.length > 0) {
var headline = spans[0].innerHTML;
// find the number of articles
var num = addCommas(parseIntFromElement(el.getElementsByClassName("more-coverage-text")[0]));
arr.push(headline +". with "+ num +" articles.");
}
}
}
}
return arr;
}
this.focusElements = function () {
return [
document,
byId("replaceable-section-headline").getElementsByClassName("blended-wrapper")[0],
byId("replaceable-section-headline").getElementsByClassName("blended-wrapper")[1],
byId("replaceable-section-headline").getElementsByClassName("blended-wrapper")[2]
];
}
};
window.VJHackerNewsApp = function () {
this.label = function () { return "Hacker News"; }
this.url = function () { return "http://news.ycombinator.com/"; }
this.topStories = function () {
var limit = 3;
var titleElements = document.getElementsByClassName("title");
var allStories = [];
for (var i = 0; i < titleElements.length; i++) {
var titleElement = titleElements[i];
var title = 0;
var points = 0;
var comments = 0;
if (!parseInt(titleElement.textContent) && titleElement.textContent != "More") {
title = titleElement.textContent.replace(/HN/g, "H N");
// find points and comments
var subtextElements = titleElement.parentNode.nextSibling.getElementsByClassName("subtext");
if (subtextElements.length > 0) {
points = parseIntFromString(subtextElements[0].firstChild.textContent);
comments = parseIntFromString(subtextElements[0].lastChild.textContent);
if (!comments) {
comments = 0;
}
}
if (title && points > 0) {
allStories.push([ title, points, comments, titleElement]);
}
}
}
allStories.sort(function (a, b) {
return (b[1] + b[2]) - (a[1] + a[2]);
});
return allStories.slice(0, limit);
}
this.sentences = function () {
var arr = [ "Hacker News. The most popular headlines are." ];
var topStories = this.topStories();
if (topStories && topStories.length > 0) {
for (var i = 0; i < topStories.length; i++) {
var story = topStories[i];
var sentence = story[0] +" with "+ story[1] +" points and "+ story[2] +" comment"+ ((story[2] != 1) ? "s" : "");
arr.push(sentence);
}
} else {
arr.push("Error parsing headlines.");
}
return arr;
}
this.focusElements = function () {
var arr = [ document.body ];
var topStories = this.topStories();
for (var i = 0; i < topStories.length; i++) {
var story = topStories[i];
arr.push(story[3]);
}
return arr;
}
};
window.MyCustomApp = function () {
this.label = function () { return "My Custom App"; }
/* The url() is optional (i.e. greeting). If implemented, it must match the browser url exactly. */
this.url = function () { return "http://verbaljuicer.com/"; }
/* The delayAfterPageLoads() is optional, for use when a site has delayed content loading (twitter).
this.delayAfterPageLoads = function () { return 2.0; }
*/
this.sentences = function () {
/* Use JavaScript to find data on the page that you want to speak. */
var sentence = "The title of the page is "+ document.title +".";
/* Return an array of sentences. */
return [ sentence, "Goodbye." ];
}
/* Optionally, provide an array of HTML DOM elements equaling the number of sentences. Use the document element to insert a "blank" step.
this.focusElements = function () {
return [
byId("logo"),
byId("topstuff")
];
}
*/
}
window.VJGitHubApp = function () {
this.label = function () { return "GitHub"; }
/* The url() is optional (i.e. greeting). If implemented, it must match the browser url exactly. */
this.url = function () { return "https://github.com/"; }
this.sentences = function () {
var sentences = [ "GitHub" ];
// unread count
var unreadCountDivs = document.getElementsByClassName("unread_count");
var unreadCount = -1;
if (unreadCountDivs.length > 0) {
unreadCount = unreadCountDivs[0].textContent;
}
if (unreadCount >= 0) {
sentences.push("You have "+ unreadCount +" unread message"+ ((unreadCount != 1) ? "s" : "" ) +".");
}
// pushed to
var maxNumberOfHours = 8;
var dashboard = byId("dashboard");
if (dashboard) {
var pushedToCount = 0;
var openedIssueCount = 0;
var closedIssueCount = 0;
var commentedOnCount = 0;
var openedPullRequestCount = 0;
var closedPullRequestCount = 0;
var alertDivs = dashboard.getElementsByClassName("alert");
var recentAlertDivs = [];
for (var i = 0; i < alertDivs.length; i++) {
var alertDiv = alertDivs[i];
var abbr = alertDiv.getElementsByTagName("abbr");
if (abbr.length > 0) {
var dateString = abbr[0].textContent;
var t = alertDiv.textContent.replace(/ /g, "").replace(/\n/g, "").replace(/\t/g, "");
if ((dateString.indexOf("hour") >= 0 && parseIntFromString(dateString) <= maxNumberOfHours)
|| dateString.indexOf("minute") >= 0) {
if (t.indexOf("pushedto") >= 0) {
pushedToCount++;
} else if (t.indexOf("openedissue") >= 0) {
openedIssueCount++;
} else if (t.indexOf("closedissue") >= 0) {
closedIssueCount++;
} else if (t.indexOf("commentedon") >= 0) {
commentedOnCount++;
} else if (t.indexOf("openedpull") >= 0) {
openedPullRequestCount++;
} else if (t.indexOf("closedpull") >= 0) {
closedPullRequestCount++;
}
}
}
}
var sentence = "In the past "+ maxNumberOfHours +" hours, there "+ ((pushedToCount != 1) ? "were" : "was" ) +" "+ pushedToCount +" push"+ ((pushedToCount != 1) ? "es" : "" ) +", "+ commentedOnCount +" comment"+ ((commentedOnCount != 1) ? "s" : "" ) +", "+ openedIssueCount +" issue"+ ((openedIssueCount != 1) ? "s" : "" ) +" opened, "+ closedIssueCount +" issue"+ ((closedIssueCount != 1) ? "s" : "" ) +" closed, "+ openedPullRequestCount +" pull request"+ ((openedPullRequestCount != 1) ? "s" : "" ) +" opened, and "+ closedPullRequestCount +" pull request"+ ((closedPullRequestCount != 1) ? "s" : "" ) +" closed.";
sentences.push(sentence);
}
/* Return an array of sentences. */
return sentences;
}
this.focusElements = function () {
return [
document.getElementsByClassName("logo")[0].getElementsByTagName("img")[0],
document.getElementsByClassName("userbox")[0],
document.getElementsByClassName("news")[0],
];
}
}
window.VJNetflixQueueApp = function () {
this.label = function () { return "Netflix"; }
/* The url() is optional (i.e. greeting). If implemented, it must match the browser url exactly. */
this.url = function () { return "http://www.netflix.com/Queue?lnkce=sntQu&lnkce=ttq&lnkctr=mhbque"; }
this.sentences = function () {
var sentences = [ "Netflix" ];
var days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
var months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
var atHomeDiv = byId("athome-items");
if (atHomeDiv) {
var movieTRs = atHomeDiv.getElementsByTagName("tr");
for (var i = 0; i < movieTRs.length; i++) {
var movieTR = movieTRs[i];
var titleElements = movieTR.getElementsByClassName("title");
if (titleElements.length > 0) {
var title = titleElements[0].textContent;
if (title) {
// find the ship date
var dateString = movieTR.getElementsByClassName("shipStatus")[0].textContent;
var d = new Date(dateString);
var sentence;
if (!isNaN(d.getTime())) {
var seconds = ((new Date()).getTime() - d.getTime()) / 1000;
var days = Math.round(seconds / 60 / 60 / 24);
sentence = title +" was shipped "+ days +" day"+ ((days != 1) ? "s" : "") +" ago.";
} else {
sentence = title +" is "+ dateString;
}
sentences.push(sentence);
}
}
}
} else {
sentences.push("It appears you are not signed in.");
}
return sentences;
}
this.focusElements = function () {
var atHomeDiv = byId("athome-items");
if (!atHomeDiv) {
return null;
}
var arr = [ byId("nflogo") ];
var atHomeDiv = byId("athome-items");
if (atHomeDiv) {
var movieTRs = atHomeDiv.getElementsByTagName("tr");
for (var i = 0; i < movieTRs.length; i++) {
var movieTR = movieTRs[i];
var titleElements = movieTR.getElementsByClassName("title");
if (titleElements.length > 0) {
arr.push(movieTRs[i]);
}
}
}
return arr;
}
}
window.VJFlurryAnalyticsApp = function () {
this.label = function () { return "Flurry Analytics"; }
/* The url() is optional (i.e. greeting). If implemented, it must match the browser url exactly. */
this.url = function () { return "http://dev.flurry.com/home.do"; }
this.delayAfterPageLoads = function () { return 1.0; }
this.sentences = function () {
var sentences = [ "Flurry: Analytics." ];
var tableBodyTags = document.getElementsByClassName("yui-dt-data");
if (tableBodyTags.length > 0) {
var tableBodyTag = tableBodyTags[0];
var tableRowTags = tableBodyTag.getElementsByTagName("tr");
for (var i = 0; i < tableRowTags.length; i++) {
var tableRowTag = tableRowTags[i];
var nameColumn = tableRowTag.getElementsByClassName("yui-dt-col-Application")[0];
var newUsersColumn = tableRowTag.getElementsByClassName("yui-dt-col-NewUsers")[0];
var activeUsersColumn = tableRowTag.getElementsByClassName("yui-dt-col-ActiveUsers")[0];
var sessionsColumn = tableRowTag.getElementsByClassName("yui-dt-col-Sessions")[0];
var name = nameColumn.textContent;
var newUsers = newUsersColumn.textContent;
var activeUsers = activeUsersColumn.textContent;
var sessions = sessionsColumn.textContent;
var sentence = name +". "+ newUsers +" new users, "+ activeUsers +" active users, and "+ sessions +" sessions.";
sentences.push(sentence);
}
}
/* Return an array of sentences. */
return [ sentences ];
}
this.focusElements = function () {
var arr = [ ];
var tableBodyTags = document.getElementsByClassName("yui-dt-data");
if (tableBodyTags.length > 0) {
var tableBodyTag = tableBodyTags[0];
var tableRowTags = tableBodyTag.getElementsByTagName("tr");
for (var i = 0; i < tableRowTags.length; i++) {
arr.push(tableRowTags[i]);
}
}
return arr;
}
}
window.VJGoogleAnalyticsApp = function () {
this.label = function () { return "Google Analytics"; }
this.url = function () {
if (window.location.toString().indexOf("www.google.com/analytics/settings/") != -1) {
return window.location;
}
return "https://www.google.com/analytics/settings/";
}
this.delayAfterPageLoads = function () {
window.setTimeout(function () {
var divs = document.getElementsByClassName("gami-btn-l");
if (divs.length > 0) {
var div = divs[0];
var a = div.getElementsByTagName("a")[0];
window.location = a.href;
}
}, 0.5 * 1000);
return 2.0;
}
this.sentences = function () {
var arr = [ "Google Analytics", "Visits Yesterday" ];
var tables = document.getElementsByClassName("profile_list_table");
if (tables.length > 0) {
var table = tables[0];
var trs = table.getElementsByTagName("tr");
for (var i = 0; i < trs.length; i++) {
var tr = trs[i];
var valueTds = tr.getElementsByClassName("value");
if (valueTds.length > 0) {
var name = valueTds[0].textContent;
var visits = valueTds[1].textContent;
var text = name +": "+ visits;
arr.push(text);
}
}
}
return arr;
}
this.focusElements = function () {
var arr = [ document ];
var tables = document.getElementsByClassName("profile_list_table");
if (tables.length > 0) {
var table = tables[0];
arr.push(table);
var trs = table.getElementsByTagName("tr");
for (var i = 0; i < trs.length; i++) {
var tr = trs[i];
var valueTds = tr.getElementsByClassName("value");
if (valueTds.length > 0) {
arr.push(tr);
}
}
}
return arr;
}
}