diff options
author | erikkay@chromium.org <erikkay@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-11-11 21:29:11 +0000 |
---|---|---|
committer | erikkay@chromium.org <erikkay@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-11-11 21:29:11 +0000 |
commit | 5e85b6df11e8a98a7384a9b2a84471e3de85011f (patch) | |
tree | 8bfd4b28fde39723c8963dc6a9256bcf12caa366 /chrome/test/data | |
parent | 6c8dcc3cb5d7f6b0523fd44b6a72aa42b911a575 (diff) | |
download | chromium_src-5e85b6df11e8a98a7384a9b2a84471e3de85011f.zip chromium_src-5e85b6df11e8a98a7384a9b2a84471e3de85011f.tar.gz chromium_src-5e85b6df11e8a98a7384a9b2a84471e3de85011f.tar.bz2 |
Moving samples into docs/examples.
Also did a little cleanup of a few of the samples.
More cleanup still to go...
BUG=26106
TEST=none
Review URL: http://codereview.chromium.org/390013
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@31714 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/test/data')
45 files changed, 0 insertions, 3037 deletions
diff --git a/chrome/test/data/extensions/samples/buildbot/bg.html b/chrome/test/data/extensions/samples/buildbot/bg.html deleted file mode 100644 index 50671d1..0000000 --- a/chrome/test/data/extensions/samples/buildbot/bg.html +++ /dev/null @@ -1,58 +0,0 @@ -<script> -var statusURL = "http://chromium-status.appspot.com/current"; - -function updateStatus(text) { - // Page outputs a line like this: - // <div class="Notice">Tree is open (issue -> person) </div> - // Although what's in the <div> is arbitrary and typed by a person. - var results = (new RegExp('"Notice"[^>]*>(.*)<', 'g')).exec(text); - if (!results || results.index < 0) { - throw new Error("couldn't find status div in " + text); - } - var status = results[1]; - chrome.browserAction.setTitle({title:status}); - var open = /open/i; - if (open.exec(status)) { - //chrome.browserAction.setBadgeText("\u263A"); - chrome.browserAction.setBadgeText({text:"\u2022"}); - chrome.browserAction.setBadgeBackgroundColor({color:[0,255,0,255]}); - } else { - //chrome.browserAction.setBadgeText("\u2639"); - chrome.browserAction.setBadgeText({text:"\u00D7"}); - chrome.browserAction.setBadgeBackgroundColor({color:[255,0,0,255]}); - } -} - -function requestStatus() { - requestURL(statusURL, updateStatus); - setTimeout(requestStatus, 30000); -} - -function requestURL(url, callback) { - console.log("requestURL: " + url); - var xhr = new XMLHttpRequest(); - try { - xhr.onreadystatechange = function(state) { - if (xhr.readyState == 4) { - var text = xhr.responseText; - //console.log(text); - callback(text); - } - } - - xhr.onerror = function(error) { - console.log("xhr error: " + JSON.stringify(error)); - console.dir(error); - } - - xhr.open("GET", url, true); - xhr.send({}); - } catch(e) { - console.log("exception: " + e); - } -} - -window.onload = function() { - window.setTimeout(requestStatus, 10); -} -</script> diff --git a/chrome/test/data/extensions/samples/buildbot/buildbot.html b/chrome/test/data/extensions/samples/buildbot/buildbot.html deleted file mode 100644 index 7da1dba..0000000 --- a/chrome/test/data/extensions/samples/buildbot/buildbot.html +++ /dev/null @@ -1,251 +0,0 @@ -<script> -var botRoot = "http://build.chromium.org/buildbot/waterfall"; -//var botRoot = "http://chrome-buildbot.corp.google.com:8010"; -var statusURL = "http://chromium-status.appspot.com/current"; -var waterfallURL = botRoot + "/bot_status.json?json=1"; -var botList; -var checkinResults; -var bots; -var lastChecked; - -function updateStatus(text) { - // Page outputs a line like this: - // <div class="Notice">Tree is open (issue -> person) </div> - // Although what's in the <div> is arbitrary and typed by a person. - var results = (new RegExp('"Notice"[^>]*>(.*)<', 'g')).exec(text); - if (!results || results.index < 0) { - throw new Error("couldn't find status div in " + text); - } - var status = results[1]; - var div = document.getElementById("status"); - div.title = status; - var open = /open/i; - if (open.exec(status)) { - div.innerHTML = "tree: open "; - div.className = "open"; - } else { - div.innerHTML = "tree: closed"; - div.className = "closed"; - } -} - -function updateBotList(text) { - var results = (new RegExp('(.*)<\/body>', 'g')).exec(text); - if (!results || results.index < 0) { - console.log("Error: couldn't find bot JSON"); - console.log(text); - return; - } - var data; - try { - data = JSON.parse(results[1]); - } catch (e) { - console.dir(e); - console.log(text); - return; - } - if (!data) { - throw new Error("JSON parse fail: " + results[1]); - } - botList = data[0]; - checkinResults = data[1]; - displayBotList(); -} - -function botClicked(botIndex) { - var bot = botList[botIndex]; - var url = botRoot + "/waterfall?builder=" + bot.name; - window.open(url); - window.event.stopPropagation(); -} - -function displayBotList() { - if (!botList) { - console.log("botList is null"); - return; - } - var html = ""; - if (bots.className == "visible") { - botList.forEach(function(bot, i) { - html += "<div class='bot " + bot.color + - "' onclick='botClicked(" + i + ")' " + - "title='" + bot.title + "'></div>"; - }); - } - bots.innerHTML = html; - - var numBots = botList.length; - var botWidth = numBots * 8 + 2; - var style = document.getElementById("bots-visible"); - style.innerText = "#bots.visible { width:" + botWidth + "px;}"; -} - -function requestStatus() { - requestURL(statusURL, updateStatus); - setTimeout(requestStatus, 120000); -} - -function requestURL(url, callback) { - console.log("requestURL: " + url); - var xhr = new XMLHttpRequest(); - try { - xhr.onreadystatechange = function(state) { - if (xhr.readyState == 4) { - var text = xhr.responseText; - //console.log(text); - callback(text); - } - } - - xhr.onerror = function(error) { - console.log("xhr error: " + JSON.stringify(error)); - console.dir(error); - } - - xhr.open("GET", url, true); - xhr.send({}); - } catch(e) { - console.log("exception: " + e); - } -} - -function showBots() { - var now = new Date(); - // Don't ever refetch the bot list more frequently than every 60 seconds. - if (!lastChecked || (now - lastChecked) > 60000) { - lastChecked = now; - requestURL(waterfallURL, updateBotList); - } - hoverTimerId = null; - bots.className = "visible"; -} - -function hideBots() { - bots.className = ""; -} - -var hoverTimerId = null; - -window.addEventListener("mouseover", function(e) { - if (hoverTimerId) { - hoverTimerId = window.clearTimeout(hoverTimerId); - } else if (bots.className != "visible") { - hoverTimerId = window.setTimeout(function() { - hoverTimerId = null; - showBots(); - }, 500); - } -}, false); - -window.addEventListener("mouseout", function(e) { - if (hoverTimerId) { - hoverTimerId = window.clearTimeout(hoverTimerId); - } else if (bots.className != "") { - hoverTimerId = window.setTimeout(function() { - hoverTimerId = null; - hideBots(); - }, 100); - } -}, false); - -window.addEventListener("click", function() { - window.open(botRoot); -}, false); - -window.onload = function() { - // This is weird, but somehow doing an XHR -- even though it is - // asynchronous!! -- in onload delays the initial render from happening. - window.setTimeout(requestStatus, 10); - bots = document.getElementById("bots"); -} -</script> - -<style id="bots-visible"> -#bots.visible { - width:1px; -} -</style> - -<style> -#status { - font-weight:bold; -} - -#change { - font-weight:bold; -} - -.open { - color: green; -} - -.closed { - color: red; -} - -#bots { - height: 100%; - /* We would rather this be zero, but a rendering bug in WebKit causes the - offset width of the document to sometimes be caluculated incorrectly that - way. */ - width: 1px; - -webkit-transition: width .2s linear; - display:-webkit-box; - -webkit-box-align:center; /* center content vertically */ - overflow: hidden; -} - -.bot { - line-height: 100%; - cursor: pointer; - -webkit-border-radius: 2px; - display:-webkit-box; - width: 6px; - height: 15px; -} - -.bot:first-child { - /* Since #bots is 1px wide, this is necessary so that we don't show the first - pixel of the first bot. */ - margin-left:1px; -} - -.running { - background-color: rgb(255, 252, 108); - border: 1px solid rgb(197, 197, 109); -} - -.notstarted { - /* background-color: white; */ - border: 1px solid rgb(170, 170, 170); -} - -.failure { - background-color: rgb(233, 128, 128); - border: 1px solid rgb(167, 114, 114); -} - -.warnings { - background-color: rgb(255, 195, 67); - border: 1px solid rgb(194, 157, 70); -} - -.success { - background-color: rgb(143, 223, 95); - border: 1px solid rgb(79, 133, 48); -} - -.exception { - background-color: rgb(224, 176, 255); - border: 1px solid rgb(172, 160, 179); -} - -</style> - -<div class="toolstrip-button"> - <span id="status" class="open"> - <span style="color:#ff6600">loading...</span> - </span> -</div> -<div id="bots"> -</div> diff --git a/chrome/test/data/extensions/samples/buildbot/chromium.png b/chrome/test/data/extensions/samples/buildbot/chromium.png Binary files differdeleted file mode 100755 index cc9fb60..0000000 --- a/chrome/test/data/extensions/samples/buildbot/chromium.png +++ /dev/null diff --git a/chrome/test/data/extensions/samples/buildbot/icon.png b/chrome/test/data/extensions/samples/buildbot/icon.png Binary files differdeleted file mode 100755 index b3c3474..0000000 --- a/chrome/test/data/extensions/samples/buildbot/icon.png +++ /dev/null diff --git a/chrome/test/data/extensions/samples/buildbot/manifest.json b/chrome/test/data/extensions/samples/buildbot/manifest.json deleted file mode 100644 index 5e0349c..0000000 --- a/chrome/test/data/extensions/samples/buildbot/manifest.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "name": "Chromium Buildbot Monitor", - "version": "0.7.1", - "description": "Displays the status of the Chromium buildbot in the toolbar. On hover, expands to give more detail about each failing bot.", - "icons": { "128": "icon.png" }, - "background_page": "bg.html", - "permissions": [ - "http://build.chromium.org/", - "http://chromium-status.appspot.com/", - "http://chrome-buildbot.corp.google.com/" - ], - "browser_action": { - "default_title": "", - "default_icon": "chromium.png", - "popup": "popup.html" - } -} diff --git a/chrome/test/data/extensions/samples/buildbot/popup.html b/chrome/test/data/extensions/samples/buildbot/popup.html deleted file mode 100644 index 8814a80..0000000 --- a/chrome/test/data/extensions/samples/buildbot/popup.html +++ /dev/null @@ -1,218 +0,0 @@ -<head>
-<script>
-var botRoot = "http://build.chromium.org/buildbot";
-//var botRoot = "http://chrome-buildbot.corp.google.com:8010";
-var waterfallURL = botRoot + "/waterfall/bot_status.json?json=1";
-var botList;
-var checkinResults;
-var bots;
-var failures;
-
-function updateBotList(text) {
- var results = (new RegExp('(.*)<\/body>', 'g')).exec(text);
- if (!results || results.index < 0) {
- console.log("Error: couldn't find bot JSON");
- console.log(text);
- return;
- }
- var data;
- try {
- data = JSON.parse(results[1]);
- } catch (e) {
- console.dir(e);
- console.log(text);
- return;
- }
- if (!data) {
- throw new Error("JSON parse fail: " + results[1]);
- }
- botList = data[0];
- checkinResults = data[1];
-
- failures = botList.filter(function(bot) {
- return (bot.color != "success");
- });
- displayFailures();
-}
-
-function displayFailures() {
- var html = "";
- if (failures.length == 0) {
- html = "<a href='' onClick='showConsole()' class='open'>" +
- "The tree is completely green.</a> (no way!)";
- } else {
- html = "<div><a class='closed' href='' onClick='showFailures()'>" +
- "failures:</a></div>";
- failures.forEach(function(bot, i) {
- html += "<div class='bot " + bot.color +
- "' onclick='showBot(" + i + ")'>" +
- bot.title + "</div>";
- });
- }
- bots.innerHTML = html;
-}
-
-function showURL(url) {
- window.open(url);
- window.event.stopPropagation();
-}
-
-function showBot(botIndex) {
- var bot = failures[botIndex];
- var url = botRoot + "/waterfall/waterfall?builder=" + bot.name;
- showURL(url);
-}
-
-function showConsole() {
- var url = botRoot + "/waterfall/console";
- showURL(url);
-}
-
-function showTry() {
- var url = botRoot + "/try-server/waterfall";
- showURL(url);
-}
-
-function showFyi() {
- var url = botRoot + "/waterfall.fyi/console";
- showURL(url);
-}
-
-function showFailures() {
- var url = botRoot + "/waterfall/waterfall?show_events=true&failures_only=true";
- showURL(url);
-}
-
-function requestURL(url, callback) {
- console.log("requestURL: " + url);
- var xhr = new XMLHttpRequest();
- try {
- xhr.onreadystatechange = function(state) {
- if (xhr.readyState == 4) {
- var text = xhr.responseText;
- //console.log(text);
- callback(text);
- }
- }
-
- xhr.onerror = function(error) {
- console.log("xhr error: " + JSON.stringify(error));
- console.dir(error);
- }
-
- xhr.open("GET", url, true);
- xhr.send({});
- } catch(e) {
- console.log("exception: " + e);
- }
-}
-window.onload = function() {
- bots = document.getElementById("bots");
-
- // XHR from onload winds up blocking the load, so we put it in a setTimeout.
- window.setTimeout(requestURL, 0, waterfallURL, updateBotList);
-}
-
-function toggle_size() {
- if (document.body.className == "big") {
- document.body.className = "small";
- } else {
- document.body.className = "big";
- }
-}
-
-</script>
-<style>
-body {
- font: menu;
- overflow: hidden;
-}
-
-#links {
- background-color: #efefef;
- border: 1px solid #cccccc;
- -webkit-border-radius: 5px;
- margin-top: 1px;
- padding: 3px;
- white-space: nowrap;
- text-align: center;
-}
-
-a {
- text-decoration: underline;
- color: #444;
-}
-
-a:hover {
- color: black;
- cursor: pointer;
-}
-
-body.big .bot {
- -webkit-transition: all .5s ease-out;
- margin: 20px;
-}
-
-body.small .bot {
- -webkit-transition: all .5s ease-out;
-}
-
-.bot {
- cursor: pointer;
- -webkit-border-radius: 5px;
- margin-top: 1px;
- padding: 3px;
- white-space: nowrap;
-}
-
-.bot:hover {
- border: 2px solid black;
- padding: 2px;
-}
-
-.open {
- color: green;
-}
-
-.closed {
- color: red;
-}
-
-.running {
- background-color: rgb(255, 252, 108);
- border: 1px solid rgb(197, 197, 109);
-}
-
-.notstarted {
- border: 1px solid rgb(170, 170, 170);
-}
-
-.failure {
- background-color: rgb(233, 128, 128);
- border: 1px solid rgb(167, 114, 114);
-}
-
-.warnings {
- background-color: rgb(255, 195, 67);
- border: 1px solid rgb(194, 157, 70);
-}
-
-.success {
- background-color: rgb(143, 223, 95);
- border: 1px solid rgb(79, 133, 48);
-}
-
-.exception {
- background-color: rgb(224, 176, 255);
- border: 1px solid rgb(172, 160, 179);
-}
-</style>
-</head>
-<body onClick="toggle_size()">
-<div id="links">
-<a href="" onclick='showConsole()'>console</a> -
-<a href="" onclick='showTry()'>try</a> -
-<a href="" onclick='showFyi()'>fyi</a>
-</div>
-<div id="bots">Loading....</div>
-</body>
\ No newline at end of file diff --git a/chrome/test/data/extensions/samples/cld/manifest.json b/chrome/test/data/extensions/samples/cld/manifest.json deleted file mode 100644 index c0f20f2..0000000 --- a/chrome/test/data/extensions/samples/cld/manifest.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "CLD", - "description": "Returns language of a tab", - "version": "0.1", - "toolstrips": ["toolstrip.html"] -} diff --git a/chrome/test/data/extensions/samples/cld/toolstrip.html b/chrome/test/data/extensions/samples/cld/toolstrip.html deleted file mode 100644 index 03851c2b..0000000 --- a/chrome/test/data/extensions/samples/cld/toolstrip.html +++ /dev/null @@ -1,36 +0,0 @@ -<!-- -Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this -source code is governed by a BSD-style license that can be found in the -LICENSE file. ---> - -<html> - <head> - <script> - -var selectedId = -1; -function refreshLanguage() { - console.log("refeshing..."); - chrome.tabs.detectLanguage(null, function(language) { - document.getElementById("languageDiv").innerHTML = language; - }); -} - -chrome.tabs.onUpdated.addListener(function(tabId, props) { - console.log("updated: " + tabId); - if (prop.status == "complete" && tabId == selectedId) - refreshLanguage(); -}); - -chrome.tabs.onSelectionChanged.addListener(function(tabId, props) { - console.log("selection: " + tabId); - selectedId = tabId; - refreshLanguage(); -}); - </script> - </head> - <body onload="refreshLanguage();"> - <div id="languageDiv" class="toolstrip-button" onclick="refreshLanguage();"> - </div> - </body> -</html>
\ No newline at end of file diff --git a/chrome/test/data/extensions/samples/gmail/gmail-128x128.png b/chrome/test/data/extensions/samples/gmail/gmail-128x128.png Binary files differdeleted file mode 100755 index ad851a6..0000000 --- a/chrome/test/data/extensions/samples/gmail/gmail-128x128.png +++ /dev/null diff --git a/chrome/test/data/extensions/samples/gmail/gmail.png b/chrome/test/data/extensions/samples/gmail/gmail.png Binary files differdeleted file mode 100644 index 24180e0..0000000 --- a/chrome/test/data/extensions/samples/gmail/gmail.png +++ /dev/null diff --git a/chrome/test/data/extensions/samples/gmail/gmail_checker.html b/chrome/test/data/extensions/samples/gmail/gmail_checker.html deleted file mode 100644 index 0f89b33..0000000 --- a/chrome/test/data/extensions/samples/gmail/gmail_checker.html +++ /dev/null @@ -1,145 +0,0 @@ -<html> -<head> -<link rel="stylesheet" type="text/css" href="styles.css"> -<script> -var gmail = "http://mail.google.com/"; -var gmailAtomRef = "http://mail.google.com/mail/feed/atom"; -var pollInterval = 1000 * 60; // 1 minute -var requestTimeout = 1000 * 5; // 5 seconds -var unreadCount; - -function init() { - window.setTimeout(startRequest, 0); -} - -function scheduleRequest() { - window.setTimeout(startRequest, pollInterval); -} - -// ajax stuff -function startRequest() { - getInboxCount( - function(count) { - toggleLoggedInState(); - updateUnreadCount(count); - scheduleRequest(); - }, - function() { - toggleLoggedOutState(); - scheduleRequest(); - } - ); -} - -function getInboxCount(onSuccess, onError) { - var xhr = new XMLHttpRequest(); - var abortTimerId = window.setTimeout(function() { - xhr.abort(); - onError(); - }, requestTimeout); - - function handleSuccess(count) { - window.clearTimeout(abortTimerId); - onSuccess(count); - } - - function handleError() { - window.clearTimeout(abortTimerId); - onError(); - } - - try { - console.log("request.."); - xhr.onreadystatechange = function(){ - console.log("readystate: " + xhr.readyState); - if (xhr.readyState == 4) { - console.log("responseText: " + xhr.responseText.substring(0, 200) + - "..."); - if (xhr.responseXML) { - var xmlDoc = xhr.responseXML; - var fullCountSet = xmlDoc.evaluate("/gmail:feed/gmail:fullcount", - xmlDoc, gmailNSResolver, XPathResult.ANY_TYPE, null); - var fullCountNode = fullCountSet.iterateNext(); - if (fullCountNode) { - handleSuccess(fullCountNode.textContent); - } else { - console.log("fullcount not found!"); - console.error("Error: feed retrieved, but no <fullcount> node " + - "found"); - handleError(); - } - } else { - console.log("No responseXML!"); - } - } - } - - xhr.onerror = function(error) { - console.log("error"); - console.log(error); - handleError(); - } - - xhr.open("GET", gmailAtomRef, true); - xhr.send(null); - } catch(e) { - console.log("ex: " + e); - console.error("exception: " + e); - handleError(); - } -} - -function gmailNSResolver(prefix) { - if(prefix == 'gmail') { - return 'http://purl.org/atom/ns#'; - } -} - -// ui stuff -function toggleLoggedInState() { - document.getElementById("notLoggedIn").style.display = "none"; - document.getElementById("loggedIn").style.display = ""; -} - -function toggleLoggedOutState() { - document.getElementById("loggedIn").style.display = "none"; - document.getElementById("notLoggedIn").style.display = ""; -} - -function updateUnreadCount(count) { - if (unreadCount != count) { - unreadCount = count; - startFlip(); - } -} - -function goToInbox() { - chrome.tabs.create({url: gmail}); -} - -// animation -function startFlip() { - document.getElementById("unreadCount").className = 'mid-flip'; - setTimeout(midFlip, 500); -} - -function midFlip() { - document.getElementById("unreadCount").className = 'post-flip'; - document.getElementById("unreadCount").innerHTML = "(" + unreadCount + ")"; - setTimeout(endFlip, 500); -} - -function endFlip() { - document.getElementById("unreadCount").className = 'base-flip'; -} - -</script> -</head> -<body onload="init()" onclick="goToInbox()"> - <div class="toolstrip-button"> - <img src="gmail.png" style="width:auto; height:auto"> - <span id="notLoggedIn" style="display:none;">Login</span> - <span id="loggedIn">Gmail - Inbox <span style="display: inline-block;" id="unreadCount" class="base-flip"></span></span> - </div> -</body> -</html> diff --git a/chrome/test/data/extensions/samples/gmail/manifest.json b/chrome/test/data/extensions/samples/gmail/manifest.json deleted file mode 100644 index b5c2dc1..0000000 --- a/chrome/test/data/extensions/samples/gmail/manifest.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "name": "Gmail Checker", - "version": "0.2", - "description": "Displays number of unread Gmail messages", - "icons": { "128": "gmail-128x128.png" }, - "permissions": [ - "http://*.google.com/", - "https://*.google.com/", - "tabs" - ], - "toolstrips": [ - "gmail_checker.html" - ] -}
\ No newline at end of file diff --git a/chrome/test/data/extensions/samples/gmail/styles.css b/chrome/test/data/extensions/samples/gmail/styles.css deleted file mode 100644 index 5587c1f..0000000 --- a/chrome/test/data/extensions/samples/gmail/styles.css +++ /dev/null @@ -1,16 +0,0 @@ -.base-flip { - opacity: 1; -} - -.mid-flip { - opacity: .1; - color:red; - -webkit-transform: rotate(180deg) scale(1.3); - -webkit-transition: all .5s ease-in; -} - -.post-flip { - opacity: 1; - -webkit-transform: rotate(360deg) scale(1); - -webkit-transition: all .5s ease-out; -} diff --git a/chrome/test/data/extensions/samples/gmail_browser_action/background.html b/chrome/test/data/extensions/samples/gmail_browser_action/background.html deleted file mode 100644 index ee1ae40..0000000 --- a/chrome/test/data/extensions/samples/gmail_browser_action/background.html +++ /dev/null @@ -1,235 +0,0 @@ -<html> -<head> -<script> -var animationFrames = 36; -var animationSpeed = 10; // ms -var canvas; -var canvasContext; -var gmail = "http://mail.google.com/"; -var gmailAtomRef = "http://mail.google.com/mail/feed/atom"; -var loggedInImage; -var pollInterval = 1000 * 10; // 10 seconds -var requestTimeout = 1000 * 2; // 5 seconds -var rotation = 0; -var unreadCount = -1; -var loadingAnimation = new LoadingAnimation(); - - -// A "loading" animation displayed while we wait for the first response from -// Gmail. This animates the badge text with a dot that cycles from left to -// right. -function LoadingAnimation() { - this.timerId_ = 0; - this.maxCount_ = 8; // Total number of states in animation - this.current_ = 0; // Current state - this.maxDot_ = 4; // Max number of dots in animation -} - -LoadingAnimation.prototype.paintFrame = function() { - var text = ""; - for (var i = 0; i < this.maxDot_; i++) { - text += (i == this.current_) ? "." : " "; - } - if (this.current_ >= this.maxDot_) - text += ""; - - chrome.browserAction.setBadgeText({text:text}); - this.current_++; - if (this.current_ == this.maxCount_) - this.current_ = 0; -} - -LoadingAnimation.prototype.start = function() { - if (this.timerId_) - return; - - var self = this; - this.timerId_ = window.setInterval(function() { - self.paintFrame(); - }, 100); -} - -LoadingAnimation.prototype.stop = function() { - if (!this.timerId_) - return; - - window.clearInterval(this.timerId_); - this.timerId_ = 0; -} - - -chrome.tabs.onUpdated.addListener(function(tabId, changeInfo) { - if (changeInfo.url && changeInfo.url.indexOf(gmail) == 0) { - console.log("saw gmail! updating..."); - getInboxCount(function(count) { - updateUnreadCount(count); - }); - } -}); - - -function init() { - canvas = document.getElementById('canvas'); - loggedInImage = document.getElementById('logged_in'); - canvasContext = canvas.getContext('2d'); - - chrome.browserAction.setIcon({path: "gmail_logged_in.png"}); - loadingAnimation.start(); - - startRequest(); -} - -function scheduleRequest() { - window.setTimeout(startRequest, pollInterval); -} - -// ajax stuff -function startRequest() { - getInboxCount( - function(count) { - loadingAnimation.stop(); - updateUnreadCount(count); - scheduleRequest(); - }, - function() { - loadingAnimation.stop(); - showLoggedOut(); - scheduleRequest(); - } - ); -} - -function getInboxCount(onSuccess, onError) { - var xhr = new XMLHttpRequest(); - var abortTimerId = window.setTimeout(function() { - xhr.abort(); - onError(); - }, requestTimeout); - - function handleSuccess(count) { - window.clearTimeout(abortTimerId); - if (onSuccess) - onSuccess(count); - } - - function handleError() { - window.clearTimeout(abortTimerId); - if (onError) - onError(); - } - - try { - console.log("request.."); - xhr.onreadystatechange = function(){ - console.log("readystate: " + xhr.readyState); - if (xhr.readyState == 4) { - console.log("responseText: " + xhr.responseText.substring(0, 200) + - "..."); - if (xhr.responseXML) { - var xmlDoc = xhr.responseXML; - var fullCountSet = xmlDoc.evaluate("/gmail:feed/gmail:fullcount", - xmlDoc, gmailNSResolver, XPathResult.ANY_TYPE, null); - var fullCountNode = fullCountSet.iterateNext(); - if (fullCountNode) { - handleSuccess(fullCountNode.textContent); - } else { - console.log("fullcount not found!"); - console.error("Error: feed retrieved, but no <fullcount> node " + - "found"); - handleError(); - } - } else { - console.log("No responseXML!"); - } - } - } - - xhr.onerror = function(error) { - console.log("error"); - console.log(error); - handleError(); - } - - xhr.open("GET", gmailAtomRef, true); - xhr.send(null); - } catch(e) { - console.log("ex: " + e); - console.error("exception: " + e); - handleError(); - } -} - -function gmailNSResolver(prefix) { - if(prefix == 'gmail') { - return 'http://purl.org/atom/ns#'; - } -} - -function updateUnreadCount(count) { - if (unreadCount != count) { - unreadCount = count; - animateFlip(); - } -} - - -function ease(x) { - return (1-Math.sin(Math.PI/2+x*Math.PI))/2; -} - -function animateFlip() { - rotation += 1/animationFrames; - drawIconAtRotation(); - - if (rotation <= 1) { - setTimeout("animateFlip()", animationSpeed); - } else { - rotation = 0; - drawIconAtRotation(); - chrome.browserAction.setBadgeText({ - text: unreadCount != "0" ? unreadCount : "" - }); - chrome.browserAction.setBadgeBackgroundColor({color:[208, 0, 24, 255]}); - } -} - -function showLoggedOut() { - unreadCount = -1; - chrome.browserAction.setIcon({path:"gmail_not_logged_in.png"}); - chrome.browserAction.setBadgeBackgroundColor({color:[190, 190, 190, 230]}); - chrome.browserAction.setBadgeText({text:"?"}); -} - -function drawIconAtRotation() { - canvasContext.save(); - canvasContext.clearRect(0, 0, canvas.width, canvas.height); - canvasContext.translate( - Math.ceil(canvas.width/2), - Math.ceil(canvas.height/2)); - canvasContext.rotate(2*Math.PI*ease(rotation)); - canvasContext.drawImage(loggedInImage, - -Math.ceil(canvas.width/2), - -Math.ceil(canvas.height/2)); - canvasContext.restore(); - - chrome.browserAction.setIcon({imageData:canvasContext.getImageData(0, 0, - canvas.width,canvas.height)}); -} - -function goToInbox() { - chrome.tabs.create({url: gmail}); -} - -// Called when the user clicks on the browser action. -chrome.browserAction.onClicked.addListener(function(tab) { - goToInbox(); -}); - -</script> -</head> -<body onload="init()"> -<img id="logged_in" src="gmail_logged_in.png"> -<canvas id="canvas" width="19" height="19"> -</body> -</html> - diff --git a/chrome/test/data/extensions/samples/gmail_browser_action/gmail_logged_in.png b/chrome/test/data/extensions/samples/gmail_browser_action/gmail_logged_in.png Binary files differdeleted file mode 100644 index 8d5e256..0000000 --- a/chrome/test/data/extensions/samples/gmail_browser_action/gmail_logged_in.png +++ /dev/null diff --git a/chrome/test/data/extensions/samples/gmail_browser_action/gmail_not_logged_in.png b/chrome/test/data/extensions/samples/gmail_browser_action/gmail_not_logged_in.png Binary files differdeleted file mode 100644 index 582d262..0000000 --- a/chrome/test/data/extensions/samples/gmail_browser_action/gmail_not_logged_in.png +++ /dev/null diff --git a/chrome/test/data/extensions/samples/gmail_browser_action/icon_128.png b/chrome/test/data/extensions/samples/gmail_browser_action/icon_128.png Binary files differdeleted file mode 100755 index 1ddc33b..0000000 --- a/chrome/test/data/extensions/samples/gmail_browser_action/icon_128.png +++ /dev/null diff --git a/chrome/test/data/extensions/samples/gmail_browser_action/manifest.json b/chrome/test/data/extensions/samples/gmail_browser_action/manifest.json deleted file mode 100644 index 3dc942f..0000000 --- a/chrome/test/data/extensions/samples/gmail_browser_action/manifest.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "name": "Google Mail Checker", - "description": "This extension adds a Google Mail button to the toolbar which displays the number of unread messages in your inbox. You can also click the button to open your inbox.", - "version": "1.0", - "background_page": "background.html", - "permissions": [ - "tabs", "http://*.google.com/", "https://*.google.com/" - ], - "browser_action": { - "default_title": "" - }, - "icons": { - "128": "icon_128.png" - } -} diff --git a/chrome/test/data/extensions/samples/mappy/icon.png b/chrome/test/data/extensions/samples/mappy/icon.png Binary files differdeleted file mode 100755 index 40ebbff..0000000 --- a/chrome/test/data/extensions/samples/mappy/icon.png +++ /dev/null diff --git a/chrome/test/data/extensions/samples/mappy/manifest.json b/chrome/test/data/extensions/samples/mappy/manifest.json deleted file mode 100755 index dbcfe06..0000000 --- a/chrome/test/data/extensions/samples/mappy/manifest.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "name": "Mappy", - "version": "0.6", - "description": "Finds addresses in the web page you're on and pops up a map window.", - "icons": { "128": "icon.png" }, - "content_scripts": [ - { "matches": ["http://*/*"], "js": ["mappy_content_script.js"] } - ], - "permissions": [ - "tabs", - "http://maps.google.com/*" - ], - "browser_action": { - "name": "Display Map", - "icons": ["marker.png"], - "popup": { "path": "popup.html", "height": 512 } - } -} diff --git a/chrome/test/data/extensions/samples/mappy/mappy_content_script.js b/chrome/test/data/extensions/samples/mappy/mappy_content_script.js deleted file mode 100755 index 7e17af7..0000000 --- a/chrome/test/data/extensions/samples/mappy/mappy_content_script.js +++ /dev/null @@ -1,55 +0,0 @@ -// find map on demand - -console.log("mappy_content_script.js loaded"); - -var maps_key = "ABQIAAAATfHumDbW3OmRByfquHd3SRTRERdeAiwZ9EeJWta3L_JZVS0bOBRQeZgr4K0xyVKzUdnnuFl8X9PX0w"; - -chrome.extension.onConnect.addListener(function(port) { - //console.log("extension connected"); - port.onMessage.addListener(function(data) { - //console.log("extension sent message"); - findAddress(port); - }); -}); - -var findAddress = function(port) { - var found; - var re = /(\d+\s+[':.,\s\w]*,\s*[A-Za-z]+\s*\d{5}(-\d{4})?)/m; - var node = document.body; - var done = false; - while (!done) { - done = true; - for (var i = 0; i < node.childNodes.length; ++i) { - var child = node.childNodes[i]; - if (child.textContent.match(re)) { - node = child; - found = node; - done = false; - break; - } - } - } - if (found) { - var text = ""; - if (found.childNodes.length) { - for (var i = 0; i < found.childNodes.length; ++i) { - text += found.childNodes[i].textContent + " "; - } - } else { - text = found.textContent; - } - var match = re.exec(text); - if (match && match.length) { - console.log("found: " + match[0]); - var trim = /\s{2,}/g; - var map = match[0].replace(trim, " "); - port.postMessage({message:"map", values:[map]}); - } else { - console.log("found bad " + found.textContent); - console.log("no match in: " + text); - } - } else { - console.log("no match in " + node.textContent); - } -} - diff --git a/chrome/test/data/extensions/samples/mappy/mappy_toolstrip.html b/chrome/test/data/extensions/samples/mappy/mappy_toolstrip.html deleted file mode 100644 index 88d1d52..0000000 --- a/chrome/test/data/extensions/samples/mappy/mappy_toolstrip.html +++ /dev/null @@ -1,71 +0,0 @@ -<style> -.chrome-toolstrip #map { - display: none; -} - -.chrome-toolstrip #button { - display: block; -} - -.chrome-mole #map { - display: block; -} - -.chrome-mole #button { - display: none; -} - -#map { - width: 512px; - height: 512px; -} -</style> -<script src="http://maps.google.com/maps?file=api&v=2&key=ABQIAAAATfHumDbW3OmRByfquHd3SRTRERdeAiwZ9EeJWta3L_JZVS0bOBRQeZgr4K0xyVKzUdnnuFl8X9PX0w&sensor=false" - type="text/javascript"></script> -<script> -var maps_key = "ABQIAAAATfHumDbW3OmRByfquHd3SRTRERdeAiwZ9EeJWta3L_JZVS0bOBRQeZgr4K0xyVKzUdnnuFl8X9PX0w"; - -function expand(url) { - var map = document.getElementById("map"); - map.src = url; - chrome.toolstrip.expand({height:512}, function() {}); -} - -function collapse() { - chrome.toolstrip.collapse({}, function() {}); -} - -function gclient_geocode(address) { - var geocoder = new GClientGeocoder(); - geocoder.getLatLng(address, function(point) { - if (!point) { - console.log(address + " not found"); - } else { - var latlng = point.toUrlValue(); - var url = "http://maps.google.com/staticmap?center=" + latlng + - "&markers=" + latlng + "&zoom=14" + - "&size=512x512&sensor=false&key=" + maps_key; - expand(url); - } - }); -} - -function map() { - chrome.tabs.getSelected(null, function(tab) { - var port = chrome.tabs.connect(tab.id); - if (!port) { - console.log("no port"); - } else { - port.onMessage.addListener(function(data) { - var address = data.values[0]; - gclient_geocode(address); - }); - port.postMessage({message: "hello tab: " + tab.id}); - } - }); -}; -</script> -<div id="button" class="toolstrip-button" onclick="map()"> -<span>Mappy</span> -</div> -<img id="map" onclick="collapse()"> diff --git a/chrome/test/data/extensions/samples/mappy/marker.png b/chrome/test/data/extensions/samples/mappy/marker.png Binary files differdeleted file mode 100755 index aa45f4d..0000000 --- a/chrome/test/data/extensions/samples/mappy/marker.png +++ /dev/null diff --git a/chrome/test/data/extensions/samples/mappy/popup.html b/chrome/test/data/extensions/samples/mappy/popup.html deleted file mode 100644 index 409b216..0000000 --- a/chrome/test/data/extensions/samples/mappy/popup.html +++ /dev/null @@ -1,51 +0,0 @@ -<head> -<style> -body { - margin: 0px; - padding: 0px; -} -#map { - width: 512px; - height: 512px; -} -</style> -<script src="http://maps.google.com/maps?file=api&v=2&key=ABQIAAAATfHumDbW3OmRByfquHd3SRTRERdeAiwZ9EeJWta3L_JZVS0bOBRQeZgr4K0xyVKzUdnnuFl8X9PX0w&sensor=false" - type="text/javascript"></script> -<script> -var maps_key = "ABQIAAAATfHumDbW3OmRByfquHd3SRTRERdeAiwZ9EeJWta3L_JZVS0bOBRQeZgr4K0xyVKzUdnnuFl8X9PX0w"; - -function gclient_geocode(address) { - var geocoder = new GClientGeocoder(); - geocoder.getLatLng(address, function(point) { - if (!point) { - console.log(address + " not found"); - } else { - var latlng = point.toUrlValue(); - var url = "http://maps.google.com/staticmap?center=" + latlng + - "&markers=" + latlng + "&zoom=14" + - "&size=512x512&sensor=false&key=" + maps_key; - var map = document.getElementById("map"); - map.src = url; - } - }); -} - -function map() { - chrome.tabs.getSelected(null, function(tab) { - var port = chrome.tabs.connect(tab.id); - if (!port) { - console.log("no port"); - } else { - port.onMessage.addListener(function(data) { - var address = data.values[0]; - gclient_geocode(address); - }); - port.postMessage({message: "hello tab: " + tab.id}); - } - }); -}; -</script> -</head> -<body onload="map()"> -<img id="map" onclick="window.close()"> -</body> diff --git a/chrome/test/data/extensions/samples/override_igoogle/manifest.json b/chrome/test/data/extensions/samples/override_igoogle/manifest.json deleted file mode 100644 index 461da24..0000000 --- a/chrome/test/data/extensions/samples/override_igoogle/manifest.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name": "iGoogle new tab page", - "version": "0.1", - "chrome_url_overrides": { - "newtab": "redirect.html" - } -}
\ No newline at end of file diff --git a/chrome/test/data/extensions/samples/override_igoogle/redirect.html b/chrome/test/data/extensions/samples/override_igoogle/redirect.html deleted file mode 100644 index 35117f4..0000000 --- a/chrome/test/data/extensions/samples/override_igoogle/redirect.html +++ /dev/null @@ -1,3 +0,0 @@ -<head> -<meta http-equiv="refresh"content="0;URL=http://www.google.com/ig"> -</head> diff --git a/chrome/test/data/extensions/samples/print_browser_action/background.html b/chrome/test/data/extensions/samples/print_browser_action/background.html deleted file mode 100644 index 5b3f930..0000000 --- a/chrome/test/data/extensions/samples/print_browser_action/background.html +++ /dev/null @@ -1,12 +0,0 @@ -<html> -<head> -<script> - // Called when the user clicks on the browser action. - chrome.browserAction.onClicked.addListener(function(tab) { - var action_url = "javascript:window.print();"; - chrome.tabs.update(tab.id, {url: action_url}); - }); -</script> -</head> -</html> - diff --git a/chrome/test/data/extensions/samples/print_browser_action/manifest.json b/chrome/test/data/extensions/samples/print_browser_action/manifest.json deleted file mode 100644 index 697c94e..0000000 --- a/chrome/test/data/extensions/samples/print_browser_action/manifest.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "name": "Print this page browser action extension", - "description": "This extension adds a print button to the toolstrip", - "version": "1.0", - "background_page": "background.html", - "permissions": [ - "tabs", "http://*/*", "https://*/*" - ], - "browser_action": { - "name": "Print this page", - "icons": ["print_16x16.png"] - } -}
\ No newline at end of file diff --git a/chrome/test/data/extensions/samples/print_browser_action/print_16x16.png b/chrome/test/data/extensions/samples/print_browser_action/print_16x16.png Binary files differdeleted file mode 100644 index d145964..0000000 --- a/chrome/test/data/extensions/samples/print_browser_action/print_16x16.png +++ /dev/null diff --git a/chrome/test/data/extensions/samples/screenshot/background.html b/chrome/test/data/extensions/samples/screenshot/background.html deleted file mode 100644 index 2955688..0000000 --- a/chrome/test/data/extensions/samples/screenshot/background.html +++ /dev/null @@ -1,10 +0,0 @@ - -<html> -<head> -<script src='screenshot.js' type='text/javascript' /> -<script> -</script> -</head> -<body> -</body> -</html> diff --git a/chrome/test/data/extensions/samples/screenshot/camera.png b/chrome/test/data/extensions/samples/screenshot/camera.png Binary files differdeleted file mode 100755 index be26c39..0000000 --- a/chrome/test/data/extensions/samples/screenshot/camera.png +++ /dev/null diff --git a/chrome/test/data/extensions/samples/screenshot/manifest.json b/chrome/test/data/extensions/samples/screenshot/manifest.json deleted file mode 100755 index 37fdbf0..0000000 --- a/chrome/test/data/extensions/samples/screenshot/manifest.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "name": "Test Screenshot Extension", - "version": "1.0", - "description": "Demonstrate screenshot functionality in the chrome.tabs api.", - "background_page": "background.html", - "browser_action": { - "default_icon": "camera.png", - "default_title": "Take a screen shot!" - }, - "permissions": ["tabs"] -} diff --git a/chrome/test/data/extensions/samples/screenshot/screenshot.html b/chrome/test/data/extensions/samples/screenshot/screenshot.html deleted file mode 100644 index 408d13d..0000000 --- a/chrome/test/data/extensions/samples/screenshot/screenshot.html +++ /dev/null @@ -1,14 +0,0 @@ -<html> -<script> -function setScreenshotUrl(url) { - document.getElementById('target').src = url; -} -</script> -<body> - Image here: - <p> - <img id="target" src="white.png" width="640" height="480"> - <p> - End image - </body> -</html> diff --git a/chrome/test/data/extensions/samples/screenshot/screenshot.js b/chrome/test/data/extensions/samples/screenshot/screenshot.js deleted file mode 100755 index 5d47a99..0000000 --- a/chrome/test/data/extensions/samples/screenshot/screenshot.js +++ /dev/null @@ -1,47 +0,0 @@ -function takeScreenshot() { - chrome.tabs.captureVisibleTab(null, function(img) { - var screenshotUrl = img; - var viewTabUrl = chrome.extension.getURL('screenshot.html'); - - chrome.tabs.create({url: viewTabUrl}, function(tab) { - var targetId = tab.id; - - var addSnapshotImageToTab = function(tabId, changedProps) { - // We are waiting for the tab we opened to finish loading. - // Check that the the tab's id matches the tab we opened, - // and that the tab is done loading. - if (tabId != targetId || changedProps.status != "complete") - return; - - // Passing the above test means this is the event we were waiting for. - // There is nothing we need to do for future onUpdated events, so we - // use removeListner to stop geting called when onUpdated events fire. - chrome.tabs.onUpdated.removeListener(addSnapshotImageToTab); - - // Look through all views to find the window which will display - // the screenshot. - var views = chrome.extension.getViews(); - for (var i = 0; i < views.length; i++) { - var view = views[i]; - // If more than one screen shot tab is opened, we need to - // ensure that we do not change an existing screen shot image. - // view.imageAlreadySet is set to true when an image is set for - // the first time. We never change an image in a window with - // this flag set. - if (view.location.href == viewTabUrl && !view.imageAlreadySet) { - view.setScreenshotUrl(screenshotUrl); - view.imageAlreadySet = true; - break; - } - } - }; - chrome.tabs.onUpdated.addListener(addSnapshotImageToTab); - - }); - }); -} - -// Listen for a click on the camera icon. On that click, take a screenshot. -chrome.browserAction.onClicked.addListener(function(tab) { - takeScreenshot(); -}); diff --git a/chrome/test/data/extensions/samples/screenshot/white.png b/chrome/test/data/extensions/samples/screenshot/white.png Binary files differdeleted file mode 100644 index 06d8aca..0000000 --- a/chrome/test/data/extensions/samples/screenshot/white.png +++ /dev/null diff --git a/chrome/test/data/extensions/samples/set_page_color/icon.png b/chrome/test/data/extensions/samples/set_page_color/icon.png Binary files differdeleted file mode 100755 index 1f1c906..0000000 --- a/chrome/test/data/extensions/samples/set_page_color/icon.png +++ /dev/null diff --git a/chrome/test/data/extensions/samples/set_page_color/manifest.json b/chrome/test/data/extensions/samples/set_page_color/manifest.json deleted file mode 100755 index f4ad151..0000000 --- a/chrome/test/data/extensions/samples/set_page_color/manifest.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "name": "A browser action with a popup that changes the page color.", - "version": "1.0", - "permissions": [ - "tabs", "http://*/*" - ], - "browser_action": { - "name": "Set this page's color.", - "icons": ["icon.png"], - "popup": { "path": "popup.html", "height": 79 } - } -}
\ No newline at end of file diff --git a/chrome/test/data/extensions/samples/set_page_color/popup.html b/chrome/test/data/extensions/samples/set_page_color/popup.html deleted file mode 100644 index 62de0ed..0000000 --- a/chrome/test/data/extensions/samples/set_page_color/popup.html +++ /dev/null @@ -1,52 +0,0 @@ -<style>
-body {
- overflow: hidden;
- margin: 0px;
- padding: 0px;
- background: white;
-}
-
-div:first-child {
- margin-top: 0px;
-}
-
-div {
- cursor: pointer;
- text-align: center;
- padding: 1px 3px;
- font: menu;
- width: 100px;
- margin-top: 1px;
- background: #cccccc;
-}
-div:hover {
- background: #aaaaaa;
-}
-#red {
- border: 1px solid red;
- color: red;
-}
-#blue {
- border: 1px solid blue;
- color: blue;
-}
-#green {
- border: 1px solid green;
- color: green;
-}
-#yellow {
- border: 1px solid yellow;
- color: yellow;
-}
-</style>
-<script>
-function click(color) {
- chrome.tabs.executeScript(null,
- {code:"document.body.bgColor='" + color.id + "'"});
- window.close();
-}
-</script>
-<div onclick="click(this)" id="red">red</div>
-<div onclick="click(this)" id="blue">blue</div>
-<div onclick="click(this)" id="green">green</div>
-<div onclick="click(this)" id="yellow">yellow</div>
diff --git a/chrome/test/data/extensions/samples/tabs/jstemplate_compiled.js b/chrome/test/data/extensions/samples/tabs/jstemplate_compiled.js deleted file mode 100644 index 2f62b31..0000000 --- a/chrome/test/data/extensions/samples/tabs/jstemplate_compiled.js +++ /dev/null @@ -1,1182 +0,0 @@ -/** - * @fileoverview This file contains miscellaneous basic functionality. - * - */ - -/** - * Creates a DOM element with the given tag name in the document of the - * owner element. - * - * @param {String} tagName The name of the tag to create. - * @param {Element} owner The intended owner (i.e., parent element) of - * the created element. - * @param {Point} opt_position The top-left corner of the created element. - * @param {Size} opt_size The size of the created element. - * @param {Boolean} opt_noAppend Do not append the new element to the owner. - * @return {Element} The newly created element node. - */ -function createElement(tagName, owner, opt_position, opt_size, opt_noAppend) { - var element = ownerDocument(owner).createElement(tagName); - if (opt_position) { - setPosition(element, opt_position); - } - if (opt_size) { - setSize(element, opt_size); - } - if (owner && !opt_noAppend) { - appendChild(owner, element); - } - - return element; -} - -/** - * Creates a text node with the given value. - * - * @param {String} value The text to place in the new node. - * @param {Element} owner The owner (i.e., parent element) of the new - * text node. - * @return {Text} The newly created text node. - */ -function createTextNode(value, owner) { - var element = ownerDocument(owner).createTextNode(value); - if (owner) { - appendChild(owner, element); - } - return element; -} - -/** - * Returns the document owner of the given element. In particular, - * returns window.document if node is null or the browser does not - * support ownerDocument. - * - * @param {Node} node The node whose ownerDocument is required. - * @returns {Document|Null} The owner document or null if unsupported. - */ -function ownerDocument(node) { - return (node ? node.ownerDocument : null) || document; -} - -/** - * Wrapper function to create CSS units (pixels) string - * - * @param {Number} numPixels Number of pixels, may be floating point. - * @returns {String} Corresponding CSS units string. - */ -function px(numPixels) { - return round(numPixels) + "px"; -} - -/** - * Sets the left and top of the given element to the given point. - * - * @param {Element} element The dom element to manipulate. - * @param {Point} point The desired position. - */ -function setPosition(element, point) { - var style = element.style; - style.position = "absolute"; - style.left = px(point.x); - style.top = px(point.y); -} - -/** - * Sets the width and height style attributes to the given size. - * - * @param {Element} element The dom element to manipulate. - * @param {Size} size The desired size. - */ -function setSize(element, size) { - var style = element.style; - style.width = px(size.width); - style.height = px(size.height); -} - -/** - * Sets display to none. Doing this as a function saves a few bytes for - * the 'style.display' property and the 'none' literal. - * - * @param {Element} node The dom element to manipulate. - */ -function displayNone(node) { - node.style.display = 'none'; -} - -/** - * Sets display to default. - * - * @param {Element} node The dom element to manipulate. - */ -function displayDefault(node) { - node.style.display = ''; -} - -/** - * Appends the given child to the given parent in the DOM - * - * @param {Element} parent The parent dom element. - * @param {Node} child The new child dom node. - */ -function appendChild(parent, child) { - parent.appendChild(child); -} - - -/** - * Wrapper for the eval() builtin function to evaluate expressions and - * obtain their value. It wraps the expression in parentheses such - * that object literals are really evaluated to objects. Without the - * wrapping, they are evaluated as block, and create syntax - * errors. Also protects against other syntax errors in the eval()ed - * code and returns null if the eval throws an exception. - * - * @param {String} expr - * @return {Object|Null} - */ -function jsEval(expr) { - try { - return eval('[' + expr + '][0]'); - } catch (e) { - return null; - } -} - - -/** - * Wrapper for the eval() builtin function to execute statements. This - * guards against exceptions thrown, but doesn't return a - * value. Still, mostly for testability, it returns a boolean to - * indicate whether execution was successful. NOTE: - * javascript's eval semantics is murky in that it confounds - * expression evaluation and statement execution into a single - * construct. Cf. jsEval(). - * - * @param {String} stmt - * @return {Boolean} - */ -function jsExec(stmt) { - try { - eval(stmt); - return true; - } catch (e) { - return false; - } -} - - -/** - * Wrapper for eval with a context. NOTE: The style guide - * deprecates eval, so this is the exception that proves the - * rule. Notice also that since the value of the expression is - * returned rather than assigned to a local variable, one major - * objection aganist the use of the with() statement, namely that - * properties of the with() target override local variables of the - * same name, is void here. - * - * @param {String} expr - * @param {Object} context - * @return {Object|Null} - */ -function jsEvalWith(expr, context) { - try { - with (context) { - return eval('[' + expr + '][0]'); - } - } catch (e) { - return null; - } -} - - -var DOM_ELEMENT_NODE = 1; -var DOM_ATTRIBUTE_NODE = 2; -var DOM_TEXT_NODE = 3; -var DOM_CDATA_SECTION_NODE = 4; -var DOM_ENTITY_REFERENCE_NODE = 5; -var DOM_ENTITY_NODE = 6; -var DOM_PROCESSING_INSTRUCTION_NODE = 7; -var DOM_COMMENT_NODE = 8; -var DOM_DOCUMENT_NODE = 9; -var DOM_DOCUMENT_TYPE_NODE = 10; -var DOM_DOCUMENT_FRAGMENT_NODE = 11; -var DOM_NOTATION_NODE = 12; - -/** - * Traverses the element nodes in the DOM tree underneath the given - * node and finds the first node with elemId, or null if there is no such - * element. Traversal is in depth-first order. - * - * NOTE: The reason this is not combined with the elem() function is - * that the implementations are different. - * elem() is a wrapper for the built-in document.getElementById() function, - * whereas this function performs the traversal itself. - * Modifying elem() to take an optional root node is a possibility, - * but the in-built function would perform better than using our own traversal. - * - * @param {Element} node Root element of subtree to traverse. - * @param {String} elemId The id of the element to search for. - * @return {Element|Null} The corresponding element, or null if not found. - */ -function nodeGetElementById(node, elemId) { - for (var c = node.firstChild; c; c = c.nextSibling) { - if (c.id == elemId) { - return c; - } - if (c.nodeType == DOM_ELEMENT_NODE) { - var n = arguments.callee.call(this, c, elemId); - if (n) { - return n; - } - } - } - return null; -} - - -/** - * Get an attribute from the DOM. Simple redirect, exists to compress code. - * - * @param {Element} node Element to interrogate. - * @param {String} name Name of parameter to extract. - * @return {String} Resulting attribute. - */ -function domGetAttribute(node, name) { - return node.getAttribute(name); -} - -/** - * Set an attribute in the DOM. Simple redirect to compress code. - * - * @param {Element} node Element to interrogate. - * @param {String} name Name of parameter to set. - * @param {String} value Set attribute to this value. - */ -function domSetAttribute(node, name, value) { - node.setAttribute(name, value); -} - -/** - * Remove an attribute from the DOM. Simple redirect to compress code. - * - * @param {Element} node Element to interrogate. - * @param {String} name Name of parameter to remove. - */ -function domRemoveAttribute(node, name) { - node.removeAttribute(name); -} - -/** - * Clone a node in the DOM. - * - * @param {Node} node Node to clone. - * @return {Node} Cloned node. - */ -function domCloneNode(node) { - return node.cloneNode(true); -} - - -/** - * Return a safe string for the className of a node. - * If className is not a string, returns "". - * - * @param {Element} node DOM element to query. - * @return {String} - */ -function domClassName(node) { - return node.className ? "" + node.className : ""; -} - -/** - * Adds a class name to the class attribute of the given node. - * - * @param {Element} node DOM element to modify. - * @param {String} className Class name to add. - */ -function domAddClass(node, className) { - var name = domClassName(node); - if (name) { - var cn = name.split(/\s+/); - var found = false; - for (var i = 0; i < jsLength(cn); ++i) { - if (cn[i] == className) { - found = true; - break; - } - } - - if (!found) { - cn.push(className); - } - - node.className = cn.join(' '); - } else { - node.className = className; - } -} - -/** - * Removes a class name from the class attribute of the given node. - * - * @param {Element} node DOM element to modify. - * @param {String} className Class name to remove. - */ -function domRemoveClass(node, className) { - var c = domClassName(node); - if (!c || c.indexOf(className) == -1) { - return; - } - var cn = c.split(/\s+/); - for (var i = 0; i < jsLength(cn); ++i) { - if (cn[i] == className) { - cn.splice(i--, 1); - } - } - node.className = cn.join(' '); -} - -/** - * Checks if a node belongs to a style class. - * - * @param {Element} node DOM element to test. - * @param {String} className Class name to check for. - * @return {Boolean} Node belongs to style class. - */ -function domTestClass(node, className) { - var cn = domClassName(node).split(/\s+/); - for (var i = 0; i < jsLength(cn); ++i) { - if (cn[i] == className) { - return true; - } - } - return false; -} - -/** - * Inserts a new child before a given sibling. - * - * @param {Node} newChild Node to insert. - * @param {Node} oldChild Sibling node. - * @return {Node} Reference to new child. - */ -function domInsertBefore(newChild, oldChild) { - return oldChild.parentNode.insertBefore(newChild, oldChild); -} - -/** - * Appends a new child to the specified (parent) node. - * - * @param {Element} node Parent element. - * @param {Node} child Child node to append. - * @return {Node} Newly appended node. - */ -function domAppendChild(node, child) { - return node.appendChild(child); -} - -/** - * Remove a new child from the specified (parent) node. - * - * @param {Element} node Parent element. - * @param {Node} child Child node to remove. - * @return {Node} Removed node. - */ -function domRemoveChild(node, child) { - return node.removeChild(child); -} - -/** - * Replaces an old child node with a new child node. - * - * @param {Node} newChild New child to append. - * @param {Node} oldChild Old child to remove. - * @return {Node} Replaced node. - */ -function domReplaceChild(newChild, oldChild) { - return oldChild.parentNode.replaceChild(newChild, oldChild); -} - -/** - * Removes a node from the DOM. - * - * @param {Node} node The node to remove. - * @return {Node} The removed node. - */ -function domRemoveNode(node) { - return domRemoveChild(node.parentNode, node); -} - -/** - * Creates a new text node in the given document. - * - * @param {Document} doc Target document. - * @param {String} text Text composing new text node. - * @return {Text} Newly constructed text node. - */ -function domCreateTextNode(doc, text) { - return doc.createTextNode(text); -} - -/** - * Creates a new node in the given document - * - * @param {Document} doc Target document. - * @param {String} name Name of new element (i.e. the tag name).. - * @return {Element} Newly constructed element. - */ -function domCreateElement(doc, name) { - return doc.createElement(name); -} - -/** - * Creates a new attribute in the given document. - * - * @param {Document} doc Target document. - * @param {String} name Name of new attribute. - * @return {Attr} Newly constructed attribute. - */ -function domCreateAttribute(doc, name) { - return doc.createAttribute(name); -} - -/** - * Creates a new comment in the given document. - * - * @param {Document} doc Target document. - * @param {String} text Comment text. - * @return {Comment} Newly constructed comment. - */ -function domCreateComment(doc, text) { - return doc.createComment(text); -} - -/** - * Creates a document fragment. - * - * @param {Document} doc Target document. - * @return {DocumentFragment} Resulting document fragment node. - */ -function domCreateDocumentFragment(doc) { - return doc.createDocumentFragment(); -} - -/** - * Redirect to document.getElementById - * - * @param {Document} doc Target document. - * @param {String} id Id of requested node. - * @return {Element|Null} Resulting element. - */ -function domGetElementById(doc, id) { - return doc.getElementById(id); -} - -/** - * Redirect to window.setInterval - * - * @param {Window} win Target window. - * @param {Function} fun Callback function. - * @param {Number} time Time in milliseconds. - * @return {Object} Contract id. - */ -function windowSetInterval(win, fun, time) { - return win.setInterval(fun, time); -} - -/** - * Redirect to window.clearInterval - * - * @param {Window} win Target window. - * @param {object} id Contract id. - * @return {any} NOTE: Return type unknown? - */ -function windowClearInterval(win, id) { - return win.clearInterval(id); -} - -/** - * Determines whether one node is recursively contained in another. - * @param parent The parent node. - * @param child The node to look for in parent. - * @return parent recursively contains child - */ -function containsNode(parent, child) { - while (parent != child && child.parentNode) { - child = child.parentNode; - } - return parent == child; -}; -/** - * @fileoverview This file contains javascript utility functions that - * do not depend on anything defined elsewhere. - * - */ - -/** - * Returns the value of the length property of the given object. Used - * to reduce compiled code size. - * - * @param {Array | String} a The string or array to interrogate. - * @return {Number} The value of the length property. - */ -function jsLength(a) { - return a.length; -} - -var min = Math.min; -var max = Math.max; -var ceil = Math.ceil; -var floor = Math.floor; -var round = Math.round; -var abs = Math.abs; - -/** - * Copies all properties from second object to the first. Modifies to. - * - * @param {Object} to The target object. - * @param {Object} from The source object. - */ -function copyProperties(to, from) { - foreachin(from, function(p) { - to[p] = from[p]; - }); -} - -/** - * Iterates over the array, calling the given function for each - * element. - * - * @param {Array} array - * @param {Function} fn - */ -function foreach(array, fn) { - var I = jsLength(array); - for (var i = 0; i < I; ++i) { - fn(array[i], i); - } -} - -/** - * Safely iterates over all properties of the given object, calling - * the given function for each property. If opt_all isn't true, uses - * hasOwnProperty() to assure the property is on the object, not on - * its prototype. - * - * @param {Object} object - * @param {Function} fn - * @param {Boolean} opt_all If true, also iterates over inherited properties. - */ -function foreachin(object, fn, opt_all) { - for (var i in object) { - if (opt_all || !object.hasOwnProperty || object.hasOwnProperty(i)) { - fn(i, object[i]); - } - } -} - -/** - * Appends the second array to the first, copying its elements. - * Optionally only a slice of the second array is copied. - * - * @param {Array} a1 Target array (modified). - * @param {Array} a2 Source array. - * @param {Number} opt_begin Begin of slice of second array (optional). - * @param {Number} opt_end End (exclusive) of slice of second array (optional). - */ -function arrayAppend(a1, a2, opt_begin, opt_end) { - var i0 = opt_begin || 0; - var i1 = opt_end || jsLength(a2); - for (var i = i0; i < i1; ++i) { - a1.push(a2[i]); - } -} - -/** - * Trim whitespace from begin and end of string. - * - * @see testStringTrim(); - * - * @param {String} str Input string. - * @return {String} Trimmed string. - */ -function stringTrim(str) { - return stringTrimRight(stringTrimLeft(str)); -} - -/** - * Trim whitespace from beginning of string. - * - * @see testStringTrimLeft(); - * - * @param {String} str Input string. - * @return {String} Trimmed string. - */ -function stringTrimLeft(str) { - return str.replace(/^\s+/, ""); -} - -/** - * Trim whitespace from end of string. - * - * @see testStringTrimRight(); - * - * @param {String} str Input string. - * @return {String} Trimmed string. - */ -function stringTrimRight(str) { - return str.replace(/\s+$/, ""); -} - -/** - * Jscompiler wrapper for parseInt() with base 10. - * - * @param {String} s String repersentation of a number. - * - * @return {Number} The integer contained in s, converted on base 10. - */ -function parseInt10(s) { - return parseInt(s, 10); -} -/** - * @fileoverview A simple formatter to project JavaScript data into - * HTML templates. The template is edited in place. I.e. in order to - * instantiate a template, clone it from the DOM first, and then - * process the cloned template. This allows for updating of templates: - * If the templates is processed again, changed values are merely - * updated. - * - * NOTE: IE DOM doesn't have importNode(). - * - * NOTE: The property name "length" must not be used in input - * data, see comment in jstSelect_(). - */ - - -/** - * Names of jstemplate attributes. These attributes are attached to - * normal HTML elements and bind expression context data to the HTML - * fragment that is used as template. - */ -var ATT_select = 'jsselect'; -var ATT_instance = 'jsinstance'; -var ATT_display = 'jsdisplay'; -var ATT_values = 'jsvalues'; -var ATT_eval = 'jseval'; -var ATT_transclude = 'transclude'; -var ATT_content = 'jscontent'; - - -/** - * Names of special variables defined by the jstemplate evaluation - * context. These can be used in js expression in jstemplate - * attributes. - */ -var VAR_index = '$index'; -var VAR_this = '$this'; - - -/** - * Context for processing a jstemplate. The context contains a context - * object, whose properties can be referred to in jstemplate - * expressions, and it holds the locally defined variables. - * - * @param {Object} opt_data The context object. Null if no context. - * - * @param {Object} opt_parent The parent context, from which local - * variables are inherited. Normally the context object of the parent - * context is the object whose property the parent object is. Null for the - * context of the root object. - * - * @constructor - */ -function JsExprContext(opt_data, opt_parent) { - var me = this; - - /** - * The local context of the input data in which the jstemplate - * expressions are evaluated. Notice that this is usually an Object, - * but it can also be a scalar value (and then still the expression - * $this can be used to refer to it). Notice this can be a scalar - * value, including undefined. - * - * @type {Object} - */ - me.data_ = opt_data; - - /** - * The context for variable definitions in which the jstemplate - * expressions are evaluated. Other than for the local context, - * which replaces the parent context, variable definitions of the - * parent are inherited. The special variable $this points to data_. - * - * @type {Object} - */ - me.vars_ = {}; - if (opt_parent) { - copyProperties(me.vars_, opt_parent.vars_); - } - this.vars_[VAR_this] = me.data_; -} - - -/** - * Evaluates the given expression in the context of the current - * context object and the current local variables. - * - * @param {String} expr A javascript expression. - * - * @param {Element} template DOM node of the template. - * - * @return The value of that expression. - */ -JsExprContext.prototype.jseval = function(expr, template) { - with (this.vars_) { - with (this.data_) { - try { - return (function() { - return eval('[' + expr + '][0]'); - }).call(template); - } catch (e) { - return null; - } - } - } -} - - -/** - * Clones the current context for a new context object. The cloned - * context has the data object as its context object and the current - * context as its parent context. It also sets the $index variable to - * the given value. This value usually is the position of the data - * object in a list for which a template is instantiated multiply. - * - * @param {Object} data The new context object. - * - * @param {Number} index Position of the new context when multiply - * instantiated. (See implementation of jstSelect().) - * - * @return {JsExprContext} - */ -JsExprContext.prototype.clone = function(data, index) { - var ret = new JsExprContext(data, this); - ret.setVariable(VAR_index, index); - if (this.resolver_) { - ret.setSubTemplateResolver(this.resolver_); - } - return ret; -} - - -/** - * Binds a local variable to the given value. If set from jstemplate - * jsvalue expressions, variable names must start with $, but in the - * API they only have to be valid javascript identifier. - * - * @param {String} name - * - * @param {Object} value - */ -JsExprContext.prototype.setVariable = function(name, value) { - this.vars_[name] = value; -} - - -/** - * Sets the function used to resolve the values of the transclude - * attribute into DOM nodes. By default, this is jstGetTemplate(). The - * value set here is inherited by clones of this context. - * - * @param {Function} resolver The function used to resolve transclude - * ids into a DOM node of a subtemplate. The DOM node returned by this - * function will be inserted into the template instance being - * processed. Thus, the resolver function must instantiate the - * subtemplate as necessary. - */ -JsExprContext.prototype.setSubTemplateResolver = function(resolver) { - this.resolver_ = resolver; -} - - -/** - * Resolves a sub template from an id. Used to process the transclude - * attribute. If a resolver function was set using - * setSubTemplateResolver(), it will be used, otherwise - * jstGetTemplate(). - * - * @param {String} id The id of the sub template. - * - * @return {Node} The root DOM node of the sub template, for direct - * insertion into the currently processed template instance. - */ -JsExprContext.prototype.getSubTemplate = function(id) { - return (this.resolver_ || jstGetTemplate).call(this, id); -} - - -/** - * HTML template processor. Data values are bound to HTML templates - * using the attributes transclude, jsselect, jsdisplay, jscontent, - * jsvalues. The template is modifed in place. The values of those - * attributes are JavaScript expressions that are evaluated in the - * context of the data object fragment. - * - * @param {JsExprContext} context Context created from the input data - * object. - * - * @param {Element} template DOM node of the template. This will be - * processed in place. After processing, it will still be a valid - * template that, if processed again with the same data, will remain - * unchanged. - */ -function jstProcess(context, template) { - var processor = new JstProcessor(); - processor.run_([ processor, processor.jstProcess_, context, template ]); -} - - -/** - * Internal class used by jstemplates to maintain context. - * NOTE: This is necessary to process deep templates in Safari - * which has a relatively shallow stack. - * @class - */ -function JstProcessor() { -} - - -/** - * Runs the state machine, beginning with function "start". - * - * @param {Array} start The first function to run, in the form - * [object, method, args ...] - */ -JstProcessor.prototype.run_ = function(start) { - var me = this; - - me.queue_ = [ start ]; - while (jsLength(me.queue_)) { - var f = me.queue_.shift(); - f[1].apply(f[0], f.slice(2)); - } -} - - -/** - * Appends a function to be called later. - * Analogous to calling that function on a subsequent line, or a subsequent - * iteration of a loop. - * - * @param {Array} f A function in the form [object, method, args ...] - */ -JstProcessor.prototype.enqueue_ = function(f) { - this.queue_.push(f); -} - - -/** - * Implements internals of jstProcess. - * - * @param {JsExprContext} context - * - * @param {Element} template - */ -JstProcessor.prototype.jstProcess_ = function(context, template) { - var me = this; - - var transclude = domGetAttribute(template, ATT_transclude); - if (transclude) { - var tr = context.getSubTemplate(transclude); - if (tr) { - domReplaceChild(tr, template); - me.enqueue_([ me, me.jstProcess_, context, tr ]); - } else { - domRemoveNode(template); - } - return; - } - - var select = domGetAttribute(template, ATT_select); - if (select) { - me.jstSelect_(context, template, select); - return; - } - - var display = domGetAttribute(template, ATT_display); - if (display) { - if (!context.jseval(display, template)) { - displayNone(template); - return; - } - - displayDefault(template); - } - - - var values = domGetAttribute(template, ATT_values); - if (values) { - me.jstValues_(context, template, values); - } - - var expressions = domGetAttribute(template, ATT_eval); - if (expressions) { - foreach(expressions.split(/\s*;\s*/), function(expression) { - expression = stringTrim(expression); - if (jsLength(expression)) { - context.jseval(expression, template); - } - }); - } - - var content = domGetAttribute(template, ATT_content); - if (content) { - me.jstContent_(context, template, content); - - } else { - var childnodes = []; - for (var i = 0; i < jsLength(template.childNodes); ++i) { - if (template.childNodes[i].nodeType == DOM_ELEMENT_NODE) { - me.enqueue_( - [ me, me.jstProcess_, context, template.childNodes[i] ]); - } - } - } -} - - -/** - * Implements the jsselect attribute: evalutes the value of the - * jsselect attribute in the current context, with the current - * variable bindings (see JsExprContext.jseval()). If the value is an - * array, the current template node is multiplied once for every - * element in the array, with the array element being the context - * object. If the array is empty, or the value is undefined, then the - * current template node is dropped. If the value is not an array, - * then it is just made the context object. - * - * @param {JsExprContext} context The current evaluation context. - * - * @param {Element} template The currently processed node of the template. - * - * @param {String} select The javascript expression to evaluate. - * - * @param {Function} process The function to continue processing with. - */ -JstProcessor.prototype.jstSelect_ = function(context, template, select) { - var me = this; - - var value = context.jseval(select, template); - domRemoveAttribute(template, ATT_select); - - var instance = domGetAttribute(template, ATT_instance); - var instance_last = false; - if (instance) { - if (instance.charAt(0) == '*') { - instance = parseInt10(instance.substr(1)); - instance_last = true; - } else { - instance = parseInt10(instance); - } - } - - var multiple = (value !== null && - typeof value == 'object' && - typeof value.length == 'number'); - var multiple_empty = (multiple && value.length == 0); - - if (multiple) { - if (multiple_empty) { - if (!instance) { - domSetAttribute(template, ATT_select, select); - domSetAttribute(template, ATT_instance, '*0'); - displayNone(template); - } else { - domRemoveNode(template); - } - - } else { - displayDefault(template); - if (instance === null || instance === "" || instance === undefined || - (instance_last && instance < jsLength(value) - 1)) { - var templatenodes = []; - var instances_start = instance || 0; - for (var i = instances_start + 1; i < jsLength(value); ++i) { - var node = domCloneNode(template); - templatenodes.push(node); - domInsertBefore(node, template); - } - templatenodes.push(template); - - for (var i = 0; i < jsLength(templatenodes); ++i) { - var ii = i + instances_start; - var v = value[ii]; - var t = templatenodes[i]; - - me.enqueue_([ me, me.jstProcess_, context.clone(v, ii), t ]); - var instanceStr = (ii == jsLength(value) - 1 ? '*' : '') + ii; - me.enqueue_( - [ null, postProcessMultiple_, t, select, instanceStr ]); - } - - } else if (instance < jsLength(value)) { - var v = value[instance]; - - me.enqueue_( - [me, me.jstProcess_, context.clone(v, instance), template]); - var instanceStr = (instance == jsLength(value) - 1 ? '*' : '') - + instance; - me.enqueue_( - [ null, postProcessMultiple_, template, select, instanceStr ]); - } else { - domRemoveNode(template); - } - } - } else { - if (value == null) { - domSetAttribute(template, ATT_select, select); - displayNone(template); - } else { - me.enqueue_( - [ me, me.jstProcess_, context.clone(value, 0), template ]); - me.enqueue_( - [ null, postProcessSingle_, template, select ]); - } - } -} - - -/** - * Sets ATT_select and ATT_instance following recursion to jstProcess. - * - * @param {Element} template The template - * - * @param {String} select The jsselect string - * - * @param {String} instanceStr The new value for the jsinstance attribute - */ -function postProcessMultiple_(template, select, instanceStr) { - domSetAttribute(template, ATT_select, select); - domSetAttribute(template, ATT_instance, instanceStr); -} - - -/** - * Sets ATT_select and makes the element visible following recursion to - * jstProcess. - * - * @param {Element} template The template - * - * @param {String} select The jsselect string - */ -function postProcessSingle_(template, select) { - domSetAttribute(template, ATT_select, select); - displayDefault(template); -} - - -/** - * Implements the jsvalues attribute: evaluates each of the values and - * assigns them to variables in the current context (if the name - * starts with '$', javascript properties of the current template node - * (if the name starts with '.'), or DOM attributes of the current - * template node (otherwise). Since DOM attribute values are always - * strings, the value is coerced to string in the latter case, - * otherwise it's the uncoerced javascript value. - * - * @param {JsExprContext} context Current evaluation context. - * - * @param {Element} template Currently processed template node. - * - * @param {String} valuesStr Value of the jsvalues attribute to be - * processed. - */ -JstProcessor.prototype.jstValues_ = function(context, template, valuesStr) { - var values = valuesStr.split(/\s*;\s*/); - for (var i = 0; i < jsLength(values); ++i) { - var colon = values[i].indexOf(':'); - if (colon < 0) { - continue; - } - var label = stringTrim(values[i].substr(0, colon)); - var value = context.jseval(values[i].substr(colon + 1), template); - - if (label.charAt(0) == '$') { - context.setVariable(label, value); - - } else if (label.charAt(0) == '.') { - var nameSpaceLabel = label.substr(1).split('.'); - var nameSpaceObject = template; - var nameSpaceDepth = jsLength(nameSpaceLabel); - for (var j = 0, J = nameSpaceDepth - 1; j < J; ++j) { - var jLabel = nameSpaceLabel[j]; - if (!nameSpaceObject[jLabel]) { - nameSpaceObject[jLabel] = {}; - } - nameSpaceObject = nameSpaceObject[jLabel]; - } - nameSpaceObject[nameSpaceLabel[nameSpaceDepth - 1]] = value; - } else if (label) { - if (typeof value == 'boolean') { - if (value) { - domSetAttribute(template, label, label); - } else { - domRemoveAttribute(template, label); - } - } else { - domSetAttribute(template, label, '' + value); - } - } - } -} - - -/** - * Implements the jscontent attribute. Evalutes the expression in - * jscontent in the current context and with the current variables, - * and assigns its string value to the content of the current template - * node. - * - * @param {JsExprContext} context Current evaluation context. - * - * @param {Element} template Currently processed template node. - * - * @param {String} content Value of the jscontent attribute to be - * processed. - */ -JstProcessor.prototype.jstContent_ = function(context, template, content) { - var value = '' + context.jseval(content, template); - if (template.innerHTML == value) { - return; - } - while (template.firstChild) { - domRemoveNode(template.firstChild); - } - var t = domCreateTextNode(ownerDocument(template), value); - domAppendChild(template, t); -} - - -/** - * Helps to implement the transclude attribute, and is the initial - * call to get hold of a template from its ID. - * - * @param {String} name The ID of the HTML element used as template. - * - * @returns {Element} The DOM node of the template. (Only element - * nodes can be found by ID, hence it's a Element.) - */ -function jstGetTemplate(name) { - var section = domGetElementById(document, name); - if (section) { - var ret = domCloneNode(section); - domRemoveAttribute(ret, 'id'); - return ret; - } else { - return null; - } -} - -window['jstGetTemplate'] = jstGetTemplate; -window['jstProcess'] = jstProcess; -window['JsExprContext'] = JsExprContext; diff --git a/chrome/test/data/extensions/samples/tabs/manifest.json b/chrome/test/data/extensions/samples/tabs/manifest.json deleted file mode 100644 index 4583e66..0000000 --- a/chrome/test/data/extensions/samples/tabs/manifest.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "TabsAPI", - "description": "Utility for working with the extension tabs api", - "version": "0.1", - "permissions": ["tabs"] -} diff --git a/chrome/test/data/extensions/samples/tabs/tabs_api.html b/chrome/test/data/extensions/samples/tabs/tabs_api.html deleted file mode 100644 index 4a784e3..0000000 --- a/chrome/test/data/extensions/samples/tabs/tabs_api.html +++ /dev/null @@ -1,390 +0,0 @@ -<html> -<head> -<script src="jstemplate_compiled.js" type="text/javascript"></script> -<script> - -tabs = {}; -tabIds = []; - -focusedWindowId = undefined; -currentWindowId = undefined; - -function bootStrap() { - chrome.windows.getCurrent(function(currentWindow) { - currentWindowId = currentWindow.id; - chrome.windows.getLastFocused(function(focusedWindow) { - focusedWindowId = focusedWindow.id; - loadWindowList(); - }); - }); -} - -function isInt(i) { - return (typeof i == "number") && !(i % 1) && !isNaN(i); -} - -function loadWindowList() { - chrome.windows.getAll({ populate: true }, function(windowList) { - tabs = {}; - tabIds = []; - for (var i = 0; i < windowList.length; i++) { - windowList[i].current = (windowList[i].id == currentWindowId); - windowList[i].focused = (windowList[i].id == focusedWindowId); - - for (var j = 0; j < windowList[i].tabs.length; j++) { - tabIds[tabIds.length] = windowList[i].tabs[j].id; - tabs[windowList[i].tabs[j].id] = windowList[i].tabs[j]; - } - } - - var input = new JsExprContext(windowList); - var output = document.getElementById('windowList'); - jstProcess(input, output); - }); -} - -function updateTabData(id) { - var retval = { - url: document.getElementById('url_' + id).value, - selected: document.getElementById('selected_' + id).value ? true : false - } - - return retval; -} - -function updateTab(id){ - try { - chrome.tabs.update(id, updateTabData(id)); - } catch (e) { - alert(e); - } -} - -function moveTabData(id) { - return { - 'index': parseInt(document.getElementById('index_' + id).value), - 'windowId': parseInt(document.getElementById('windowId_' + id).value) - } -} -function moveTab(id) { - try { - chrome.tabs.move(id, moveTabData(id)); - } catch (e) { - alert(e); - } -} - -function createTabData(id) { - return { - 'index': parseInt(document.getElementById('index_' + id).value), - 'windowId': parseInt(document.getElementById('windowId_' + id).value), - 'index': parseInt(document.getElementById('index_' + id).value), - 'url': document.getElementById('url_' + id).value, - 'selected': document.getElementById('selected_' + id).value ? true : false - } -} - -function createTab() { - var args = createTabData('new') - - if (!isInt(args.windowId)) - delete args.windowId; - if (!isInt(args.index)) - delete args.index; - - try { - chrome.tabs.create(args); - } catch (e) { - alert(e); - } -} - -function updateAll() { - try { - for (var i = 0; i < tabIds.length; i++) { - chrome.tabs.update(tabIds[i], updateTabData(tabIds[i])); - } - } catch(e) { - alert(e); - } -} - -function moveAll() { - appendToLog('moving all'); - try { - for (var i = 0; i < tabIds.length; i++) { - chrome.tabs.move(tabIds[i], moveTabData(tabIds[i])); - } - } catch(e) { - alert(e); - } -} - -function removeTab(tabId) { - try { - chrome.tabs.remove(tabId, function() { - appendToLog('tab: ' + tabId + ' removed.'); - }); - } catch (e) { - alert(e); - } -} - -function appendToLog(logLine) { - var log = document.getElementById('log'); - log.innerHTML = '<div> > ' + logLine + '</div>' + log.innerHTML; -} - -function clearLog() { - document.getElementById('log').innerHTML = ''; -} - -chrome.windows.onCreated.addListener(function(createInfo) { - appendToLog('windows.onCreated -- window: ' + createInfo.id); - loadWindowList(); -}); - -chrome.windows.onFocusChanged.addListener(function(windowId) { - focusedWindowId = windowId; - appendToLog('windows.onFocusChanged -- window: ' + windowId); - loadWindowList(); -}); - -chrome.windows.onRemoved.addListener(function(windowId) { - appendToLog('windows.onRemoved -- window: ' + windowId); - loadWindowList(); -}); - -chrome.tabs.onCreated.addListener(function(tab) { - appendToLog('tabs.onCreated -- window: ' + tab.windowId + ' tab: ' + tab.id + ' title: ' + tab.title + ' index ' + tab.index + ' url ' + tab.url); - loadWindowList(); -}); - -chrome.tabs.onAttached.addListener(function(tabId, props) { - appendToLog('tabs.onAttached -- window: ' + props.newWindowId + ' tab: ' + tabId + ' index ' + props.newPosition); - loadWindowList(); -}); - -chrome.tabs.onMoved.addListener(function(tabId, props) { - appendToLog('tabs.onMoved -- window: ' + props.windowId + ' tab: ' + tabId + ' from ' + props.fromIndex + ' to ' + props.toIndex); - loadWindowList(); -}); - -function refreshTab(tabId) { - chrome.tabs.get(tabId, function(tab) { - var input = new JsExprContext(tab); - var output = document.getElementById('tab_' + tab.id); - jstProcess(input, output); - appendToLog('tab refreshed -- tabId: ' + tab.id + ' url: ' + tab.url); - }); -} - -chrome.tabs.onUpdated.addListener(function(tabId, props) { - appendToLog('tabs.onUpdated -- tab: ' + tabId + ' status ' + props.status + ' url ' + props.url); - refreshTab(tabId); -}); - -chrome.tabs.onDetached.addListener(function(tabId, props) { - appendToLog('tabs.onDetached -- window: ' + props.oldWindowId + ' tab: ' + tabId + ' index ' + props.oldPosition); - loadWindowList(); -}); - -chrome.tabs.onSelectionChanged.addListener(function(tabId, props) { - appendToLog('tabs.onSelectionChanged -- window: ' + props.windowId + ' tab: ' + tabId); - loadWindowList(); -}); - -chrome.tabs.onRemoved.addListener(function(tabId) { - appendToLog('tabs.onRemoved -- tab: ' + tabId); - loadWindowList(); -}); - -function createWindow() { - var args = { - 'left': parseInt(document.getElementById('new_window_left').value), - 'top': parseInt(document.getElementById('new_window_top').value), - 'width': parseInt(document.getElementById('new_window_width').value), - 'height': parseInt(document.getElementById('new_window_height').value), - 'url': document.getElementById('new_window_url').value - } - - if (!isInt(args.left)) - delete args.left; - if (!isInt(args.top)) - delete args.top; - if (!isInt(args.width)) - delete args.width; - if (!isInt(args.height)) - delete args.height; - if (!args.url) - delete args.url; - - try { - chrome.windows.create(args); - } catch(e) { - alert(e); - } -} - -function refreshWindow(windowId) { - chrome.windows.get(windowId, function(window) { - chrome.tabs.getAllInWindow(window.id, function(tabList) { - window.tabs = tabList; - var input = new JsExprContext(window); - var output = document.getElementById('window_' + window.id); - jstProcess(input, output); - - appendToLog('window refreshed -- windowId: ' + window.id + ' tab count:' + window.tabs.length); - }); - }); -} - -function updateWindowData(id) { - var retval = { - left: parseInt(document.getElementById('left_' + id).value), - top: parseInt(document.getElementById('top_' + id).value), - width: parseInt(document.getElementById('width_' + id).value), - height: parseInt(document.getElementById('height_' + id).value) - } - - if (!isInt(retval.left)) - delete retval.left; - if (!isInt(retval.top)) - delete retval.top; - if (!isInt(retval.width)) - delete retval.width; - if (!isInt(retval.height)) - delete retval.height; - - return retval; -} - -function updateWindow(id){ - try { - chrome.windows.update(id, updateWindowData(id)); - } catch (e) { - alert(e); - } -} - -function removeWindow(windowId) { - try { - chrome.windows.remove(windowId, function() { - appendToLog('window: ' + windowId + ' removed.'); - }); - } catch (e) { - alert(e); - } -} - -function refreshSelectedTab(windowId) { - chrome.tabs.getSelected(windowId, function(tab) { - var input = new JsExprContext(tab); - var output = document.getElementById('tab_' + tab.id); - jstProcess(input, output); - appendToLog('selected tab refreshed -- tabId: ' + tab.id + ' url:' + tab.url); - }); -} - -</script> -</head> - <body onload="bootStrap();"> - <div id="windowList"> - <div style="background-color: #AAEEEE; margin: 4px; padding: 8px; margin: 20px" jsselect="$this" - jsvalues="id:'window_' + id"> - <div style="font-style: italic; width: 80px; display: inline-block"> - Window: <span jscontent="id"></span> - </div> - <div style="display: inline-block"> - left: <input style="width: 60px" type="text" jsvalues="value:$this.left;id:'left_' + id" /> - top: <input style="width: 60px" type="text" jsvalues="value:$this.top;id:'top_' + id" /> - width: <input style="width: 60px" type="text" jsvalues="value:$this.width;id:'width_' + id" /> - height: <input style="width: 60px" type="text" jsvalues="value:$this.height;id:'height_' + id" /> - <input type="checkbox" jsvalues="checked:focused; id:'focused_' + id" /> Focused - <input type="checkbox" jsvalues="checked:current; id:'current_' + id" /> Current - <button onclick="refreshWindow(this.jstdata);" jsvalues=".jstdata:id">Refresh</button> - </div> - <div id="tabList"> - <div jsselect="tabs"> - <div style="background-color: #EEEEEE; margin: 8px; padding: 4px" jsvalues="id:'tab_' + id"> - <div style="margin: 8px"> - <div style="font-style: italic; width: 80px; display: inline-block" jscontent="'TabId: ' + id"></div> - <div style="width: 300px; display: inline-block"> - index: <input style="width: 20px" type="text" jsvalues="value:$this.index;id:'index_' + id" /> - windowId: <input style="width: 20px" type="text" jsvalues="value:windowId;id:'windowId_' + id" /> - <button onclick="moveTab(this.jstdata);" jsvalues=".jstdata:id">Move</button> - <button onclick="refreshTab(this.jstdata);" jsvalues=".jstdata:id">Refresh</button> - </div> - </div> - <div style="margin: 8px"> - <div> - <div style="width: 40px; display:inline-block">title:</div> - <input style="width: 90%" type="text" jsvalues="value:title;id:'title_' + id" /> - </div> - <div> - <div style="width: 40px; display:inline-block">url:</div> - <input style="width: 90%" type="text" jsvalues="value:url;id:'url_' + id" /> - </div> - <div><input type="checkbox" jsvalues="checked:selected; id:'selected_' + id" /> Selected</div> - </div> - <button onclick="updateTab(this.jstdata)" jsvalues=".jstdata:id">Update Tab</button> - <button onclick="removeTab(this.jstdata);" jsvalues=".jstdata:id">Close Tab</button> - </div> - </div> - </div> - <button onclick="updateWindow(this.jstdata);" jsvalues=".jstdata:id">Update Window</button> - <button onclick="removeWindow(this.jstdata);" jsvalues=".jstdata:id">Close Window</button> - <button onclick="refreshSelectedTab(this.jstdata);" jsvalues=".jstdata:id">Refresh Selected Tab</button> - </div> - </div> - <div style="background-color: #EEEEBB; margin: 20px; padding: 8px"> - <h3 style="text-align: center; margin: 8px"> Create Window</h3> - <div style="margin: 8px"> - <div style="width: 300px; display: inline-block"> - left: <input style="width: 20px" type="text" id="new_window_left" /> - top: <input style="width: 20px" type="text" id="new_window_top" /> - width: <input style="width: 20px" type="text" id="new_window_width" /> - height: <input style="width: 20px" type="text" id="new_window_height" /> - </div> - </div> - <div style="margin: 8px"> - <div> - <div style="width: 40px; display:inline-block">url:</div> - <input style="width: 90%" type="text" id="new_window_url" /> - </div> - </div> - <button onclick="createWindow();">Create</button> - </div> - <div style="background-color: #EEEEAA; margin: 20px; padding: 8px"> - <h3 style="text-align: center; margin: 8px"> Create Tab</h3> - <div style="margin: 8px"> - <div style="width: 300px; display: inline-block"> - index: <input style="width: 20px" type="text" id="index_new" /> - windowId: <input style="width: 20px" type="text" id="windowId_new" /> - <button onclick="moveTab(this.jstdata);" jsvalues=".jstdata:id">Move</button> - </div> - </div> - <div style="margin: 8px"> - <div> - <div style="width: 40px; display:inline-block">title:</div> - <input style="width: 90%" type="text" id="title_new" /> - </div> - <div> - <div style="width: 40px; display:inline-block">url:</div> - <input style="width: 90%" type="text" id="url_new" /> - </div> - <div><input type="checkbox" id="selected_new" /> Selected</div> - </div> - <button onclick="createTab();">Create</button> - </div> - <div style="margin: 20px;"> - <button onclick="loadWindowList();">Refresh</button> - <button onclick="updateAll();">Update All</button> - <button onclick="moveAll();">Move All</button> - <button onclick="clearLog();">-->Clear Log</button> - <button onclick="chrome.windows.create();">New Window</button> - </div> - <div id="log" style="background-color: #EEAAEE; margin: 20px; padding: 8px"> - </div> - </body> -</html>
\ No newline at end of file diff --git a/chrome/test/data/extensions/samples/test_page_action/background.html b/chrome/test/data/extensions/samples/test_page_action/background.html deleted file mode 100644 index 2b77a66..0000000 --- a/chrome/test/data/extensions/samples/test_page_action/background.html +++ /dev/null @@ -1,62 +0,0 @@ -<html> -<head> -<script> - var lastTabId = 0; - var visible = false; - chrome.tabs.onUpdated.addListener(function(tabId, p) { - lastTabId = tabId; - chrome.pageAction.show(tabId); - }); - - // Called when the user clicks on the page action. - var clicks = 0; - var text = ""; - chrome.pageAction.onClicked.addListener(function(_, info) { - chrome.pageAction.setIcon({path: "icon" + (clicks + 1) + ".png", - tabId: info.tabId}); - if (clicks % 2) { - chrome.pageAction.show(info.tabId); - } else { - chrome.pageAction.hide(info.tabId); - setTimeout(function() { chrome.pageAction.show(info.tabId); }, 200); - } - chrome.pageAction.setTitle({title: "click:" + clicks, tabId: info.tabId}); - text += clicks.toString(); - - // We only have 2 icons, but cycle through 3 icons to test the - // out-of-bounds index bug. - clicks++; - if (clicks > 3) - clicks = 0; - }); - var i = 0; - - window.setInterval(function() { - // Don't animate while in "click" mode. - if (clicks > 0) return; - - // Don't do anything if we don't have a tab yet. - if (lastTabId == 0) return; - - i++; - chrome.pageAction.setIcon({imageData: draw(i*2, i*4), tabId: lastTabId}); - }, 50); - - function draw(starty, startx) { - var canvas = document.getElementById('canvas'); - var context = canvas.getContext('2d'); - context.clearRect(0, 0, canvas.width, canvas.height); - context.fillStyle = "rgba(0,200,0,255)"; - context.fillRect(startx % 19, starty % 19, 8, 8); - context.fillStyle = "rgba(0,0,200,255)"; - context.fillRect((startx + 5) % 19, (starty + 5) % 19, 8, 8); - context.fillStyle = "rgba(200,0,0,255)"; - context.fillRect((startx + 10) % 19, (starty + 10) % 19, 8, 8); - return context.getImageData(0, 0, 19, 19); - } -</script> -</head> -<body> -<canvas id="canvas" width="19" height="19"></canvas> -</body> -</html> diff --git a/chrome/test/data/extensions/samples/test_page_action/icon1.png b/chrome/test/data/extensions/samples/test_page_action/icon1.png Binary files differdeleted file mode 100755 index 9a79a46..0000000 --- a/chrome/test/data/extensions/samples/test_page_action/icon1.png +++ /dev/null diff --git a/chrome/test/data/extensions/samples/test_page_action/icon2.png b/chrome/test/data/extensions/samples/test_page_action/icon2.png Binary files differdeleted file mode 100755 index 8d3f710..0000000 --- a/chrome/test/data/extensions/samples/test_page_action/icon2.png +++ /dev/null diff --git a/chrome/test/data/extensions/samples/test_page_action/manifest.json b/chrome/test/data/extensions/samples/test_page_action/manifest.json deleted file mode 100644 index 5a374e8..0000000 --- a/chrome/test/data/extensions/samples/test_page_action/manifest.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "name": "Animated Page Action", - "description": "This extension adds an animated browser action to the toolbar.", - "version": "1.0", - "permissions": ["tabs"], - "background_page": "background.html", - "page_action": { - "default_title": "First icon" - } -} |