summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoraa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-04-29 20:03:07 +0000
committeraa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-04-29 20:03:07 +0000
commit072bbfa45e16385741fd00dede5c4c31e42438a6 (patch)
treef9bce083a9fc551dba0219582e1db774a18e64e9
parentdacb10dd3adcd8bed394fef63657a0b8ad45ffe4 (diff)
downloadchromium_src-072bbfa45e16385741fd00dede5c4c31e42438a6.zip
chromium_src-072bbfa45e16385741fd00dede5c4c31e42438a6.tar.gz
chromium_src-072bbfa45e16385741fd00dede5c4c31e42438a6.tar.bz2
Part 1 of sample sprucing. Also, change chromium_extension.py to generate a random ID if the manifest doesn't have one.
* Create a test/data/extensions/samples directory and add Reader and Gmail samples to it. * Minor fixes to buildbot sample to fit better visually. * Minor fixes to bookmarks sample to use new button styles. * Workaround for bug in bookmark sample where extension APIs do not load the first time. * Move Resizer extension into samples/. * Fix TabsAPI sample to not use old deprecated manifest properties anymore. Part 2 will move the remaining samples into samples/ (don't want to do that at the same time because git-cl doesn't know how to tell Rietveld about moves and it would be confusing to review). Review URL: http://codereview.chromium.org/99172 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@14872 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/test/data/extensions/bookmarks/bookmark_api.html33
-rw-r--r--chrome/test/data/extensions/bookmarks/bookmark_view.html8
-rwxr-xr-xchrome/test/data/extensions/bookmarks/extensions_toolstrip.css89
-rw-r--r--chrome/test/data/extensions/buildbot/buildbot.html46
-rwxr-xr-xchrome/test/data/extensions/buildbot/extensions_toolstrip.css89
-rw-r--r--chrome/test/data/extensions/buildbot/manifest.json15
-rw-r--r--chrome/test/data/extensions/samples/buildbot.crxbin0 -> 14132 bytes
-rw-r--r--chrome/test/data/extensions/samples/gmail.crxbin0 -> 63077 bytes
-rw-r--r--chrome/test/data/extensions/samples/gmail/extensions_toolstrip.css89
-rw-r--r--chrome/test/data/extensions/samples/gmail/gmail.pngbin0 -> 48123 bytes
-rw-r--r--chrome/test/data/extensions/samples/gmail/gmail_checker.html89
-rw-r--r--chrome/test/data/extensions/samples/gmail/manifest.json13
-rw-r--r--chrome/test/data/extensions/samples/gmail/styles.css16
-rw-r--r--chrome/test/data/extensions/samples/resizer/manifest.json (renamed from chrome/test/data/extensions/test/Resizer/manifest.json)0
-rw-r--r--chrome/test/data/extensions/samples/resizer/resizer.html (renamed from chrome/test/data/extensions/test/Resizer/resizer.html)0
-rw-r--r--chrome/test/data/extensions/samples/subscribe.crxbin0 -> 30322 bytes
-rw-r--r--chrome/test/data/extensions/samples/subscribe/extensions_toolstrip.css89
-rw-r--r--chrome/test/data/extensions/samples/subscribe/feed_finder.js19
-rw-r--r--chrome/test/data/extensions/samples/subscribe/icon.pngbin0 -> 3305 bytes
-rw-r--r--chrome/test/data/extensions/samples/subscribe/icon_disabled.pngbin0 -> 3280 bytes
-rw-r--r--chrome/test/data/extensions/samples/subscribe/icon_subscribed.pngbin0 -> 3364 bytes
-rw-r--r--chrome/test/data/extensions/samples/subscribe/manifest.json22
-rw-r--r--chrome/test/data/extensions/samples/subscribe/toolstrip.html53
-rw-r--r--chrome/test/data/extensions/test/TabsAPI/1/manifest.json5
-rwxr-xr-xchrome/tools/extensions/chromium_extension.py16
25 files changed, 621 insertions, 70 deletions
diff --git a/chrome/test/data/extensions/bookmarks/bookmark_api.html b/chrome/test/data/extensions/bookmarks/bookmark_api.html
index 0e46bbb..ba8084e 100644
--- a/chrome/test/data/extensions/bookmarks/bookmark_api.html
+++ b/chrome/test/data/extensions/bookmarks/bookmark_api.html
@@ -1,26 +1,5 @@
<html>
-<style>
-body {
- overflow: hidden;
- margin: 0 0 0 0;
-}
-
-/* TODO: put the background style into body when
- https://bugs.webkit.org/show_bug.cgi?id=18445 is fixed. */
-.content {
- background: -webkit-gradient(linear, left top, left bottom, from(rgb(222, 234, 248)), to(rgb(237, 244, 252)));
- padding: 1;
- white-space: nowrap;
-}
-
-.button {
- display: inline;
- border: 1px solid silver;
- padding: 2px;
- margin: 1px 3px;
- height: 100%;
-}
-</style>
+<link rel="stylesheet" type="text/css" href="extensions_toolstrip.css">
<script>
var dump = function(obj, indent) {
@@ -105,13 +84,11 @@ var dumpBookmarks = function(event) {
};
</script>
<body>
-<div class="content">
-<div class="button" onclick="dumpBookmarks(window.event);">
-Dump Bookmarks
-</div>
-<div class="button" onclick="testMoveBookmarks(window.event);">
-Test Move
+<div class="toolstrip-button" onclick="dumpBookmarks(window.event);">
+<span>Dump Bookmarks</span>
</div>
+<div class="toolstrip-button" onclick="testMoveBookmarks(window.event);">
+<span>Test Move</span>
</div>
</body>
</html>
diff --git a/chrome/test/data/extensions/bookmarks/bookmark_view.html b/chrome/test/data/extensions/bookmarks/bookmark_view.html
index f3f45b5..f038e97 100644
--- a/chrome/test/data/extensions/bookmarks/bookmark_view.html
+++ b/chrome/test/data/extensions/bookmarks/bookmark_view.html
@@ -20,6 +20,14 @@
</style>
<script>
+// XXX Hack: When you call window.open('chrome-extension://...'), the window is
+// first navigated to about:blank, and then to the final URL. This confuses the
+// code that sets up our v8 extensions, and we don't end up with them running.
+//
+// If we noticed this happened, reload ourselves, which should fix it.
+if (!chromium.bookmarks)
+ location.reload();
+
var prefix = "bookmark_";
var toggleBookmark = function(event) {
diff --git a/chrome/test/data/extensions/bookmarks/extensions_toolstrip.css b/chrome/test/data/extensions/bookmarks/extensions_toolstrip.css
new file mode 100755
index 0000000..3ba1892
--- /dev/null
+++ b/chrome/test/data/extensions/bookmarks/extensions_toolstrip.css
@@ -0,0 +1,89 @@
+/**
+ * NOTE: This shouldn't need to be included in every toolstrip manually, but we
+ * currently have a race where it sometimes isn't applied, so we include it
+ * manually to be sure. In the future, these styles will be applied to all
+ * toolstrips automatically.
+ */
+
+
+/**
+ * Body styles. This makes the toolstrip layout fit in with the Windows
+ * bookmarkbar. Note that the background is provided separately, by
+ * RenderWidget.
+ */
+body {
+ display:-webkit-box;
+ -webkit-box-orient:horizontal;
+ -webkit-box-align:stretch;
+ white-space:nowrap;
+ overflow: hidden;
+ margin: 0;
+ padding:0;
+ font: menu;
+ color: #062D75;
+ text-shadow: #FFFFFF 1px 1px 0px;
+ -webkit-user-select:none;
+ cursor:default;
+}
+
+/**
+ * Toolstrip Buttons. The following styles make
+ * <div class="toolstrip-button"><img><span>Woot</span></div> look like the
+ * bookmarkbar buttons on Windows.
+ *
+ * TODO(aa): We may have to come up with a way to modify these slightly on
+ * different platforms.
+ *
+ * TODO(aa): It would be nice if we could use actual <button> tags work here,
+ * which should work once https://bugs.webkit.org/show_bug.cgi?id=25406 is
+ * fixed.
+ */
+div.toolstrip-button {
+ display:-webkit-box;
+ -webkit-box-orient:horizontal;
+ -webkit-box-align:center;
+ border:6px solid transparent;
+ font:menu;
+ background:transparent;
+ color: #062D75;
+ text-shadow: #FFFFFF 1px 1px 0px;
+ line-height:100%;
+ padding:0;
+}
+
+div.toolstrip-button>img {
+ display:-webkit-box;
+ width:16px;
+ height:16px;
+ /**
+ * We inset the image slightly vertically, so that the button can be shorter
+ * than would otherwise be possibe with our fat borders.
+ */
+ margin:-1px 5px -1px 0;
+}
+
+div.toolstrip-button>span {
+ display:-webkit-box;
+ margin-right:1px;
+ /**
+ * Hack: WebKit appears to measure text height slightly differently than we do
+ * in native code, making us not line up when centering, so we shift ourselves
+ * up one pixel to match.
+ */
+ margin-top:-1px;
+}
+
+/**
+ * TODO(aa): It would be nice if these border images could be stored in Chrome
+ * as, normal images even if those images are just translated into data URLs at
+ * runtime.
+ */
+div.toolstrip-button:hover {
+ border-width:6px;
+ -webkit-border-image:url(data:image/png;base64,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) 6 round round;
+}
+
+div.toolstrip-button:active {
+ border-width:6px;
+ -webkit-border-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAYCAYAAADKx8xXAAAACXBIWXMAAAsTAAALEwEAmpwYAAAKT2lDQ1BQaG90b3Nob3AgSUNDIHByb2ZpbGUAAHjanVNnVFPpFj333vRCS4iAlEtvUhUIIFJCi4AUkSYqIQkQSoghodkVUcERRUUEG8igiAOOjoCMFVEsDIoK2AfkIaKOg6OIisr74Xuja9a89+bN/rXXPues852zzwfACAyWSDNRNYAMqUIeEeCDx8TG4eQuQIEKJHAAEAizZCFz/SMBAPh+PDwrIsAHvgABeNMLCADATZvAMByH/w/qQplcAYCEAcB0kThLCIAUAEB6jkKmAEBGAYCdmCZTAKAEAGDLY2LjAFAtAGAnf+bTAICd+Jl7AQBblCEVAaCRACATZYhEAGg7AKzPVopFAFgwABRmS8Q5ANgtADBJV2ZIALC3AMDOEAuyAAgMADBRiIUpAAR7AGDIIyN4AISZABRG8lc88SuuEOcqAAB4mbI8uSQ5RYFbCC1xB1dXLh4ozkkXKxQ2YQJhmkAuwnmZGTKBNA/g88wAAKCRFRHgg/P9eM4Ors7ONo62Dl8t6r8G/yJiYuP+5c+rcEAAAOF0ftH+LC+zGoA7BoBt/qIl7gRoXgugdfeLZrIPQLUAoOnaV/Nw+H48PEWhkLnZ2eXk5NhKxEJbYcpXff5nwl/AV/1s+X48/Pf14L7iJIEyXYFHBPjgwsz0TKUcz5IJhGLc5o9H/LcL//wd0yLESWK5WCoU41EScY5EmozzMqUiiUKSKcUl0v9k4t8s+wM+3zUAsGo+AXuRLahdYwP2SycQWHTA4vcAAPK7b8HUKAgDgGiD4c93/+8//UegJQCAZkmScQAAXkQkLlTKsz/HCAAARKCBKrBBG/TBGCzABhzBBdzBC/xgNoRCJMTCQhBCCmSAHHJgKayCQiiGzbAdKmAv1EAdNMBRaIaTcA4uwlW4Dj1wD/phCJ7BKLyBCQRByAgTYSHaiAFiilgjjggXmYX4IcFIBBKLJCDJiBRRIkuRNUgxUopUIFVIHfI9cgI5h1xGupE7yAAygvyGvEcxlIGyUT3UDLVDuag3GoRGogvQZHQxmo8WoJvQcrQaPYw2oefQq2gP2o8+Q8cwwOgYBzPEbDAuxsNCsTgsCZNjy7EirAyrxhqwVqwDu4n1Y8+xdwQSgUXACTYEd0IgYR5BSFhMWE7YSKggHCQ0EdoJNwkDhFHCJyKTqEu0JroR+cQYYjIxh1hILCPWEo8TLxB7iEPENyQSiUMyJ7mQAkmxpFTSEtJG0m5SI+ksqZs0SBojk8naZGuyBzmULCAryIXkneTD5DPkG+Qh8lsKnWJAcaT4U+IoUspqShnlEOU05QZlmDJBVaOaUt2ooVQRNY9aQq2htlKvUYeoEzR1mjnNgxZJS6WtopXTGmgXaPdpr+h0uhHdlR5Ol9BX0svpR+iX6AP0dwwNhhWDx4hnKBmbGAcYZxl3GK+YTKYZ04sZx1QwNzHrmOeZD5lvVVgqtip8FZHKCpVKlSaVGyovVKmqpqreqgtV81XLVI+pXlN9rkZVM1PjqQnUlqtVqp1Q61MbU2epO6iHqmeob1Q/pH5Z/YkGWcNMw09DpFGgsV/jvMYgC2MZs3gsIWsNq4Z1gTXEJrHN2Xx2KruY/R27iz2qqaE5QzNKM1ezUvOUZj8H45hx+Jx0TgnnKKeX836K3hTvKeIpG6Y0TLkxZVxrqpaXllirSKtRq0frvTau7aedpr1Fu1n7gQ5Bx0onXCdHZ4/OBZ3nU9lT3acKpxZNPTr1ri6qa6UbobtEd79up+6Ynr5egJ5Mb6feeb3n+hx9L/1U/W36p/VHDFgGswwkBtsMzhg8xTVxbzwdL8fb8VFDXcNAQ6VhlWGX4YSRudE8o9VGjUYPjGnGXOMk423GbcajJgYmISZLTepN7ppSTbmmKaY7TDtMx83MzaLN1pk1mz0x1zLnm+eb15vft2BaeFostqi2uGVJsuRaplnutrxuhVo5WaVYVVpds0atna0l1rutu6cRp7lOk06rntZnw7Dxtsm2qbcZsOXYBtuutm22fWFnYhdnt8Wuw+6TvZN9un2N/T0HDYfZDqsdWh1+c7RyFDpWOt6azpzuP33F9JbpL2dYzxDP2DPjthPLKcRpnVOb00dnF2e5c4PziIuJS4LLLpc+Lpsbxt3IveRKdPVxXeF60vWdm7Obwu2o26/uNu5p7ofcn8w0nymeWTNz0MPIQ+BR5dE/C5+VMGvfrH5PQ0+BZ7XnIy9jL5FXrdewt6V3qvdh7xc+9j5yn+M+4zw33jLeWV/MN8C3yLfLT8Nvnl+F30N/I/9k/3r/0QCngCUBZwOJgUGBWwL7+Hp8Ib+OPzrbZfay2e1BjKC5QRVBj4KtguXBrSFoyOyQrSH355jOkc5pDoVQfujW0Adh5mGLw34MJ4WHhVeGP45wiFga0TGXNXfR3ENz30T6RJZE3ptnMU85ry1KNSo+qi5qPNo3ujS6P8YuZlnM1VidWElsSxw5LiquNm5svt/87fOH4p3iC+N7F5gvyF1weaHOwvSFpxapLhIsOpZATIhOOJTwQRAqqBaMJfITdyWOCnnCHcJnIi/RNtGI2ENcKh5O8kgqTXqS7JG8NXkkxTOlLOW5hCepkLxMDUzdmzqeFpp2IG0yPTq9MYOSkZBxQqohTZO2Z+pn5mZ2y6xlhbL+xW6Lty8elQfJa7OQrAVZLQq2QqboVFoo1yoHsmdlV2a/zYnKOZarnivN7cyzytuQN5zvn//tEsIS4ZK2pYZLVy0dWOa9rGo5sjxxedsK4xUFK4ZWBqw8uIq2Km3VT6vtV5eufr0mek1rgV7ByoLBtQFr6wtVCuWFfevc1+1dT1gvWd+1YfqGnRs+FYmKrhTbF5cVf9go3HjlG4dvyr+Z3JS0qavEuWTPZtJm6ebeLZ5bDpaql+aXDm4N2dq0Dd9WtO319kXbL5fNKNu7g7ZDuaO/PLi8ZafJzs07P1SkVPRU+lQ27tLdtWHX+G7R7ht7vPY07NXbW7z3/T7JvttVAVVN1WbVZftJ+7P3P66Jqun4lvttXa1ObXHtxwPSA/0HIw6217nU1R3SPVRSj9Yr60cOxx++/p3vdy0NNg1VjZzG4iNwRHnk6fcJ3/ceDTradox7rOEH0x92HWcdL2pCmvKaRptTmvtbYlu6T8w+0dbq3nr8R9sfD5w0PFl5SvNUyWna6YLTk2fyz4ydlZ19fi753GDborZ752PO32oPb++6EHTh0kX/i+c7vDvOXPK4dPKy2+UTV7hXmq86X23qdOo8/pPTT8e7nLuarrlca7nuer21e2b36RueN87d9L158Rb/1tWeOT3dvfN6b/fF9/XfFt1+cif9zsu72Xcn7q28T7xf9EDtQdlD3YfVP1v+3Njv3H9qwHeg89HcR/cGhYPP/pH1jw9DBY+Zj8uGDYbrnjg+OTniP3L96fynQ89kzyaeF/6i/suuFxYvfvjV69fO0ZjRoZfyl5O/bXyl/erA6xmv28bCxh6+yXgzMV70VvvtwXfcdx3vo98PT+R8IH8o/2j5sfVT0Kf7kxmTk/8EA5jz/GMzLdsAAAAgY0hSTQAAeiUAAICDAAD5/wAAgOkAAHUwAADqYAAAOpgAABdvkl/FRgAAAeFJREFUeNqMlMlu20AQRF8Ph5KGVETFS2LAt/z/PyWHHOIYRkRYCxeRlcOQMqUscgPDbbpYXb2MfX2uJAkDnANnhjPOrBf0En0PAswMj0RioK6l3JRsypLd7nAGzPPAuihYrQpcktJLeMNQ1/Lz6YnuWHNXZHx5vMcnCRAZXvcHNuWW6lDx6fMD5tK4vylLumPN48Mti0Ug9SnOObCIDCHjpij49v0H29eS4uYO58zYbEqKZcZiHpilswga6QZNaZpyf7tmt9/HPDiDw6FimQd8mmJmoz+aLIAPecaxbXEGDgMhEu8jSGdkJ5PAuQQhzMAbUcq/TBd/GH39ewGX5swMM/uvk4aLBsbYAFdMA3UEvxF4uxKqJtqmz+5M8VSDiwvZKcxTrCPwHQpPyLEK/l+oaVZ1WQ8jTpC9I6Pjy9U6TpH6Syv5WMfrWZ3GeqqjmVE1HX6mC9d4GvSK6ZQ6vE+GrEpkIVDVDX3f/xFnLyEMIZqmIVssQML1wHq9Yrvb0R07NGia3pFwGFVVkS+X9ICXoFh/5Ni2vPx6Ic9XZFnADSNmBnVV0TQ1s9QTsjx+fyobGaD+yGG/pa5rmqaZTgHz+ZxFCMzmASyJDfT82mpsZGeRwbC3gikOuhSPyTGZvwcAgLLi1uEcpE8AAAAASUVORK5CYII=) 6 round round;
+}
diff --git a/chrome/test/data/extensions/buildbot/buildbot.html b/chrome/test/data/extensions/buildbot/buildbot.html
index ee21e7d7..e3878e1 100644
--- a/chrome/test/data/extensions/buildbot/buildbot.html
+++ b/chrome/test/data/extensions/buildbot/buildbot.html
@@ -57,14 +57,8 @@ function statusClick() {
requestStatus();
</script>
+<link rel="stylesheet" type="text/css" href="extensions_toolstrip.css">
<style>
-#main {
- /* TODO(erikkay) this shouldn't be necessary, see extensions_toolstrip.css */
- white-space: nowrap;
- padding-top: 0px;
- height: 100%;
-}
-
.open {
color: green;
}
@@ -73,40 +67,30 @@ requestStatus();
color: red;
}
-.button {
- padding: 2px 5px;
- height: 20px;
- float: left;
- display: table;
-}
-
-.button:hover {
- padding: 0px 4px;
- border: 1px solid silver;
- -webkit-border-radius: 5px;
- background-color: rgb(237, 244, 252);
- cursor: pointer;
-}
-
#bots {
- border: 1px solid rgb(237, 244, 252);
+ border: none;
height: 20px; /* hardcoded height sucks */
width: 435px; /* hardcoded width sucks */
background-color: transparent;
+ display:-webkit-box;
}
-#status {
- display: table-cell;
- vertical-align: middle;
+#frame-wrapper {
+ /* This is used to get us to vertically center the iframe in the vertical
+ space. */
+ display:-webkit-box;
+ -webkit-box-align:center;
+ /* Also, scooch the frame in a bit, under the button, because the content of
+ the frame has some extra built-in left padding. */
+ margin-left:-10px;
}
</style>
-<div id="main">
-<div class="button" onclick="statusClick();">
-<div id="status" class="open">
-tree: open?
-</div>
+<div class="toolstrip-button" onclick="statusClick();">
+<span id="status" class="open">tree: open?</span>
</div>
+
+<div id="frame-wrapper">
<iframe scrolling='no' id='bots' src="http://build.chromium.org/buildbot/waterfall/horizontal_one_box_per_builder"></iframe>
</div>
diff --git a/chrome/test/data/extensions/buildbot/extensions_toolstrip.css b/chrome/test/data/extensions/buildbot/extensions_toolstrip.css
new file mode 100755
index 0000000..3ba1892
--- /dev/null
+++ b/chrome/test/data/extensions/buildbot/extensions_toolstrip.css
@@ -0,0 +1,89 @@
+/**
+ * NOTE: This shouldn't need to be included in every toolstrip manually, but we
+ * currently have a race where it sometimes isn't applied, so we include it
+ * manually to be sure. In the future, these styles will be applied to all
+ * toolstrips automatically.
+ */
+
+
+/**
+ * Body styles. This makes the toolstrip layout fit in with the Windows
+ * bookmarkbar. Note that the background is provided separately, by
+ * RenderWidget.
+ */
+body {
+ display:-webkit-box;
+ -webkit-box-orient:horizontal;
+ -webkit-box-align:stretch;
+ white-space:nowrap;
+ overflow: hidden;
+ margin: 0;
+ padding:0;
+ font: menu;
+ color: #062D75;
+ text-shadow: #FFFFFF 1px 1px 0px;
+ -webkit-user-select:none;
+ cursor:default;
+}
+
+/**
+ * Toolstrip Buttons. The following styles make
+ * <div class="toolstrip-button"><img><span>Woot</span></div> look like the
+ * bookmarkbar buttons on Windows.
+ *
+ * TODO(aa): We may have to come up with a way to modify these slightly on
+ * different platforms.
+ *
+ * TODO(aa): It would be nice if we could use actual <button> tags work here,
+ * which should work once https://bugs.webkit.org/show_bug.cgi?id=25406 is
+ * fixed.
+ */
+div.toolstrip-button {
+ display:-webkit-box;
+ -webkit-box-orient:horizontal;
+ -webkit-box-align:center;
+ border:6px solid transparent;
+ font:menu;
+ background:transparent;
+ color: #062D75;
+ text-shadow: #FFFFFF 1px 1px 0px;
+ line-height:100%;
+ padding:0;
+}
+
+div.toolstrip-button>img {
+ display:-webkit-box;
+ width:16px;
+ height:16px;
+ /**
+ * We inset the image slightly vertically, so that the button can be shorter
+ * than would otherwise be possibe with our fat borders.
+ */
+ margin:-1px 5px -1px 0;
+}
+
+div.toolstrip-button>span {
+ display:-webkit-box;
+ margin-right:1px;
+ /**
+ * Hack: WebKit appears to measure text height slightly differently than we do
+ * in native code, making us not line up when centering, so we shift ourselves
+ * up one pixel to match.
+ */
+ margin-top:-1px;
+}
+
+/**
+ * TODO(aa): It would be nice if these border images could be stored in Chrome
+ * as, normal images even if those images are just translated into data URLs at
+ * runtime.
+ */
+div.toolstrip-button:hover {
+ border-width:6px;
+ -webkit-border-image:url(data:image/png;base64,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) 6 round round;
+}
+
+div.toolstrip-button:active {
+ border-width:6px;
+ -webkit-border-image:url(data:image/png;base64,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) 6 round round;
+}
diff --git a/chrome/test/data/extensions/buildbot/manifest.json b/chrome/test/data/extensions/buildbot/manifest.json
index 7c52761..c584f8d 100644
--- a/chrome/test/data/extensions/buildbot/manifest.json
+++ b/chrome/test/data/extensions/buildbot/manifest.json
@@ -1,6 +1,9 @@
-{
- "name": "buildbot",
- "description": "Buildbot waterfall monitor",
- "version": "0.1",
- "toolstrips": ["buildbot.html"]
-}
+{
+ "description": "Buildbot waterfall monitor",
+ "id": "7868865ECC233B0400ABE5D38D88355C03C4BB1A",
+ "name": "buildbot",
+ "toolstrips": [
+ "buildbot.html"
+ ],
+ "version": "0.1"
+} \ No newline at end of file
diff --git a/chrome/test/data/extensions/samples/buildbot.crx b/chrome/test/data/extensions/samples/buildbot.crx
new file mode 100644
index 0000000..8f31ba4
--- /dev/null
+++ b/chrome/test/data/extensions/samples/buildbot.crx
Binary files differ
diff --git a/chrome/test/data/extensions/samples/gmail.crx b/chrome/test/data/extensions/samples/gmail.crx
new file mode 100644
index 0000000..316ab0d
--- /dev/null
+++ b/chrome/test/data/extensions/samples/gmail.crx
Binary files differ
diff --git a/chrome/test/data/extensions/samples/gmail/extensions_toolstrip.css b/chrome/test/data/extensions/samples/gmail/extensions_toolstrip.css
new file mode 100644
index 0000000..3ba1892
--- /dev/null
+++ b/chrome/test/data/extensions/samples/gmail/extensions_toolstrip.css
@@ -0,0 +1,89 @@
+/**
+ * NOTE: This shouldn't need to be included in every toolstrip manually, but we
+ * currently have a race where it sometimes isn't applied, so we include it
+ * manually to be sure. In the future, these styles will be applied to all
+ * toolstrips automatically.
+ */
+
+
+/**
+ * Body styles. This makes the toolstrip layout fit in with the Windows
+ * bookmarkbar. Note that the background is provided separately, by
+ * RenderWidget.
+ */
+body {
+ display:-webkit-box;
+ -webkit-box-orient:horizontal;
+ -webkit-box-align:stretch;
+ white-space:nowrap;
+ overflow: hidden;
+ margin: 0;
+ padding:0;
+ font: menu;
+ color: #062D75;
+ text-shadow: #FFFFFF 1px 1px 0px;
+ -webkit-user-select:none;
+ cursor:default;
+}
+
+/**
+ * Toolstrip Buttons. The following styles make
+ * <div class="toolstrip-button"><img><span>Woot</span></div> look like the
+ * bookmarkbar buttons on Windows.
+ *
+ * TODO(aa): We may have to come up with a way to modify these slightly on
+ * different platforms.
+ *
+ * TODO(aa): It would be nice if we could use actual <button> tags work here,
+ * which should work once https://bugs.webkit.org/show_bug.cgi?id=25406 is
+ * fixed.
+ */
+div.toolstrip-button {
+ display:-webkit-box;
+ -webkit-box-orient:horizontal;
+ -webkit-box-align:center;
+ border:6px solid transparent;
+ font:menu;
+ background:transparent;
+ color: #062D75;
+ text-shadow: #FFFFFF 1px 1px 0px;
+ line-height:100%;
+ padding:0;
+}
+
+div.toolstrip-button>img {
+ display:-webkit-box;
+ width:16px;
+ height:16px;
+ /**
+ * We inset the image slightly vertically, so that the button can be shorter
+ * than would otherwise be possibe with our fat borders.
+ */
+ margin:-1px 5px -1px 0;
+}
+
+div.toolstrip-button>span {
+ display:-webkit-box;
+ margin-right:1px;
+ /**
+ * Hack: WebKit appears to measure text height slightly differently than we do
+ * in native code, making us not line up when centering, so we shift ourselves
+ * up one pixel to match.
+ */
+ margin-top:-1px;
+}
+
+/**
+ * TODO(aa): It would be nice if these border images could be stored in Chrome
+ * as, normal images even if those images are just translated into data URLs at
+ * runtime.
+ */
+div.toolstrip-button:hover {
+ border-width:6px;
+ -webkit-border-image:url(data:image/png;base64,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) 6 round round;
+}
+
+div.toolstrip-button:active {
+ border-width:6px;
+ -webkit-border-image:url(data:image/png;base64,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) 6 round round;
+}
diff --git a/chrome/test/data/extensions/samples/gmail/gmail.png b/chrome/test/data/extensions/samples/gmail/gmail.png
new file mode 100644
index 0000000..24180e0
--- /dev/null
+++ b/chrome/test/data/extensions/samples/gmail/gmail.png
Binary files differ
diff --git a/chrome/test/data/extensions/samples/gmail/gmail_checker.html b/chrome/test/data/extensions/samples/gmail/gmail_checker.html
new file mode 100644
index 0000000..1e461e5
--- /dev/null
+++ b/chrome/test/data/extensions/samples/gmail/gmail_checker.html
@@ -0,0 +1,89 @@
+<html>
+<head>
+<link rel="stylesheet" type="text/css" href="extensions_toolstrip.css">
+<link rel="stylesheet" type="text/css" href="styles.css">
+<script>
+gmail_atom_href = "http://mail.google.com/mail/feed/atom";
+var poll_timeout = 2000;
+var unreadCount;
+var debug = true;
+
+function gmailNSResolver(prefix) {
+ if(prefix == 'gmail') {
+ return 'http://purl.org/atom/ns#';
+ }
+}
+
+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';
+}
+
+function updateUnreadCount(count) {
+ if (unreadCount != count) {
+ unreadCount = count;
+ startFlip();
+ }
+}
+
+function requestUnreadFeed() {
+ var xhr = new XMLHttpRequest();
+ try {
+ console.log("request..");
+ xhr.onreadystatechange = function(){
+ console.log("readystate: " + xhr.readyState);
+ if (xhr.readyState == 4) {
+ console.log("response..");
+ var xmlDoc = xhr.responseXML;
+ var fullCountSet = xmlDoc.evaluate("/gmail:feed/gmail:fullcount",
+ xmlDoc, gmailNSResolver, XPathResult.ANY_TYPE, null);
+ var fullCountNode = fullCountSet.iterateNext();
+ if (fullCountNode) {
+ updateUnreadCount(fullCountNode.textContent);
+ } else {
+ console.log("fullcount not found!");
+ console.error("Error: feed retrieved, but no <fullcount> node found");
+ }
+
+ window.setTimeout(requestUnreadFeed, poll_timeout);
+ }
+ }
+
+ xhr.onerror = function(error) {
+ debugger;
+ console.log("error: " + error);
+ window.setTimeout(requestUnreadFeed, poll_timeout);
+ }
+
+ xhr.open("GET", gmail_atom_href);
+ xhr.send({});
+ } catch(e) {
+ console.log("ex: " + e);
+ console.error("exception: " + e);
+ window.setTimeout(requestUnreadFeed, poll_timeout);
+ }
+}
+
+function goToInbox() {
+ chromium.tabs.createTab({url:"http://www.gmail.com/"});
+}
+
+</script>
+</head>
+<body onload="requestUnreadFeed();" onclick="goToInbox()">
+ <div class="toolstrip-button">
+ <img src="gmail.png" style="width:auto; height:auto">
+ <span>Gmail - Inbox <span style="display: inline-block;" id="unreadCount" class="base-flip" onclick="startFlip();"></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
new file mode 100644
index 0000000..bf7faf7
--- /dev/null
+++ b/chrome/test/data/extensions/samples/gmail/manifest.json
@@ -0,0 +1,13 @@
+{
+ "description": "Displays number of unread Gmail messages",
+ "id": "DE6C0EDB5E435EC06E4E0E36E77EB241E1831273",
+ "name": "Gmail Checker",
+ "permissions": [
+ "http://*.google.com/*",
+ "https://*.google.com/*"
+ ],
+ "toolstrips": [
+ "gmail_checker.html"
+ ],
+ "version": "0.1"
+} \ 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
new file mode 100644
index 0000000..5587c1f
--- /dev/null
+++ b/chrome/test/data/extensions/samples/gmail/styles.css
@@ -0,0 +1,16 @@
+.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/test/Resizer/manifest.json b/chrome/test/data/extensions/samples/resizer/manifest.json
index 20ae7f9..20ae7f9 100644
--- a/chrome/test/data/extensions/test/Resizer/manifest.json
+++ b/chrome/test/data/extensions/samples/resizer/manifest.json
diff --git a/chrome/test/data/extensions/test/Resizer/resizer.html b/chrome/test/data/extensions/samples/resizer/resizer.html
index 0542474..0542474 100644
--- a/chrome/test/data/extensions/test/Resizer/resizer.html
+++ b/chrome/test/data/extensions/samples/resizer/resizer.html
diff --git a/chrome/test/data/extensions/samples/subscribe.crx b/chrome/test/data/extensions/samples/subscribe.crx
new file mode 100644
index 0000000..5345bb5
--- /dev/null
+++ b/chrome/test/data/extensions/samples/subscribe.crx
Binary files differ
diff --git a/chrome/test/data/extensions/samples/subscribe/extensions_toolstrip.css b/chrome/test/data/extensions/samples/subscribe/extensions_toolstrip.css
new file mode 100644
index 0000000..3ba1892
--- /dev/null
+++ b/chrome/test/data/extensions/samples/subscribe/extensions_toolstrip.css
@@ -0,0 +1,89 @@
+/**
+ * NOTE: This shouldn't need to be included in every toolstrip manually, but we
+ * currently have a race where it sometimes isn't applied, so we include it
+ * manually to be sure. In the future, these styles will be applied to all
+ * toolstrips automatically.
+ */
+
+
+/**
+ * Body styles. This makes the toolstrip layout fit in with the Windows
+ * bookmarkbar. Note that the background is provided separately, by
+ * RenderWidget.
+ */
+body {
+ display:-webkit-box;
+ -webkit-box-orient:horizontal;
+ -webkit-box-align:stretch;
+ white-space:nowrap;
+ overflow: hidden;
+ margin: 0;
+ padding:0;
+ font: menu;
+ color: #062D75;
+ text-shadow: #FFFFFF 1px 1px 0px;
+ -webkit-user-select:none;
+ cursor:default;
+}
+
+/**
+ * Toolstrip Buttons. The following styles make
+ * <div class="toolstrip-button"><img><span>Woot</span></div> look like the
+ * bookmarkbar buttons on Windows.
+ *
+ * TODO(aa): We may have to come up with a way to modify these slightly on
+ * different platforms.
+ *
+ * TODO(aa): It would be nice if we could use actual <button> tags work here,
+ * which should work once https://bugs.webkit.org/show_bug.cgi?id=25406 is
+ * fixed.
+ */
+div.toolstrip-button {
+ display:-webkit-box;
+ -webkit-box-orient:horizontal;
+ -webkit-box-align:center;
+ border:6px solid transparent;
+ font:menu;
+ background:transparent;
+ color: #062D75;
+ text-shadow: #FFFFFF 1px 1px 0px;
+ line-height:100%;
+ padding:0;
+}
+
+div.toolstrip-button>img {
+ display:-webkit-box;
+ width:16px;
+ height:16px;
+ /**
+ * We inset the image slightly vertically, so that the button can be shorter
+ * than would otherwise be possibe with our fat borders.
+ */
+ margin:-1px 5px -1px 0;
+}
+
+div.toolstrip-button>span {
+ display:-webkit-box;
+ margin-right:1px;
+ /**
+ * Hack: WebKit appears to measure text height slightly differently than we do
+ * in native code, making us not line up when centering, so we shift ourselves
+ * up one pixel to match.
+ */
+ margin-top:-1px;
+}
+
+/**
+ * TODO(aa): It would be nice if these border images could be stored in Chrome
+ * as, normal images even if those images are just translated into data URLs at
+ * runtime.
+ */
+div.toolstrip-button:hover {
+ border-width:6px;
+ -webkit-border-image:url(data:image/png;base64,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) 6 round round;
+}
+
+div.toolstrip-button:active {
+ border-width:6px;
+ -webkit-border-image:url(data:image/png;base64,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) 6 round round;
+}
diff --git a/chrome/test/data/extensions/samples/subscribe/feed_finder.js b/chrome/test/data/extensions/samples/subscribe/feed_finder.js
new file mode 100644
index 0000000..91593b5
--- /dev/null
+++ b/chrome/test/data/extensions/samples/subscribe/feed_finder.js
@@ -0,0 +1,19 @@
+find();
+window.addEventListener("focus", find);
+
+function find() {
+ if (window == top) {
+ // Find all the RSS link elements.
+ var result = document.evaluate(
+ '//link[@rel="alternate"][contains(@type, "rss") or ' +
+ 'contains(@type, "atom") or contains(@type, "rdf")]',
+ document, null, 0, null);
+
+ var feeds = [];
+ var item;
+ while (item = result.iterateNext())
+ feeds.push(item.href);
+
+ chromium.extension.connect().postMessage(feeds);
+ }
+}
diff --git a/chrome/test/data/extensions/samples/subscribe/icon.png b/chrome/test/data/extensions/samples/subscribe/icon.png
new file mode 100644
index 0000000..ea1997f
--- /dev/null
+++ b/chrome/test/data/extensions/samples/subscribe/icon.png
Binary files differ
diff --git a/chrome/test/data/extensions/samples/subscribe/icon_disabled.png b/chrome/test/data/extensions/samples/subscribe/icon_disabled.png
new file mode 100644
index 0000000..f5d7a9c
--- /dev/null
+++ b/chrome/test/data/extensions/samples/subscribe/icon_disabled.png
Binary files differ
diff --git a/chrome/test/data/extensions/samples/subscribe/icon_subscribed.png b/chrome/test/data/extensions/samples/subscribe/icon_subscribed.png
new file mode 100644
index 0000000..8091305
--- /dev/null
+++ b/chrome/test/data/extensions/samples/subscribe/icon_subscribed.png
Binary files differ
diff --git a/chrome/test/data/extensions/samples/subscribe/manifest.json b/chrome/test/data/extensions/samples/subscribe/manifest.json
new file mode 100644
index 0000000..fa98e31
--- /dev/null
+++ b/chrome/test/data/extensions/samples/subscribe/manifest.json
@@ -0,0 +1,22 @@
+{
+ "content_scripts": [
+ {
+ "js": [
+ "feed_finder.js"
+ ],
+ "matches": [
+ "http://*/*"
+ ]
+ }
+ ],
+ "description": "Adds one-click subscription with Google Reader to your toolbar",
+ "id": "8962A8B1A1063945CEDE08181EA28D2D65124E86",
+ "name": "Subscribe in Reader",
+ "permissions": [
+ "http://www.google.com/*"
+ ],
+ "toolstrips": [
+ "toolstrip.html"
+ ],
+ "version": "1.0"
+} \ No newline at end of file
diff --git a/chrome/test/data/extensions/samples/subscribe/toolstrip.html b/chrome/test/data/extensions/samples/subscribe/toolstrip.html
new file mode 100644
index 0000000..98de1b3
--- /dev/null
+++ b/chrome/test/data/extensions/samples/subscribe/toolstrip.html
@@ -0,0 +1,53 @@
+<html>
+<link rel="stylesheet" type="text/css" href="extensions_toolstrip.css">
+<div id="button" class="toolstrip-button">
+ <img id="icon" src="icon_disabled.png"><span>Subscribe</span>
+</div>
+
+<script>
+ var icon = document.getElementById("icon");
+ var button = document.getElementById("button");
+ var enabled = false;
+ var feedUrl, req;
+
+ button.onclick = handleClick;
+
+ chromium.self.onConnect.addListener(function(port) {
+ port.onMessage.addListener(function(feedUrls) {
+ // TODO(aa): When we have the ability to display drop downs, we should let
+ // the user pick which feed to subscribe. Right now, we just pick the
+ // first.
+ feedUrl = feedUrls[0];
+ if (!feedUrl) {
+ icon.src = "icon_disabled.png";
+ enabled = false;
+ } else {
+ icon.src = "icon.png";
+ enabled = true;
+
+ feedUrl = encodeURIComponent(feedUrl);
+ req = new XMLHttpRequest();
+ req.onload = handleResponse;
+ req.open("GET",
+ "http://www.google.com/reader/api/0/subscribed?s=feed%2F" + feedUrl,
+ false);
+ req.send(null);
+ }
+ });
+ });
+
+ function handleResponse() {
+ if (req.responseText == "true") {
+ icon.src = "icon_subscribed.png";
+ enabled = false;
+ }
+ }
+
+ function handleClick() {
+ if (enabled) {
+ var url = "http://www.google.com/reader/view/feed/" + feedUrl;
+ chromium.tabs.createTab({url: url});
+ }
+ }
+</script>
+</html>
diff --git a/chrome/test/data/extensions/test/TabsAPI/1/manifest.json b/chrome/test/data/extensions/test/TabsAPI/1/manifest.json
index b4b5e4d..12c530d 100644
--- a/chrome/test/data/extensions/test/TabsAPI/1/manifest.json
+++ b/chrome/test/data/extensions/test/TabsAPI/1/manifest.json
@@ -1,8 +1,5 @@
{
- "id": "1234567890123456789012345678901234567890",
"name": "TabsAPI",
"description": "Utility for working with the extension tabs api",
- "version": "0.1",
- "format_version": 1,
- "toolstrips": ["tabs_api.html"]
+ "version": "0.1"
}
diff --git a/chrome/tools/extensions/chromium_extension.py b/chrome/tools/extensions/chromium_extension.py
index 81e4662..f6ecebc4 100755
--- a/chrome/tools/extensions/chromium_extension.py
+++ b/chrome/tools/extensions/chromium_extension.py
@@ -10,6 +10,7 @@ import hashlib
import logging
import optparse
import os
+import random
import re
import shutil
import sys
@@ -53,10 +54,23 @@ class ExtensionDir:
if not self.validate():
return False
try:
- f = open(os.path.join(self._root, MANIFEST_FILENAME))
+ f = open(os.path.join(self._root, MANIFEST_FILENAME), "r")
manifest = json.load(f)
f.close()
+ # Temporary hack: If the manifest doesn't have an ID, generate a random
+ # one. This is to make it easier for people to play with the extension
+ # system while we don't have the real ID mechanism in place.
+ if not "id" in manifest:
+ random_id = ""
+ for i in range(0, 40):
+ random_id += "0123456789ABCDEF"[random.randrange(0, 15)]
+ logging.info("Generated extension ID: %s" % random_id)
+ manifest["id"] = random_id;
+ f = open(os.path.join(self._root, MANIFEST_FILENAME), "w")
+ f.write(json.dumps(manifest, sort_keys=True, indent=2));
+ f.close();
+
zip_path = path + ".zip"
if os.path.exists(zip_path):
os.remove(zip_path)