[Extensions Docs] Remove old examples
The new doc site forked all the examples into a new repo (outside of
Chromium). Remove the old examples.
One of these examples (the calculator app) was used in a browsertest.
Move it to chrome/test/data/extensions, and the test to
chrome/browser/extensions.
Bug: 1161364
Change-Id: Ieaaa062455cddfe8c21974cf7e640fa88141e835
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2602446
Commit-Queue: Devlin <rdevlin.cronin@chromium.org>
Reviewed-by: Karan Bhatia <karandeepb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#840761}
diff --git a/WATCHLISTS b/WATCHLISTS
index 6d9bfd58..54b418be9 100644
--- a/WATCHLISTS
+++ b/WATCHLISTS
@@ -767,9 +767,6 @@
'|device/bluetooth/chromeos/'\
'|ui/webui/resources/cr_components/chromeos/bluetooth*'
},
- 'chromeos_calculator': {
- 'filepath': 'chrome/common/extensions/docs/examples/apps/calculator/',
- },
'chromeos_cellular': {
'filepath': 'chrome/browser/resources/chromeos/cellular_setup/|'\
'chrome/browser/ui/webui/chromeos/cellular_setup/|'\
@@ -2394,7 +2391,6 @@
'chromeos_attestation': ['dkrahn+watch@chromium.org'],
'chromeos_bluetooth': ['hansberry+watch-bluetooth@chromium.org',
'vecore+watch-bluetooth@google.com'],
- 'chromeos_calculator': ['dharcourt@chromium.org'],
'chromeos_cellular': ['azeemarshad+watch-cellular@chromium.org',
'benchan+watch-cellular@chromium.org',
'ejcaruso+watch-cellular@chromium.org',
diff --git a/chrome/browser/extensions/calculator_app_browsertest.cc b/chrome/browser/extensions/calculator_app_browsertest.cc
new file mode 100644
index 0000000..ce4a7bd
--- /dev/null
+++ b/chrome/browser/extensions/calculator_app_browsertest.cc
@@ -0,0 +1,35 @@
+// Copyright (c) 2012 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.
+
+#include "base/files/file_path.h"
+#include "base/path_service.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/tabs/tab_strip_model.h"
+#include "chrome/common/chrome_paths.h"
+#include "chrome/test/base/in_process_browser_test.h"
+#include "chrome/test/base/ui_test_utils.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/test/browser_test.h"
+#include "content/public/test/browser_test_utils.h"
+#include "net/base/filename_util.h"
+
+class CalculatorBrowserTest : public InProcessBrowserTest {};
+
+IN_PROC_BROWSER_TEST_F(CalculatorBrowserTest, Model) {
+ base::FilePath test_file;
+ base::PathService::Get(chrome::DIR_TEST_DATA, &test_file);
+ test_file =
+ test_file.AppendASCII("extensions/calculator_app/tests/automatic.html");
+
+ ui_test_utils::NavigateToURL(browser(), net::FilePathToFileURL(test_file));
+
+ bool success;
+ bool executed = content::ExecuteScriptAndExtractBool(
+ browser()->tab_strip_model()->GetActiveWebContents(),
+ "window.domAutomationController.send(window.runTests().success)",
+ &success);
+
+ ASSERT_TRUE(executed);
+ ASSERT_TRUE(success);
+}
diff --git a/chrome/browser/extensions/docs/examples/apps/calculator_browsertest.cc b/chrome/browser/extensions/docs/examples/apps/calculator_browsertest.cc
deleted file mode 100644
index 3969068..0000000
--- a/chrome/browser/extensions/docs/examples/apps/calculator_browsertest.cc
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright (c) 2012 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.
-
-#include "base/files/file_path.h"
-#include "base/path_service.h"
-#include "chrome/browser/ui/browser.h"
-#include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_paths.h"
-#include "chrome/test/base/in_process_browser_test.h"
-#include "chrome/test/base/ui_test_utils.h"
-#include "content/public/browser/web_contents.h"
-#include "content/public/test/browser_test.h"
-#include "content/public/test/browser_test_utils.h"
-#include "net/base/filename_util.h"
-
-class CalculatorBrowserTest : public InProcessBrowserTest {
-};
-
-IN_PROC_BROWSER_TEST_F(CalculatorBrowserTest, Model) {
- base::FilePath test_file;
- base::PathService::Get(chrome::DIR_TEST_DATA, &test_file);
- test_file = test_file.DirName().DirName()
- .AppendASCII("common").AppendASCII("extensions").AppendASCII("docs")
- .AppendASCII("examples").AppendASCII("apps").AppendASCII("calculator")
- .AppendASCII("tests").AppendASCII("automatic.html");
-
- ui_test_utils::NavigateToURL(browser(), net::FilePathToFileURL(test_file));
-
- bool success;
- bool executed = content::ExecuteScriptAndExtractBool(
- browser()->tab_strip_model()->GetActiveWebContents(),
- "window.domAutomationController.send(window.runTests().success)",
- &success);
-
- ASSERT_TRUE(executed);
- ASSERT_TRUE(success);
-}
diff --git a/chrome/common/extensions/docs/examples/README.chromium b/chrome/common/extensions/docs/examples/README.chromium
deleted file mode 100644
index 034abed..0000000
--- a/chrome/common/extensions/docs/examples/README.chromium
+++ /dev/null
@@ -1,5 +0,0 @@
-Name: Extensions examples
-URL: None
-License: Apache 2.0, MIT, X11, BSD, and GPL v2 licenses
-License File: NOT_SHIPPED
-Security Critical: no
diff --git a/chrome/common/extensions/docs/examples/README.txt b/chrome/common/extensions/docs/examples/README.txt
deleted file mode 100644
index de6e8e3..0000000
--- a/chrome/common/extensions/docs/examples/README.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-Chromium Extension Examples
-
-The directory structure is as follows:
-* api/ - trivial extensions focused on a single API package
-* howto/ - simple extensions showing how to perform a particular task
-* tutorials/ - multi-step walkthroughs referenced inline in the docs
-* extensions/ - full featured extensions spanning multiple API packages
diff --git a/chrome/common/extensions/docs/examples/api/bookmarks/basic/icon.png b/chrome/common/extensions/docs/examples/api/bookmarks/basic/icon.png
deleted file mode 100644
index ea42f3f..0000000
--- a/chrome/common/extensions/docs/examples/api/bookmarks/basic/icon.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/bookmarks/basic/manifest.json b/chrome/common/extensions/docs/examples/api/bookmarks/basic/manifest.json
deleted file mode 100644
index 2135c3cbf..0000000
--- a/chrome/common/extensions/docs/examples/api/bookmarks/basic/manifest.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "name": "My Bookmarks",
- "version": "1.1",
- "description": "A browser action with a popup dump of all bookmarks, including search, add, edit and delete.",
- "permissions": [
- "bookmarks"
- ],
- "browser_action": {
- "default_title": "My Bookmarks",
- "default_icon": "icon.png",
- "default_popup": "popup.html"
- },
- "manifest_version": 2,
- "content_security_policy": "script-src 'self' https://ajax.googleapis.com; object-src 'self'"
-}
diff --git a/chrome/common/extensions/docs/examples/api/bookmarks/basic/popup.html b/chrome/common/extensions/docs/examples/api/bookmarks/basic/popup.html
deleted file mode 100644
index 2a3370b..0000000
--- a/chrome/common/extensions/docs/examples/api/bookmarks/basic/popup.html
+++ /dev/null
@@ -1,13 +0,0 @@
-<html>
-<head>
- <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
- <script src="popup.js"></script>
-</head>
-<body style="width: 400px">
- <div>Search Bookmarks: <input id="search"></div>
- <div id="bookmarks"></div>
- <div id="editdialog"></div>
- <div id="deletedialog"></div>
- <div id="adddialog"></div>
-</body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/api/bookmarks/basic/popup.js b/chrome/common/extensions/docs/examples/api/bookmarks/basic/popup.js
deleted file mode 100644
index ca72daaf..0000000
--- a/chrome/common/extensions/docs/examples/api/bookmarks/basic/popup.js
+++ /dev/null
@@ -1,128 +0,0 @@
-// Copyright (c) 2012 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.
-
-// Search the bookmarks when entering the search keyword.
-$(function() {
- $('#search').change(function() {
- $('#bookmarks').empty();
- dumpBookmarks($('#search').val());
- });
-});
-// Traverse the bookmark tree, and print the folder and nodes.
-function dumpBookmarks(query) {
- var bookmarkTreeNodes = chrome.bookmarks.getTree(
- function(bookmarkTreeNodes) {
- $('#bookmarks').append(dumpTreeNodes(bookmarkTreeNodes, query));
- });
-}
-function dumpTreeNodes(bookmarkNodes, query) {
- var list = $('<ul>');
- var i;
- for (i = 0; i < bookmarkNodes.length; i++) {
- list.append(dumpNode(bookmarkNodes[i], query));
- }
- return list;
-}
-function dumpNode(bookmarkNode, query) {
- if (bookmarkNode.title) {
- if (query && !bookmarkNode.children) {
- if (String(bookmarkNode.title).indexOf(query) == -1) {
- return $('<span></span>');
- }
- }
- var anchor = $('<a>');
- anchor.attr('href', bookmarkNode.url);
- anchor.text(bookmarkNode.title);
- /*
- * When clicking on a bookmark in the extension, a new tab is fired with
- * the bookmark url.
- */
- anchor.click(function() {
- chrome.tabs.create({url: bookmarkNode.url});
- });
- var span = $('<span>');
- var options = bookmarkNode.children ?
- $('<span>[<a href="#" id="addlink">Add</a>]</span>') :
- $('<span>[<a id="editlink" href="#">Edit</a> <a id="deletelink" ' +
- 'href="#">Delete</a>]</span>');
- var edit = bookmarkNode.children ? $('<table><tr><td>Name</td><td>' +
- '<input id="title"></td></tr><tr><td>URL</td><td><input id="url">' +
- '</td></tr></table>') : $('<input>');
- // Show add and edit links when hover over.
- span.hover(function() {
- span.append(options);
- $('#deletelink').click(function() {
- $('#deletedialog').empty().dialog({
- autoOpen: false,
- title: 'Confirm Deletion',
- resizable: false,
- height: 140,
- modal: true,
- overlay: {
- backgroundColor: '#000',
- opacity: 0.5
- },
- buttons: {
- 'Yes, Delete It!': function() {
- chrome.bookmarks.remove(String(bookmarkNode.id));
- span.parent().remove();
- $(this).dialog('destroy');
- },
- Cancel: function() {
- $(this).dialog('destroy');
- }
- }
- }).dialog('open');
- });
- $('#addlink').click(function() {
- $('#adddialog').empty().append(edit).dialog({autoOpen: false,
- closeOnEscape: true, title: 'Add New Bookmark', modal: true,
- buttons: {
- 'Add' : function() {
- chrome.bookmarks.create({parentId: bookmarkNode.id,
- title: $('#title').val(), url: $('#url').val()});
- $('#bookmarks').empty();
- $(this).dialog('destroy');
- window.dumpBookmarks();
- },
- 'Cancel': function() {
- $(this).dialog('destroy');
- }
- }}).dialog('open');
- });
- $('#editlink').click(function() {
- edit.val(anchor.text());
- $('#editdialog').empty().append(edit).dialog({autoOpen: false,
- closeOnEscape: true, title: 'Edit Title', modal: true,
- show: 'slide', buttons: {
- 'Save': function() {
- chrome.bookmarks.update(String(bookmarkNode.id), {
- title: edit.val()
- });
- anchor.text(edit.val());
- options.show();
- $(this).dialog('destroy');
- },
- 'Cancel': function() {
- $(this).dialog('destroy');
- }
- }}).dialog('open');
- });
- options.fadeIn();
- },
- // unhover
- function() {
- options.remove();
- }).append(anchor);
- }
- var li = $(bookmarkNode.title ? '<li>' : '<div>').append(span);
- if (bookmarkNode.children && bookmarkNode.children.length > 0) {
- li.append(dumpTreeNodes(bookmarkNode.children, query));
- }
- return li;
-}
-
-document.addEventListener('DOMContentLoaded', function () {
- dumpBookmarks();
-});
diff --git a/chrome/common/extensions/docs/examples/api/browserAction/make_page_red/background.js b/chrome/common/extensions/docs/examples/api/browserAction/make_page_red/background.js
deleted file mode 100644
index 80f6ec79..0000000
--- a/chrome/common/extensions/docs/examples/api/browserAction/make_page_red/background.js
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) 2011 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.
-
-// Called when the user clicks on the browser action.
-chrome.browserAction.onClicked.addListener(function(tab) {
- // No tabs or host permissions needed!
- console.log('Turning ' + tab.url + ' red!');
- chrome.tabs.executeScript({
- code: 'document.body.style.backgroundColor="red"'
- });
-});
diff --git a/chrome/common/extensions/docs/examples/api/browserAction/make_page_red/manifest.json b/chrome/common/extensions/docs/examples/api/browserAction/make_page_red/manifest.json
deleted file mode 100644
index b901108..0000000
--- a/chrome/common/extensions/docs/examples/api/browserAction/make_page_red/manifest.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
- "name": "Page Redder",
- "description": "Make the current page red",
- "version": "2.0",
- "permissions": [
- "activeTab"
- ],
- "background": {
- "scripts": ["background.js"],
- "persistent": false
- },
- "browser_action": {
- "default_title": "Make this page red"
- },
- "manifest_version": 2
-}
diff --git a/chrome/common/extensions/docs/examples/api/browserAction/print/background.js b/chrome/common/extensions/docs/examples/api/browserAction/print/background.js
deleted file mode 100644
index 92209e1..0000000
--- a/chrome/common/extensions/docs/examples/api/browserAction/print/background.js
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright (c) 2012 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.
-
-// Called when the user clicks on the browser action.
-chrome.browserAction.onClicked.addListener(function(tab) {
- chrome.tabs.executeScript(
- tab.id,
- {code: 'window.print();'});
-});
diff --git a/chrome/common/extensions/docs/examples/api/browserAction/print/manifest.json b/chrome/common/extensions/docs/examples/api/browserAction/print/manifest.json
deleted file mode 100644
index e6feef4..0000000
--- a/chrome/common/extensions/docs/examples/api/browserAction/print/manifest.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- "name": "Print this page",
- "description": "Adds a print button to the browser.",
- "version": "1.2",
- "background": {
- "scripts": ["background.js"],
- "persistent": false
- },
- "permissions": [
- "activeTab"
- ],
- "browser_action": {
- "default_title": "Print this page",
- "default_icon": "print_16x16.png"
- },
- "manifest_version": 2
-}
diff --git a/chrome/common/extensions/docs/examples/api/browserAction/print/print_16x16.png b/chrome/common/extensions/docs/examples/api/browserAction/print/print_16x16.png
deleted file mode 100644
index 360c8eb..0000000
--- a/chrome/common/extensions/docs/examples/api/browserAction/print/print_16x16.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/browserAction/set_icon_path/background.js b/chrome/common/extensions/docs/examples/api/browserAction/set_icon_path/background.js
deleted file mode 100644
index 9289794..0000000
--- a/chrome/common/extensions/docs/examples/api/browserAction/set_icon_path/background.js
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 2011 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.
-
-'use strict';
-
-chrome.runtime.onInstalled.addListener(function() {
- chrome.storage.sync.set({number: 1}, function() {
- console.log('The number is set to 1.');
- });
-});
-
-function updateIcon() {
- chrome.storage.sync.get('number', function(data) {
- var current = data.number;
- chrome.browserAction.setIcon({path: 'icon' + current + '.png'});
- current++;
- if (current > 5)
- current = 1;
- chrome.storage.sync.set({number: current}, function() {
- console.log('The number is set to ' + current);
- });
- });
-};
-
-chrome.browserAction.onClicked.addListener(updateIcon);
-updateIcon();
diff --git a/chrome/common/extensions/docs/examples/api/browserAction/set_icon_path/icon1.png b/chrome/common/extensions/docs/examples/api/browserAction/set_icon_path/icon1.png
deleted file mode 100644
index ea42f3f..0000000
--- a/chrome/common/extensions/docs/examples/api/browserAction/set_icon_path/icon1.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/browserAction/set_icon_path/icon2.png b/chrome/common/extensions/docs/examples/api/browserAction/set_icon_path/icon2.png
deleted file mode 100644
index da75c5f..0000000
--- a/chrome/common/extensions/docs/examples/api/browserAction/set_icon_path/icon2.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/browserAction/set_icon_path/icon3.png b/chrome/common/extensions/docs/examples/api/browserAction/set_icon_path/icon3.png
deleted file mode 100644
index a60a52d..0000000
--- a/chrome/common/extensions/docs/examples/api/browserAction/set_icon_path/icon3.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/browserAction/set_icon_path/icon4.png b/chrome/common/extensions/docs/examples/api/browserAction/set_icon_path/icon4.png
deleted file mode 100644
index 217e30f..0000000
--- a/chrome/common/extensions/docs/examples/api/browserAction/set_icon_path/icon4.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/browserAction/set_icon_path/icon5.png b/chrome/common/extensions/docs/examples/api/browserAction/set_icon_path/icon5.png
deleted file mode 100644
index 32dfa18..0000000
--- a/chrome/common/extensions/docs/examples/api/browserAction/set_icon_path/icon5.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/browserAction/set_icon_path/manifest.json b/chrome/common/extensions/docs/examples/api/browserAction/set_icon_path/manifest.json
deleted file mode 100644
index 597e0036..0000000
--- a/chrome/common/extensions/docs/examples/api/browserAction/set_icon_path/manifest.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "name": "A browser action which changes its icon when clicked",
- "description": "Click browser action icon to change color!",
- "version": "1.3",
- "background": {
- "scripts": ["background.js"],
- "persistent": false
- },
- "permissions": ["storage"],
- "browser_action": {
- "name": "Click to change the icon's color"
- },
- "manifest_version": 2
-}
diff --git a/chrome/common/extensions/docs/examples/api/browserAction/set_page_color/icon.png b/chrome/common/extensions/docs/examples/api/browserAction/set_page_color/icon.png
deleted file mode 100644
index 46819c7..0000000
--- a/chrome/common/extensions/docs/examples/api/browserAction/set_page_color/icon.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/browserAction/set_page_color/manifest.json b/chrome/common/extensions/docs/examples/api/browserAction/set_page_color/manifest.json
deleted file mode 100644
index cecb2bc..0000000
--- a/chrome/common/extensions/docs/examples/api/browserAction/set_page_color/manifest.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "name": "A browser action with a popup that changes the page color",
- "description": "Change the current page color",
- "version": "1.0",
- "permissions": [
- "activeTab"
- ],
- "browser_action": {
- "default_title": "Set this page's color.",
- "default_icon": "icon.png",
- "default_popup": "popup.html"
- },
- "manifest_version": 2
-}
diff --git a/chrome/common/extensions/docs/examples/api/browserAction/set_page_color/popup.html b/chrome/common/extensions/docs/examples/api/browserAction/set_page_color/popup.html
deleted file mode 100644
index bf1b42b..0000000
--- a/chrome/common/extensions/docs/examples/api/browserAction/set_page_color/popup.html
+++ /dev/null
@@ -1,55 +0,0 @@
-<!doctype html>
-<html>
- <head>
- <title>Set Page Color Popup</title>
- <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-family: sans-serif;
- font-size: 0.8em;
- 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 src="popup.js"></script>
- </head>
- <body>
- <div id="red">red</div>
- <div id="blue">blue</div>
- <div id="green">green</div>
- <div id="yellow">yellow</div>
- </body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/api/browserAction/set_page_color/popup.js b/chrome/common/extensions/docs/examples/api/browserAction/set_page_color/popup.js
deleted file mode 100644
index 3c04801..0000000
--- a/chrome/common/extensions/docs/examples/api/browserAction/set_page_color/popup.js
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright (c) 2012 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.
-
-'use strict';
-
-function click(e) {
- chrome.tabs.executeScript(null,
- {code:"document.body.style.backgroundColor='" + e.target.id + "'"});
- window.close();
-}
-
-document.addEventListener('DOMContentLoaded', function () {
- var divs = document.querySelectorAll('div');
- for (var i = 0; i < divs.length; i++) {
- divs[i].addEventListener('click', click);
- }
-});
diff --git a/chrome/common/extensions/docs/examples/api/browsingData/basic/icon.png b/chrome/common/extensions/docs/examples/api/browsingData/basic/icon.png
deleted file mode 100644
index 8a72625..0000000
--- a/chrome/common/extensions/docs/examples/api/browsingData/basic/icon.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/browsingData/basic/manifest.json b/chrome/common/extensions/docs/examples/api/browsingData/basic/manifest.json
deleted file mode 100644
index d228729..0000000
--- a/chrome/common/extensions/docs/examples/api/browsingData/basic/manifest.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "name" : "BrowsingData API: Basics",
- "version" : "1.1",
- "description" : "A trivial usage example.",
- "permissions": [
- "browsingData"
- ],
- "browser_action": {
- "default_icon": "icon.png",
- "default_popup": "popup.html"
- },
- "manifest_version": 2
-}
diff --git a/chrome/common/extensions/docs/examples/api/browsingData/basic/popup.css b/chrome/common/extensions/docs/examples/api/browsingData/basic/popup.css
deleted file mode 100644
index 52b1af4..0000000
--- a/chrome/common/extensions/docs/examples/api/browsingData/basic/popup.css
+++ /dev/null
@@ -1,72 +0,0 @@
-/**
- * Copyright (c) 2012 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.
- */
-
-body {
- margin: 5px 10px 10px;
-}
-
-h1 {
- color: #53637D;
- font: 26px/1.2 Helvetica, sans-serif;
- font-size: 200%;
- margin: 0;
- padding-bottom: 4px;
- text-shadow: white 0 1px 2px;
-}
-
-label {
- color: #222;
- font: 18px/1.4 Helvetica, sans-serif;
- margin: 0.5em 0;
- display: inline-block;
-}
-
-form {
- transition: transform 0.25s ease;
- width: 563px;
-}
-
-button {
- display: block;
- border-radius: 2px;
- box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.1);
- -webkit-user-select: none;
- background: -webkit-linear-gradient(#FAFAFA, #F4F4F4 40%, #E5E5E5);
- border: 1px solid #AAA;
- color: #444;
- margin-bottom: 0;
- min-width: 4em;
- padding: 3px 12px;
- margin-top: 0;
- font-size: 1.1em;
-}
-
-.overlay {
- display: block;
- text-align: center;
- position: absolute;
- left: 50%;
- top: 50%;
- width: 500px;
- padding: 20px;
- margin: -40px 0 0 -270px;
- opacity: 0;
- background: rgba(0, 0, 0, 0.75);
- border-radius: 5px;
- color: #FFF;
- font: 1.5em/1.2 Helvetica Neue, sans-serif;
- transition: all 1.0s ease;
- transform: scale(0);
-}
-
-.overlay a {
- color: #FFF;
-}
-
-.overlay.visible {
- opacity: 1;
- transform: scale(1);
-}
diff --git a/chrome/common/extensions/docs/examples/api/browsingData/basic/popup.html b/chrome/common/extensions/docs/examples/api/browsingData/basic/popup.html
deleted file mode 100644
index 64ed40e..0000000
--- a/chrome/common/extensions/docs/examples/api/browsingData/basic/popup.html
+++ /dev/null
@@ -1,24 +0,0 @@
-<!DOCTYPE html>
-<html>
- <head>
- <title>Popup</title>
- <link href="popup.css" rel="stylesheet">
- <script src="popup.js"></script>
- </head>
- <body>
- <h1>BrowsingData API Sample</h1>
- <div role="main">
- <form>
- <label for="timeframe">Remove all browsing data from:</label>
- <select id="timeframe">
- <option value="hour">the past hour</option>
- <option value="day">the past day</option>
- <option value="week">the past week</option>
- <option value="4weeks">the past four weeks</option>
- <option value="forever">the beginning of time</option>
- </select>
- <button id="button">OBLITERATE!</button>
- </form>
- </div>
- </body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/api/browsingData/basic/popup.js b/chrome/common/extensions/docs/examples/api/browsingData/basic/popup.js
deleted file mode 100644
index ee7b2654..0000000
--- a/chrome/common/extensions/docs/examples/api/browsingData/basic/popup.js
+++ /dev/null
@@ -1,137 +0,0 @@
-// Copyright (c) 2012 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.
-
-/**
- * This class wraps the popup's form, and performs the proper clearing of data
- * based on the user's selections. It depends on the form containing a single
- * select element with an id of 'timeframe', and a single button with an id of
- * 'button'. When you write actual code you should probably be a little more
- * accepting of variance, but this is just a sample app. :)
- *
- * Most of this is boilerplate binding the controller to the UI. The bits that
- * specifically will be useful when using the BrowsingData API are contained in
- * `parseMilliseconds_`, `handleCallback_`, and `handleClick_`.
- *
- * @constructor
- */
-var PopupController = function () {
- this.button_ = document.getElementById('button');
- this.timeframe_ = document.getElementById('timeframe');
- this.addListeners_();
-};
-
-PopupController.prototype = {
- /**
- * A cached reference to the button element.
- *
- * @type {Element}
- * @private
- */
- button_: null,
-
- /**
- * A cached reference to the select element.
- *
- * @type {Element}
- * @private
- */
- timeframe_: null,
-
- /**
- * Adds event listeners to the button in order to capture a user's click, and
- * perform some action in response.
- *
- * @private
- */
- addListeners_: function () {
- this.button_.addEventListener('click', this.handleClick_.bind(this));
- },
-
- /**
- * Given a string, return milliseconds since epoch. If the string isn't
- * valid, returns undefined.
- *
- * @param {string} timeframe One of 'hour', 'day', 'week', '4weeks', or
- * 'forever'.
- * @returns {number} Milliseconds since epoch.
- * @private
- */
- parseMilliseconds_: function (timeframe) {
- var now = new Date().getTime();
- var milliseconds = {
- 'hour': 60 * 60 * 1000,
- 'day': 24 * 60 * 60 * 1000,
- 'week': 7 * 24 * 60 * 60 * 1000,
- '4weeks': 4 * 7 * 24 * 60 * 60 * 1000
- };
-
- if (milliseconds[timeframe])
- return now - milliseconds[timeframe];
-
- if (timeframe === 'forever')
- return 0;
-
- return null;
- },
-
- /**
- * Handle a success/failure callback from the `browsingData` API methods,
- * updating the UI appropriately.
- *
- * @private
- */
- handleCallback_: function () {
- var success = document.createElement('div');
- success.classList.add('overlay');
- success.setAttribute('role', 'alert');
- success.textContent = 'Data has been cleared.';
- document.body.appendChild(success);
-
- setTimeout(function() { success.classList.add('visible'); }, 10);
- setTimeout(function() {
- if (close === false)
- success.classList.remove('visible');
- else
- window.close();
- }, 4000);
- },
-
- /**
- * When a user clicks the button, this method is called: it reads the current
- * state of `timeframe_` in order to pull a timeframe, then calls the clearing
- * method with appropriate arguments.
- *
- * @private
- */
- handleClick_: function () {
- var removal_start = this.parseMilliseconds_(this.timeframe_.value);
- if (removal_start !== undefined) {
- this.button_.setAttribute('disabled', 'disabled');
- this.button_.innerText = 'Clearing...';
- chrome.browsingData.remove(
- {'since': removal_start}, {
- 'appcache': true,
- 'cache': true,
- 'cacheStorage': true,
- 'cookies': true,
- 'downloads': true,
- 'fileSystems': true,
- 'formData': true,
- 'history': true,
- 'indexedDB': true,
- 'localStorage': true,
- 'serverBoundCertificates': true,
- 'serviceWorkers': true,
- 'pluginData': true,
- 'passwords': true,
- 'webSQL': true
- },
- this.handleCallback_.bind(this));
- }
- }
-};
-
-document.addEventListener('DOMContentLoaded', function () {
- window.PC = new PopupController();
-});
diff --git a/chrome/common/extensions/docs/examples/api/commands/background.js b/chrome/common/extensions/docs/examples/api/commands/background.js
deleted file mode 100644
index 5661f24..0000000
--- a/chrome/common/extensions/docs/examples/api/commands/background.js
+++ /dev/null
@@ -1,7 +0,0 @@
-// Copyright (c) 2012 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.
-
-chrome.commands.onCommand.addListener(function(command) {
- console.log('onCommand event received for message: ', command);
-});
diff --git a/chrome/common/extensions/docs/examples/api/commands/browser_action.html b/chrome/common/extensions/docs/examples/api/commands/browser_action.html
deleted file mode 100644
index 499473a..0000000
--- a/chrome/common/extensions/docs/examples/api/commands/browser_action.html
+++ /dev/null
@@ -1 +0,0 @@
-This is a sample browser action popup.
\ No newline at end of file
diff --git a/chrome/common/extensions/docs/examples/api/commands/manifest.json b/chrome/common/extensions/docs/examples/api/commands/manifest.json
deleted file mode 100644
index a22622c..0000000
--- a/chrome/common/extensions/docs/examples/api/commands/manifest.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
- "name": "Sample Extension Commands extension",
- "description": "Press Ctrl+Shift+F to open the browser action popup, press Ctrl+Shift+Y to send an event.",
- "version": "1.0",
- "manifest_version": 2,
- "background": {
- "scripts": ["background.js"],
- "persistent": false
- },
- "browser_action": {
- "default_popup": "browser_action.html"
- },
- "commands": {
- "toggle-feature": {
- "suggested_key": {
- "default": "Ctrl+Shift+Y",
- "mac": "MacCtrl+Shift+Y"
- },
- "description": "Send a 'toggle-feature' event to the extension"
- },
- "_execute_browser_action": {
- "suggested_key": {
- "default": "Ctrl+Shift+F",
- "mac": "MacCtrl+Shift+F"
- }
- }
- }
-}
diff --git a/chrome/common/extensions/docs/examples/api/contentSettings/contentSettings.png b/chrome/common/extensions/docs/examples/api/contentSettings/contentSettings.png
deleted file mode 100644
index 80657a9..0000000
--- a/chrome/common/extensions/docs/examples/api/contentSettings/contentSettings.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/contentSettings/manifest.json b/chrome/common/extensions/docs/examples/api/contentSettings/manifest.json
deleted file mode 100644
index adf1daef..0000000
--- a/chrome/common/extensions/docs/examples/api/contentSettings/manifest.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "name" : "Content settings",
- "version" : "0.2",
- "description" : "Shows the content settings for the current site.",
- "permissions": [ "contentSettings", "tabs" ],
- "browser_action": {
- "default_icon": "contentSettings.png",
- "default_popup": "popup.html"
- },
- "manifest_version": 2
-}
diff --git a/chrome/common/extensions/docs/examples/api/contentSettings/popup.html b/chrome/common/extensions/docs/examples/api/contentSettings/popup.html
deleted file mode 100644
index ae2be39..0000000
--- a/chrome/common/extensions/docs/examples/api/contentSettings/popup.html
+++ /dev/null
@@ -1,80 +0,0 @@
-<!DOCTYPE html>
-<html>
- <head>
- <title>Popup</title>
- <style>
- dt { white-space: nowrap }
- </style>
- <script src="popup.js"></script>
- </head>
- <body>
- <fieldset>
- <dl>
- <dt><label for="cookies">Cookies: </label></dt>
- <dd><select id="cookies" disabled>
- <option value="allow">Allow</option>
- <option value="session_only">Session only</option>
- <option value="block">Block</option>
- </select></dd>
- <dt><label for="images">Images: </label></dt>
- <dd><select id="images" disabled>
- <option value="allow">Allow</option>
- <option value="block">Block</option>
- </select>
- <dt><label for="javascript">Javascript: </label></dt>
- <dd><select id="javascript" disabled>
- <option value="allow">Allow</option>
- <option value="block">Block</option>
- </select></dd>
- <dt><label for="location">Location: </label></dt>
- <dd><select id="location" disabled>
- <option value="allow">Allow</option>
- <option value="ask">Ask</option>
- <option value="block">Block</option>
- </select></dd>
- <dt><label for="plugins">Plugins: </label></dt>
- <dd><select id="plugins" disabled>
- <option value="allow">Allow</option>
- <option value="block">Block</option>
- </select></dd>
- <dt><label for="popups">Pop-ups: </label></dt>
- <dd><select id="popups" disabled>
- <option value="allow">Allow</option>
- <option value="block">Block</option>
- </select></dd>
- <dt><label for="notifications">Notifications: </label></dt>
- <dd><select id="notifications" disabled>
- <option value="allow">Allow</option>
- <option value="ask">Ask</option>
- <option value="block">Block</option>
- </select></dd>
- <dt><label for="microphone">Microphone: </label></dt>
- <dd><select id="microphone" disabled>
- <option value="allow">Allow</option>
- <option value="ask">Ask</option>
- <option value="block">Block</option>
- </select></dd>
- <dt><label for="camera">Camera: </label></dt>
- <dd><select id="camera" disabled>
- <option value="allow">Allow</option>
- <option value="ask">Ask</option>
- <option value="block">Block</option>
- </select></dd>
- <dt><label for="unsandboxedPlugins">Unsandboxed plugin access: </label></dt>
- <dd><select id="unsandboxedPlugins" disabled>
- <option value="allow">Allow</option>
- <option value="ask">Ask</option>
- <option value="block">Block</option>
- </select></dd>
- <dt><label for="automaticDownloads">Automatic Downloads: </label></dt>
- <dd><select id="automaticDownloads" disabled>
- <option value="allow">Allow</option>
- <option value="ask">Ask</option>
- <option value="block">Block</option>
- </select></dd>
- </dl>
- </fieldset>
-
-
- </body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/api/contentSettings/popup.js b/chrome/common/extensions/docs/examples/api/contentSettings/popup.js
deleted file mode 100644
index c623a8c..0000000
--- a/chrome/common/extensions/docs/examples/api/contentSettings/popup.js
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright (c) 2011 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.
-
-var incognito;
-var url;
-
-function settingChanged() {
- var type = this.id;
- var setting = this.value;
- var pattern = /^file:/.test(url) ? url : url.replace(/\/[^\/]*?$/, '/*');
- console.log(type+' setting for '+pattern+': '+setting);
- // HACK: [type] is not recognised by the docserver's sample crawler, so
- // mention an explicit
- // type: chrome.contentSettings.cookies.set - See http://crbug.com/299634
- chrome.contentSettings[type].set({
- 'primaryPattern': pattern,
- 'setting': setting,
- 'scope': (incognito ? 'incognito_session_only' : 'regular')
- });
-}
-
-document.addEventListener('DOMContentLoaded', function () {
- chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
- var current = tabs[0];
- incognito = current.incognito;
- url = current.url;
- var types = [
- 'cookies', 'images', 'javascript', 'location', 'popups', 'notifications',
- 'microphone', 'camera', 'automaticDownloads'
- ];
- types.forEach(function(type) {
- // HACK: [type] is not recognised by the docserver's sample crawler, so
- // mention an explicit
- // type: chrome.contentSettings.cookies.get - See http://crbug.com/299634
- chrome.contentSettings[type] && chrome.contentSettings[type].get({
- 'primaryUrl': url,
- 'incognito': incognito
- },
- function(details) {
- document.getElementById(type).disabled = false;
- document.getElementById(type).value = details.setting;
- });
- });
- });
-
- var selects = document.querySelectorAll('select');
- for (var i = 0; i < selects.length; i++) {
- selects[i].addEventListener('change', settingChanged);
- }
-});
-
diff --git a/chrome/common/extensions/docs/examples/api/contextMenus/basic/manifest.json b/chrome/common/extensions/docs/examples/api/contextMenus/basic/manifest.json
deleted file mode 100644
index c59cec1..0000000
--- a/chrome/common/extensions/docs/examples/api/contextMenus/basic/manifest.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "name": "Context Menus Sample",
- "description": "Shows some of the features of the Context Menus API",
- "version": "0.6",
- "permissions": ["contextMenus"],
- "background": {
- "scripts": ["sample.js"]
- },
- "manifest_version": 2
-}
diff --git a/chrome/common/extensions/docs/examples/api/contextMenus/basic/sample.js b/chrome/common/extensions/docs/examples/api/contextMenus/basic/sample.js
deleted file mode 100644
index be77af0..0000000
--- a/chrome/common/extensions/docs/examples/api/contextMenus/basic/sample.js
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright (c) 2010 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.
-
-// A generic onclick callback function.
-function genericOnClick(info, tab) {
- console.log("item " + info.menuItemId + " was clicked");
- console.log("info: " + JSON.stringify(info));
- console.log("tab: " + JSON.stringify(tab));
-}
-
-// Create one test item for each context type.
-var contexts = ["page","selection","link","editable","image","video",
- "audio"];
-for (var i = 0; i < contexts.length; i++) {
- var context = contexts[i];
- var title = "Test '" + context + "' menu item";
- var id = chrome.contextMenus.create({"title": title, "contexts":[context],
- "onclick": genericOnClick});
- console.log("'" + context + "' item:" + id);
-}
-
-
-// Create a parent item and two children.
-var parent = chrome.contextMenus.create({"title": "Test parent item"});
-var child1 = chrome.contextMenus.create(
- {"title": "Child 1", "parentId": parent, "onclick": genericOnClick});
-var child2 = chrome.contextMenus.create(
- {"title": "Child 2", "parentId": parent, "onclick": genericOnClick});
-console.log("parent:" + parent + " child1:" + child1 + " child2:" + child2);
-
-
-// Create some radio items.
-function radioOnClick(info, tab) {
- console.log("radio item " + info.menuItemId +
- " was clicked (previous checked state was " +
- info.wasChecked + ")");
-}
-var radio1 = chrome.contextMenus.create({"title": "Radio 1", "type": "radio",
- "onclick":radioOnClick});
-var radio2 = chrome.contextMenus.create({"title": "Radio 2", "type": "radio",
- "onclick":radioOnClick});
-console.log("radio1:" + radio1 + " radio2:" + radio2);
-
-
-// Create some checkbox items.
-function checkboxOnClick(info, tab) {
- console.log(JSON.stringify(info));
- console.log("checkbox item " + info.menuItemId +
- " was clicked, state is now: " + info.checked +
- "(previous state was " + info.wasChecked + ")");
-
-}
-var checkbox1 = chrome.contextMenus.create(
- {"title": "Checkbox1", "type": "checkbox", "onclick":checkboxOnClick});
-var checkbox2 = chrome.contextMenus.create(
- {"title": "Checkbox2", "type": "checkbox", "onclick":checkboxOnClick});
-console.log("checkbox1:" + checkbox1 + " checkbox2:" + checkbox2);
-
-
-// Intentionally create an invalid item, to show off error checking in the
-// create callback.
-console.log("About to try creating an invalid item - an error about " +
- "item 999 should show up");
-chrome.contextMenus.create({"title": "Oops", "parentId":999}, function() {
- if (chrome.extension.lastError) {
- console.log("Got expected error: " + chrome.extension.lastError.message);
- }
-});
diff --git a/chrome/common/extensions/docs/examples/api/contextMenus/event_page/manifest.json b/chrome/common/extensions/docs/examples/api/contextMenus/event_page/manifest.json
deleted file mode 100644
index 8279823d..0000000
--- a/chrome/common/extensions/docs/examples/api/contextMenus/event_page/manifest.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "name": "Context Menus Sample (with Event Page)",
- "description": "Shows some of the features of the Context Menus API using an event page",
- "version": "0.7",
- "permissions": ["contextMenus"],
- "background": {
- "persistent": false,
- "scripts": ["sample.js"]
- },
- "manifest_version": 2
-}
diff --git a/chrome/common/extensions/docs/examples/api/contextMenus/event_page/sample.js b/chrome/common/extensions/docs/examples/api/contextMenus/event_page/sample.js
deleted file mode 100644
index 227dd0c..0000000
--- a/chrome/common/extensions/docs/examples/api/contextMenus/event_page/sample.js
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright (c) 2012 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.
-
-// The onClicked callback function.
-function onClickHandler(info, tab) {
- if (info.menuItemId == "radio1" || info.menuItemId == "radio2") {
- console.log("radio item " + info.menuItemId +
- " was clicked (previous checked state was " +
- info.wasChecked + ")");
- } else if (info.menuItemId == "checkbox1" || info.menuItemId == "checkbox2") {
- console.log(JSON.stringify(info));
- console.log("checkbox item " + info.menuItemId +
- " was clicked, state is now: " + info.checked +
- " (previous state was " + info.wasChecked + ")");
-
- } else {
- console.log("item " + info.menuItemId + " was clicked");
- console.log("info: " + JSON.stringify(info));
- console.log("tab: " + JSON.stringify(tab));
- }
-};
-
-chrome.contextMenus.onClicked.addListener(onClickHandler);
-
-// Set up context menu tree at install time.
-chrome.runtime.onInstalled.addListener(function() {
- // Create one test item for each context type.
- var contexts = ["page","selection","link","editable","image","video",
- "audio"];
- for (var i = 0; i < contexts.length; i++) {
- var context = contexts[i];
- var title = "Test '" + context + "' menu item";
- var id = chrome.contextMenus.create({"title": title, "contexts":[context],
- "id": "context" + context});
- console.log("'" + context + "' item:" + id);
- }
-
- // Create a parent item and two children.
- chrome.contextMenus.create({"title": "Test parent item", "id": "parent"});
- chrome.contextMenus.create(
- {"title": "Child 1", "parentId": "parent", "id": "child1"});
- chrome.contextMenus.create(
- {"title": "Child 2", "parentId": "parent", "id": "child2"});
- console.log("parent child1 child2");
-
- // Create some radio items.
- chrome.contextMenus.create({"title": "Radio 1", "type": "radio",
- "id": "radio1"});
- chrome.contextMenus.create({"title": "Radio 2", "type": "radio",
- "id": "radio2"});
- console.log("radio1 radio2");
-
- // Create some checkbox items.
- chrome.contextMenus.create(
- {"title": "Checkbox1", "type": "checkbox", "id": "checkbox1"});
- chrome.contextMenus.create(
- {"title": "Checkbox2", "type": "checkbox", "id": "checkbox2"});
- console.log("checkbox1 checkbox2");
-
- // Intentionally create an invalid item, to show off error checking in the
- // create callback.
- console.log("About to try creating an invalid item - an error about " +
- "duplicate item child1 should show up");
- chrome.contextMenus.create({"title": "Oops", "id": "child1"}, function() {
- if (chrome.extension.lastError) {
- console.log("Got expected error: " + chrome.extension.lastError.message);
- }
- });
-});
diff --git a/chrome/common/extensions/docs/examples/api/contextMenus/global_context_search/background.js b/chrome/common/extensions/docs/examples/api/contextMenus/global_context_search/background.js
deleted file mode 100644
index a70763d..0000000
--- a/chrome/common/extensions/docs/examples/api/contextMenus/global_context_search/background.js
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2017 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.
-
-'use strict';
-// Add a listener to create the initial context menu items,
-// context menu items only need to be created at runtime.onInstalled
-chrome.runtime.onInstalled.addListener(function() {
- for (let key of Object.keys(kLocales)) {
- chrome.contextMenus.create({
- id: key,
- title: kLocales[key],
- type: 'normal',
- contexts: ['selection'],
- });
- }
-});
-
-chrome.contextMenus.onClicked.addListener(function(item, tab) {
- let url =
- 'https://google.' + item.menuItemId + '/search?q=' + item.selectionText;
- chrome.tabs.create({url: url, index: tab.index + 1});
-});
-
-chrome.storage.onChanged.addListener(function(list, sync) {
- let newlyDisabled = [];
- let newlyEnabled = [];
- let currentRemoved = list.removedContextMenu.newValue;
- let oldRemoved = list.removedContextMenu.oldValue || [];
- for (let key of Object.keys(kLocales)) {
- if (currentRemoved.includes(key) && !oldRemoved.includes(key)) {
- newlyDisabled.push(key);
- } else if (oldRemoved.includes(key) && !currentRemoved.includes(key)) {
- newlyEnabled.push({
- id: key,
- title: kLocales[key]
- });
- }
- }
- for (let locale of newlyEnabled) {
- chrome.contextMenus.create({
- id: locale.id,
- title: locale.title,
- type: 'normal',
- contexts: ['selection'],
- });
- }
- for (let locale of newlyDisabled) {
- chrome.contextMenus.remove(locale);
- }
-});
diff --git a/chrome/common/extensions/docs/examples/api/contextMenus/global_context_search/globalGoogle128.png b/chrome/common/extensions/docs/examples/api/contextMenus/global_context_search/globalGoogle128.png
deleted file mode 100644
index cd1903dd..0000000
--- a/chrome/common/extensions/docs/examples/api/contextMenus/global_context_search/globalGoogle128.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/contextMenus/global_context_search/globalGoogle16.png b/chrome/common/extensions/docs/examples/api/contextMenus/global_context_search/globalGoogle16.png
deleted file mode 100644
index 77540d1..0000000
--- a/chrome/common/extensions/docs/examples/api/contextMenus/global_context_search/globalGoogle16.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/contextMenus/global_context_search/globalGoogle48.png b/chrome/common/extensions/docs/examples/api/contextMenus/global_context_search/globalGoogle48.png
deleted file mode 100644
index d01e5d9..0000000
--- a/chrome/common/extensions/docs/examples/api/contextMenus/global_context_search/globalGoogle48.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/contextMenus/global_context_search/locales.js b/chrome/common/extensions/docs/examples/api/contextMenus/global_context_search/locales.js
deleted file mode 100644
index f02e6ae..0000000
--- a/chrome/common/extensions/docs/examples/api/contextMenus/global_context_search/locales.js
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2017 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.
-
-const kLocales = {
- 'com.au': 'Australia',
- 'com.br': 'Brazil',
- 'ca': 'Canada',
- 'cn': 'China',
- 'fr': 'France',
- 'it': 'Italy',
- 'co.in': 'India',
- 'co.jp': 'Japan',
- 'com.ms': 'Mexico',
- 'ru': 'Russia',
- 'co.za': 'South Africa',
- 'co.uk': 'United Kingdom'
-};
diff --git a/chrome/common/extensions/docs/examples/api/contextMenus/global_context_search/manifest.json b/chrome/common/extensions/docs/examples/api/contextMenus/global_context_search/manifest.json
deleted file mode 100644
index df745d5..0000000
--- a/chrome/common/extensions/docs/examples/api/contextMenus/global_context_search/manifest.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
- "name": "Global Google Search",
- "description": "Use the context menu to search a different country's Google",
- "version": "1.0",
- "manifest_version": 2,
- "options_page": "options.html",
- "permissions": ["contextMenus", "storage"],
- "background": {
- "scripts": [ "locales.js", "background.js"],
- "persistent": false
- },
- "browser_action": {
- "default_popup": "options.html"
- },
- "icons": {
- "16": "globalGoogle16.png",
- "48": "globalGoogle48.png",
- "128": "globalGoogle128.png"
- }
-}
diff --git a/chrome/common/extensions/docs/examples/api/contextMenus/global_context_search/options.html b/chrome/common/extensions/docs/examples/api/contextMenus/global_context_search/options.html
deleted file mode 100644
index b6dcbbaf7..0000000
--- a/chrome/common/extensions/docs/examples/api/contextMenus/global_context_search/options.html
+++ /dev/null
@@ -1,26 +0,0 @@
-<!DOCTYPE html>
-<html>
- <head>
- <title>Global Context Search</title>
- <style>
- body {
- min-width: 300px;
- font-size: 15px;
- }
- input {
- margin: 5px;
- outline: none;
- }
- </style>
- </head>
-
- <body>
- <h2>Global Google Search</h2>
- <h3>Country Options</h3>
- <form id="form">
- </form>
- <button type='submit' value='Submit' id='optionsSubmit'>Submit</button>
- </body>
- <script src="locales.js"></script>
- <script src="options.js"></script>
-</html>
diff --git a/chrome/common/extensions/docs/examples/api/contextMenus/global_context_search/options.js b/chrome/common/extensions/docs/examples/api/contextMenus/global_context_search/options.js
deleted file mode 100644
index 3b30672..0000000
--- a/chrome/common/extensions/docs/examples/api/contextMenus/global_context_search/options.js
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2017 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.
-
-function createForm() {
- chrome.storage.sync.get(['removedContextMenu'], function(list) {
- let removed = list.removedContextMenu || [];
- let form = document.getElementById('form');
- for (let key of Object.keys(kLocales)) {
- let div = document.createElement('div');
- let checkbox = document.createElement('input');
- checkbox.type = 'checkbox';
- checkbox.checked = true;
- if (removed.includes(key)) {
- checkbox.checked = false;
- }
- checkbox.name = key;
- checkbox.value = kLocales[key];
- let span = document.createElement('span');
- span.textContent = kLocales[key];
- div.appendChild(checkbox);
- div.appendChild(span);
- form.appendChild(div);
- }
- });
-}
-
-createForm();
-
-document.getElementById('optionsSubmit').onclick = function() {
- let checkboxes = document.getElementsByTagName('input');
- let removed = [];
- for (i=0; i<checkboxes.length; i++) {
- if (checkboxes[i].checked == false) {
- removed.push(checkboxes[i].name);
- }
- }
- chrome.storage.sync.set({removedContextMenu: removed});
- window.close();
-}
diff --git a/chrome/common/extensions/docs/examples/api/cookies/background.js b/chrome/common/extensions/docs/examples/api/cookies/background.js
deleted file mode 100644
index 0e42ddb5..0000000
--- a/chrome/common/extensions/docs/examples/api/cookies/background.js
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (c) 2012 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.
-
-chrome.cookies.onChanged.addListener(function(info) {
- console.log("onChanged" + JSON.stringify(info));
-});
-
-function focusOrCreateTab(url) {
- chrome.windows.getAll({"populate":true}, function(windows) {
- var existing_tab = null;
- for (var i in windows) {
- var tabs = windows[i].tabs;
- for (var j in tabs) {
- var tab = tabs[j];
- if (tab.url == url) {
- existing_tab = tab;
- break;
- }
- }
- }
- if (existing_tab) {
- chrome.tabs.update(existing_tab.id, {"selected":true});
- } else {
- chrome.tabs.create({"url":url, "selected":true});
- }
- });
-}
-
-chrome.browserAction.onClicked.addListener(function(tab) {
- var manager_url = chrome.extension.getURL("manager.html");
- focusOrCreateTab(manager_url);
-});
diff --git a/chrome/common/extensions/docs/examples/api/cookies/cookie.png b/chrome/common/extensions/docs/examples/api/cookies/cookie.png
deleted file mode 100644
index 21b5073..0000000
--- a/chrome/common/extensions/docs/examples/api/cookies/cookie.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/cookies/manager.html b/chrome/common/extensions/docs/examples/api/cookies/manager.html
deleted file mode 100644
index b1d93b5..0000000
--- a/chrome/common/extensions/docs/examples/api/cookies/manager.html
+++ /dev/null
@@ -1,43 +0,0 @@
-<html>
-<head>
-<style>
-table {
- border-collapse:collapse;
-}
-
-td {
- border: 1px solid black;
- padding-left: 5px;
-}
-
-td.button {
- border: none;
-}
-
-td.cookie_count {
- text-align: right;
-}
-
-</style>
-<script src="manager.js"></script>
-</head>
-<body>
- <h2>Cookies! ... Nom Nom Nom...</h2>
- <button id="remove_button">DELETE ALL!</button>
- <div id="filter_div">
- Filter: <input id="filter" type="text">
- <button>x</button>
- </div>
- <br />
- <div id="summary_div">
- Showing <span id="filter_count"></span> of <span id="total_count"></span> cookie domains.
- <span id="delete_all_button"></span>
- </div>
- <br />
- <table id="cookies">
- <tr class="header">
- <th>Name</th>
- <th>#Cookies</th>
- </tr>
- </body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/api/cookies/manager.js b/chrome/common/extensions/docs/examples/api/cookies/manager.js
deleted file mode 100644
index bcf3500..0000000
--- a/chrome/common/extensions/docs/examples/api/cookies/manager.js
+++ /dev/null
@@ -1,260 +0,0 @@
-// Copyright (c) 2012 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.
-
-if (!chrome.cookies) {
- chrome.cookies = chrome.experimental.cookies;
-}
-
-// A simple Timer class.
-function Timer() {
- this.start_ = new Date();
-
- this.elapsed = function() {
- return (new Date()) - this.start_;
- }
-
- this.reset = function() {
- this.start_ = new Date();
- }
-}
-
-// Compares cookies for "key" (name, domain, etc.) equality, but not "value"
-// equality.
-function cookieMatch(c1, c2) {
- return (c1.name == c2.name) && (c1.domain == c2.domain) &&
- (c1.hostOnly == c2.hostOnly) && (c1.path == c2.path) &&
- (c1.secure == c2.secure) && (c1.httpOnly == c2.httpOnly) &&
- (c1.session == c2.session) && (c1.storeId == c2.storeId);
-}
-
-// Returns an array of sorted keys from an associative array.
-function sortedKeys(array) {
- var keys = [];
- for (var i in array) {
- keys.push(i);
- }
- keys.sort();
- return keys;
-}
-
-// Shorthand for document.querySelector.
-function select(selector) {
- return document.querySelector(selector);
-}
-
-// An object used for caching data about the browser's cookies, which we update
-// as notifications come in.
-function CookieCache() {
- this.cookies_ = {};
-
- this.reset = function() {
- this.cookies_ = {};
- }
-
- this.add = function(cookie) {
- var domain = cookie.domain;
- if (!this.cookies_[domain]) {
- this.cookies_[domain] = [];
- }
- this.cookies_[domain].push(cookie);
- };
-
- this.remove = function(cookie) {
- var domain = cookie.domain;
- if (this.cookies_[domain]) {
- var i = 0;
- while (i < this.cookies_[domain].length) {
- if (cookieMatch(this.cookies_[domain][i], cookie)) {
- this.cookies_[domain].splice(i, 1);
- } else {
- i++;
- }
- }
- if (this.cookies_[domain].length == 0) {
- delete this.cookies_[domain];
- }
- }
- };
-
- // Returns a sorted list of cookie domains that match |filter|. If |filter| is
- // null, returns all domains.
- this.getDomains = function(filter) {
- var result = [];
- sortedKeys(this.cookies_).forEach(function(domain) {
- if (!filter || domain.indexOf(filter) != -1) {
- result.push(domain);
- }
- });
- return result;
- }
-
- this.getCookies = function(domain) {
- return this.cookies_[domain];
- };
-}
-
-
-var cache = new CookieCache();
-
-
-function removeAllForFilter() {
- var filter = select("#filter").value;
- var timer = new Timer();
- cache.getDomains(filter).forEach(function(domain) {
- removeCookiesForDomain(domain);
- });
-}
-
-function removeAll() {
- var all_cookies = [];
- cache.getDomains().forEach(function(domain) {
- cache.getCookies(domain).forEach(function(cookie) {
- all_cookies.push(cookie);
- });
- });
- cache.reset();
- var count = all_cookies.length;
- var timer = new Timer();
- for (var i = 0; i < count; i++) {
- removeCookie(all_cookies[i]);
- }
- timer.reset();
- chrome.cookies.getAll({}, function(cookies) {
- for (var i in cookies) {
- cache.add(cookies[i]);
- removeCookie(cookies[i]);
- }
- });
-}
-
-function removeCookie(cookie) {
- var url = "http" + (cookie.secure ? "s" : "") + "://" + cookie.domain +
- cookie.path;
- chrome.cookies.remove({"url": url, "name": cookie.name});
-}
-
-function removeCookiesForDomain(domain) {
- var timer = new Timer();
- cache.getCookies(domain).forEach(function(cookie) {
- removeCookie(cookie);
- });
-}
-
-function resetTable() {
- var table = select("#cookies");
- while (table.rows.length > 1) {
- table.deleteRow(table.rows.length - 1);
- }
-}
-
-var reload_scheduled = false;
-
-function scheduleReloadCookieTable() {
- if (!reload_scheduled) {
- reload_scheduled = true;
- setTimeout(reloadCookieTable, 250);
- }
-}
-
-function reloadCookieTable() {
- reload_scheduled = false;
-
- var filter = select("#filter").value;
-
- var domains = cache.getDomains(filter);
-
- select("#filter_count").innerText = domains.length;
- select("#total_count").innerText = cache.getDomains().length;
-
- select("#delete_all_button").innerHTML = "";
- if (domains.length) {
- var button = document.createElement("button");
- button.onclick = removeAllForFilter;
- button.innerText = "delete all " + domains.length;
- select("#delete_all_button").appendChild(button);
- }
-
- resetTable();
- var table = select("#cookies");
-
- domains.forEach(function(domain) {
- var cookies = cache.getCookies(domain);
- var row = table.insertRow(-1);
- row.insertCell(-1).innerText = domain;
- var cell = row.insertCell(-1);
- cell.innerText = cookies.length;
- cell.setAttribute("class", "cookie_count");
-
- var button = document.createElement("button");
- button.innerText = "delete";
- button.onclick = (function(dom){
- return function() {
- removeCookiesForDomain(dom);
- };
- }(domain));
- var cell = row.insertCell(-1);
- cell.appendChild(button);
- cell.setAttribute("class", "button");
- });
-}
-
-function focusFilter() {
- select("#filter").focus();
-}
-
-function resetFilter() {
- var filter = select("#filter");
- filter.focus();
- if (filter.value.length > 0) {
- filter.value = "";
- reloadCookieTable();
- }
-}
-
-var ESCAPE_KEY = 27;
-window.onkeydown = function(event) {
- if (event.keyCode == ESCAPE_KEY) {
- resetFilter();
- }
-}
-
-function listener(info) {
- cache.remove(info.cookie);
- if (!info.removed) {
- cache.add(info.cookie);
- }
- scheduleReloadCookieTable();
-}
-
-function startListening() {
- chrome.cookies.onChanged.addListener(listener);
-}
-
-function stopListening() {
- chrome.cookies.onChanged.removeListener(listener);
-}
-
-function onload() {
- focusFilter();
- var timer = new Timer();
- chrome.cookies.getAll({}, function(cookies) {
- startListening();
- start = new Date();
- for (var i in cookies) {
- cache.add(cookies[i]);
- }
- timer.reset();
- reloadCookieTable();
- });
-}
-
-document.addEventListener('DOMContentLoaded', function() {
- onload();
- document.body.addEventListener('click', focusFilter);
- document.querySelector('#remove_button').addEventListener('click', removeAll);
- document.querySelector('#filter_div input').addEventListener(
- 'input', reloadCookieTable);
- document.querySelector('#filter_div button').addEventListener(
- 'click', resetFilter);
-});
diff --git a/chrome/common/extensions/docs/examples/api/cookies/manifest.json b/chrome/common/extensions/docs/examples/api/cookies/manifest.json
deleted file mode 100644
index eb7da26..0000000
--- a/chrome/common/extensions/docs/examples/api/cookies/manifest.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "name" : "Cookie API Test Extension",
- "version" : "0.8",
- "description" : "Testing Cookie API",
- "permissions": [ "cookies", "tabs", "http://*/*", "https://*/*" ],
- "icons": { "16": "cookie.png", "48": "cookie.png", "128": "cookie.png" },
- "browser_action": {
- "default_icon": "cookie.png"
- },
- "background": {
- "scripts": ["background.js"]
- },
- "manifest_version": 2
-}
diff --git a/chrome/common/extensions/docs/examples/api/debugger/live-headers/background.js b/chrome/common/extensions/docs/examples/api/debugger/live-headers/background.js
deleted file mode 100644
index 45c0bbe..0000000
--- a/chrome/common/extensions/docs/examples/api/debugger/live-headers/background.js
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright (c) 2012 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.
-
-chrome.browserAction.onClicked.addListener(function(tab) {
- chrome.debugger.attach({tabId:tab.id}, version,
- onAttach.bind(null, tab.id));
-});
-
-var version = "1.0";
-
-function onAttach(tabId) {
- if (chrome.runtime.lastError) {
- alert(chrome.runtime.lastError.message);
- return;
- }
-
- chrome.windows.create(
- {url: "headers.html?" + tabId, type: "popup", width: 800, height: 600});
-}
diff --git a/chrome/common/extensions/docs/examples/api/debugger/live-headers/headers.html b/chrome/common/extensions/docs/examples/api/debugger/live-headers/headers.html
deleted file mode 100644
index 3c042e9..0000000
--- a/chrome/common/extensions/docs/examples/api/debugger/live-headers/headers.html
+++ /dev/null
@@ -1,32 +0,0 @@
-<!--
-Copyright (c) 2012 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>
-<style>
-body {
- font-family: monospace;
- word-wrap: break-word;
-}
-
-#container {
- white-space: pre;
-}
-
-.request {
- border-top: 1px solid black;
- margin-bottom: 10px;
-}
-
-</style>
-
-<script src="headers.js"></script>
-</head>
-
-<body>
-<div id="container"></div>
-</body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/api/debugger/live-headers/headers.js b/chrome/common/extensions/docs/examples/api/debugger/live-headers/headers.js
deleted file mode 100644
index eac021e4..0000000
--- a/chrome/common/extensions/docs/examples/api/debugger/live-headers/headers.js
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright (c) 2012 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.
-
-var tabId = parseInt(window.location.search.substring(1));
-
-window.addEventListener("load", function() {
- chrome.debugger.sendCommand({tabId:tabId}, "Network.enable");
- chrome.debugger.onEvent.addListener(onEvent);
-});
-
-window.addEventListener("unload", function() {
- chrome.debugger.detach({tabId:tabId});
-});
-
-var requests = {};
-
-function onEvent(debuggeeId, message, params) {
- if (tabId != debuggeeId.tabId)
- return;
-
- if (message == "Network.requestWillBeSent") {
- var requestDiv = requests[params.requestId];
- if (!requestDiv) {
- var requestDiv = document.createElement("div");
- requestDiv.className = "request";
- requests[params.requestId] = requestDiv;
- var urlLine = document.createElement("div");
- urlLine.textContent = params.request.url;
- requestDiv.appendChild(urlLine);
- }
-
- if (params.redirectResponse)
- appendResponse(params.requestId, params.redirectResponse);
-
- var requestLine = document.createElement("div");
- requestLine.textContent = "\n" + params.request.method + " " +
- parseURL(params.request.url).path + " HTTP/1.1";
- requestDiv.appendChild(requestLine);
- document.getElementById("container").appendChild(requestDiv);
- } else if (message == "Network.responseReceived") {
- appendResponse(params.requestId, params.response);
- }
-}
-
-function appendResponse(requestId, response) {
- var requestDiv = requests[requestId];
- requestDiv.appendChild(formatHeaders(response.requestHeaders));
-
- var statusLine = document.createElement("div");
- statusLine.textContent = "\nHTTP/1.1 " + response.status + " " +
- response.statusText;
- requestDiv.appendChild(statusLine);
- requestDiv.appendChild(formatHeaders(response.headers));
-}
-
-function formatHeaders(headers) {
- var text = "";
- for (name in headers)
- text += name + ": " + headers[name] + "\n";
- var div = document.createElement("div");
- div.textContent = text;
- return div;
-}
-
-function parseURL(url) {
- var result = {};
- var match = url.match(
- /^([^:]+):\/\/([^\/:]*)(?::([\d]+))?(?:(\/[^#]*)(?:#(.*))?)?$/i);
- if (!match)
- return result;
- result.scheme = match[1].toLowerCase();
- result.host = match[2];
- result.port = match[3];
- result.path = match[4] || "/";
- result.fragment = match[5];
- return result;
-}
\ No newline at end of file
diff --git a/chrome/common/extensions/docs/examples/api/debugger/live-headers/icon.png b/chrome/common/extensions/docs/examples/api/debugger/live-headers/icon.png
deleted file mode 100644
index e35e317..0000000
--- a/chrome/common/extensions/docs/examples/api/debugger/live-headers/icon.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/debugger/live-headers/manifest.json b/chrome/common/extensions/docs/examples/api/debugger/live-headers/manifest.json
deleted file mode 100644
index 19b6554..0000000
--- a/chrome/common/extensions/docs/examples/api/debugger/live-headers/manifest.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- "name": "Live HTTP headers",
- "description": "Displays the live log with the http requests headers",
- "version": "0.7",
- "permissions": [
- "debugger"
- ],
- "background": {
- "scripts": ["background.js"]
- },
- "browser_action": {
- "default_icon": "icon.png",
- "default_title": "Live HTTP headers"
- },
- "manifest_version": 2
-}
-
diff --git a/chrome/common/extensions/docs/examples/api/debugger/pause-resume/background.js b/chrome/common/extensions/docs/examples/api/debugger/pause-resume/background.js
deleted file mode 100644
index c5399a4..0000000
--- a/chrome/common/extensions/docs/examples/api/debugger/pause-resume/background.js
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright (c) 2011 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.
-
-var attachedTabs = {};
-var version = "1.0";
-
-chrome.debugger.onEvent.addListener(onEvent);
-chrome.debugger.onDetach.addListener(onDetach);
-
-chrome.browserAction.onClicked.addListener(function(tab) {
- var tabId = tab.id;
- var debuggeeId = {tabId:tabId};
-
- if (attachedTabs[tabId] == "pausing")
- return;
-
- if (!attachedTabs[tabId])
- chrome.debugger.attach(debuggeeId, version, onAttach.bind(null, debuggeeId));
- else if (attachedTabs[tabId])
- chrome.debugger.detach(debuggeeId, onDetach.bind(null, debuggeeId));
-});
-
-function onAttach(debuggeeId) {
- if (chrome.runtime.lastError) {
- alert(chrome.runtime.lastError.message);
- return;
- }
-
- var tabId = debuggeeId.tabId;
- chrome.browserAction.setIcon({tabId: tabId, path:"debuggerPausing.png"});
- chrome.browserAction.setTitle({tabId: tabId, title:"Pausing JavaScript"});
- attachedTabs[tabId] = "pausing";
- chrome.debugger.sendCommand(
- debuggeeId, "Debugger.enable", {},
- onDebuggerEnabled.bind(null, debuggeeId));
-}
-
-function onDebuggerEnabled(debuggeeId) {
- chrome.debugger.sendCommand(debuggeeId, "Debugger.pause");
-}
-
-function onEvent(debuggeeId, method) {
- var tabId = debuggeeId.tabId;
- if (method == "Debugger.paused") {
- attachedTabs[tabId] = "paused";
- chrome.browserAction.setIcon({tabId:tabId, path:"debuggerContinue.png"});
- chrome.browserAction.setTitle({tabId:tabId, title:"Resume JavaScript"});
- }
-}
-
-function onDetach(debuggeeId) {
- var tabId = debuggeeId.tabId;
- delete attachedTabs[tabId];
- chrome.browserAction.setIcon({tabId:tabId, path:"debuggerPause.png"});
- chrome.browserAction.setTitle({tabId:tabId, title:"Pause JavaScript"});
-}
diff --git a/chrome/common/extensions/docs/examples/api/debugger/pause-resume/debuggerContinue.png b/chrome/common/extensions/docs/examples/api/debugger/pause-resume/debuggerContinue.png
deleted file mode 100644
index 3a344c8..0000000
--- a/chrome/common/extensions/docs/examples/api/debugger/pause-resume/debuggerContinue.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/debugger/pause-resume/debuggerPause.png b/chrome/common/extensions/docs/examples/api/debugger/pause-resume/debuggerPause.png
deleted file mode 100644
index 8f7ff3d7..0000000
--- a/chrome/common/extensions/docs/examples/api/debugger/pause-resume/debuggerPause.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/debugger/pause-resume/debuggerPausing.png b/chrome/common/extensions/docs/examples/api/debugger/pause-resume/debuggerPausing.png
deleted file mode 100644
index 68932fa..0000000
--- a/chrome/common/extensions/docs/examples/api/debugger/pause-resume/debuggerPausing.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/debugger/pause-resume/manifest.json b/chrome/common/extensions/docs/examples/api/debugger/pause-resume/manifest.json
deleted file mode 100644
index fdc7e3d..0000000
--- a/chrome/common/extensions/docs/examples/api/debugger/pause-resume/manifest.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
- "name": "JavaScript pause/resume",
- "description": "Pauses / resumes JavaScript execution",
- "version": "0.7",
- "permissions": [
- "debugger"
- ],
- "background": {
- "scripts": ["background.js"]
- },
- "browser_action": {
- "default_icon": "debuggerPause.png",
- "default_title": "Pause JavaScript"
- },
- "manifest_version": 2
-}
diff --git a/chrome/common/extensions/docs/examples/api/default_command_override/background.js b/chrome/common/extensions/docs/examples/api/default_command_override/background.js
deleted file mode 100644
index 5d31360..0000000
--- a/chrome/common/extensions/docs/examples/api/default_command_override/background.js
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2017 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.
-chrome.commands.onCommand.addListener(function(command) {
- chrome.tabs.query({currentWindow: true}, function(tabs) {
- // Sort tabs according to their index in the window.
- tabs.sort((a, b) => { return a.index < b.index; });
- let activeIndex = tabs.findIndex((tab) => { return tab.active; });
- let lastTab = tabs.length - 1;
- let newIndex = -1;
- if (command === 'flip-tabs-forward')
- newIndex = activeIndex === 0 ? lastTab : activeIndex - 1;
- else // 'flip-tabs-backwards'
- newIndex = activeIndex === lastTab ? 0 : activeIndex + 1;
- chrome.tabs.update(tabs[newIndex].id, {active: true, highlighted: true});
- });
-});
diff --git a/chrome/common/extensions/docs/examples/api/default_command_override/images/tabFlipper128.png b/chrome/common/extensions/docs/examples/api/default_command_override/images/tabFlipper128.png
deleted file mode 100644
index 1d1dcb8..0000000
--- a/chrome/common/extensions/docs/examples/api/default_command_override/images/tabFlipper128.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/default_command_override/images/tabFlipper16.png b/chrome/common/extensions/docs/examples/api/default_command_override/images/tabFlipper16.png
deleted file mode 100644
index 695f64e..0000000
--- a/chrome/common/extensions/docs/examples/api/default_command_override/images/tabFlipper16.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/default_command_override/images/tabFlipper32.png b/chrome/common/extensions/docs/examples/api/default_command_override/images/tabFlipper32.png
deleted file mode 100644
index 67ef0d3..0000000
--- a/chrome/common/extensions/docs/examples/api/default_command_override/images/tabFlipper32.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/default_command_override/images/tabFlipper48.png b/chrome/common/extensions/docs/examples/api/default_command_override/images/tabFlipper48.png
deleted file mode 100644
index 4bf7680..0000000
--- a/chrome/common/extensions/docs/examples/api/default_command_override/images/tabFlipper48.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/default_command_override/manifest.json b/chrome/common/extensions/docs/examples/api/default_command_override/manifest.json
deleted file mode 100644
index 803f2b9c..0000000
--- a/chrome/common/extensions/docs/examples/api/default_command_override/manifest.json
+++ /dev/null
@@ -1,36 +0,0 @@
-{
- "name": "Tab Flipper",
- "description": "Press Ctrl+Shift+Right or Ctrl+Shift+Left (Command+Shift+Right or Command+Shift+Left on a Mac) to flip through window tabs",
- "version": "1.0",
- "manifest_version": 2,
- "background": {
- "scripts": ["background.js"],
- "persistent": false
- },
- "browser_action": {
- "default_icon": "images/tabFlipper16.png",
- "default_title": "Press Ctrl(Win)/Command(Mac)+Shift+ Left or Right to Flip Tabs"
- },
- "commands": {
- "flip-tabs-forward": {
- "suggested_key": {
- "default": "Ctrl+Shift+Right",
- "mac": "Command+Shift+Right"
- },
- "description": "Flip tabs forward"
- },
- "flip-tabs-backwards": {
- "suggested_key": {
- "default": "Ctrl+Shift+Left",
- "mac": "Command+Shift+Left"
- },
- "description": "Flip tabs backwards"
- }
- },
- "icons": {
- "16": "images/tabFlipper16.png",
- "32": "images/tabFlipper32.png",
- "48": "images/tabFlipper48.png",
- "128": "images/tabFlipper128.png"
- }
-}
diff --git a/chrome/common/extensions/docs/examples/api/desktopCapture/app.js b/chrome/common/extensions/docs/examples/api/desktopCapture/app.js
deleted file mode 100644
index c470940..0000000
--- a/chrome/common/extensions/docs/examples/api/desktopCapture/app.js
+++ /dev/null
@@ -1,137 +0,0 @@
-// Copyright 2013 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.
-
-'use strict';
-
-const DESKTOP_MEDIA = ['screen', 'window', 'tab', 'audio'];
-
-var pending_request_id = null;
-var pc1 = null;
-var pc2 = null;
-
-// Launch the chooseDesktopMedia().
-document.querySelector('#start').addEventListener('click', function(event) {
- pending_request_id = chrome.desktopCapture.chooseDesktopMedia(
- DESKTOP_MEDIA, onAccessApproved);
-});
-
-document.querySelector('#cancel').addEventListener('click', function(event) {
- if (pending_request_id != null) {
- chrome.desktopCapture.cancelChooseDesktopMedia(pending_request_id);
- }
-});
-
-document.querySelector('#startFromBackgroundPage')
- .addEventListener('click', function(event) {
- chrome.runtime.sendMessage(
- {}, function(response) { console.log(response.farewell); });
- });
-
-// Launch webkitGetUserMedia() based on selected media id.
-function onAccessApproved(id, options) {
- if (!id) {
- console.log('Access rejected.');
- return;
- }
-
- var audioConstraint = {
- mandatory: {
- chromeMediaSource: 'desktop',
- chromeMediaSourceId: id
- }
- };
-
- console.log(options.canRequestAudioTrack);
- if (!options.canRequestAudioTrack)
- audioConstraint = false;
-
- navigator.webkitGetUserMedia({
- audio: audioConstraint,
- video: {
- mandatory: {
- chromeMediaSource: 'desktop',
- chromeMediaSourceId: id,
- maxWidth:screen.width,
- maxHeight:screen.height} }
- }, gotStream, getUserMediaError);
-}
-
-function getUserMediaError(error) {
- console.log('navigator.webkitGetUserMedia() errot: ', error);
-}
-
-// Capture video/audio of media and initialize RTC communication.
-function gotStream(stream) {
- console.log('Received local stream', stream);
- var video = document.querySelector('video');
- try {
- video.srcObject = stream;
- } catch (error) {
- video.src = URL.createObjectURL(stream);
- }
- stream.onended = function() { console.log('Ended'); };
-
- pc1 = new RTCPeerConnection();
- pc1.onicecandidate = function(event) {
- onIceCandidate(pc1, event);
- };
- pc2 = new RTCPeerConnection();
- pc2.onicecandidate = function(event) {
- onIceCandidate(pc2, event);
- };
- pc1.oniceconnectionstatechange = function(event) {
- onIceStateChange(pc1, event);
- };
- pc2.oniceconnectionstatechange = function(event) {
- onIceStateChange(pc2, event);
- };
- pc2.onaddstream = gotRemoteStream;
-
- pc1.addStream(stream);
-
- pc1.createOffer(onCreateOfferSuccess, function() {});
-}
-
-function onCreateOfferSuccess(desc) {
- pc1.setLocalDescription(desc);
- pc2.setRemoteDescription(desc);
- // Since the 'remote' side has no media stream we need
- // to pass in the right constraints in order for it to
- // accept the incoming offer of audio and video.
- var sdpConstraints = {
- 'mandatory': {
- 'OfferToReceiveAudio': true,
- 'OfferToReceiveVideo': true
- }
- };
- pc2.createAnswer(onCreateAnswerSuccess, function(){}, sdpConstraints);
-}
-
-function gotRemoteStream(event) {
- // Call the polyfill wrapper to attach the media stream to this element.
- console.log('hitting this code');
- try {
- remoteVideo.srcObject = event.stream;
- } catch (error) {
- remoteVideo.src = URL.createObjectURL(event.stream);
- }
-}
-
-function onCreateAnswerSuccess(desc) {
- pc2.setLocalDescription(desc);
- pc1.setRemoteDescription(desc);
-}
-
-function onIceCandidate(pc, event) {
- if (event.candidate) {
- var remotePC = (pc === pc1) ? pc2 : pc1;
- remotePC.addIceCandidate(new RTCIceCandidate(event.candidate));
- }
-}
-
-function onIceStateChange(pc, event) {
- if (pc) {
- console.log('ICE state change event: ', event);
- }
-}
diff --git a/chrome/common/extensions/docs/examples/api/desktopCapture/background.js b/chrome/common/extensions/docs/examples/api/desktopCapture/background.js
deleted file mode 100644
index 30e4779cf..0000000
--- a/chrome/common/extensions/docs/examples/api/desktopCapture/background.js
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2013 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.
-
-chrome.app.runtime.onLaunched.addListener(function() {
- chrome.app.window.create('index.html', {
- bounds: {
- width: 1080,
- height: 550
- }
- });
-});
-
-chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) {
- chrome.desktopCapture.chooseDesktopMedia(
- ["screen", "window"],
- function(id) {
- sendResponse({"id": id});
- });
-});
diff --git a/chrome/common/extensions/docs/examples/api/desktopCapture/icon.png b/chrome/common/extensions/docs/examples/api/desktopCapture/icon.png
deleted file mode 100644
index c252ed6..0000000
--- a/chrome/common/extensions/docs/examples/api/desktopCapture/icon.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/desktopCapture/index.html b/chrome/common/extensions/docs/examples/api/desktopCapture/index.html
deleted file mode 100644
index fca9053..0000000
--- a/chrome/common/extensions/docs/examples/api/desktopCapture/index.html
+++ /dev/null
@@ -1,31 +0,0 @@
-<html>
-<head>
-<style>
- body {
- background: white;
- display: -webkit-flex;
- -webkit-justify-content: center;
- -webkit-align-items: center;
- -webkit-flex-direction: column;
- }
- video {
- width: 480px;
- height: 360px;
- border: 1px solid #e2e2e2;
- box-shadow: 0 1px 1px rgba(0,0,0,0.2);
- }
-</style>
-</head>
-<body>
- <div>
- <video id="video" autoplay></video>
- <video id="remoteVideo" autoplay></video>
- </div>
- <p>
- <button id="start">Start</button>
- <button id="cancel">Cancel</button>
- <button id="startFromBackgroundPage">Start from background page</button>
- </p>
- <script src="app.js"></script>
-</body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/api/desktopCapture/manifest.json b/chrome/common/extensions/docs/examples/api/desktopCapture/manifest.json
deleted file mode 100644
index 6a59859..0000000
--- a/chrome/common/extensions/docs/examples/api/desktopCapture/manifest.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- "key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjd3VZe2un2t/ju5HGcZrbD862LLhtukwtXeySPzbQaq9zEyFzr+pVd1EeAW7ZPUA86K9/mpWiDycoSMMj9hpm+QQqBnQDrPPtBJfogkFvWsgDQaw6SXZmErTlzz1wukn/0YLQrPLJ7JPj3zGzWcoVj9AhOjQeDpq2E9P3lz85mHwG0RrxgpknP1wGNNkXl/y4WDaWHZyoX1zgcn2r3bzTdb77RWiA9pduXSn6d14GA9B9CdQA4bTDmc9HY1WaVGK0oDX2A2eJEllHqdeBJmpqPqds4cIhm0Gq6lKvxB61I2UZlbCaSIMfTTxBnt+r7NPgpxHBKJIF1xOCpuGtWuc0wIDAQAB",
- "name": "Desktop Capture Example",
- "description": "Show desktop media picker UI",
- "version": "1",
- "manifest_version": 3,
- "icons": {
- "16": "icon.png",
- "128": "icon.png"
- },
- "app": {
- "background": {
- "scripts": ["background.js"]
- }
- },
- "permissions": [
- "desktopCapture"
- ]
-}
diff --git a/chrome/common/extensions/docs/examples/api/deviceInfo/basic/icon.png b/chrome/common/extensions/docs/examples/api/deviceInfo/basic/icon.png
deleted file mode 100644
index ea42f3f..0000000
--- a/chrome/common/extensions/docs/examples/api/deviceInfo/basic/icon.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/deviceInfo/basic/manifest.json b/chrome/common/extensions/docs/examples/api/deviceInfo/basic/manifest.json
deleted file mode 100644
index 4d376d8..0000000
--- a/chrome/common/extensions/docs/examples/api/deviceInfo/basic/manifest.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "name": "My Devices",
- "version": "1.1",
- "description": "A browser action with a popup dump of all devices signed into the same account as the current profile.",
- "permissions": [
- "signedInDevices"
- ],
- "browser_action": {
- "default_title": "My Devices",
- "default_icon": "icon.png",
- "default_popup": "popup.html"
- },
- "manifest_version": 2,
- "content_security_policy": "script-src 'self' https://ajax.googleapis.com; object-src 'self'"
-}
diff --git a/chrome/common/extensions/docs/examples/api/deviceInfo/basic/popup.html b/chrome/common/extensions/docs/examples/api/deviceInfo/basic/popup.html
deleted file mode 100644
index 4b46611..0000000
--- a/chrome/common/extensions/docs/examples/api/deviceInfo/basic/popup.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<html>
-<head>
- <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
- <script src="popup.js"></script>
-</head>
-<body style="width: 400px">
- <div id="deviceinfos"></div>
-</body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/api/deviceInfo/basic/popup.js b/chrome/common/extensions/docs/examples/api/deviceInfo/basic/popup.js
deleted file mode 100644
index 3a8265d..0000000
--- a/chrome/common/extensions/docs/examples/api/deviceInfo/basic/popup.js
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2013 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.
-
-function dumpDevices(devices) {
- $('#deviceinfos').empty();
- $('#deviceinfos').append(outputDevicesToList(devices));
-}
-
-function outputDevicesToList(devices) {
- var table = $('<table border="1">');
- table.append($("<tr>" +
- "<th>" + "Name" + "</th>" +
- "<th>" + "OS" + "</th>" +
- "<th>" + "Id" + "</th>" +
- "<th>" + "Type" + "</th>" +
- "<th>" + "Chrome Version" + "</th>" +
- "</tr>"));
- for (i = 0; i < devices.length; i++) {
- table.append($("<tr>" +
- "<td>" + devices[i].name + "</td>" +
- "<td>" + devices[i].os + "</td>" +
- "<td>" + devices[i].id + "</td>" +
- "<td>" + devices[i].type + "</td>" +
- "<td>" + devices[i].chromeVersion + "</td>" +
- "</tr>"));
- }
- return table;
-}
-
-// Add an event listener to listen for changes to device info. The
-// callback would redisplay the list of devices.
-chrome.signedInDevices.onDeviceInfoChange.addListener(dumpDevices);
-
-function populateDevices() {
- // Get the list of devices and display it.
- chrome.signedInDevices.get(false, dumpDevices);
-}
-
-document.addEventListener('DOMContentLoaded', function () {
- populateDevices();
-});
diff --git a/chrome/common/extensions/docs/examples/api/devtools/network/chrome-firephp/background.js b/chrome/common/extensions/docs/examples/api/devtools/network/chrome-firephp/background.js
deleted file mode 100644
index 8496dcb..0000000
--- a/chrome/common/extensions/docs/examples/api/devtools/network/chrome-firephp/background.js
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright (c) 2011 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.
-
-const tab_log = function(json_args) {
- var args = JSON.parse(unescape(json_args));
- console[args[0]].apply(console, Array.prototype.slice.call(args, 1));
-}
-
-chrome.extension.onRequest.addListener(function(request) {
- if (request.command !== 'sendToConsole')
- return;
- chrome.tabs.executeScript(request.tabId, {
- code: "("+ tab_log + ")('" + request.args + "');",
- });
-});
diff --git a/chrome/common/extensions/docs/examples/api/devtools/network/chrome-firephp/devtools.html b/chrome/common/extensions/docs/examples/api/devtools/network/chrome-firephp/devtools.html
deleted file mode 100644
index 553696e7..0000000
--- a/chrome/common/extensions/docs/examples/api/devtools/network/chrome-firephp/devtools.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<!doctype html>
-<html>
- <head>
- <title>Devtools Page</title>
- <script src="devtools.js"></script>
- <script src="./background.js" type="text/javascript"></script>
- </head>
- <body>
- </body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/api/devtools/network/chrome-firephp/devtools.js b/chrome/common/extensions/docs/examples/api/devtools/network/chrome-firephp/devtools.js
deleted file mode 100644
index 554d3807..0000000
--- a/chrome/common/extensions/docs/examples/api/devtools/network/chrome-firephp/devtools.js
+++ /dev/null
@@ -1,185 +0,0 @@
-// Copyright (c) 2011 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.
-
-function Console() {
-}
-
-Console.Type = {
- LOG: "log",
- DEBUG: "debug",
- INFO: "info",
- WARN: "warn",
- ERROR: "error",
- GROUP: "group",
- GROUP_COLLAPSED: "groupCollapsed",
- GROUP_END: "groupEnd"
-};
-
-Console.addMessage = function(type, format, args) {
- chrome.extension.sendRequest({
- command: "sendToConsole",
- tabId: chrome.devtools.tabId,
- args: escape(JSON.stringify(Array.prototype.slice.call(arguments, 0)))
- });
-};
-
-// Generate Console output methods, i.e. Console.log(), Console.debug() etc.
-(function() {
- var console_types = Object.getOwnPropertyNames(Console.Type);
- for (var type = 0; type < console_types.length; ++type) {
- var method_name = Console.Type[console_types[type]];
- Console[method_name] = Console.addMessage.bind(Console, method_name);
- }
-})();
-
-function ChromeFirePHP() {
-};
-
-ChromeFirePHP.handleFirePhpHeaders = function(har_entry) {
- var response_headers = har_entry.response.headers;
- var wf_header_map = {};
- var had_wf_headers = false;
-
- for (var i = 0; i < response_headers.length; ++i) {
- var header = response_headers[i];
- if (/^X-Wf-/.test(header.name)) {
- wf_header_map[header.name] = header.value;
- had_wf_headers = true;
- }
- }
-
- var proto_header = wf_header_map["X-Wf-Protocol-1"];
- if (!had_wf_headers || !this._checkProtoVersion(proto_header))
- return;
-
- var message_objects = this._buildMessageObjects(wf_header_map);
- message_objects.sort(function(a, b) {
- var aFile = a.File || "";
- var bFile = b.File || "";
- if (aFile !== bFile)
- return aFile.localeCompare(bFile);
- var aLine = a.Line !== undefined ? a.Line : -1;
- var bLine = b.Line !== undefined ? b.Line : -1;
- return aLine - bLine;
- });
-
- var context = { pageRef: har_entry.pageref };
- for (var i = 0; i < message_objects.length; ++i)
- this._processLogMessage(message_objects[i], context);
- if (context.groupStarted)
- Console.groupEnd();
-};
-
-ChromeFirePHP._processLogMessage = function(message, context) {
- var meta = message[0];
- if (!meta) {
- Console.error("No Meta in FirePHP message");
- return;
- }
-
- var body = message[1];
- var type = meta.Type;
- if (!type) {
- Console.error("No Type for FirePHP message");
- return;
- }
-
- switch (type) {
- case "LOG":
- case "INFO":
- case "WARN":
- case "ERROR":
- if (!context.groupStarted) {
- context.groupStarted = true;
- Console.groupCollapsed(context.pageRef || "");
- }
- Console.addMessage(Console.Type[type], "%s%o",
- (meta.Label ? meta.Label + ": " : ""), body);
- break;
- case "EXCEPTION":
- case "TABLE":
- case "TRACE":
- case "GROUP_START":
- case "GROUP_END":
- // FIXME: implement
- break;
- }
-};
-
-ChromeFirePHP._buildMessageObjects = function(header_map)
-{
- const normal_header_prefix = "X-Wf-1-1-1-";
-
- return this._collectMessageObjectsForPrefix(header_map, normal_header_prefix);
-};
-
-ChromeFirePHP._collectMessageObjectsForPrefix = function(header_map, prefix) {
- var results = [];
- const header_regexp = /(?:\d+)?\|(.+)/;
- var json = "";
- for (var i = 1; ; ++i) {
- var name = prefix + i;
- var value = header_map[name];
- if (!value)
- break;
-
- var match = value.match(header_regexp);
- if (!match) {
- Console.error("Failed to parse FirePHP log message: " + value);
- break;
- }
- var json_part = match[1];
- json += json_part.substring(0, json_part.lastIndexOf("|"));
- if (json_part.charAt(json_part.length - 1) === "\\")
- continue;
- try {
- var message = JSON.parse(json);
- results.push(message);
- } catch(e) {
- Console.error("Failed to parse FirePHP log message: " + json);
- }
- json = "";
- }
- return results;
-};
-
-ChromeFirePHP._checkProtoVersion = function(proto_header) {
- if (!proto_header) {
- Console.warn("WildFire protocol header not found");
- return;
- }
-
- var match = /http:\/\/meta\.wildfirehq\.org\/Protocol\/([^\/]+)\/(.+)/.exec(
- proto_header);
- if (!match) {
- Console.warn("Invalid WildFire protocol header");
- return;
- }
- var proto_name = match[1];
- var proto_version = match[2];
- if (proto_name !== "JsonStream" || proto_version !== "0.2") {
- Console.warn(
- "Unknown FirePHP protocol version: %s (expecting JsonStream/0.2)",
- proto_name + "/" + proto_version);
- return false;
- }
- return true;
-};
-
-chrome.devtools.network.addRequestHeaders({
- "X-FirePHP-Version": "0.0.6"
-});
-
-chrome.devtools.network.getHAR(function(result) {
- var entries = result.entries;
- if (!entries.length) {
- Console.warn("ChromeFirePHP suggests that you reload the page to track" +
- " FirePHP messages for all the requests");
- }
- for (var i = 0; i < entries.length; ++i)
- ChromeFirePHP.handleFirePhp_headers(entries[i]);
-
- chrome.devtools.network.onRequestFinished.addListener(
- ChromeFirePHP.handleFirePhpHeaders.bind(ChromeFirePHP));
-});
diff --git a/chrome/common/extensions/docs/examples/api/devtools/network/chrome-firephp/manifest.json b/chrome/common/extensions/docs/examples/api/devtools/network/chrome-firephp/manifest.json
deleted file mode 100644
index 275dced..0000000
--- a/chrome/common/extensions/docs/examples/api/devtools/network/chrome-firephp/manifest.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "name": "FirePHP for Chrome",
- "version": "1.1",
- "minimum_chrome_version": "10.0",
- "description": "Extends the Developer Tools, adding support for parsing FirePHP messages from server",
- "devtools_page": "devtools.html",
- "background": { "scripts": ["background.js"] },
- "permissions": [
- "http://*/*",
- "https://*/*"
- ],
- "manifest_version": 2
-}
diff --git a/chrome/common/extensions/docs/examples/api/devtools/panels/chrome-query/devtools.html b/chrome/common/extensions/docs/examples/api/devtools/panels/chrome-query/devtools.html
deleted file mode 100644
index bcf0413f..0000000
--- a/chrome/common/extensions/docs/examples/api/devtools/panels/chrome-query/devtools.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<html>
-<body>
-<script src="devtools.js"></script>
-</body>
-</html>
\ No newline at end of file
diff --git a/chrome/common/extensions/docs/examples/api/devtools/panels/chrome-query/devtools.js b/chrome/common/extensions/docs/examples/api/devtools/panels/chrome-query/devtools.js
deleted file mode 100644
index 5bf6a83..0000000
--- a/chrome/common/extensions/docs/examples/api/devtools/panels/chrome-query/devtools.js
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright (c) 2012 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.
-
-// The function below is executed in the context of the inspected page.
-var page_getProperties = function() {
- var data = window.jQuery && $0 ? jQuery.data($0) : {};
- // Make a shallow copy with a null prototype, so that sidebar does not
- // expose prototype.
- var props = Object.getOwnPropertyNames(data);
- var copy = { __proto__: null };
- for (var i = 0; i < props.length; ++i)
- copy[props[i]] = data[props[i]];
- return copy;
-}
-
-chrome.devtools.panels.elements.createSidebarPane(
- "jQuery Properties",
- function(sidebar) {
- function updateElementProperties() {
- sidebar.setExpression("(" + page_getProperties.toString() + ")()");
- }
- updateElementProperties();
- chrome.devtools.panels.elements.onSelectionChanged.addListener(
- updateElementProperties);
-});
diff --git a/chrome/common/extensions/docs/examples/api/devtools/panels/chrome-query/manifest.json b/chrome/common/extensions/docs/examples/api/devtools/panels/chrome-query/manifest.json
deleted file mode 100644
index a60485d7..0000000
--- a/chrome/common/extensions/docs/examples/api/devtools/panels/chrome-query/manifest.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- "name": "Chrome Query",
- "version": "1.1",
- "description": "Extends the Developer Tools, adding a sidebar that displays the jQuery data associated with the selected DOM element.",
- "devtools_page": "devtools.html",
- "manifest_version": 2
-}
diff --git a/chrome/common/extensions/docs/examples/api/displaySource/tabCast/README b/chrome/common/extensions/docs/examples/api/displaySource/tabCast/README
deleted file mode 100644
index c775b70..0000000
--- a/chrome/common/extensions/docs/examples/api/displaySource/tabCast/README
+++ /dev/null
@@ -1,2 +0,0 @@
-Demo Chrome extension that utilizes chrome.displaySource API's.
-The extension creates a WiFi Display Session from the captured tab media stream.
diff --git a/chrome/common/extensions/docs/examples/api/displaySource/tabCast/background.js b/chrome/common/extensions/docs/examples/api/displaySource/tabCast/background.js
deleted file mode 100644
index 830f273..0000000
--- a/chrome/common/extensions/docs/examples/api/displaySource/tabCast/background.js
+++ /dev/null
@@ -1,110 +0,0 @@
-// Copyright 2016 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.
-
-var g_sessionInfo = {};
-
-/**
- * When extension icon clicked, get device list
- * Then return the list to popup page
- */
-chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) {
- if (message.browserActionClicked) {
- getDeviceList(function(deviceList) {
- sendResponse({ returnDeviceList: deviceList });
- });
- }
- return true;
-});
-
-function getDeviceList(callback) {
- chrome.displaySource.getAvailableSinks(callback);
-}
-
-chrome.displaySource.onSessionTerminated.addListener(function(terminatedSink) {
- chrome.runtime.sendMessage({ sessionTerminated: true,
- currentSinkId: terminatedSink });
-
- if (g_sessionInfo.stream) {
- g_sessionInfo.stream.getTracks().forEach(function (track) {
- track.stop(); });
- delete g_sessionInfo.stream;
- }
- delete g_sessionInfo.sinkId;
-});
-
-chrome.displaySource.onSinksUpdated.addListener(function(updatedSinks) {
- console.log('Sinks updated');
- chrome.runtime.sendMessage({ sinksUpdated: true,
- currentSinkId: g_sessionInfo.sinkId,
- sinksList: updatedSinks});
-});
-
-function start(sinkId) {
- // If no session, proceed.
- if (!g_sessionInfo.sinkId) {
- g_sessionInfo.sinkId = parseInt(sinkId);
- captureTabAndStartSession(g_sessionInfo.sinkId);
- }
-}
-
-function captureTabAndStartSession(sink_id) {
- chrome.tabs.getCurrent(function(tab) {
- var video_constraints = {
- mandatory: {
- chromeMediaSource: 'tab',
- minWidth: 1920,
- minHeight: 1080,
- maxWidth: 1920,
- maxHeight: 1080,
- minFrameRate: 60,
- maxFrameRate: 60
- }
- };
-
- var constraints = {
- audio: true,
- video: true,
- videoConstraints: video_constraints
- };
-
- function onStream(stream) {
- g_sessionInfo.stream = stream;
- var session_info = {
- sinkId: sink_id,
- videoTrack: g_sessionInfo.stream.getVideoTracks()[0],
- audioTrack: g_sessionInfo.stream.getAudioTracks()[0]
- };
-
- function onStarted() {
- if (chrome.runtime.error) {
- console.log('The Session to sink ' + g_sessionInfo.sinkId
- + 'could not start, error: '
- + chrome.runtime.lastError.message);
- } else {
- console.log('The Session to sink ' + g_sessionInfo.sinkId
- + ' has started.');
- }
- }
- console.log('Starting session to sink: ' + sink_id);
- chrome.displaySource.startSession(session_info, onStarted);
- }
-
- chrome.tabCapture.capture(constraints, onStream);
- });
-}
-
-function stop() {
- function onTerminated() {
- if (chrome.runtime.lastError) {
- console.log('The Session to sink ' + g_sessionInfo.sinkId
- + 'could not terminate, error: '
- + chrome.runtime.lastError.message);
- } else {
- console.log('The Session to sink ' + g_sessionInfo.sinkId
- + ' has terminated.');
- }
- }
- console.log('Terminating session to sink: ' + g_sessionInfo.sinkId);
- chrome.displaySource.terminateSession(g_sessionInfo.sinkId, onTerminated);
-}
diff --git a/chrome/common/extensions/docs/examples/api/displaySource/tabCast/main.css b/chrome/common/extensions/docs/examples/api/displaySource/tabCast/main.css
deleted file mode 100644
index 70cd202..0000000
--- a/chrome/common/extensions/docs/examples/api/displaySource/tabCast/main.css
+++ /dev/null
@@ -1,60 +0,0 @@
-/* Copyright 2016 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.
- */
-
-.connecting {
- animation: glowing 1500ms infinite;
- background-color: #004A7F;
- border-radius: 10px;
- border: none;
- color: #FFFFFF;
- cursor: pointer;
- font-size: 20px;
- margin: 1px;
- outline: none;
- padding: 5px 10px;
- width: 170px;
-}
-
-.disconnected {
- background-color: #004A7F;
- border-radius: 10px;
- border: none;
- color: #FFFFFF;
- cursor: pointer;
- font-size: 20px;
- margin: 1px;
- outline: none;
- padding: 5px 10px;
- width: 170px;
-}
-
-.connected {
- background-color: #0094FF;
- border-radius: 10px;
- border: none;
- box-shadow: 0 0 20px #0094FF;
- color: #FFFFFF;
- cursor: pointer;
- font-size: 20px;
- margin: 1px;
- outline: none;
- padding: 5px 10px;
- width: 170px;
-}
-
-@keyframes glowing {
- 0% {
- background-color: #004A7F;
- box-shadow: 0 0 3px #004A7F;
- }
- 50% {
- background-color: #0094FF;
- box-shadow: 0 0 10px #0094FF;
- }
- 100% {
- background-color: #004A7F;
- box-shadow: 0 0 3px #004A7F;
- }
-}
diff --git a/chrome/common/extensions/docs/examples/api/displaySource/tabCast/main.html b/chrome/common/extensions/docs/examples/api/displaySource/tabCast/main.html
deleted file mode 100644
index 69cc035..0000000
--- a/chrome/common/extensions/docs/examples/api/displaySource/tabCast/main.html
+++ /dev/null
@@ -1,16 +0,0 @@
-<!--
- * Copyright 2016 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.
--->
-<!doctype html>
-<html>
-<head>
- <title>chrome.displaySource API test</title>
- <script src='main.js'></script>
- <link rel='stylesheet' type='text/css' href='main.css'>
-</head>
-<body>
- <div id='deviceList'></div>
-</body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/api/displaySource/tabCast/main.js b/chrome/common/extensions/docs/examples/api/displaySource/tabCast/main.js
deleted file mode 100644
index 4b08b26..0000000
--- a/chrome/common/extensions/docs/examples/api/displaySource/tabCast/main.js
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright 2016 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.
-
-chrome.runtime.sendMessage({ browserActionClicked : true }, function(response) {
- var deviceList = response.returnDeviceList;
- var backgroundPage = chrome.extension.getBackgroundPage();
- createButtonList(deviceList, backgroundPage);
-});
-
-chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) {
- var deviceButton = document.getElementById(message.currentSinkId);
- var backgroundPage = chrome.extension.getBackgroundPage();
-
- if (message.sinksUpdated) {
- var sinks = message.sinksList;
- var changedSink = null;
-
- for (let sink of sinks) {
- if (sink.id == message.currentSinkId) {
- changedSink = sink;
- }
- }
-
- if (!changedSink) {
- console.error('Failed to find sink: ' + message.currentSinkId);
- return;
- }
-
- if (changedSink.state == 'Connecting') {
- changeButtonState(deviceButton, 'connecting', backgroundPage.stop);
- } else if (changedSink.state == 'Connected') {
- changeButtonState(deviceButton, 'connected', backgroundPage.stop);
- }
- } else if (message.sessionTerminated) {
- changeButtonState(deviceButton, 'disconnected', backgroundPage.start);
- }
-});
-
-function createButtonList(deviceList, backgroundPage) {
- var divElement = document.getElementById('deviceList');
- if (!deviceList || !deviceList.length) {
- var errorMessage = document.createTextNode('No available '
- + 'sink devices found');
- divElement.appendChild(errorMessage);
- return;
- }
-
- deviceList.forEach(function(device) {
- if (!document.getElementById(device.id)) {
- var deviceButton = document.createElement('input');
-
- deviceButton.type = 'button';
- deviceButton.value = device.name;
- deviceButton.id = device.id;
-
- if (device.state == 'Disconnected') {
- changeButtonState(deviceButton, 'disconnected', backgroundPage.start);
- } else if (device.state == 'Connecting') {
- changeButtonState(deviceButton, 'connecting', backgroundPage.stop);
- } else if (device.state == 'Connected') {
- changeButtonState(deviceButton, 'connected', backgroundPage.stop);
- } else {
- console.error('Unexpected sink state.');
- return;
- }
-
- divElement.appendChild(deviceButton);
- }
- });
-}
-
-function changeButtonState(button, styleName, method) {
- button.className = styleName;
- var sinkId = parseInt(button.id);
- button.onclick = function() { method(sinkId) };
-}
-
diff --git a/chrome/common/extensions/docs/examples/api/displaySource/tabCast/manifest.json b/chrome/common/extensions/docs/examples/api/displaySource/tabCast/manifest.json
deleted file mode 100644
index b3fc8aa1..0000000
--- a/chrome/common/extensions/docs/examples/api/displaySource/tabCast/manifest.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- "name": "tabCast",
- "version": "0.1",
- "manifest_version": 2,
- "description": "Creates a WiFi Display Session from the captured tab media stream using chrome.displaySource API.",
- "permissions": [
- "tabCapture", "tabs", "displaySource"
- ],
- "browser_action": {
- "default_title": "Tab cast",
- "default_popup": "main.html"
- },
- "background": {
- "scripts": ["background.js"],
- "persistent": false
- }
-}
diff --git a/chrome/common/extensions/docs/examples/api/document_scan/README.md b/chrome/common/extensions/docs/examples/api/document_scan/README.md
deleted file mode 100644
index 22c61ca..0000000
--- a/chrome/common/extensions/docs/examples/api/document_scan/README.md
+++ /dev/null
@@ -1,10 +0,0 @@
-# Document Scanning API Sample
-
-This demo interfaces with the Chrome document scanning API to acquire scanned
-images.
-
-## APIs
-
-* [Document scanning API](https://developer.chrome.com/apps/document_scan)
-* [Runtime](https://developer.chrome.com/apps/runtime)
-* [Window](https://developer.chrome.com/apps/app_window)
diff --git a/chrome/common/extensions/docs/examples/api/document_scan/background.js b/chrome/common/extensions/docs/examples/api/document_scan/background.js
deleted file mode 100644
index 7f7faf23..0000000
--- a/chrome/common/extensions/docs/examples/api/document_scan/background.js
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2014 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.
-
-chrome.app.runtime.onLaunched.addListener(function() {
- chrome.app.window.create('scan.html', {
- singleton: true,
- id: "ChromeApps-Sample-Document-Scan",
- bounds: {
- 'width': 480,
- 'height': 640
- }
- });
-});
diff --git a/chrome/common/extensions/docs/examples/api/document_scan/manifest.json b/chrome/common/extensions/docs/examples/api/document_scan/manifest.json
deleted file mode 100644
index 8f788d3..0000000
--- a/chrome/common/extensions/docs/examples/api/document_scan/manifest.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "name": "Document Scanning API Sample",
- "version": "0.1",
- "manifest_version": 2,
- "minimum_chrome_version": "37",
- "app": {
- "background": {
- "scripts": ["background.js"]
- }
- },
- "permissions": [],
- "optional_permissions": [ "documentScan" ]
-}
diff --git a/chrome/common/extensions/docs/examples/api/document_scan/scan.css b/chrome/common/extensions/docs/examples/api/document_scan/scan.css
deleted file mode 100644
index 899b0f6..0000000
--- a/chrome/common/extensions/docs/examples/api/document_scan/scan.css
+++ /dev/null
@@ -1,36 +0,0 @@
-/* Copyright 2014 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.
- */
-
-#waitAnimation {
- position: absolute;
- left: 0px;
- top: 0px;
- height:100%;
- width:100%;
- z-index:1000;
- background-color:black;
- opacity:0.6;
-}
-
-#waitSpinner {
- position: absolute;
- height:60px;
- width:60px;
- top: 50%;
- left: 50%;
- margin-left: -30px;
- margin-top: -30px;
- animation: rotation .6s infinite linear;
- border-left:6px solid rgba(180,174,239,.15);
- border-right:6px solid rgba(180,174,239,.15);
- border-bottom:6px solid rgba(180,174,239,.15);
- border-top:6px solid rgba(180,174,239,.8);
- border-radius:100%;
-}
-
-@keyframes rotation {
- from {transform: rotate(0deg);}
- to {transform: rotate(359deg);}
-}
diff --git a/chrome/common/extensions/docs/examples/api/document_scan/scan.html b/chrome/common/extensions/docs/examples/api/document_scan/scan.html
deleted file mode 100644
index a7b24b6..0000000
--- a/chrome/common/extensions/docs/examples/api/document_scan/scan.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE html>
-<html>
- <head>
- <title>Scanner Control</title>
- <link rel="stylesheet" type="text/css" href="scan.css">
- </head>
- <body>
- <div id="waitAnimation" style="display: none;">
- <div id="waitSpinner"></div>
- </div>
- </img>
- <button id="requestButton">Request App permissions</button>
- <button id="scanButton">Scan</button>
- <div id="scannedImages">
- </div>
- <script src="scan.js"></script>
- </body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/api/document_scan/scan.js b/chrome/common/extensions/docs/examples/api/document_scan/scan.js
deleted file mode 100644
index 23d84957..0000000
--- a/chrome/common/extensions/docs/examples/api/document_scan/scan.js
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright 2014 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.
-
-var requestButton = document.getElementById("requestButton");
-var scanButton = document.getElementById('scanButton');
-var scannedImages = document.getElementById('scannedImages');
-var waitAnimation = document.getElementById('waitAnimation');
-var imageMimeType;
-
-function setOnlyChild(parent, child) {
- while (parent.firstChild) {
- parent.removeChild(parent.firstChild);
- }
- parent.appendChild(child);
-}
-
-var gotPermission = function(result) {
- waitAnimation.style.display = 'block';
- requestButton.style.display = 'none';
- scanButton.style.display = 'block';
- console.log('App was granted the "documentScan" permission.');
- waitAnimation.style.display = 'none';
-};
-
-var permissionObj = {permissions: ['documentScan']};
-
-requestButton.addEventListener('click', function() {
- waitAnimation.style.display = 'block';
- chrome.permissions.request( permissionObj, function(result) {
- if (result) {
- gotPermission();
- } else {
- console.log('App was not granted the "documentScan" permission.');
- console.log(chrome.runtime.lastError);
- }
- });
-});
-
-var onScanCompleted = function(scan_results) {
- waitAnimation.style.display = 'none';
- if (chrome.runtime.lastError) {
- console.log('Scan failed: ' + chrome.runtime.lastError.message);
- return;
- }
- numImages = scan_results.dataUrls.length;
- console.log('Scan completed with ' + numImages + ' images.');
- for (var i = 0; i < numImages; i++) {
- urlData = scan_results.dataUrls[i]
- console.log('Scan ' + i + ' data length ' +
- urlData.length + '.');
- console.log('URL is ' + urlData);
- var scannedImage = document.createElement('img');
- scannedImage.src = urlData;
- scannedImages.insertBefore(scannedImage, scannedImages.firstChild);
- }
-};
-
-scanButton.addEventListener('click', function() {
- var scanProperties = {};
- waitAnimation.style.display = 'block';
- chrome.documentScan.scan(scanProperties, onScanCompleted);
-});
-
-chrome.permissions.contains(permissionObj, function(result) {
- if (result) {
- gotPermission();
- }
-});
diff --git a/chrome/common/extensions/docs/examples/api/downloads/download_filename_controller/bg.js b/chrome/common/extensions/docs/examples/api/downloads/download_filename_controller/bg.js
deleted file mode 100644
index 3494607..0000000
--- a/chrome/common/extensions/docs/examples/api/downloads/download_filename_controller/bg.js
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright (c) 2012 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.
-
-function matches(rule, item) {
- if (rule.matcher == 'js')
- return eval(rule.match_param);
- if (rule.matcher == 'hostname') {
- var link = document.createElement('a');
- link.href = item.url.toLowerCase();
- var host = (rule.match_param.indexOf(':') < 0) ? link.hostname : link.host;
- return (host.indexOf(rule.match_param.toLowerCase()) ==
- (host.length - rule.match_param.length));
- }
- if (rule.matcher == 'default')
- return item.filename == rule.match_param;
- if (rule.matcher == 'url-regex')
- return (new RegExp(rule.match_param)).test(item.url);
- if (rule.matcher == 'default-regex')
- return (new RegExp(rule.match_param)).test(item.filename);
- return false;
-}
-
-chrome.downloads.onDeterminingFilename.addListener(function(item, __suggest) {
- function suggest(filename, conflictAction) {
- __suggest({filename: filename,
- conflictAction: conflictAction,
- conflict_action: conflictAction});
- // conflict_action was renamed to conflictAction in
- // https://chromium.googlesource.com/chromium/src/+/f1d784d6938b8fe8e0d257e41b26341992c2552c
- // which was first picked up in branch 1580.
- }
- var rules = localStorage.rules;
- try {
- rules = JSON.parse(rules);
- } catch (e) {
- localStorage.rules = JSON.stringify([]);
- }
- for (var index = 0; index < rules.length; ++index) {
- var rule = rules[index];
- if (rule.enabled && matches(rule, item)) {
- if (rule.action == 'overwrite') {
- suggest(item.filename, 'overwrite');
- } else if (rule.action == 'prompt') {
- suggest(item.filename, 'prompt');
- } else if (rule.action == 'js') {
- eval(rule.action_js);
- }
- break;
- }
- }
-});
diff --git a/chrome/common/extensions/docs/examples/api/downloads/download_filename_controller/manifest.json b/chrome/common/extensions/docs/examples/api/downloads/download_filename_controller/manifest.json
deleted file mode 100644
index 6bdb58ec..0000000
--- a/chrome/common/extensions/docs/examples/api/downloads/download_filename_controller/manifest.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{"name": "Download Filename Controller",
- "description": "Download Filename Controller",
- "version": "0.1",
- "background": {"scripts": ["bg.js"], "persistent": false},
- "options_page": "options.html",
- "permissions": ["downloads"],
- "content_security_policy": "script-src 'self'; default-src 'self'",
- "manifest_version": 2}
diff --git a/chrome/common/extensions/docs/examples/api/downloads/download_filename_controller/options.html b/chrome/common/extensions/docs/examples/api/downloads/download_filename_controller/options.html
deleted file mode 100644
index 01d5317f..0000000
--- a/chrome/common/extensions/docs/examples/api/downloads/download_filename_controller/options.html
+++ /dev/null
@@ -1,39 +0,0 @@
-<!doctype html>
-<html>
-<head>
-<title>Download Filename Controller</title>
-<script src="options.js"></script>
-</head>
-<body>
-<table id=rules></table>
-<button id=new>New Rule</button>
-<table hidden>
-<tr id=rule-template hidden>
- <td class=nowrap><button class=move-up>↑</button>
- <button class=move-down>↓</button></td>
- <td>
- <select class=matcher>
- <option value=hostname>Hostname</option>
- <option value=url-regex>URL RegExp</option>
- <option value=default>Default Filename</option>
- <option value=default-regex>Default Filename RegExp</option>
- <option value=js>Javascript</option>
- </select>
- <input type=text class=match-param>
- <select class=action>
- <option value=overwrite>Overwrite default filename</option>
- <option value=prompt>Prompt if default filename exists</option>
- <option value=js>Javascript</option>
- </select>
- <textarea class=action-js rows=5 cols=83>console.log(item.url)
-console.log(item.filename)
-// http://developer.chrome.com/extensions/downloads.html#type-DownloadItem
-// http://developer.chrome.com/extensions/downloads.html#type-FilenameConflictAction
-suggest('hello.txt', 'overwrite')</textarea></td>
- <td><span class=nowrap><input type=checkbox class=enabled checked>
- <label class=enabled-label>Enabled</label></span>
- <button class=remove>Remove</button></td>
-</tr>
-</table>
-</body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/api/downloads/download_filename_controller/options.js b/chrome/common/extensions/docs/examples/api/downloads/download_filename_controller/options.js
deleted file mode 100644
index d25ae42..0000000
--- a/chrome/common/extensions/docs/examples/api/downloads/download_filename_controller/options.js
+++ /dev/null
@@ -1,96 +0,0 @@
-// Copyright (c) 2013 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.
-
-function Rule(data) {
- var rules = document.getElementById('rules');
- this.node = document.getElementById('rule-template').cloneNode(true);
- this.node.id = 'rule' + (Rule.next_id++);
- this.node.rule = this;
- rules.appendChild(this.node);
- this.node.hidden = false;
-
- if (data) {
- this.getElement('matcher').value = data.matcher;
- this.getElement('match-param').value = data.match_param;
- this.getElement('action').value = data.action;
- this.getElement('action-js').value = data.action_js;
- this.getElement('enabled').checked = data.enabled;
- }
-
- this.getElement('enabled-label').htmlFor = this.getElement('enabled').id =
- this.node.id + '-enabled';
-
- this.render();
-
- this.getElement('matcher').onchange = storeRules;
- this.getElement('match-param').onkeyup = storeRules;
- this.getElement('action').onchange = storeRules;
- this.getElement('action-js').onkeyup = storeRules;
- this.getElement('enabled').onchange = storeRules;
-
- var rule = this;
- this.getElement('move-up').onclick = function() {
- var sib = rule.node.previousSibling;
- rule.node.parentNode.removeChild(rule.node);
- sib.parentNode.insertBefore(rule.node, sib);
- storeRules();
- };
- this.getElement('move-down').onclick = function() {
- var parentNode = rule.node.parentNode;
- var sib = rule.node.nextSibling.nextSibling;
- parentNode.removeChild(rule.node);
- if (sib) {
- parentNode.insertBefore(rule.node, sib);
- } else {
- parentNode.appendChild(rule.node);
- }
- storeRules();
- };
- this.getElement('remove').onclick = function() {
- rule.node.parentNode.removeChild(rule.node);
- storeRules();
- };
- storeRules();
-}
-
-Rule.prototype.getElement = function(name) {
- return document.querySelector('#' + this.node.id + ' .' + name);
-}
-
-Rule.prototype.render = function() {
- this.getElement('move-up').disabled = !this.node.previousSibling;
- this.getElement('move-down').disabled = !this.node.nextSibling;
- this.getElement('action-js').style.display =
- (this.getElement('action').value == 'js') ? 'block' : 'none';
-}
-
-Rule.next_id = 0;
-
-function loadRules() {
- var rules = localStorage.rules;
- try {
- JSON.parse(rules).forEach(function(rule) {new Rule(rule);});
- } catch (e) {
- localStorage.rules = JSON.stringify([]);
- }
-}
-
-function storeRules() {
- localStorage.rules = JSON.stringify(Array.prototype.slice.apply(
- document.getElementById('rules').childNodes).map(function(node) {
- node.rule.render();
- return {matcher: node.rule.getElement('matcher').value,
- match_param: node.rule.getElement('match-param').value,
- action: node.rule.getElement('action').value,
- action_js: node.rule.getElement('action-js').value,
- enabled: node.rule.getElement('enabled').checked};
- }));
-}
-
-window.onload = function() {
- loadRules();
- document.getElementById('new').onclick = function() {
- new Rule();
- };
-}
diff --git a/chrome/common/extensions/docs/examples/api/downloads/download_links/manifest.json b/chrome/common/extensions/docs/examples/api/downloads/download_links/manifest.json
deleted file mode 100644
index f252f0d..0000000
--- a/chrome/common/extensions/docs/examples/api/downloads/download_links/manifest.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "name": "Download Selected Links",
- "description": "Select links on a page and download them.",
- "version": "0.1",
- "minimum_chrome_version": "16.0.884",
- "permissions": ["downloads", "<all_urls>"],
- "browser_action": {"default_popup": "popup.html"},
- "manifest_version": 2
-}
diff --git a/chrome/common/extensions/docs/examples/api/downloads/download_links/popup.html b/chrome/common/extensions/docs/examples/api/downloads/download_links/popup.html
deleted file mode 100644
index cba0b76..0000000
--- a/chrome/common/extensions/docs/examples/api/downloads/download_links/popup.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE html>
-<head>
-<script src='popup.js'></script>
-</head>
-<body>
-<input type=text id=filter placeholder=Filter>
-<input type=checkbox id=regex>
-<label for=regex>Regex</label><br>
-<button id=download0>Download All!</button>
-<table id=links>
- <tr>
- <th><input type=checkbox checked id=toggle_all></th>
- <th align=left>URL</th>
- </tr>
-</table>
-<button id=download1>Download All!</button>
-</body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/api/downloads/download_links/popup.js b/chrome/common/extensions/docs/examples/api/downloads/download_links/popup.js
deleted file mode 100644
index c889245..0000000
--- a/chrome/common/extensions/docs/examples/api/downloads/download_links/popup.js
+++ /dev/null
@@ -1,117 +0,0 @@
-// Copyright (c) 2012 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.
-
-// This extension demonstrates using chrome.downloads.download() to
-// download URLs.
-
-var allLinks = [];
-var visibleLinks = [];
-
-// Display all visible links.
-function showLinks() {
- var linksTable = document.getElementById('links');
- while (linksTable.children.length > 1) {
- linksTable.removeChild(linksTable.children[linksTable.children.length - 1])
- }
- for (var i = 0; i < visibleLinks.length; ++i) {
- var row = document.createElement('tr');
- var col0 = document.createElement('td');
- var col1 = document.createElement('td');
- var checkbox = document.createElement('input');
- checkbox.checked = true;
- checkbox.type = 'checkbox';
- checkbox.id = 'check' + i;
- col0.appendChild(checkbox);
- col1.innerText = visibleLinks[i];
- col1.style.whiteSpace = 'nowrap';
- col1.onclick = function() {
- checkbox.checked = !checkbox.checked;
- }
- row.appendChild(col0);
- row.appendChild(col1);
- linksTable.appendChild(row);
- }
-}
-
-// Toggle the checked state of all visible links.
-function toggleAll() {
- var checked = document.getElementById('toggle_all').checked;
- for (var i = 0; i < visibleLinks.length; ++i) {
- document.getElementById('check' + i).checked = checked;
- }
-}
-
-// Download all visible checked links.
-function downloadCheckedLinks() {
- for (var i = 0; i < visibleLinks.length; ++i) {
- if (document.getElementById('check' + i).checked) {
- chrome.downloads.download({url: visibleLinks[i]},
- function(id) {
- });
- }
- }
- window.close();
-}
-
-// Re-filter allLinks into visibleLinks and reshow visibleLinks.
-function filterLinks() {
- var filterValue = document.getElementById('filter').value;
- if (document.getElementById('regex').checked) {
- visibleLinks = allLinks.filter(function(link) {
- return link.match(filterValue);
- });
- } else {
- var terms = filterValue.split(' ');
- visibleLinks = allLinks.filter(function(link) {
- for (var termI = 0; termI < terms.length; ++termI) {
- var term = terms[termI];
- if (term.length != 0) {
- var expected = (term[0] != '-');
- if (!expected) {
- term = term.substr(1);
- if (term.length == 0) {
- continue;
- }
- }
- var found = (-1 !== link.indexOf(term));
- if (found != expected) {
- return false;
- }
- }
- }
- return true;
- });
- }
- showLinks();
-}
-
-// Add links to allLinks and visibleLinks, sort and show them. send_links.js is
-// injected into all frames of the active tab, so this listener may be called
-// multiple times.
-chrome.extension.onRequest.addListener(function(links) {
- for (var index in links) {
- allLinks.push(links[index]);
- }
- allLinks.sort();
- visibleLinks = allLinks;
- showLinks();
-});
-
-// Set up event handlers and inject send_links.js into all frames in the active
-// tab.
-window.onload = function() {
- document.getElementById('filter').onkeyup = filterLinks;
- document.getElementById('regex').onchange = filterLinks;
- document.getElementById('toggle_all').onchange = toggleAll;
- document.getElementById('download0').onclick = downloadCheckedLinks;
- document.getElementById('download1').onclick = downloadCheckedLinks;
-
- chrome.windows.getCurrent(function (currentWindow) {
- chrome.tabs.query({active: true, windowId: currentWindow.id},
- function(activeTabs) {
- chrome.tabs.executeScript(
- activeTabs[0].id, {file: 'send_links.js', allFrames: true});
- });
- });
-};
diff --git a/chrome/common/extensions/docs/examples/api/downloads/download_links/send_links.js b/chrome/common/extensions/docs/examples/api/downloads/download_links/send_links.js
deleted file mode 100644
index 29a06a6..0000000
--- a/chrome/common/extensions/docs/examples/api/downloads/download_links/send_links.js
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright (c) 2012 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.
-
-// Send back to the popup a sorted deduped list of valid link URLs on this page.
-// The popup injects this script into all frames in the active tab.
-
-var links = [].slice.apply(document.getElementsByTagName('a'));
-links = links.map(function(element) {
- // Return an anchor's href attribute, stripping any URL fragment (hash '#').
- // If the html specifies a relative path, chrome converts it to an absolute
- // URL.
- var href = element.href;
- var hashIndex = href.indexOf('#');
- if (hashIndex >= 0) {
- href = href.substr(0, hashIndex);
- }
- return href;
-});
-
-links.sort();
-
-// Remove duplicates and invalid URLs.
-var kBadPrefix = 'javascript';
-for (var i = 0; i < links.length;) {
- if (((i > 0) && (links[i] == links[i - 1])) ||
- (links[i] == '') ||
- (kBadPrefix == links[i].toLowerCase().substr(0, kBadPrefix.length))) {
- links.splice(i, 1);
- } else {
- ++i;
- }
-}
-
-chrome.extension.sendRequest(links);
diff --git a/chrome/common/extensions/docs/examples/api/downloads/download_manager/_locales/en/messages.json b/chrome/common/extensions/docs/examples/api/downloads/download_manager/_locales/en/messages.json
deleted file mode 100644
index 83d05e7..0000000
--- a/chrome/common/extensions/docs/examples/api/downloads/download_manager/_locales/en/messages.json
+++ /dev/null
@@ -1,290 +0,0 @@
-{"extName": {
- "message": "Download Manager Button",
- "description": "Extension name"},
- "extDesc": {
- "message": "Browser Action Download Manager User Interface for Google Chrome",
- "description": "Extension description"},
- "badChromeVersion": {
- "message": "The downloads API is only available on the canary, dev, and beta channels.",
- "description": ""},
- "tabTitle": {
- "message": "Downloads",
- "description": "tab title"},
- "searchPlaceholder": {
- "message": "Search Downloads",
- "description": ""},
- "clearAllTitle": {
- "message": "Erase All Visible Downloads",
- "description": ""},
- "openDownloadsFolderTitle": {
- "message": "Open Downloads Folder",
- "description": ""},
- "zeroItems": {
- "message": "There are zero download items.",
- "description": ""},
- "searching": {
- "message": "Teleporting lots of goats...",
- "description": ""},
- "zeroSearchResults": {
- "message": "Zero matches",
- "description": ""},
- "managementPermissionInfo": {
- "message": "Some files were downloaded by an extension.",
- "description": ""},
- "grantManagementPermission": {
- "message": "Show links to extensions that download files.",
- "description": ""},
- "showOlderDownloads": {
- "message": "Show Older Downloads",
- "description": ""},
- "loadingOlderDownloads": {
- "message": "Loading Older Downloads...",
- "description": ""},
- "openTitle": {
- "message": "Open",
- "description": ""},
- "pauseTitle": {
- "message": "Pause",
- "description": ""},
- "resumeTitle": {
- "message": "Resume",
- "description": ""},
- "cancelTitle": {
- "message": "Cancel",
- "description": ""},
- "removeFileTitle": {
- "message": "Remove file",
- "description": ""},
- "eraseTitle": {
- "message": "Erase",
- "description": ""},
- "retryTitle": {
- "message": "Retry",
- "description": ""},
- "referrerTitle": {
- "message": "Referrer",
- "description": ""},
- "month0abbr": {"message": "Jan","description": ""},
- "month1abbr": {"message": "Feb","description": ""},
- "month2abbr": {"message": "Mar","description": ""},
- "month3abbr": {"message": "Apr","description": ""},
- "month4abbr": {"message": "May","description": ""},
- "month5abbr": {"message": "Jun","description": ""},
- "month6abbr": {"message": "Jul","description": ""},
- "month7abbr": {"message": "Aug","description": ""},
- "month8abbr": {"message": "Sep","description": ""},
- "month9abbr": {"message": "Oct","description": ""},
- "month10abbr": {"message": "Nov","description": ""},
- "month11abbr": {"message": "Dec","description": ""},
- "openWhenCompleteFinishing": {
- "message": "Opening in just a moment",
- "description": ""},
- "timeLeftFinishing": {
- "message": "finishing...",
- "description": ""},
- "openWhenCompleteDays": {
- "message": "Opening in $days$d $hours$h",
- "description": "",
- "placeholders": {
- "days": {
- "content": "$1",
- "example": "2"},
- "hours": {
- "content": "$2",
- "example": "23"}}},
- "timeLeftDays": {
- "message": "$days$d $hours$h left",
- "description": "",
- "placeholders": {
- "days": {
- "content": "$1",
- "example": "2"},
- "hours": {
- "content": "$2",
- "example": "23"}}},
- "openWhenCompleteHours": {
- "message": "Opening in $hours$h $mins$m",
- "description": "",
- "placeholders": {
- "hours": {
- "content": "$1",
- "example": "23"},
- "mins": {
- "content": "$2",
- "example": "59"}}},
- "timeLeftHours": {
- "message": "$hours$h $mins$m left",
- "description": "",
- "placeholders": {
- "hours": {
- "content": "$1",
- "example": "23"},
- "mins": {
- "content": "$2",
- "example": "59"}}},
- "openWhenCompleteMinutes": {
- "message": "Opening in $mins$m $sec$s",
- "description": "",
- "placeholders": {
- "mins": {
- "content": "$1",
- "example": "59"},
- "sec": {
- "content": "$2",
- "example": "59"}}},
- "timeLeftMinutes": {
- "message": "$mins$m $sec$s left",
- "description": "",
- "placeholders": {
- "mins": {
- "content": "$1",
- "example": "59"},
- "sec": {
- "content": "$2",
- "example": "59"}}},
- "openWhenCompleteSeconds": {
- "message": "Opening in $sec$s",
- "description": "",
- "placeholders": {
- "sec": {
- "content": "$1",
- "example": "59"}}},
- "timeLeftSeconds": {
- "message": "$sec$s left",
- "description": "",
- "placeholders": {
- "sec": {
- "content": "$1",
- "example": "59"}}},
- "error_FILE_FAILED": {
- "message": "File Failed",
- "description": ""},
- "error_FILE_ACCESS_DENIED": {
- "message": "File-System Access Denied",
- "description": ""},
- "error_FILE_NO_SPACE": {
- "message": "No Space On Disk",
- "description": ""},
- "error_FILE_NAME_TOO_LONG": {
- "message": "Filename Too Long",
- "description": ""},
- "error_FILE_TOO_LARGE": {
- "message": "File Too Large",
- "description": ""},
- "error_FILE_VIRUS_INFECTED": {
- "message": "Virus Infected",
- "description": ""},
- "error_FILE_TRANSIENT_ERROR": {
- "message": "Transient File-System Error",
- "description": ""},
- "error_FILE_BLOCKED": {
- "message": "File Blocked",
- "description": ""},
- "error_FILE_SECURITY_CHECK_FAILED": {
- "message": "Security Check Failed",
- "description": ""},
- "error_FILE_TOO_SHORT": {
- "message": "File Too Short",
- "description": ""},
- "error_NETWORK_FAILED": {
- "message": "Network Failure",
- "description": ""},
- "error_NETWORK_TIMEOUT": {
- "message": "Network Timeout",
- "description": ""},
- "error_NETWORK_DISCONNECTED": {
- "message": "Network Disconnected",
- "description": ""},
- "error_NETWORK_SERVER_DOWN": {
- "message": "Server Down",
- "description": ""},
- "error_SERVER_FAILED": {
- "message": "Server Failure",
- "description": ""},
- "error_SERVER_NO_RANGE": {
- "message": "Server No Range",
- "description": ""},
- "error_SERVER_PRECONDITION": {
- "message": "Server Precondition Failure",
- "description": ""},
- "error_SERVER_BAD_CONTENT": {
- "message": "Bad Content",
- "description": ""},
- "error_USER_CANCELED": {
- "message": "Cancelled",
- "description": ""},
- "error_USER_SHUTDOWN": {
- "message": "Cancelled",
- "description": ""},
- "error_CRASH": {
- "message": "Crash",
- "description": ""},
- "error_1": {
- "message": "File Failed",
- "description": ""},
- "error_2": {
- "message": "File-System Access Denied",
- "description": ""},
- "error_3": {
- "message": "No Space On Disk",
- "description": ""},
- "error_5": {
- "message": "Filename Too Long",
- "description": ""},
- "error_6": {
- "message": "File Too Large",
- "description": ""},
- "error_7": {
- "message": "Virus Infected",
- "description": ""},
- "error_10": {
- "message": "Transient File-System Error",
- "description": ""},
- "error_11": {
- "message": "File Blocked",
- "description": ""},
- "error_12": {
- "message": "Security Check Failed",
- "description": ""},
- "error_13": {
- "message": "File Too Short",
- "description": ""},
- "error_20": {
- "message": "Network Failure",
- "description": ""},
- "error_21": {
- "message": "Network Timeout",
- "description": ""},
- "error_22": {
- "message": "Network Disconnected",
- "description": ""},
- "error_23": {
- "message": "Server Down",
- "description": ""},
- "error_30": {
- "message": "Server Failure",
- "description": ""},
- "error_31": {
- "message": "Server No Range",
- "description": ""},
- "error_32": {
- "message": "Server Precondition Failure",
- "description": ""},
- "error_33": {
- "message": "Bad Content",
- "description": ""},
- "error_40": {
- "message": "Cancelled",
- "description": ""},
- "error_41": {
- "message": "Cancelled",
- "description": ""},
- "error_50": {
- "message": "Crash",
- "description": ""},
- "errorRemoved": {
- "message": "Removed",
- "description": ""},
- "showInFolderTitle": {
- "message": "Show in Folder",
- "description": "Alt text for show in folder icon"}}
diff --git a/chrome/common/extensions/docs/examples/api/downloads/download_manager/background.js b/chrome/common/extensions/docs/examples/api/downloads/download_manager/background.js
deleted file mode 100644
index b1f8f2cd..0000000
--- a/chrome/common/extensions/docs/examples/api/downloads/download_manager/background.js
+++ /dev/null
@@ -1,267 +0,0 @@
-// Copyright (c) 2013 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.
-
-if (chrome.downloads.setShelfEnabled)
- chrome.downloads.setShelfEnabled(false);
-
-var colors = {
- progressColor: '#0d0',
- arrow: '#555',
- danger: 'red',
- complete: 'green',
- paused: 'grey',
- background: 'white',
-};
-
-function drawLine(ctx, x1, y1, x2, y2) {
- ctx.beginPath();
- ctx.moveTo(x1, y1);
- ctx.lineTo(x2, y2);
- ctx.stroke();
-}
-
-Math.TAU = 2 * Math.PI; // http://tauday.com/tau-manifesto
-
-function drawProgressArc(ctx, startAngle, endAngle) {
- var center = ctx.canvas.width/2;
- ctx.lineWidth = Math.round(ctx.canvas.width*0.1);
- ctx.beginPath();
- ctx.moveTo(center, center);
- ctx.arc(center, center, center * 0.9, startAngle, endAngle, false);
- ctx.fill();
- ctx.stroke();
-}
-
-function drawUnknownProgressSpinner(ctx) {
- var center = ctx.canvas.width/2;
- const segments = 16;
- var segArc = Math.TAU / segments;
- for (var seg = 0; seg < segments; ++seg) {
- ctx.fillStyle = ctx.strokeStyle = (
- ((seg % 2) == 0) ? colors.progressColor : colors.background);
- drawProgressArc(ctx, (seg-4)*segArc, (seg-3)*segArc);
- }
-}
-
-function drawProgressSpinner(ctx, stage) {
- ctx.fillStyle = ctx.strokeStyle = colors.progressColor;
- var clocktop = -Math.TAU/4;
- drawProgressArc(ctx, clocktop, clocktop + (stage * Math.TAU));
-}
-
-function drawArrow(ctx) {
- ctx.beginPath();
- ctx.lineWidth = Math.round(ctx.canvas.width*0.1);
- ctx.lineJoin = 'round';
- ctx.strokeStyle = ctx.fillStyle = colors.arrow;
- var center = ctx.canvas.width/2;
- var minw2 = center*0.2;
- var maxw2 = center*0.60;
- var height2 = maxw2;
- ctx.moveTo(center-minw2, center-height2);
- ctx.lineTo(center+minw2, center-height2);
- ctx.lineTo(center+minw2, center);
- ctx.lineTo(center+maxw2, center);
- ctx.lineTo(center, center+height2);
- ctx.lineTo(center-maxw2, center);
- ctx.lineTo(center-minw2, center);
- ctx.lineTo(center-minw2, center-height2);
- ctx.lineTo(center+minw2, center-height2);
- ctx.stroke();
- ctx.fill();
-}
-
-function drawDangerBadge(ctx) {
- var s = ctx.canvas.width/100;
- ctx.fillStyle = colors.danger;
- ctx.strokeStyle = colors.background;
- ctx.lineWidth = Math.round(s*5);
- var edge = ctx.canvas.width-ctx.lineWidth;
- ctx.beginPath();
- ctx.moveTo(s*75, s*55);
- ctx.lineTo(edge, edge);
- ctx.lineTo(s*55, edge);
- ctx.lineTo(s*75, s*55);
- ctx.lineTo(edge, edge);
- ctx.fill();
- ctx.stroke();
-}
-
-function drawPausedBadge(ctx) {
- var s = ctx.canvas.width/100;
- ctx.beginPath();
- ctx.strokeStyle = colors.background;
- ctx.lineWidth = Math.round(s*5);
- ctx.rect(s*55, s*55, s*15, s*35);
- ctx.fillStyle = colors.paused;
- ctx.fill();
- ctx.stroke();
- ctx.rect(s*75, s*55, s*15, s*35);
- ctx.fill();
- ctx.stroke();
-}
-
-function drawCompleteBadge(ctx) {
- var s = ctx.canvas.width/100;
- ctx.beginPath();
- ctx.arc(s*75, s*75, s*15, 0, Math.TAU, false);
- ctx.fillStyle = colors.complete;
- ctx.fill();
- ctx.strokeStyle = colors.background;
- ctx.lineWidth = Math.round(s*5);
- ctx.stroke();
-}
-
-function drawIcon(side, options) {
- var canvas = document.createElement('canvas');
- canvas.width = canvas.height = side;
- document.body.appendChild(canvas);
- var ctx = canvas.getContext('2d');
- if (options.anyInProgress) {
- if (options.anyMissingTotalBytes) {
- drawUnknownProgressSpinner(ctx);
- } else {
- drawProgressSpinner(ctx, (options.totalBytesReceived /
- options.totalTotalBytes));
- }
- }
- drawArrow(ctx);
- if (options.anyDangerous) {
- drawDangerBadge(ctx);
- } else if (options.anyPaused) {
- drawPausedBadge(ctx);
- } else if (options.anyRecentlyCompleted) {
- drawCompleteBadge(ctx);
- }
- return canvas;
-}
-
-function maybeOpen(id) {
- var openWhenComplete = [];
- try {
- openWhenComplete = JSON.parse(localStorage.openWhenComplete);
- } catch (e) {
- localStorage.openWhenComplete = JSON.stringify(openWhenComplete);
- }
- var openNowIndex = openWhenComplete.indexOf(id);
- if (openNowIndex >= 0) {
- chrome.downloads.open(id);
- openWhenComplete.splice(openNowIndex, 1);
- localStorage.openWhenComplete = JSON.stringify(openWhenComplete);
- }
-}
-
-function setBrowserActionIcon(options) {
- var canvas1 = drawIcon(19, options);
- var canvas2 = drawIcon(38, options);
- var imageData = {};
- imageData['' + canvas1.width] = canvas1.getContext('2d').getImageData(
- 0, 0, canvas1.width, canvas1.height);
- imageData['' + canvas2.width] = canvas2.getContext('2d').getImageData(
- 0, 0, canvas2.width, canvas2.height);
- chrome.browserAction.setIcon({imageData:imageData});
- canvas1.parentNode.removeChild(canvas1);
- canvas2.parentNode.removeChild(canvas2);
-}
-
-function pollProgress() {
- pollProgress.tid = -1;
- chrome.downloads.search({}, function(items) {
- var popupLastOpened = parseInt(localStorage.popupLastOpened);
- var options = {anyMissingTotalBytes: false,
- anyInProgress: false,
- anyRecentlyCompleted: false,
- anyPaused: false,
- anyDangerous: false,
- totalBytesReceived: 0,
- totalTotalBytes: 0};
- items.forEach(function(item) {
- if (item.state == 'in_progress') {
- options.anyInProgress = true;
- if (item.totalBytes) {
- options.totalTotalBytes += item.totalBytes;
- options.totalBytesReceived += item.bytesReceived;
- } else {
- options.anyMissingTotalBytes = true;
- }
- var dangerous = ((item.danger != 'safe') &&
- (item.danger != 'accepted'));
- options.anyDangerous = options.anyDangerous || dangerous;
- options.anyPaused = options.anyPaused || item.paused;
- } else if ((item.state == 'complete') && item.endTime && !item.error) {
- options.anyRecentlyCompleted = (
- options.anyRecentlyCompleted ||
- ((new Date(item.endTime)).getTime() >= popupLastOpened));
- maybeOpen(item.id);
- }
- });
-
- var targetIcon = JSON.stringify(options);
- if (sessionStorage.currentIcon != targetIcon) {
- setBrowserActionIcon(options);
- sessionStorage.currentIcon = targetIcon;
- }
-
- if (options.anyInProgress &&
- (pollProgress.tid < 0)) {
- pollProgress.start();
- }
- });
-}
-pollProgress.tid = -1;
-pollProgress.MS = 200;
-
-pollProgress.start = function() {
- if (pollProgress.tid < 0) {
- pollProgress.tid = setTimeout(pollProgress, pollProgress.MS);
- }
-};
-
-function isNumber(n) {
- return !isNaN(parseFloat(n)) && isFinite(n);
-}
-
-if (!isNumber(localStorage.popupLastOpened)) {
- localStorage.popupLastOpened = '' + (new Date()).getTime();
-}
-
-chrome.downloads.onCreated.addListener(function(item) {
- pollProgress();
-});
-
-pollProgress();
-
-function openWhenComplete(downloadId) {
- var ids = [];
- try {
- ids = JSON.parse(localStorage.openWhenComplete);
- } catch (e) {
- localStorage.openWhenComplete = JSON.stringify(ids);
- }
- pollProgress.start();
- if (ids.indexOf(downloadId) >= 0) {
- return;
- }
- ids.push(downloadId);
- localStorage.openWhenComplete = JSON.stringify(ids);
-}
-
-chrome.runtime.onMessage.addListener(function(request) {
- if (request == 'poll') {
- pollProgress.start();
- }
- if (request == 'icons') {
- [16, 19, 38, 128].forEach(function(s) {
- var canvas = drawIcon(s);
- chrome.downloads.download({
- url: canvas.toDataURL('image/png', 1.0),
- filename: 'icon' + s + '.png',
- });
- canvas.parentNode.removeChild(canvas);
- });
- }
- if (isNumber(request.openWhenComplete)) {
- openWhenComplete(request.openWhenComplete);
- }
-});
diff --git a/chrome/common/extensions/docs/examples/api/downloads/download_manager/icon128.png b/chrome/common/extensions/docs/examples/api/downloads/download_manager/icon128.png
deleted file mode 100644
index 4d3610d..0000000
--- a/chrome/common/extensions/docs/examples/api/downloads/download_manager/icon128.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/downloads/download_manager/icon19.png b/chrome/common/extensions/docs/examples/api/downloads/download_manager/icon19.png
deleted file mode 100644
index 0aa6033..0000000
--- a/chrome/common/extensions/docs/examples/api/downloads/download_manager/icon19.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/downloads/download_manager/icon38.png b/chrome/common/extensions/docs/examples/api/downloads/download_manager/icon38.png
deleted file mode 100644
index 84563d75..0000000
--- a/chrome/common/extensions/docs/examples/api/downloads/download_manager/icon38.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/downloads/download_manager/icons.html b/chrome/common/extensions/docs/examples/api/downloads/download_manager/icons.html
deleted file mode 100644
index fca4bf2..0000000
--- a/chrome/common/extensions/docs/examples/api/downloads/download_manager/icons.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<title>Icon Generator</title>
-<script src='icons.js'></script>
-</head>
-<body>
-<button id=download>Generate Manifest Icons</button>
-</body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/api/downloads/download_manager/icons.js b/chrome/common/extensions/docs/examples/api/downloads/download_manager/icons.js
deleted file mode 100644
index d1bc098..0000000
--- a/chrome/common/extensions/docs/examples/api/downloads/download_manager/icons.js
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) 2013 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.
-
-window.onload = function() {
- var download = document.getElementById('download');
- download.onclick = function() {
- chrome.runtime.sendMessage('icons');
- download.disabled = true;
- return false;
- };
-};
diff --git a/chrome/common/extensions/docs/examples/api/downloads/download_manager/manifest.json b/chrome/common/extensions/docs/examples/api/downloads/download_manager/manifest.json
deleted file mode 100644
index 156e69c..0000000
--- a/chrome/common/extensions/docs/examples/api/downloads/download_manager/manifest.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{"name": "__MSG_extName__",
- "version": "0.3",
- "manifest_version": 2,
- "description": "__MSG_extDesc__",
- "icons": {"128": "icon128.png"},
- "browser_action": {
- "default_icon": {
- "19": "icon19.png",
- "38": "icon38.png"},
- "default_title": "__MSG_extName__",
- "default_popup": "popup.html"},
- "background": {"persistent": false, "scripts": ["background.js"]},
- "default_locale": "en",
- "optional_permissions": ["management"],
- "permissions": ["downloads", "downloads.open", "downloads.shelf"]}
diff --git a/chrome/common/extensions/docs/examples/api/downloads/download_manager/popup.css b/chrome/common/extensions/docs/examples/api/downloads/download_manager/popup.css
deleted file mode 100644
index 72c73fc..0000000
--- a/chrome/common/extensions/docs/examples/api/downloads/download_manager/popup.css
+++ /dev/null
@@ -1,226 +0,0 @@
-/* Copyright (c) 2013 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. */
-
-#outer,
-#empty,
-#open-folder,
-.file-url,
-.time-left,
-.more-left {
- display: inline-block;
-}
-
-#q-outer {
- display:inline-block;
- height:1.7em;
- overflow:hidden;
-}
-
-#q {
- margin-right: 2em;
-}
-
-#head {
- position: fixed;
- z-index: 2;
- width: 100%;
- left: 0;
- top: 0;
- background: white;
- border-bottom: 1px solid grey;
-}
-
-#search-zero,
-#items {
- margin-top: 2em;
-}
-
-#head,
-#empty,
-#searching,
-#search-zero,
-.item,
-.start-time,
-.complete-size,
-.error,
-.file-url-head,
-.removed,
-.open-filename,
-.progress,
-.time-left,
-.url,
-#text-width-probe {
- white-space: nowrap;
-}
-
-#head,
-.item {
- text-align: left;
-}
-
-#empty {
- vertical-align: bottom;
- height: 2em;
-}
-
-#q {
- margin-left: 3%;
-}
-
-.by-ext img,
-svg {
- width: 2em;
- height: 2em;
-}
-
-svg rect.border {
- fill-opacity: 0;
- stroke-width: 6;
-}
-
-#open-folder svg,
-.show-folder svg {
- stroke: brown;
- fill: white;
- stroke-width: 3;
-}
-
-#clear-all svg {
- fill: white;
- stroke-width: 3;
-}
-
-#clear-all svg,
-.remove-file svg,
-.erase svg {
- stroke: black;
-}
-
-#older,
-#loading-older,
-.item {
- margin-top: 1em;
-}
-
-.more {
- position: absolute;
- border: 1px solid grey;
- background: white;
- z-index: 3;
-}
-
-.complete-size,
-.error,
-.removed,
-.open-filename,
-.progress,
-.time-left {
- margin-right: 0.4em;
-}
-
-.error {
- color: darkred;
-}
-
-.referrer svg {
- stroke: blue;
- fill-opacity: 0;
- stroke-width: 7;
-}
-
-.removed,
-.open-filename {
- max-width: 400px;
- overflow: hidden;
- display: inline-block;
-}
-
-.remove-file svg {
- fill-opacity: 0;
- stroke-width: 5;
-}
-
-.remove-file svg line {
- stroke-width: 7;
- stroke: red;
-}
-
-.erase svg ellipse,
-.erase svg line {
- fill-opacity: 0;
- stroke-width: 5;
-}
-
-.pause svg {
- stroke: #333;
-}
-
-.resume svg {
- stroke: rgb(68, 187, 68);
- fill: rgb(68, 187, 68);
-}
-
-.cancel svg line {
- stroke-width: 7;
-}
-
-.cancel svg {
- stroke: rgb(204, 68, 68);
-}
-
-.meter {
- height: 0.5em;
- position: relative;
- background: grey;
-}
-
-.meter > span {
- display: block;
- height: 100%;
- background-color: rgb(43, 194, 83);
- background-image: -webkit-gradient(
- linear, left bottom, left top,
- color-stop(0, rgb(43,194,83)),
- color-stop(1, rgb(84,240,84)));
- position: relative;
- overflow: hidden;
-}
-
-.meter > span:after {
- content: '';
- position: absolute;
- top: 0; left: 0; bottom: 0; right: 0;
- background-image: -webkit-gradient(
- linear, 0 0, 100% 100%,
- color-stop(.25, rgba(255, 255, 255, .2)),
- color-stop(.25, transparent),
- color-stop(.5, transparent),
- color-stop(.5, rgba(255, 255, 255, .2)),
- color-stop(.75, rgba(255, 255, 255, .2)),
- color-stop(.75, transparent),
- to(transparent));
- z-index: 1;
- -webkit-background-size: 50px 50px;
- background-size: 50px 50px;
- animation: move 2s linear infinite;
- overflow: hidden;
-}
-
-@keyframes move {
- 0% { background-position: 0 0; }
- 100% { background-position: 50px 50px; }
-}
-
-.url {
- color: grey;
- max-width: 700px;
- overflow: hidden;
- display: block;
-}
-
-#text-width-probe {
- position: absolute;
- top: -100px;
- left: 0;
-}
diff --git a/chrome/common/extensions/docs/examples/api/downloads/download_manager/popup.html b/chrome/common/extensions/docs/examples/api/downloads/download_manager/popup.html
deleted file mode 100644
index 95933be..0000000
--- a/chrome/common/extensions/docs/examples/api/downloads/download_manager/popup.html
+++ /dev/null
@@ -1,110 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
- <title></title>
- <script src="popup.js"></script>
- <link rel="stylesheet" type="text/css" href="popup.css">
- <link rel="icon" href="icon19.png">
-</head>
-<body>
-<div id="outer">
- <div id="head">
- <a id="bad-chrome-version" hidden
- href="https://www.google.com/intl/en/chrome/browser/beta.html"></a>
- <span id="empty" hidden></span>
- <div id="q-outer">
- <input type="search" id="q" incremental><br>
- </div>
- <a href="#" id="clear-all"><svg viewBox="0 0 100 100"><g>
- <rect x="5" y="5" rx="20" ry="20" width="90" height="90" class="border" />
- <ellipse rx="30" ry="8" cx="50" cy="55" />
- <ellipse rx="20" ry="5" cx="50" cy="80" />
- <line x1="20" y1="55" x2="30" y2="83" />
- <line x1="40" y1="60" x2="43" y2="83" />
- <line x1="60" y1="60" x2="56" y2="83" />
- <line x1="80" y1="55" x2="69" y2="83" />
- <polygon points="25,20 35,20 35,40 40,40 30,55 20,40 25,40" />
- <polygon points="45,20 55,20 55,40 60,40 50,55 40,40 45,40" />
- <polygon points="65,20 75,20 75,40 80,40 70,55 60,40 65,40" />
- </g></svg></a>
- <a href="#" id="open-folder"><svg viewBox="0 0 100 100"><g>
- <rect x="5" y="5" rx="20" ry="20" width="90" height="90" class="border" />
- <polygon points="20,20 20,80 60,80 60,30 35,30 35,20" />
- <polygon points="20,80 60,80 80,45 40,45" />
- </g></svg></a>
- </div>
- <div id="searching" hidden></div>
- <div id="search-zero" hidden></div>
- <div id="items"></div>
- <a href="#" id="older" hidden></a>
- <span id="loading-older" hidden></span>
- <div id="request-management-permission" hidden><div
- id="management-permission-info"></div>
- <a href="#" id="grant-management-permission"></a>
- </div>
-</div>
-
-<div class="item" hidden>
- <img class="icon" src="icon38.png">
- <div class="more" hidden>
- <span class="more-left">
- <div class="start-time"></div>
- <div class="complete-size"></div>
- </span>
- <a href="#" class="referrer"><svg viewBox="0 0 100 100"><g>
- <rect x="5" y="5" rx="20" ry="20" width="90" height="90" class="border" />
- <ellipse cx="35" cy="50" rx="20" ry="20" />
- <ellipse cx="60" cy="50" rx="20" ry="20" />
- </g></svg></a>
- <a href="#" class="by-ext"><img /></a>
- <a href="#" class="show-folder"><svg viewBox="0 0 100 100"><g>
- <rect x="5" y="5" rx="20" ry="20" width="90" height="90" class="border" />
- <polygon points="20,20 20,80 60,80 60,30 35,30 35,20" />
- <polygon points="20,80 60,80 80,45 40,45" />
- </g></svg></a>
- <a href="#" class="remove-file"><svg viewBox="0 0 100 100"><g>
- <rect x="5" y="5" rx="20" ry="20" width="90" height="90" class="border" />
- <polygon points="20,45 45,20 75,20 75,75 20,75, 20,45 45,45 45,20" />
- <line x1="45" y1="45" x2="80" y2="80" />
- <line x1="80" y1="45" x2="45" y2="80" />
- </g></svg></a>
- <a href="#" class="erase"><svg viewBox="0 0 100 100"><g>
- <rect x="5" y="5" rx="20" ry="20" width="90" height="90" class="border" />
- <ellipse rx="30" ry="10" cx="50" cy="40" />
- <ellipse rx="20" ry="10" cx="50" cy="70" />
- <line x1="20" y1="35" x2="30" y2="75" />
- <line x1="80" y1="35" x2="65" y2="75" />
- <line x1="50" y1="50" x2="50" y2="80" />
- </g></svg></a>
- </div>
- <a href="#" class="pause"><svg viewBox="0 0 100 100"><g>
- <rect x="5" y="5" rx="20" ry="20" width="90" height="90" class="border" />
- <rect x="25" y="25" rx="20" ry="20" width="15" height="50" />
- <rect x="55" y="25" rx="20" ry="20" width="15" height="50" />
- </g></svg></a>
- <a href="#" class="resume"><svg viewBox="0 0 100 100"><g>
- <rect x="5" y="5" rx="20" ry="20" width="90" height="90" class="border" />
- <polygon points="25,25 75,50 25,75">
- </g></svg></a>
- <a href="#" class="cancel"><svg viewBox="0 0 100 100"><g>
- <rect x="5" y="5" rx="20" ry="20" width="90" height="90" class="border" />
- <line x1="25" y1="25" x2="75" y2="75" />
- <line x1="75" y1="25" x2="25" y2="75" />
- </g></svg></a>
- <span class="file-url">
- <div class="file-url-head">
- <span class="removed"></span>
- <a href="#" class="open-filename"></a>
- <span class="error"></span>
- <span class="in-progress">
- <span class="progress"></span>
- <span class="time-left"></span>
- </span>
- </div>
- <div class="meter"><span /></div>
- <a href="#" class="url" download=""></a>
- </span>
-</div>
-<span id="text-width-probe"></span>
-</body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/api/downloads/download_manager/popup.js b/chrome/common/extensions/docs/examples/api/downloads/download_manager/popup.js
deleted file mode 100644
index 412a3af..0000000
--- a/chrome/common/extensions/docs/examples/api/downloads/download_manager/popup.js
+++ /dev/null
@@ -1,781 +0,0 @@
-// Copyright (c) 2013 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.
-
-function pointInElement(p, elem) {
- return ((p.x >= elem.offsetLeft) &&
- (p.x <= (elem.offsetLeft + elem.offsetWidth)) &&
- (p.y >= elem.offsetTop) &&
- (p.y <= (elem.offsetTop + elem.offsetHeight)));
-};
-
-function setLastOpened() {
- localStorage.popupLastOpened = (new Date()).getTime();
- chrome.runtime.sendMessage('poll');
-};
-
-function loadI18nMessages() {
- function setProperty(selector, prop, msg) {
- document.querySelector(selector)[prop] = chrome.i18n.getMessage(msg);
- }
-
- setProperty('title', 'innerText', 'tabTitle');
- setProperty('#q', 'placeholder', 'searchPlaceholder');
- setProperty('#clear-all', 'title', 'clearAllTitle');
- setProperty('#open-folder', 'title', 'openDownloadsFolderTitle');
- setProperty('#empty', 'innerText', 'zeroItems');
- setProperty('#searching', 'innerText', 'searching');
- setProperty('#search-zero', 'innerText', 'zeroSearchResults');
- setProperty('#management-permission-info', 'innerText',
- 'managementPermissionInfo');
- setProperty('#grant-management-permission', 'innerText',
- 'grantManagementPermission');
- setProperty('#older', 'innerText', 'showOlderDownloads');
- setProperty('#loading-older', 'innerText', 'loadingOlderDownloads');
- setProperty('.pause', 'title', 'pauseTitle');
- setProperty('.resume', 'title', 'resumeTitle');
- setProperty('.cancel', 'title', 'cancelTitle');
- setProperty('.show-folder', 'title', 'showInFolderTitle');
- setProperty('.erase', 'title', 'eraseTitle');
- setProperty('.url', 'title', 'retryTitle');
- setProperty('.referrer', 'title', 'referrerTitle');
- setProperty('.open-filename', 'title', 'openTitle');
- setProperty('#bad-chrome-version', 'innerText', 'badChromeVersion');
- setProperty('.remove-file', 'title', 'removeFileTitle');
-
- document.querySelector('.progress').style.minWidth =
- getTextWidth(formatBytes(1024 * 1024 * 1023.9) + '/' +
- formatBytes(1024 * 1024 * 1023.9)) + 'px';
-
- // This only covers {timeLeft,openWhenComplete}{Finishing,Days}. If
- // ...Hours/Minutes/Seconds could be longer for any locale, then this should
- // test them.
- var max_time_left_width = 0;
- for (var i = 0; i < 4; ++i) {
- max_time_left_width = Math.max(max_time_left_width, getTextWidth(
- formatTimeLeft(0 == (i % 2),
- (i < 2) ? 0 : ((100 * 24) + 23) * 60 * 60 * 1000)));
- }
- document.querySelector('body div.item span.time-left').style.minWidth =
- max_time_left_width + 'px';
-};
-
-function getTextWidth(s) {
- var probe = document.getElementById('text-width-probe');
- probe.innerText = s;
- return probe.offsetWidth;
-};
-
-function formatDateTime(date) {
- var now = new Date();
- var zpad_mins = ':' + (date.getMinutes() < 10 ? '0' : '') + date.getMinutes();
- if (date.getYear() != now.getYear()) {
- return '' + (1900 + date.getYear());
- } else if ((date.getMonth() != now.getMonth()) ||
- (date.getDate() != now.getDate())) {
- return date.getDate() + ' ' + chrome.i18n.getMessage(
- 'month' + date.getMonth() + 'abbr');
- } else if (date.getHours() == 12) {
- return '12' + zpad_mins + 'pm';
- } else if (date.getHours() > 12) {
- return (date.getHours() - 12) + zpad_mins + 'pm';
- }
- return date.getHours() + zpad_mins + 'am';
-}
-
-function formatBytes(n) {
- if (n < 1024) {
- return n + 'B';
- }
- var prefixes = 'KMGTPEZY';
- var mul = 1024;
- for (var i = 0; i < prefixes.length; ++i) {
- if (n < (1024 * mul)) {
- return (parseInt(n / mul) + '.' + parseInt(10 * ((n / mul) % 1)) +
- prefixes[i] + 'B');
- }
- mul *= 1024;
- }
- return '!!!';
-}
-
-function formatTimeLeft(openWhenComplete, ms) {
- var prefix = openWhenComplete ? 'openWhenComplete' : 'timeLeft';
- if (ms < 1000) {
- return chrome.i18n.getMessage(prefix + 'Finishing');
- }
- var days = parseInt(ms / (24 * 60 * 60 * 1000));
- var hours = parseInt(ms / (60 * 60 * 1000)) % 24;
- if (days) {
- return chrome.i18n.getMessage(prefix + 'Days', [days, hours]);
- }
- var minutes = parseInt(ms / (60 * 1000)) % 60;
- if (hours) {
- return chrome.i18n.getMessage(prefix + 'Hours', [hours, minutes]);
- }
- var seconds = parseInt(ms / 1000) % 60;
- if (minutes) {
- return chrome.i18n.getMessage(prefix + 'Minutes', [minutes, seconds]);
- }
- return chrome.i18n.getMessage(prefix + 'Seconds', [seconds]);
-}
-
-function ratchetWidth(w) {
- var current = parseInt(document.body.style.minWidth) || 0;
- document.body.style.minWidth = Math.max(w, current) + 'px';
-}
-
-function ratchetHeight(h) {
- var current = parseInt(document.body.style.minHeight) || 0;
- document.body.style.minHeight = Math.max(h, current) + 'px';
-}
-
-function binarySearch(array, target, cmp) {
- var low = 0, high = array.length - 1, i, comparison;
- while (low <= high) {
- i = (low + high) >> 1;
- comparison = cmp(target, array[i]);
- if (comparison < 0) {
- low = i + 1;
- } else if (comparison > 0) {
- high = i - 1;
- } else {
- return i;
- }
- }
- return i;
-};
-
-function arrayFrom(seq) {
- return Array.prototype.slice.apply(seq);
-};
-
-function DownloadItem(data) {
- var item = this;
- for (var prop in data) {
- item[prop] = data[prop];
- }
- item.startTime = new Date(item.startTime);
- if (item.canResume == undefined) {
- DownloadItem.canResumeHack = true;
- }
-
- item.div = document.querySelector('body>div.item').cloneNode(true);
- item.div.id = 'item' + item.id;
- item.div.item = item;
-
- var items_div = document.getElementById('items');
- if ((items_div.childNodes.length == 0) ||
- (item.startTime.getTime() < items_div.childNodes[
- items_div.childNodes.length - 1].item.startTime.getTime())) {
- items_div.appendChild(item.div);
- } else if (item.startTime.getTime() >
- items_div.childNodes[0].item.startTime.getTime()) {
- items_div.insertBefore(item.div, items_div.childNodes[0]);
- } else {
- var adjacent_div = items_div.childNodes[
- binarySearch(arrayFrom(items_div.childNodes),
- item.startTime.getTime(),
- function(target, other) {
- return target - other.item.startTime.getTime();
- })];
- var adjacent_item = adjacent_div.item;
- if (adjacent_item.startTime.getTime() < item.startTime.getTime()) {
- items_div.insertBefore(item.div, adjacent_div);
- } else {
- items_div.insertBefore(item.div, adjacent_div.nextSibling);
- }
- }
-
- item.getElement('referrer').onclick = function() {
- chrome.tabs.create({url: item.referrer});
- return false;
- };
- item.getElement('by-ext').onclick = function() {
- chrome.tabs.create({url: 'chrome://extensions#' + item.byExtensionId});
- return false;
- }
- item.getElement('open-filename').onclick = function() {
- item.open();
- return false;
- };
- item.getElement('pause').onclick = function() {
- item.pause();
- return false;
- };
- item.getElement('cancel').onclick = function() {
- item.cancel();
- return false;
- };
- item.getElement('resume').onclick = function() {
- item.resume();
- return false;
- };
- item.getElement('show-folder').onclick = function() {
- item.show();
- return false;
- };
- item.getElement('remove-file').onclick = function() {
- item.removeFile();
- return false;
- };
- item.getElement('erase').onclick = function() {
- item.erase();
- return false;
- };
-
- item.more_mousemove = function(evt) {
- var mouse = {x:evt.x, y:evt.y+document.body.scrollTop};
- if (item.getElement('more') &&
- (pointInElement(mouse, item.div) ||
- pointInElement(mouse, item.getElement('more')))) {
- return;
- }
- if (item.getElement('more')) {
- item.getElement('more').hidden = true;
- }
- window.removeEventListener('mousemove', item.more_mousemove);
- };
- [item.div, item.getElement('more')].concat(
- item.getElement('more').children).forEach(function(elem) {
- elem.onmouseover = function() {
- arrayFrom(items_div.children).forEach(function(other) {
- if (other.item != item) {
- other.item.getElement('more').hidden = true;
- }
- });
- item.getElement('more').hidden = false;
- item.getElement('more').style.top =
- (item.div.offsetTop + item.div.offsetHeight) + 'px';
- item.getElement('more').style.left = item.div.offsetLeft + 'px';
- if (window.innerHeight < (parseInt(item.getElement('more').style.top) +
- item.getElement('more').offsetHeight)) {
- item.getElement('more').style.top = (
- item.div.offsetTop - item.getElement('more').offsetHeight) + 'px';
- }
- window.addEventListener('mousemove', item.more_mousemove);
- };
- });
-
- if (item.referrer) {
- item.getElement('referrer').href = item.referrer;
- } else {
- item.getElement('referrer').hidden = true;
- }
- item.getElement('url').href = item.url;
- item.getElement('url').innerText = item.url;
- item.render();
-}
-DownloadItem.canResumeHack = false;
-
-DownloadItem.prototype.getElement = function(name) {
- return document.querySelector('#item' + this.id + ' .' + name);
-};
-
-DownloadItem.prototype.render = function() {
- var item = this;
- var now = new Date();
- var in_progress = (item.state == 'in_progress')
- var openable = (item.state != 'interrupted') && item.exists && !item.deleted;
-
- item.startTime = new Date(item.startTime);
- if (DownloadItem.canResumeHack) {
- item.canResume = in_progress && item.paused;
- }
- if (item.filename) {
- item.basename = item.filename.substring(Math.max(
- item.filename.lastIndexOf('\\'),
- item.filename.lastIndexOf('/')) + 1);
- }
- if (item.estimatedEndTime) {
- item.estimatedEndTime = new Date(item.estimatedEndTime);
- }
- if (item.endTime) {
- item.endTime = new Date(item.endTime);
- }
-
- if (item.filename && !item.icon_url) {
- chrome.downloads.getFileIcon(
- item.id,
- {'size': 32},
- function(icon_url) {
- item.getElement('icon').hidden = !icon_url;
- if (icon_url) {
- item.icon_url = icon_url;
- item.getElement('icon').src = icon_url;
- }
- });
- }
-
- item.getElement('removed').style.display = openable ? 'none' : 'inline';
- item.getElement('open-filename').style.display = (
- openable ? 'inline' : 'none');
- item.getElement('in-progress').hidden = !in_progress;
- item.getElement('pause').style.display = (
- !in_progress || item.paused) ? 'none' : 'inline-block';
- item.getElement('resume').style.display = (
- !in_progress || !item.canResume) ? 'none' : 'inline-block';
- item.getElement('cancel').style.display = (
- !in_progress ? 'none' : 'inline-block');
- item.getElement('remove-file').hidden = (
- (item.state != 'complete') ||
- !item.exists ||
- item.deleted ||
- !chrome.downloads.removeFile);
- item.getElement('erase').hidden = in_progress;
-
- var could_progress = in_progress || item.canResume;
- item.getElement('progress').style.display = (
- could_progress ? 'inline-block' : 'none');
- item.getElement('meter').hidden = !could_progress || !item.totalBytes;
-
- item.getElement('removed').innerText = item.basename;
- item.getElement('open-filename').innerText = item.basename;
-
- function setByExtension(show) {
- if (show) {
- item.getElement('by-ext').title = item.byExtensionName;
- item.getElement('by-ext').href =
- 'chrome://extensions#' + item.byExtensionId;
- item.getElement('by-ext img').src =
- 'chrome://extension-icon/' + item.byExtensionId + '/48/1';
- } else {
- item.getElement('by-ext').hidden = true;
- }
- }
- if (item.byExtensionId && item.byExtensionName) {
- chrome.permissions.contains({permissions: ['management']},
- function(result) {
- if (result) {
- setByExtension(true);
- } else {
- setByExtension(false);
- if (!localStorage.managementPermissionDenied) {
- document.getElementById('request-management-permission').hidden =
- false;
- document.getElementById('grant-management-permission').onclick =
- function() {
- chrome.permissions.request({permissions: ['management']},
- function(granted) {
- setByExtension(granted);
- if (!granted) {
- localStorage.managementPermissionDenied = true;
- }
- });
- return false;
- };
- }
- }
- });
- } else {
- setByExtension(false);
- }
-
- if (!item.getElement('error').hidden) {
- if (item.error) {
- // TODO(benjhayden) When https://codereview.chromium.org/16924017/ is
- // released, set minimum_chrome_version and remove the error_N messages.
- item.getElement('error').innerText = chrome.i18n.getMessage(
- 'error_' + item.error);
- if (!item.getElement('error').innerText) {
- item.getElement('error').innerText = item.error;
- }
- } else if (!openable) {
- item.getElement('error').innerText = chrome.i18n.getMessage(
- 'errorRemoved');
- }
- }
-
- item.getElement('complete-size').innerText = formatBytes(
- item.bytesReceived);
- if (item.totalBytes && (item.state != 'complete')) {
- item.getElement('progress').innerText = (
- item.getElement('complete-size').innerText + '/' +
- formatBytes(item.totalBytes));
- item.getElement('meter').children[0].style.width = parseInt(
- 100 * item.bytesReceived / item.totalBytes) + '%';
- }
-
- if (in_progress) {
- if (item.estimatedEndTime && !item.paused) {
- var openWhenComplete = false;
- try {
- openWhenComplete = JSON.parse(localStorage.openWhenComplete).indexOf(
- item.id) >= 0;
- } catch (e) {
- }
- item.getElement('time-left').innerText = formatTimeLeft(
- openWhenComplete, item.estimatedEndTime.getTime() - now.getTime());
- } else {
- item.getElement('time-left').innerText = String.fromCharCode(160);
- }
- }
-
- if (item.startTime) {
- item.getElement('start-time').innerText = formatDateTime(
- item.startTime);
- }
-
- ratchetWidth(item.getElement('icon').offsetWidth +
- item.getElement('file-url').offsetWidth +
- item.getElement('cancel').offsetWidth +
- item.getElement('pause').offsetWidth +
- item.getElement('resume').offsetWidth);
- ratchetWidth(item.getElement('more').offsetWidth);
-
- this.maybeAccept();
-};
-
-DownloadItem.prototype.onChanged = function(delta) {
- for (var key in delta) {
- if (key != 'id') {
- this[key] = delta[key].current;
- }
- }
- this.render();
- if (delta.state) {
- setLastOpened();
- }
- if ((this.state == 'in_progress') && !this.paused) {
- DownloadManager.startPollingProgress();
- }
-};
-
-DownloadItem.prototype.onErased = function() {
- window.removeEventListener('mousemove', this.more_mousemove);
- document.getElementById('items').removeChild(this.div);
-};
-
-DownloadItem.prototype.show = function() {
- chrome.downloads.show(this.id);
-};
-
-DownloadItem.prototype.open = function() {
- if (this.state == 'complete') {
- chrome.downloads.open(this.id);
- return;
- }
- chrome.runtime.sendMessage({openWhenComplete:this.id});
-};
-
-DownloadItem.prototype.removeFile = function() {
- chrome.downloads.removeFile(this.id);
- this.deleted = true;
- this.render();
-};
-
-DownloadItem.prototype.erase = function() {
- chrome.downloads.erase({id: this.id});
-};
-
-DownloadItem.prototype.pause = function() {
- chrome.downloads.pause(this.id);
-};
-
-DownloadItem.prototype.resume = function() {
- chrome.downloads.resume(this.id);
-};
-
-DownloadItem.prototype.cancel = function() {
- chrome.downloads.cancel(this.id);
-};
-
-DownloadItem.prototype.maybeAccept = function() {
- // This function is safe to call at any time for any item, and it will always
- // do the right thing, which is to display the danger prompt only if the item
- // is in_progress and dangerous, and if the prompt is not already displayed.
- if ((this.state != 'in_progress') ||
- (this.danger == 'safe') ||
- (this.danger == 'accepted') ||
- DownloadItem.prototype.maybeAccept.accepting_danger) {
- return;
- }
- ratchetWidth(400);
- ratchetHeight(200);
- DownloadItem.prototype.maybeAccept.accepting_danger = true;
- // On Mac, window.onload is run while the popup is animating in, before it is
- // considered "visible". Prompts will not be displayed over an invisible
- // window, so the popup will become stuck. Just wait a little bit for the
- // window to finish animating in. http://crbug.com/280107
- // This has been fixed, so this setTimeout can be removed when the fix has
- // been released to stable, and minimum_chrome_version can be set.
- var id = this.id;
- setTimeout(function() {
- chrome.downloads.acceptDanger(id, function() {
- DownloadItem.prototype.maybeAccept.accepting_danger = false;
- arrayFrom(document.getElementById('items').childNodes).forEach(
- function(item_div) { item_div.item.maybeAccept(); });
- });
- }, 500);
-};
-DownloadItem.prototype.maybeAccept.accepting_danger = false;
-
-var DownloadManager = {};
-
-DownloadManager.showingOlder = false;
-
-DownloadManager.getItem = function(id) {
- var item_div = document.getElementById('item' + id);
- return item_div ? item_div.item : null;
-};
-
-DownloadManager.getOrCreate = function(data) {
- var item = DownloadManager.getItem(data.id);
- return item ? item : new DownloadItem(data);
-};
-
-DownloadManager.forEachItem = function(cb) {
- // Calls cb(item, index) in the order that they are displayed, i.e. in order
- // of decreasing startTime.
- arrayFrom(document.getElementById('items').childNodes).forEach(
- function(item_div, index) { cb(item_div.item, index); });
-};
-
-DownloadManager.startPollingProgress = function() {
- if (DownloadManager.startPollingProgress.tid < 0) {
- DownloadManager.startPollingProgress.tid = setTimeout(
- DownloadManager.startPollingProgress.pollProgress,
- DownloadManager.startPollingProgress.MS);
- }
-}
-DownloadManager.startPollingProgress.MS = 200;
-DownloadManager.startPollingProgress.tid = -1;
-DownloadManager.startPollingProgress.pollProgress = function() {
- DownloadManager.startPollingProgress.tid = -1;
- chrome.downloads.search({state: 'in_progress', paused: false},
- function(results) {
- if (!results.length)
- return;
- results.forEach(function(result) {
- var item = DownloadManager.getOrCreate(result);
- for (var prop in result) {
- item[prop] = result[prop];
- }
- item.render();
- if ((item.state == 'in_progress') && !item.paused) {
- DownloadManager.startPollingProgress();
- }
- });
- });
-};
-
-DownloadManager.showNew = function() {
- var any_items = (document.getElementById('items').childNodes.length > 0);
- document.getElementById('empty').style.display =
- any_items ? 'none' : 'inline-block';
- document.getElementById('head').style.borderBottomWidth =
- (any_items ? 1 : 0) + 'px';
- document.getElementById('clear-all').hidden = !any_items;
-
- var query_search = document.getElementById('q');
- query_search.hidden = !any_items;
-
- if (!any_items) {
- return;
- }
- var old_ms = (new Date()).getTime() - kOldMs;
- var any_hidden = false;
- var any_showing = false;
- // First show up to kShowNewMax items newer than kOldMs. If there aren't any
- // items newer than kOldMs, then show up to kShowNewMax items of any age. If
- // there are any hidden items, show the Show Older button.
- DownloadManager.forEachItem(function(item, index) {
- item.div.hidden = !DownloadManager.showingOlder && (
- (item.startTime.getTime() < old_ms) || (index >= kShowNewMax));
- any_hidden = any_hidden || item.div.hidden;
- any_showing = any_showing || !item.div.hidden;
- });
- if (!any_showing) {
- any_hidden = false;
- DownloadManager.forEachItem(function(item, index) {
- item.div.hidden = !DownloadManager.showingOlder && (index >= kShowNewMax);
- any_hidden = any_hidden || item.div.hidden;
- any_showing = any_showing || !item.div.hidden;
- });
- }
- document.getElementById('older').hidden = !any_hidden;
-
- query_search.focus();
-};
-
-DownloadManager.showOlder = function() {
- DownloadManager.showingOlder = true;
- var loading_older_span = document.getElementById('loading-older');
- document.getElementById('older').hidden = true;
- loading_older_span.hidden = false;
- chrome.downloads.search({}, function(results) {
- results.forEach(function(result) {
- var item = DownloadManager.getOrCreate(result);
- item.div.hidden = false;
- });
- loading_older_span.hidden = true;
- });
-};
-
-DownloadManager.onSearch = function() {
- // split string by space, but ignore space in quotes
- // http://stackoverflow.com/questions/16261635
- var query = document.getElementById('q').value.match(/(?:[^\s"]+|"[^"]*")+/g);
- if (!query) {
- DownloadManager.showNew();
- document.getElementById('search-zero').hidden = true;
- } else {
- query = query.map(function(term) {
- // strip quotes
- return (term.match(/\s/) &&
- term[0].match(/["']/) &&
- term[term.length - 1] == term[0]) ?
- term.substr(1, term.length - 2) : term;
- });
- var searching = document.getElementById('searching');
- searching.hidden = false;
- chrome.downloads.search({query: query}, function(results) {
- document.getElementById('older').hidden = true;
- DownloadManager.forEachItem(function(item) {
- item.div.hidden = true;
- });
- results.forEach(function(result) {
- DownloadManager.getOrCreate(result).div.hidden = false;
- });
- searching.hidden = true;
- document.getElementById('search-zero').hidden = (results.length != 0);
- });
- }
-};
-
-DownloadManager.clearAll = function() {
- DownloadManager.forEachItem(function(item) {
- if (!item.div.hidden) {
- item.erase();
- // The onErased handler should circle back around to loadItems.
- }
- });
-};
-
-var kShowNewMax = 50;
-var kOldMs = 1000 * 60 * 60 * 24 * 7;
-
-// These settings can be tuned by modifying localStorage in dev-tools.
-if ('kShowNewMax' in localStorage) {
- kShowNewMax = parseInt(localStorage.kShowNewMax);
-}
-if ('kOldMs' in localStorage) {
- kOldMs = parseInt(localStorage.kOldMs);
-}
-
-DownloadManager.loadItems = function() {
- // Request up to kShowNewMax + 1, but only display kShowNewMax; the +1 is a
- // probe to see if there are any older downloads.
- // TODO(benjhayden) When https://codereview.chromium.org/16924017/ is
- // released, set minimum_chrome_version and remove this try/catch.
- try {
- chrome.downloads.search({
- orderBy: ['-startTime'],
- limit: kShowNewMax + 1},
- function(results) {
- DownloadManager.loadItems.items = results;
- DownloadManager.loadItems.onLoaded();
- });
- } catch (exc) {
- chrome.downloads.search({
- orderBy: '-startTime',
- limit: kShowNewMax + 1},
- function(results) {
- DownloadManager.loadItems.items = results;
- DownloadManager.loadItems.onLoaded();
- });
- }
-};
-DownloadManager.loadItems.items = [];
-DownloadManager.loadItems.window_loaded = false;
-
-DownloadManager.loadItems.onLoaded = function() {
- if (!DownloadManager.loadItems.window_loaded) {
- return;
- }
- DownloadManager.loadItems.items.forEach(function(item) {
- DownloadManager.getOrCreate(item);
- });
- DownloadManager.loadItems.items = [];
- DownloadManager.showNew();
-};
-
-DownloadManager.loadItems.onWindowLoaded = function() {
- DownloadManager.loadItems.window_loaded = true;
- DownloadManager.loadItems.onLoaded();
-};
-
-// If this extension is installed on a stable-channel chrome, where the
-// downloads API is not available, do not use the downloads API, and link to the
-// beta channel.
-if (chrome.downloads) {
- // Start searching ASAP, don't wait for onload.
- DownloadManager.loadItems();
-
- chrome.downloads.onCreated.addListener(function(item) {
- DownloadManager.getOrCreate(item);
- DownloadManager.showNew();
- DownloadManager.startPollingProgress();
- });
-
- chrome.downloads.onChanged.addListener(function(delta) {
- var item = DownloadManager.getItem(delta.id);
- if (item) {
- item.onChanged(delta);
- }
- });
-
- chrome.downloads.onErased.addListener(function(id) {
- var item = DownloadManager.getItem(id);
- if (!item) {
- return;
- }
- item.onErased();
- DownloadManager.loadItems();
- });
-
- window.onload = function() {
- ratchetWidth(
- document.getElementById('q-outer').offsetWidth +
- document.getElementById('clear-all').offsetWidth +
- document.getElementById('open-folder').offsetWidth);
- setLastOpened();
- loadI18nMessages();
- DownloadManager.loadItems.onWindowLoaded();
- document.getElementById('older').onclick = function() {
- DownloadManager.showOlder();
- return false;
- };
- document.getElementById('q').onsearch = function() {
- DownloadManager.onSearch();
- };
- document.getElementById('clear-all').onclick = function() {
- DownloadManager.clearAll();
- return false;
- };
- if (chrome.downloads.showDefaultFolder) {
- document.getElementById('open-folder').onclick = function() {
- chrome.downloads.showDefaultFolder();
- return false;
- };
- } else {
- document.getElementById('open-folder').hidden = true;
- }
- };
-} else {
- // The downloads API is not available.
- // TODO(benjhayden) Remove this when minimum_chrome_version is set.
- window.onload = function() {
- loadI18nMessages();
- var bad_version = document.getElementById('bad-chrome-version');
- bad_version.hidden = false;
- bad_version.onclick = function() {
- chrome.tabs.create({url: bad_version.href});
- return false;
- };
- document.getElementById('empty').style.display = 'none';
- document.getElementById('q').style.display = 'none';
- document.getElementById('open-folder').style.display = 'none';
- document.getElementById('clear-all').style.display = 'none';
- };
-}
diff --git a/chrome/common/extensions/docs/examples/api/downloads/download_open/_locales/en/messages.json b/chrome/common/extensions/docs/examples/api/downloads/download_open/_locales/en/messages.json
deleted file mode 100644
index eae1fbe9..0000000
--- a/chrome/common/extensions/docs/examples/api/downloads/download_open/_locales/en/messages.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{"extName": {
- "message": "Download and Open Button",
- "description": "Extension name"},
- "extDesc": {
- "message": "Download and Open Context Menu Button",
- "description": "Extension description"},
- "openContextMenuTitle": {
- "message": "Download and Open",
- "description": "context menu button text"}}
diff --git a/chrome/common/extensions/docs/examples/api/downloads/download_open/background.js b/chrome/common/extensions/docs/examples/api/downloads/download_open/background.js
deleted file mode 100644
index bfc40ec5..0000000
--- a/chrome/common/extensions/docs/examples/api/downloads/download_open/background.js
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright (c) 2013 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.
-
-function getOpeningIds() {
- var ids = [];
- try {
- ids = JSON.parse(localStorage.openWhenComplete);
- } catch (e) {
- localStorage.openWhenComplete = JSON.stringify(ids);
- }
- return ids;
-}
-
-function setOpeningIds(ids) {
- localStorage.openWhenComplete = JSON.stringify(ids);
-}
-
-chrome.downloads.onChanged.addListener(function(delta) {
- if (!delta.state ||
- (delta.state.current != 'complete')) {
- return;
- }
- var ids = getOpeningIds();
- if (ids.indexOf(delta.id) < 0) {
- return;
- }
- chrome.downloads.open(delta.id);
- ids.splice(ids.indexOf(delta.id), 1);
- setOpeningIds(ids);
-});
-
-chrome.contextMenus.onClicked.addListener(function(info, tab) {
- chrome.downloads.download({url: info.linkUrl}, function(downloadId) {
- var ids = getOpeningIds();
- if (ids.indexOf(downloadId) >= 0) {
- return;
- }
- ids.push(downloadId);
- setOpeningIds(ids);
- });
-});
-
-chrome.contextMenus.create({
- id: 'open',
- title: chrome.i18n.getMessage('openContextMenuTitle'),
- contexts: ['link'],
-});
diff --git a/chrome/common/extensions/docs/examples/api/downloads/download_open/icon128.png b/chrome/common/extensions/docs/examples/api/downloads/download_open/icon128.png
deleted file mode 100644
index 50b99a1..0000000
--- a/chrome/common/extensions/docs/examples/api/downloads/download_open/icon128.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/downloads/download_open/icon16.png b/chrome/common/extensions/docs/examples/api/downloads/download_open/icon16.png
deleted file mode 100644
index 0f3aceb..0000000
--- a/chrome/common/extensions/docs/examples/api/downloads/download_open/icon16.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/downloads/download_open/manifest.json b/chrome/common/extensions/docs/examples/api/downloads/download_open/manifest.json
deleted file mode 100644
index 98a49ab..0000000
--- a/chrome/common/extensions/docs/examples/api/downloads/download_open/manifest.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{"name": "__MSG_extName__",
- "version": "0.1",
- "manifest_version": 2,
- "description": "__MSG_extDesc__",
- "icons": {"16": "icon16.png", "128": "icon128.png"},
- "background": {"persistent": false, "scripts": ["background.js"]},
- "default_locale": "en",
- "permissions": ["contextMenus", "downloads", "downloads.open"]}
diff --git a/chrome/common/extensions/docs/examples/api/downloads/downloads_overwrite/bg.js b/chrome/common/extensions/docs/examples/api/downloads/downloads_overwrite/bg.js
deleted file mode 100644
index f01c7b1..0000000
--- a/chrome/common/extensions/docs/examples/api/downloads/downloads_overwrite/bg.js
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright (c) 2012 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.
-
-// Force all downloads to overwrite any existing files instead of inserting
-// ' (1)', ' (2)', etc.
-
-chrome.downloads.onDeterminingFilename.addListener(function(item, suggest) {
- suggest({filename: item.filename,
- conflict_action: 'overwrite',
- conflictAction: 'overwrite'});
- // conflict_action was renamed to conflictAction in
- // https://chromium.googlesource.com/chromium/src/+/f1d784d6938b8fe8e0d257e41b26341992c2552c
- // which was first picked up in branch 1580.
-});
diff --git a/chrome/common/extensions/docs/examples/api/downloads/downloads_overwrite/manifest.json b/chrome/common/extensions/docs/examples/api/downloads/downloads_overwrite/manifest.json
deleted file mode 100644
index c1f8999d..0000000
--- a/chrome/common/extensions/docs/examples/api/downloads/downloads_overwrite/manifest.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "name": "Downloads Overwrite Existing Files",
- "description": "All downloads overwrite existing files instead of adding ' (1)', ' (2)', etc.",
- "version": "1",
- "minimum_chrome_version": "26.0.1428",
- "background": {
- "scripts": ["bg.js"],
- "persistent": false
- },
- "permissions": [
- "downloads"
- ],
- "manifest_version": 2
-}
diff --git a/chrome/common/extensions/docs/examples/api/eventPage/basic/background.js b/chrome/common/extensions/docs/examples/api/eventPage/basic/background.js
deleted file mode 100644
index fe937e0f5..0000000
--- a/chrome/common/extensions/docs/examples/api/eventPage/basic/background.js
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright (c) 2012 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.
-
-// Global variables only exist for the life of the page, so they get reset
-// each time the page is unloaded.
-var counter = 1;
-
-var lastTabId = -1;
-function sendMessage() {
- chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
- lastTabId = tabs[0].id;
- chrome.tabs.sendMessage(lastTabId, "Background page started.");
- });
-}
-
-sendMessage();
-chrome.browserAction.setBadgeText({text: "ON"});
-console.log("Loaded.");
-
-chrome.runtime.onInstalled.addListener(function() {
- console.log("Installed.");
-
- // localStorage is persisted, so it's a good place to keep state that you
- // need to persist across page reloads.
- localStorage.counter = 1;
-
- // Register a webRequest rule to redirect bing to google.
- var wr = chrome.declarativeWebRequest;
- chrome.declarativeWebRequest.onRequest.addRules([{
- id: "0",
- conditions: [new wr.RequestMatcher({url: {hostSuffix: "bing.com"}})],
- actions: [new wr.RedirectRequest({redirectUrl: "http://google.com"})]
- }]);
-});
-
-chrome.bookmarks.onRemoved.addListener(function(id, info) {
- alert("I never liked that site anyway.");
-});
-
-chrome.browserAction.onClicked.addListener(function() {
- // The event page will unload after handling this event (assuming nothing
- // else is keeping it awake). The content script will become the main way to
- // interact with us.
- chrome.tabs.create({url: "http://google.com"}, function(tab) {
- chrome.tabs.executeScript(tab.id, {file: "content.js"}, function() {
- // Note: we also sent a message above, upon loading the event page,
- // but the content script will not be loaded at that point, so we send
- // another here.
- sendMessage();
- });
- });
-});
-
-chrome.commands.onCommand.addListener(function(command) {
- chrome.tabs.create({url: "http://www.google.com/"});
-});
-
-chrome.runtime.onMessage.addListener(function(msg, _, sendResponse) {
- if (msg.setAlarm) {
- // For testing only. delayInMinutes will be rounded up to at least 1 in a
- // packed or released extension.
- chrome.alarms.create({delayInMinutes: 0.1});
- } else if (msg.delayedResponse) {
- // Note: setTimeout itself does NOT keep the page awake. We return true
- // from the onMessage event handler, which keeps the message channel open -
- // in turn keeping the event page awake - until we call sendResponse.
- setTimeout(function() {
- sendResponse("Got your message.");
- }, 5000);
- return true;
- } else if (msg.getCounters) {
- sendResponse({counter: counter++,
- persistentCounter: localStorage.counter++});
- }
- // If we don't return anything, the message channel will close, regardless
- // of whether we called sendResponse.
-});
-
-chrome.alarms.onAlarm.addListener(function() {
- alert("Time's up!");
-});
-
-chrome.runtime.onSuspend.addListener(function() {
- chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
- // After the unload event listener runs, the page will unload, so any
- // asynchronous callbacks will not fire.
- alert("This does not show up.");
- });
- console.log("Unloading.");
- chrome.browserAction.setBadgeText({text: ""});
- chrome.tabs.sendMessage(lastTabId, "Background page unloaded.");
-});
diff --git a/chrome/common/extensions/docs/examples/api/eventPage/basic/content.js b/chrome/common/extensions/docs/examples/api/eventPage/basic/content.js
deleted file mode 100644
index 3bb880cc..0000000
--- a/chrome/common/extensions/docs/examples/api/eventPage/basic/content.js
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright (c) 2012 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.
-
-document.body.innerHTML = "";
-
-function addButton(name, cb) {
- var a = document.createElement("button");
- a.innerText = name;
- a.onclick = cb;
- document.body.appendChild(document.createElement("br"));
- document.body.appendChild(a);
-}
-
-function log(str) {
- console.log(str);
- logDiv.innerHTML += str + "<br>";
-}
-
-addButton("Clear logs", function() {
- logDiv.innerHTML = "";
-});
-
-addButton("Send message with delayed response", function() {
- chrome.runtime.sendMessage({delayedResponse: true}, function(response) {
- log("Background page responded: " + response);
- });
-});
-
-addButton("Show counters", function() {
- chrome.runtime.sendMessage({getCounters: true}, function(response) {
- log("In-memory counter is: " + response.counter);
- log("Persisted counter is: " + response.persistentCounter);
- });
-});
-
-addButton("Set an alarm", function() {
- chrome.runtime.sendMessage({setAlarm: true});
-});
-
-chrome.runtime.onMessage.addListener(function(msg, _, sendResponse) {
- log("Got message from background page: " + msg);
-});
-
-var logDiv = document.createElement("div");
-logDiv.style.border = "1px dashed black";
-document.body.appendChild(document.createElement("br"));
-document.body.appendChild(logDiv);
-
-log("Ready.");
diff --git a/chrome/common/extensions/docs/examples/api/eventPage/basic/icon.png b/chrome/common/extensions/docs/examples/api/eventPage/basic/icon.png
deleted file mode 100644
index 821bc49..0000000
--- a/chrome/common/extensions/docs/examples/api/eventPage/basic/icon.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/eventPage/basic/manifest.json b/chrome/common/extensions/docs/examples/api/eventPage/basic/manifest.json
deleted file mode 100644
index 7a6e1f43..0000000
--- a/chrome/common/extensions/docs/examples/api/eventPage/basic/manifest.json
+++ /dev/null
@@ -1,24 +0,0 @@
-{
- "name": "Event Page Example",
- "description": "Demonstrates usage and features of the event page",
- "version": "1.0",
- "manifest_version": 2,
- "permissions": ["alarms", "tabs", "bookmarks", "declarativeWebRequest", "*://*/*"],
- "background": {
- "scripts": ["background.js"],
- "persistent": false
- },
- "browser_action": {
- "default_icon" : "icon.png",
- "default_title": "Start Event Page"
- },
- "commands": {
- "open-google": {
- "description": "Open a tab to google.com",
- "suggested_key": { "default": "Ctrl+Shift+L" }
- },
- "_execute_browser_action": {
- "suggested_key": { "default": "Ctrl+Shift+K" }
- }
- }
-}
diff --git a/chrome/common/extensions/docs/examples/api/extension/isAllowedAccess/manifest.json b/chrome/common/extensions/docs/examples/api/extension/isAllowedAccess/manifest.json
deleted file mode 100644
index 66241fc3..0000000
--- a/chrome/common/extensions/docs/examples/api/extension/isAllowedAccess/manifest.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
- "name" : "`extension.isAllowedFileSchemeAccess` and `extension.isAllowedIncognitoAccess` Example",
- "version" : "1.0.0",
- "description" : "Demonstrates the `extension.isAllowedFileSchemeAccess` and `extesion.isAllowedIncognitoAccess` APIs",
- "permissions" : [ "file://*" ],
- "browser_action" : {
- "default_popup": "popup.html",
- "default_icon" : "sample-19.png"
- },
- "icons" : {
- "16" : "sample-16.png",
- "48" : "sample-48.png",
- "128" : "sample-128.png"
- },
- "manifest_version": 2
-}
diff --git a/chrome/common/extensions/docs/examples/api/extension/isAllowedAccess/popup.html b/chrome/common/extensions/docs/examples/api/extension/isAllowedAccess/popup.html
deleted file mode 100644
index 29f8071..0000000
--- a/chrome/common/extensions/docs/examples/api/extension/isAllowedAccess/popup.html
+++ /dev/null
@@ -1,32 +0,0 @@
-<!DOCTYPE html>
-<!--
- * Copyright (c) 2011 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>
- <title>extension.isAllowedAccess Sample</title>
- <link rel="stylesheet" href="./sample.css">
- </head>
- <body>
- <h1>extension.isAllowedAccess Sample</h1>
- <section>
- <ol>
- <li><p>
- <span>1</span> chrome.extension.isAllowedFileSchemeAccess:
- <code id="file">unknown</code> (unpacked extensions always have
- file scheme access, you'll need to install this as a packed
- extension to toggle it properly)
- </p></li>
- <li><p>
- <span>2</span> chrome.extension.isAllowedIncognitoAccess:
- <code id="incognito">unknown</code>
- </p></li>
- </ol>
- </section>
- <script src="./popup.js"></script>
- <script>
- </script>
- </body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/api/extension/isAllowedAccess/popup.js b/chrome/common/extensions/docs/examples/api/extension/isAllowedAccess/popup.js
deleted file mode 100644
index 27a7f400..0000000
--- a/chrome/common/extensions/docs/examples/api/extension/isAllowedAccess/popup.js
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) 2011 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.
-
-chrome.extension.isAllowedFileSchemeAccess(function(state) {
- var el = document.getElementById('file');
- el.textContent = el.className = state ? 'true': 'false';
-});
-chrome.extension.isAllowedIncognitoAccess(function(state) {
- var el = document.getElementById('incognito');
- el.textContent = el.className = state ? 'true': 'false';
-});
diff --git a/chrome/common/extensions/docs/examples/api/extension/isAllowedAccess/sample-128.png b/chrome/common/extensions/docs/examples/api/extension/isAllowedAccess/sample-128.png
deleted file mode 100644
index 19a29c81..0000000
--- a/chrome/common/extensions/docs/examples/api/extension/isAllowedAccess/sample-128.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/extension/isAllowedAccess/sample-16.png b/chrome/common/extensions/docs/examples/api/extension/isAllowedAccess/sample-16.png
deleted file mode 100644
index 5308fc9..0000000
--- a/chrome/common/extensions/docs/examples/api/extension/isAllowedAccess/sample-16.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/extension/isAllowedAccess/sample-19.png b/chrome/common/extensions/docs/examples/api/extension/isAllowedAccess/sample-19.png
deleted file mode 100644
index 108b2a7..0000000
--- a/chrome/common/extensions/docs/examples/api/extension/isAllowedAccess/sample-19.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/extension/isAllowedAccess/sample-48.png b/chrome/common/extensions/docs/examples/api/extension/isAllowedAccess/sample-48.png
deleted file mode 100644
index 617bc3db..0000000
--- a/chrome/common/extensions/docs/examples/api/extension/isAllowedAccess/sample-48.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/extension/isAllowedAccess/sample.css b/chrome/common/extensions/docs/examples/api/extension/isAllowedAccess/sample.css
deleted file mode 100644
index 2f35d4a..0000000
--- a/chrome/common/extensions/docs/examples/api/extension/isAllowedAccess/sample.css
+++ /dev/null
@@ -1,61 +0,0 @@
-body {
- margin: 5px 10px 10px;
-}
-
-h1 {
- color: #53637D;
- font: 26px/1.2 Helvetica, sans-serif;
- font-size: 200%;
- margin: 0;
- padding-bottom: 4px;
- text-shadow: white 0 1px 2px;
-}
-
-body > section {
- border-radius: 5px;
- background: -webkit-linear-gradient(rgba(234, 238, 243, 0.2), #EAEEF3),
- -webkit-linear-gradient(left, #EAEEF3, #EAEEF3 97%, #D3D7DB);
- font: 14px/1 Arial,Sans Serif;
- padding: 10px;
- width: 563px;
- max-height: 400px;
- overflow-y: auto;
- box-shadow: inset 0px 2px 5px rgba(0,0,0,0.5);
-}
-
-body > section > ol {
- padding: 0;
- margin: 0;
- list-style: none inside;
-}
-
-body > section > ol > li {
- position: relative;
- margin: 0.5em 0 0.5em 40px;
-}
-
-code {
- word-wrap: break-word;
- background: rgba(255,255,0, 0.5);
-}
- code.true {
- background: rgba(0, 255, 0, 0.5);
- }
- code.false {
- background: rgba(255, 0, 0, 0.5);
- }
-
-li > p > span:first-child {
- position: absolute;
- top: 0px;
- left: -40px;
- width: 30px;
- text-align: right;
- font: 30px/1 Helvetica, sans-serif;
- font-weight: 700;
-}
-
-p {
- min-height: 30px;
- line-height: 1.2;
-}
diff --git a/chrome/common/extensions/docs/examples/api/fileSystemProvider/archive/background.js b/chrome/common/extensions/docs/examples/api/fileSystemProvider/archive/background.js
deleted file mode 100644
index 303a52e..0000000
--- a/chrome/common/extensions/docs/examples/api/fileSystemProvider/archive/background.js
+++ /dev/null
@@ -1,257 +0,0 @@
-// Copyright 2014 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.
-
-'use strict';
-
-// Metadata is stored in files as serialized to JSON maps. See contents of
-// example1.fake and example2.fake.
-
-// Multiple volumes can be opened at the same time. The key is the
-// fileSystemId, which is the same as the file's displayPath.
-// The value is a Volume object.
-var volumes = {};
-
-// Defines a volume object that contains information about a mounted file
-// system.
-function Volume(entry, metadata, openedFiles) {
- // Used for restoring the opened file entry after resuming the event page.
- this.entry = entry;
-
- // The volume metadata.
- this.metadata = [];
- for (var path in metadata) {
- this.metadata[path] = metadata[path];
- // Date object is serialized in JSON as string.
- this.metadata[path].modificationTime =
- new Date(metadata[path].modificationTime);
- }
-
- // A map with currently opened files. The key is a requestId value from the
- // openFileRequested event, and the value is the file path.
- this.openedFiles = openedFiles;
-};
-
-function onUnmountRequested(options, onSuccess, onError) {
- restoreState(options.fileSystemId, function() {
- if (Object.keys(volumes[options.fileSystemId].openedFiles).length != 0) {
- onError('IN_USE');
- return;
- }
-
- chrome.fileSystemProvider.unmount(
- {fileSystemId: options.fileSystemId},
- function() {
- if (chrome.runtime.lastError) {
- onError(chrome.runtime.lastError.message);
- return;
- }
- delete volumes[options.fileSystemId];
- saveState(); // Remove volume from local storage state.
- onSuccess();
- });
- }, onError);
-};
-
-function onGetMetadataRequested(options, onSuccess, onError) {
- restoreState(options.fileSystemId, function () {
- var entryMetadata =
- volumes[options.fileSystemId].metadata[options.entryPath];
- if (!entryMetadata)
- error('NOT_FOUND');
- else
- onSuccess(entryMetadata);
- }, onError);
-};
-
-function onReadDirectoryRequested(options, onSuccess, onError) {
- restoreState(options.fileSystemId, function () {
- var directoryMetadata =
- volumes[options.fileSystemId].metadata[options.directoryPath];
- if (!directoryMetadata) {
- onError('NOT_FOUND');
- return;
- }
- if (!directoryMetadata.isDirectory) {
- onError('NOT_A_DIRECTORY');
- return;
- }
-
- // Retrieve directory contents from metadata.
- var entries = [];
- for (var entry in volumes[options.fileSystemId].metadata) {
- // Do not add itself on the list.
- if (entry == options.directoryPath)
- continue;
- // Check if the entry is a child of the requested directory.
- if (entry.indexOf(options.directoryPath) != 0)
- continue;
- // Restrict to direct children only.
- if (entry.substring(options.directoryPath.length + 1).indexOf('/') != -1)
- continue;
-
- entries.push(volumes[options.fileSystemId].metadata[entry]);
- }
- onSuccess(entries, false /* Last call. */);
- }, onError);
-};
-
-function onOpenFileRequested(options, onSuccess, onError) {
- restoreState(options.fileSystemId, function () {
- if (options.mode != 'READ' || options.create) {
- onError('INVALID_OPERATION');
- } else {
- volumes[options.fileSystemId].openedFiles[options.requestId] =
- options.filePath;
- onSuccess();
- }
- }, onError);
-};
-
-function onCloseFileRequested(options, onSuccess, onError) {
- restoreState(options.fileSystemId, function () {
- if (!volumes[options.fileSystemId].openedFiles[options.openRequestId]) {
- onError('INVALID_OPERATION');
- } else {
- delete volumes[options.fileSystemId].openedFiles[options.openRequestId];
- onSuccess();
- }
- }, onError);
-};
-
-function onReadFileRequested(options, onSuccess, onError) {
- restoreState(options.fileSystemId, function () {
- var filePath =
- volumes[options.fileSystemId].openedFiles[options.openRequestId];
- if (!filePath) {
- onError('INVALID_OPERATION');
- return;
- }
-
- var contents = volumes[options.fileSystemId].metadata[filePath].contents;
-
- // Write the contents as ASCII text.
- var buffer = new ArrayBuffer(options.length);
- var bufferView = new Uint8Array(buffer);
- for (var i = 0; i < options.length; i++) {
- bufferView[i] = contents.charCodeAt(i);
- }
-
- onSuccess(buffer, false /* Last call. */);
- }, onError);
-};
-
-// Saves state in case of restarts, event page suspend, crashes, etc.
-function saveState() {
- var state = {};
- for (var volumeId in volumes) {
- var entryId = chrome.fileSystem.retainEntry(volumes[volumeId].entry);
- state[volumeId] = {
- entryId: entryId
- };
- }
- chrome.storage.local.set({state: state});
-}
-
-// Restores metadata for the passed file system ID.
-function restoreState(fileSystemId, onSuccess, onError) {
- chrome.storage.local.get(['state'], function(result) {
- // Check if metadata for the given file system is already in memory.
- if (volumes[fileSystemId]) {
- onSuccess();
- return;
- }
-
- chrome.fileSystem.restoreEntry(
- result.state[fileSystemId].entryId,
- function(entry) {
- readMetadataFromFile(entry,
- function(metadata) {
- chrome.fileSystemProvider.get(fileSystemId, function(info) {
- if (chrome.runtime.lastError) {
- onError(chrome.runtime.lastError.message);
- return;
- }
- volumes[fileSystemId] = new Volume(entry, metadata,
- info.openedFiles);
- onSuccess();
- });
- }, onError);
- });
- });
-}
-
-// Reads metadata from a file and returns it with the onSuccess callback.
-function readMetadataFromFile(entry, onSuccess, onError) {
- entry.file(function(file) {
- var fileReader = new FileReader();
- fileReader.onload = function(event) {
- onSuccess(JSON.parse(event.target.result));
- };
-
- fileReader.onerror = function(event) {
- onError('FAILED');
- };
-
- fileReader.readAsText(file);
- });
-}
-
-// Event called on opening a file with the extension or mime type
-// declared in the manifest file.
-chrome.app.runtime.onLaunched.addListener(function(event) {
- event.items.forEach(function(item) {
- readMetadataFromFile(item.entry,
- function(metadata) {
- // Mount the volume and save its information in local storage
- // in order to be able to recover the metadata in case of
- // restarts, system crashes, etc.
- chrome.fileSystem.getDisplayPath(item.entry, function(displayPath) {
- volumes[displayPath] = new Volume(item.entry, metadata, []);
- chrome.fileSystemProvider.mount(
- {fileSystemId: displayPath, displayName: item.entry.name},
- function() {
- if (chrome.runtime.lastError) {
- console.error('Failed to mount because of: ' +
- chrome.runtime.lastError.message);
- return;
- };
- saveState();
- });
- });
- },
- function(error) {
- console.error(error);
- });
- });
-});
-
-// Event called on a profile startup.
-chrome.runtime.onStartup.addListener(function () {
- chrome.storage.local.get(['state'], function(result) {
- // Nothing to change.
- if (!result.state)
- return;
-
- chrome.storage.local.set({state: result.state});
- });
-});
-
-// Save the state before suspending the event page, so we can resume it
-// once new events arrive.
-chrome.runtime.onSuspend.addListener(function() {
- saveState();
-});
-
-chrome.fileSystemProvider.onUnmountRequested.addListener(
- onUnmountRequested);
-chrome.fileSystemProvider.onGetMetadataRequested.addListener(
- onGetMetadataRequested);
-chrome.fileSystemProvider.onReadDirectoryRequested.addListener(
- onReadDirectoryRequested);
-chrome.fileSystemProvider.onOpenFileRequested.addListener(
- onOpenFileRequested);
-chrome.fileSystemProvider.onCloseFileRequested.addListener(
- onCloseFileRequested);
-chrome.fileSystemProvider.onReadFileRequested.addListener(
- onReadFileRequested);
diff --git a/chrome/common/extensions/docs/examples/api/fileSystemProvider/archive/example1.fake b/chrome/common/extensions/docs/examples/api/fileSystemProvider/archive/example1.fake
deleted file mode 100644
index 6d7cc11..0000000
--- a/chrome/common/extensions/docs/examples/api/fileSystemProvider/archive/example1.fake
+++ /dev/null
@@ -1,34 +0,0 @@
-{
- "/": {
- "isDirectory": true,
- "name": "",
- "size": 0,
- "modificationTime": "2014-06-26T08:47:11.591Z"
- },
- "/file1.txt": {
- "isDirectory": false,
- "name": "file1.txt",
- "size": 46,
- "modificationTime": "2014-06-26T08:47:11.591Z",
- "contents": "It works!\nEverything gets displayed correctly."
- },
- "/file2": {
- "isDirectory": false,
- "name": "file2",
- "size": 150,
- "modificationTime": "2014-06-26T08:47:11.591Z"
- },
- "/dir": {
- "isDirectory": true,
- "name": "dir",
- "size": 0,
- "modificationTime": "2014-06-26T08:47:11.591Z"
- },
- "/dir/file3.txt": {
- "isDirectory": false,
- "name": "file3.txt",
- "size": 21,
- "modificationTime": "2014-06-26T08:47:11.591Z",
- "contents": "Just another example."
- }
-}
diff --git a/chrome/common/extensions/docs/examples/api/fileSystemProvider/archive/example2.fake b/chrome/common/extensions/docs/examples/api/fileSystemProvider/archive/example2.fake
deleted file mode 100644
index 385688c..0000000
--- a/chrome/common/extensions/docs/examples/api/fileSystemProvider/archive/example2.fake
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "/": {
- "isDirectory": true,
- "name": "",
- "size": 0,
- "modificationTime": "2014-06-26T08:47:11.591Z"
- },
- "/file.txt": {
- "isDirectory": false,
- "name": "file.txt",
- "size": 9,
- "modificationTime": "2014-06-26T08:47:11.591Z",
- "contents": "It works!"
- }
-}
diff --git a/chrome/common/extensions/docs/examples/api/fileSystemProvider/archive/manifest.json b/chrome/common/extensions/docs/examples/api/fileSystemProvider/archive/manifest.json
deleted file mode 100644
index 025b5d3..0000000
--- a/chrome/common/extensions/docs/examples/api/fileSystemProvider/archive/manifest.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
- "name": "Fake Archive Handler App",
- "version": "0.1",
- "manifest_version": 2,
- "description": "Demonstrate File System Provider API usage for apps.",
- "permissions": [
- "fileSystemProvider",
- {"fileSystem": ["retainEntries"]},
- "storage"
- ],
- "file_handlers": {
- "fake": {
- "types": ["application/fake"],
- "extensions": ["fake"]
- }
- },
- "file_system_provider_capabilities": {
- "multiple_mounts": true,
- "source": "file"
- },
- "app": {
- "background": {
- "scripts": [
- "background.js"
- ]
- }
- }
-}
diff --git a/chrome/common/extensions/docs/examples/api/fileSystemProvider/basic/background.js b/chrome/common/extensions/docs/examples/api/fileSystemProvider/basic/background.js
deleted file mode 100644
index 8c08f42..0000000
--- a/chrome/common/extensions/docs/examples/api/fileSystemProvider/basic/background.js
+++ /dev/null
@@ -1,142 +0,0 @@
-// Copyright 2014 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.
-
-'use strict';
-
-// Fake data similar to a file system structure.
-var MODIFICATION_DATE = new Date();
-var SHORT_CONTENTS = 'Just another example.';
-var LONGER_CONTENTS = 'It works!\nEverything gets displayed correctly.';
-
-var METADATA = {
- '/': {isDirectory: true, name: '', size: 0,
- modificationTime: MODIFICATION_DATE},
- '/file1.txt': {isDirectory: false, name: 'file1.txt',
- size: LONGER_CONTENTS.length, modificationTime: MODIFICATION_DATE,
- contents: LONGER_CONTENTS},
- '/file2': {isDirectory: false, name: 'file2', size: 150,
- modificationTime: MODIFICATION_DATE},
- '/dir': {isDirectory: true, name: 'dir', size: 0,
- modificationTime: MODIFICATION_DATE},
- '/dir/file3.txt': {isDirectory: false, name: 'file3.txt',
- size: SHORT_CONTENTS.length, modificationTime: MODIFICATION_DATE,
- contents: SHORT_CONTENTS}};
-
-// A map with currently opened files. As key it has requestId of
-// openFileRequested and as a value the file path.
-var openedFiles = {};
-
-function onGetMetadataRequested(options, onSuccess, onError) {
- if (!METADATA[options.entryPath])
- onError('NOT_FOUND');
- else
- onSuccess(METADATA[options.entryPath]);
-}
-
-function onReadDirectoryRequested(options, onSuccess, onError) {
- if (!METADATA[options.directoryPath]) {
- onError('NOT_FOUND');
- return;
- }
- if (!METADATA[options.directoryPath].isDirectory) {
- onError('NOT_A_DIRECTORY');
- return;
- }
-
- // Retrieve directory contents from METADATA.
- var entries = [];
- for (var entry in METADATA) {
- // Do not add itself on the list.
- if (entry == options.directoryPath)
- continue;
- // Check if the entry is a child of the requested directory.
- if (entry.indexOf(options.directoryPath) != 0)
- continue;
- // Restrict to direct children only.
- if (entry.substring(options.directoryPath.length + 1).indexOf('/') != -1)
- continue;
-
- entries.push(METADATA[entry]);
- }
- onSuccess(entries, false /* Last call. */);
-}
-
-function onOpenFileRequested(options, onSuccess, onError) {
- if (options.mode != 'READ' || options.create) {
- onError('INVALID_OPERATION');
- } else {
- openedFiles[options.requestId] = options.filePath;
- onSuccess();
- }
-}
-
-function onCloseFileRequested(options, onSuccess, onError) {
- if (!openedFiles[options.openRequestId]) {
- onError('INVALID_OPERATION');
- } else {
- delete openedFiles[options.openRequestId];
- onSuccess();
- }
-}
-
-function onReadFileRequested(options, onSuccess, onError) {
- if (!openedFiles[options.openRequestId]) {
- onError('INVALID_OPERATION');
- return;
- }
-
- var contents =
- METADATA[openedFiles[options.openRequestId]].contents;
-
- var remaining = Math.max(0, contents.length - options.offset);
- var length = Math.min(remaining, options.length);
-
- // Write the contents as ASCII text.
- var buffer = new ArrayBuffer(length);
- var bufferView = new Uint8Array(buffer);
- for (var i = 0; i < length; i++) {
- bufferView[i] = contents.charCodeAt(i + options.offset);
- }
-
- onSuccess(buffer, false /* Last call. */);
-}
-
-function onMountRequested(onSuccess, onError) {
- chrome.fileSystemProvider.mount(
- {fileSystemId: 'sample-file-system', displayName: 'Sample File System'},
- function() {
- if (chrome.runtime.lastError) {
- onError(chrome.runtime.lastError.message);
- console.error('Failed to mount because of: ' +
- chrome.runtime.lastError.message);
- return;
- }
- onSuccess();
- });
-}
-
-function onUnmountRequested(options, onSuccess, onError) {
- chrome.fileSystemProvider.unmount(
- {fileSystemId: options.fileSystemId},
- function() {
- if (chrome.runtime.lastError) {
- onError(chrome.runtime.lastError.message);
- console.error('Failed to unmount because of: ' +
- chrome.runtime.lastError.message);
- return;
- }
- onSuccess();
- });
-}
-
-chrome.fileSystemProvider.onGetMetadataRequested.addListener(
- onGetMetadataRequested);
-chrome.fileSystemProvider.onReadDirectoryRequested.addListener(
- onReadDirectoryRequested);
-chrome.fileSystemProvider.onOpenFileRequested.addListener(onOpenFileRequested);
-chrome.fileSystemProvider.onCloseFileRequested.addListener(
- onCloseFileRequested);
-chrome.fileSystemProvider.onReadFileRequested.addListener(onReadFileRequested);
-chrome.fileSystemProvider.onMountRequested.addListener(onMountRequested);
-chrome.fileSystemProvider.onUnmountRequested.addListener(onUnmountRequested);
diff --git a/chrome/common/extensions/docs/examples/api/fileSystemProvider/basic/manifest.json b/chrome/common/extensions/docs/examples/api/fileSystemProvider/basic/manifest.json
deleted file mode 100644
index fcb281c..0000000
--- a/chrome/common/extensions/docs/examples/api/fileSystemProvider/basic/manifest.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
- "name": "File System Provider API Extension Example",
- "version": "0.1",
- "manifest_version": 2,
- "description":
- "Demonstrate features of the API like mounting, listing directories, etc for extensions.",
- "permissions": [
- "fileSystemProvider"
- ],
- "file_system_provider_capabilities": {
- "source": "network"
- },
- "background": {
- "scripts": [
- "background.js"
- ]
- }
-}
diff --git a/chrome/common/extensions/docs/examples/api/fontSettings/css/chrome_shared.css b/chrome/common/extensions/docs/examples/api/fontSettings/css/chrome_shared.css
deleted file mode 100644
index 007d6f440..0000000
--- a/chrome/common/extensions/docs/examples/api/fontSettings/css/chrome_shared.css
+++ /dev/null
@@ -1,100 +0,0 @@
-/* Copyright (c) 2012 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. */
-
-/* Copy of /resources/shared/css/chrome_shared.css for sample extension. */
-
-/* Prevent CSS from overriding the hidden property. */
-[hidden] {
- display: none !important;
-}
-
-html.loading * {
- transition-delay: 0ms !important;
- transition-duration: 0ms !important;
-}
-
-body {
- cursor: default;
- margin: 0;
-}
-
-p {
- line-height: 1.8em;
-}
-
-h1,
-h2,
-h3 {
- -webkit-user-select: none;
- font-weight: normal;
- /* Makes the vertical size of the text the same for all fonts. */
- line-height: 1;
-}
-
-h1 {
- font-size: 1.5em;
-}
-
-h2 {
- font-size: 1.3em;
- margin-bottom: 0.4em;
-}
-
-h3 {
- color: black;
- font-size: 1.2em;
- margin-bottom: 0.8em;
-}
-
-a {
- color: rgb(17, 85, 204);
- text-decoration: underline;
-}
-
-a:active {
- color: rgb(5, 37, 119);
-}
-
-/* Elements that need to be LTR even in an RTL context, but should align
- * right. (Namely, URLs, search engine names, etc.)
- */
-html[dir='rtl'] .weakrtl {
- direction: ltr;
- text-align: right;
-}
-
-/* Input fields in search engine table need to be weak-rtl. Since those input
- * fields are generated for all cr.ListItem elements (and we only want weakrtl
- * on some), the class needs to be on the enclosing div.
- */
-html[dir='rtl'] div.weakrtl input {
- direction: ltr;
- text-align: right;
-}
-
-html[dir='rtl'] .favicon-cell.weakrtl {
- padding-inline-end: 22px;
- padding-inline-start: 0;
-}
-
-/* weakrtl for selection drop downs needs to account for the fact that
- * Webkit does not honor the text-align attribute for the select element.
- * (See Webkit bug #40216)
- */
-html[dir='rtl'] select.weakrtl {
- direction: rtl;
-}
-
-html[dir='rtl'] select.weakrtl option {
- direction: ltr;
-}
-
-/* WebKit does not honor alignment for text specified via placeholder attribute.
- * This CSS is a workaround. Please remove once WebKit bug is fixed.
- * https://bugs.webkit.org/show_bug.cgi?id=63367
- */
-html[dir='rtl'] input.weakrtl::-webkit-input-placeholder,
-html[dir='rtl'] .weakrtl input::-webkit-input-placeholder {
- direction: rtl;
-}
diff --git a/chrome/common/extensions/docs/examples/api/fontSettings/css/overlay.css b/chrome/common/extensions/docs/examples/api/fontSettings/css/overlay.css
deleted file mode 100644
index 432ca62..0000000
--- a/chrome/common/extensions/docs/examples/api/fontSettings/css/overlay.css
+++ /dev/null
@@ -1,162 +0,0 @@
-/* Copyright (c) 2012 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. */
-
-/* The shield that overlays the background. */
-.overlay {
- -webkit-box-align: center;
- -webkit-box-orient: vertical;
- -webkit-box-pack: center;
- background-color: rgba(255, 255, 255, 0.75);
- bottom: 0;
- display: -webkit-box;
- left: 0;
- overflow: auto;
- padding: 20px;
- position: fixed;
- right: 0;
- top: 0;
- transition: 200ms opacity;
-}
-
-/* Used to slide in the overlay. */
-.overlay.transparent .page {
- /* TODO(flackr): Add perspective(500px) rotateX(5deg) when accelerated
- * compositing is enabled on chrome:// pages. See http://crbug.com/116800. */
- transform: scale(0.99) translateY(-20px);
-}
-
-/* The foreground dialog. */
-.overlay .page {
- -webkit-border-radius: 3px;
- -webkit-box-orient: vertical;
- background: white;
- box-shadow: 0 4px 23px 5px rgba(0, 0, 0, 0.2), 0 2px 6px rgba(0,0,0,0.15);
- color: #333;
- display: -webkit-box;
- min-width: 400px;
- padding: 0;
- position: relative;
- transition: 200ms transform;
-}
-
-/* If the options page is loading don't do the transition. */
-.loading .overlay,
-.loading .overlay .page {
- transition-duration: 0ms !important;
-}
-
-/* keyframes used to pulse the overlay */
-@keyframes pulse {
- 0% {
- transform: scale(1);
- }
- 40% {
- transform: scale(1.02);
- }
- 60% {
- transform: scale(1.02);
- }
- 100% {
- transform: scale(1);
- }
-}
-
-.overlay .page.pulse {
- animation-duration: 180ms;
- animation-iteration-count: 1;
- animation-name: pulse;
- animation-timing-function: ease-in-out;
-}
-
-.overlay .page > .close-button {
- background-image: url('../images/x.png');
- background-position: center;
- background-repeat: no-repeat;
- height: 14px;
- position: absolute;
- right: 7px;
- top: 7px;
- width: 14px;
-}
-
-html[dir='rtl'] .overlay .page > .close-button {
- left: 10px;
- right: auto;
-}
-
-.overlay .page > .close-button:hover {
- background-image: url('../images/x-hover.png');
-}
-
-.overlay .page > .close-button:active {
- background-image: url('../images/x-pressed.png');
-}
-
-.overlay .page h1 {
- -webkit-user-select: none;
- color: #333;
- /* 120% of the body's font-size of 84% is 16px. This will keep the relative
- * size between the body and these titles consistent. */
- font-size: 120%;
- /* TODO(flackr): Pages like sync-setup and delete user collapse the margin
- * above the top of the page. Use padding instead to make sure that the
- * headers of these pages have the correct spacing, but this should not be
- * necessary. See http://crbug.com/119029. */
- margin: 0;
- padding: 14px 17px 14px;
- text-shadow: white 0 1px 2px;
-}
-
-.overlay .page .content-area {
- -webkit-box-flex: 1;
- overflow: auto;
- padding: 6px 17px 6px;
- position: relative;
-}
-
-.overlay .page .action-area {
- -webkit-box-align: center;
- -webkit-box-orient: horizontal;
- -webkit-box-pack: end;
- display: -webkit-box;
- padding: 14px 17px;
-}
-
-html[dir='rtl'] .overlay .page .action-area {
- left: 0;
-}
-
-.overlay .page .action-area-right {
- display: -webkit-box;
-}
-
-.overlay .page .button-strip {
- -webkit-box-orient: horizontal;
- display: -webkit-box;
-}
-
-.overlay .page .button-strip > button {
- display: block;
- margin-inline-start: 10px;
-}
-
-/* On OSX 10.7, hidden scrollbars may prevent the user from realizing that the
- * overlay contains scrollable content. To resolve this, style the scrollbars on
- * OSX so they are always visible. See http://crbug.com/123010. */
-<if expr="is_macosx">
-.overlay .page .content-area::-webkit-scrollbar {
- -webkit-appearance: none;
- width: 11px;
-}
-
-.overlay .page .content-area::-webkit-scrollbar-thumb {
- background-color: rgba(0, 0, 0, 0.2);
- border: 2px solid white;
- border-radius: 8px;
-}
-
-.overlay .page .content-area::-webkit-scrollbar-thumb:hover {
- background-color: rgba(0, 0, 0, 0.5);
-}
-</if>
diff --git a/chrome/common/extensions/docs/examples/api/fontSettings/css/uber_shared.css b/chrome/common/extensions/docs/examples/api/fontSettings/css/uber_shared.css
deleted file mode 100644
index 482451b5..0000000
--- a/chrome/common/extensions/docs/examples/api/fontSettings/css/uber_shared.css
+++ /dev/null
@@ -1,118 +0,0 @@
-/* Copyright (c) 2012 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. */
-
-body.uber-frame {
- color: rgb(48, 57, 66);
- margin-inline-start: 155px;
-}
-
-html[dir='rtl'] body.uber-frame {
- /* Enable vertical scrollbar at all times in RTL to avoid visual glitches when
- * showing sub-pages that vertically overflow. */
- overflow-y: scroll;
-}
-
-/* TODO(dbeam): Remove .page class from overlays in settings so the junk below
- * isn't necessary. */
-body.uber-frame #extension-settings.page,
-body.uber-frame #mainview-content .page,
-body.uber-frame .subpage-sheet-container .page,
-body.uber-frame > .page {
- margin-inline-end: 24px;
- min-width: 576px;
- padding-bottom: 20px;
- padding-top: 55px;
-}
-
-body.uber-frame header {
- background-image: -webkit-linear-gradient(white,
- white 40%,
- rgba(255, 255, 255, 0.92));
- left: 155px;
- /* <section>s in options currently amount to 638px total, broken up into
- * 600px max-width + 18px padding-inline-start + 20px margin-inline-end
- * so we mirror this value here so the headers match width and horizontal
- * alignment when scrolling sideways. */
- max-width: 738px;
- min-width: 600px;
- position: fixed;
- right: 0;
- top: 0;
- /* list.css sets a z-index of up to 2, this is set to 3 to ensure that the
- * header is in front of the selected list item. */
- z-index: 3;
-}
-
-html[dir='rtl'] body.uber-frame header {
- left: 0;
- right: 155px;
-}
-
-body.uber-frame header > .search-field-container,
-body.uber-frame header > .header-extras,
-body.uber-frame header > button {
- position: absolute;
- right: 20px;
- top: 21px;
-}
-
-html[dir='rtl'] body.uber-frame header > .search-field-container,
-html[dir='rtl'] body.uber-frame header > .header-extras,
-html[dir='rtl'] body.uber-frame header > button {
- left: 20px;
- right: auto;
-}
-
-body.uber-frame header input[type='search'],
-body.uber-frame header input[type='text'],
-body.uber-frame header button {
- margin: 0;
-}
-
-body.uber-frame header > h1 {
- margin: 0;
- padding: 21px 0 13px;
-}
-
-/* Create a border under the h1 (but before anything that gets appended
- * to the end of the header). */
-body.uber-frame header > h1::after {
- background-color: #eee;
- content: ' ';
- display: block;
- height: 1px;
- margin-inline-end: 20px;
- position: relative;
- top: 13px;
-}
-
-body.uber-frame footer {
- border-top: 1px solid #eee;
- margin-top: 16px;
- /* min-width and max-width should match the header */
- max-width: 638px;
- min-width: 600px;
- padding: 8px 0;
-}
-
-/* Sections are used in options pages, help page and history page. This defines
- * the section metrics to match the header metrics above. */
-body.uber-frame section {
- margin-bottom: 24px;
- margin-top: 8px;
- max-width: 600px;
- padding-inline-start: 18px;
-}
-
-body.uber-frame section:last-of-type {
- margin-bottom: 0;
-}
-
-body.uber-frame section > h3 {
- margin-inline-start: -18px;
-}
-
-body.uber-frame section > div:only-of-type {
- -webkit-box-flex: 1;
-}
diff --git a/chrome/common/extensions/docs/examples/api/fontSettings/css/widgets.css b/chrome/common/extensions/docs/examples/api/fontSettings/css/widgets.css
deleted file mode 100644
index dee76357..0000000
--- a/chrome/common/extensions/docs/examples/api/fontSettings/css/widgets.css
+++ /dev/null
@@ -1,306 +0,0 @@
-/* Copyright (c) 2012 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.
- */
-
-/* This file defines styles for form controls. The order of rule blocks is
- * important as there are some rules with equal specificity that rely on order
- * as a tiebreaker. These are marked with OVERRIDE.
- */
-
-/* Default state **************************************************************/
-
-:-webkit-any(button,
- input[type='button'],
- input[type='submit']):not(.custom-appearance):not(.link-button),
-select,
-input[type='checkbox'],
-input[type='radio'] {
- -webkit-appearance: none;
- -webkit-user-select: none;
- background-image: -webkit-linear-gradient(#ededed, #ededed 38%, #dedede);
- border: 1px solid rgba(0, 0, 0, 0.25);
- border-radius: 2px;
- box-shadow: 0 1px 0 rgba(0, 0, 0, 0.08),
- inset 0 1px 2px rgba(255, 255, 255, 0.75);
- color: #444;
- font: inherit;
- margin: 0 1px 0 0;
- text-shadow: 0 1px 0 rgb(240, 240, 240);
-}
-
-:-webkit-any(button,
- input[type='button'],
- input[type='submit']):not(.custom-appearance):not(.link-button),
-select {
- min-height: 2em;
- min-width: 4em;
-<if expr="is_win">
- /* The following platform-specific rule is necessary to get adjacent
- * buttons, text inputs, and so forth to align on their borders while also
- * aligning on the text's baselines. */
- padding-bottom: 1px;
-</if>
-}
-
-:-webkit-any(button,
- input[type='button'],
- input[type='submit']):not(.custom-appearance):not(.link-button) {
- padding-inline-end: 10px;
- padding-inline-start: 10px;
-}
-
-select {
- -webkit-appearance: none;
- /* OVERRIDE */
- background-image: url('../images/select.png'),
- -webkit-linear-gradient(#ededed, #ededed 38%, #dedede);
- background-position: right center;
- background-repeat: no-repeat;
- padding-inline-end: 20px;
- padding-inline-start: 6px;
-}
-
-html[dir='rtl'] select {
- background-position: center left;
-}
-
-input[type='checkbox'] {
- bottom: 2px;
- height: 13px;
- position: relative;
- vertical-align: middle;
- width: 13px;
-}
-
-input[type='radio'] {
- /* OVERRIDE */
- border-radius: 100%;
- bottom: 3px;
- height: 15px;
- position: relative;
- vertical-align: middle;
- width: 15px;
-}
-
-/* TODO(estade): add more types here? */
-input[type='password'],
-input[type='search'],
-input[type='text'],
-input[type='url'],
-input[type='number'],
-input:not([type]),
-textarea {
- border: 1px solid #bfbfbf;
- border-radius: 2px;
- box-sizing: border-box;
- color: #444;
- font: inherit;
- margin: 0;
- /* Use min-height to accommodate addditional padding for touch as needed. */
- min-height: 2em;
- padding: 3px;
-<if expr="is_win or is_macosx">
- /* For better alignment between adjacent buttons and inputs. */
- padding-bottom: 4px;
-</if>
-}
-
-input[type='search'] {
- -webkit-appearance: textfield;
- /* NOTE: Keep a relatively high min-width for this so we don't obscure the end
- * of the default text in relatively spacious languages (i.e. German). */
- min-width: 160px;
-}
-
-/* Checked ********************************************************************/
-
-input[type='checkbox']:checked::before {
- -webkit-user-select: none;
- background-image: url('../images/check.png');
- background-size: 100% 100%;
- content: '';
- display: block;
- height: 100%;
- width: 100%;
-}
-
-html[dir='rtl'] input[type='checkbox']:checked::before {
- transform: scaleX(-1);
-}
-
-input[type='radio']:checked::before {
- background-color: #666;
- border-radius: 100%;
- bottom: 3px;
- content: '';
- display: block;
- left: 3px;
- position: absolute;
- right: 3px;
- top: 3px;
-}
-
-/* Hover **********************************************************************/
-
-:enabled:hover:-webkit-any(
- select,
- input[type='checkbox'],
- input[type='radio'],
- :-webkit-any(
- button,
- input[type='button'],
- input[type='submit']):not(.custom-appearance):not(.link-button)) {
- background-image: -webkit-linear-gradient(#f0f0f0, #f0f0f0 38%, #e0e0e0);
- border-color: rgba(0, 0, 0, 0.3);
- box-shadow: 0 1px 0 rgba(0, 0, 0, 0.12),
- inset 0 1px 2px rgba(255, 255, 255, 0.95);
- color: black;
-}
-
-:enabled:hover:-webkit-any(select) {
- /* OVERRIDE */
- background-image: url('../images/select.png'),
- -webkit-linear-gradient(#f0f0f0, #f0f0f0 38%, #e0e0e0);
-}
-
-/* Active *********************************************************************/
-
-:enabled:active:-webkit-any(
- select,
- input[type='checkbox'],
- input[type='radio'],
- :-webkit-any(
- button,
- input[type='button'],
- input[type='submit']):not(.custom-appearance):not(.link-button)) {
- background-image: -webkit-linear-gradient(#e7e7e7, #e7e7e7 38%, #d7d7d7);
- box-shadow: none;
- text-shadow: none;
-}
-
-:enabled:active:-webkit-any(select) {
- /* OVERRIDE */
- background-image: url('../images/select.png'),
- -webkit-linear-gradient(#e7e7e7, #e7e7e7 38%, #d7d7d7);
-}
-
-/* Disabled *******************************************************************/
-
-:disabled:-webkit-any(
- button,
- input[type='button'],
- input[type='submit']):not(.custom-appearance):not(.link-button),
-select:disabled {
- background-image: -webkit-linear-gradient(#f1f1f1, #f1f1f1 38%, #e6e6e6);
- border-color: rgba(80, 80, 80, 0.2);
- box-shadow: 0 1px 0 rgba(80, 80, 80, 0.08),
- inset 0 1px 2px rgba(255, 255, 255, 0.75);
- color: #aaa;
-}
-
-select:disabled {
- /* OVERRIDE */
- background-image: url('../images/disabled_select.png'),
- -webkit-linear-gradient(#f1f1f1, #f1f1f1 38%, #e6e6e6);
-}
-
-input:disabled:-webkit-any([type='checkbox'],
- [type='radio']) {
- opacity: .75;
-}
-
-input:disabled:-webkit-any([type='password'],
- [type='search'],
- [type='text'],
- [type='url'],
- :not([type])) {
- color: #999;
-}
-
-/* Focus **********************************************************************/
-
-:enabled:focus:-webkit-any(
- select,
- input[type='checkbox'],
- input[type='password'],
- input[type='radio'],
- input[type='search'],
- input[type='text'],
- input[type='url'],
- input:not([type]),
- :-webkit-any(
- button,
- input[type='button'],
- input[type='submit']):not(.custom-appearance):not(.link-button)) {
- /* OVERRIDE */
- transition: border-color 200ms;
- /* We use border color because it follows the border radius (unlike outline).
- * This is particularly noticeable on mac. */
- border-color: rgb(77, 144, 254);
- outline: none;
-}
-
-/* Link buttons ***************************************************************/
-
-.link-button {
- -webkit-box-shadow: none;
- background: transparent none;
- border: none;
- color: rgb(17, 85, 204);
- cursor: pointer;
- /* Input elements have -webkit-small-control which can override the body font.
- * Resolve this by using 'inherit'. */
- font: inherit;
- margin: 0;
- padding: 0 4px;
-}
-
-.link-button:hover {
- text-decoration: underline;
-}
-
-.link-button:active {
- color: rgb(5, 37, 119);
- text-decoration: underline;
-}
-
-.link-button[disabled] {
- color: #999;
- cursor: default;
- text-decoration: none;
-}
-
-/* Checkbox/radio helpers ******************************************************
- *
- * .checkbox and .radio classes wrap labels. Checkboxes and radios should use
- * these classes with the markup structure:
- *
- * <div class="checkbox">
- * <label>
- * <input type="checkbox"></input>
- * <span>
- * </label>
- * </div>
- */
-
-:-webkit-any(.checkbox, .radio) label {
- /* Don't expand horizontally: <http://crbug.com/112091>. */
- display: -webkit-inline-box;
- padding-bottom: 7px;
- padding-top: 7px;
-}
-
-:-webkit-any(.checkbox, .radio) label input ~ span {
- /* Make sure long spans wrap at the same horizontal position they start. */
- display: block;
- margin-inline-start: 0.6em;
-}
-
-:-webkit-any(.checkbox, .radio) label:hover {
- color: black;
-}
-
-label > input:disabled:-webkit-any([type='checkbox'], [type='radio']) ~ span {
- color: #999;
-}
diff --git a/chrome/common/extensions/docs/examples/api/fontSettings/fonts128.png b/chrome/common/extensions/docs/examples/api/fontSettings/fonts128.png
deleted file mode 100644
index 0127cde..0000000
--- a/chrome/common/extensions/docs/examples/api/fontSettings/fonts128.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/fontSettings/fonts16.png b/chrome/common/extensions/docs/examples/api/fontSettings/fonts16.png
deleted file mode 100644
index 47e5aa6c..0000000
--- a/chrome/common/extensions/docs/examples/api/fontSettings/fonts16.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/fontSettings/images/disabled_select.png b/chrome/common/extensions/docs/examples/api/fontSettings/images/disabled_select.png
deleted file mode 100644
index 9bce7a3..0000000
--- a/chrome/common/extensions/docs/examples/api/fontSettings/images/disabled_select.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/fontSettings/images/select.png b/chrome/common/extensions/docs/examples/api/fontSettings/images/select.png
deleted file mode 100644
index 3cb71fb..0000000
--- a/chrome/common/extensions/docs/examples/api/fontSettings/images/select.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/fontSettings/images/slider/slide_bar_center.png b/chrome/common/extensions/docs/examples/api/fontSettings/images/slider/slide_bar_center.png
deleted file mode 100644
index e916da0c..0000000
--- a/chrome/common/extensions/docs/examples/api/fontSettings/images/slider/slide_bar_center.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/fontSettings/images/slider/slide_bar_disabled_center.png b/chrome/common/extensions/docs/examples/api/fontSettings/images/slider/slide_bar_disabled_center.png
deleted file mode 100644
index 9003650e..0000000
--- a/chrome/common/extensions/docs/examples/api/fontSettings/images/slider/slide_bar_disabled_center.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/fontSettings/images/slider/slide_bar_disabled_left.png b/chrome/common/extensions/docs/examples/api/fontSettings/images/slider/slide_bar_disabled_left.png
deleted file mode 100644
index 76915f1..0000000
--- a/chrome/common/extensions/docs/examples/api/fontSettings/images/slider/slide_bar_disabled_left.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/fontSettings/images/slider/slide_bar_disabled_right.png b/chrome/common/extensions/docs/examples/api/fontSettings/images/slider/slide_bar_disabled_right.png
deleted file mode 100644
index fda2c53..0000000
--- a/chrome/common/extensions/docs/examples/api/fontSettings/images/slider/slide_bar_disabled_right.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/fontSettings/images/slider/slide_bar_fill_center.png b/chrome/common/extensions/docs/examples/api/fontSettings/images/slider/slide_bar_fill_center.png
deleted file mode 100644
index e427ede5..0000000
--- a/chrome/common/extensions/docs/examples/api/fontSettings/images/slider/slide_bar_fill_center.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/fontSettings/images/slider/slide_bar_fill_left.png b/chrome/common/extensions/docs/examples/api/fontSettings/images/slider/slide_bar_fill_left.png
deleted file mode 100644
index 345a7fe..0000000
--- a/chrome/common/extensions/docs/examples/api/fontSettings/images/slider/slide_bar_fill_left.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/fontSettings/images/slider/slider_bar_right.png b/chrome/common/extensions/docs/examples/api/fontSettings/images/slider/slider_bar_right.png
deleted file mode 100644
index 01566d18..0000000
--- a/chrome/common/extensions/docs/examples/api/fontSettings/images/slider/slider_bar_right.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/fontSettings/images/slider/slider_thumb.png b/chrome/common/extensions/docs/examples/api/fontSettings/images/slider/slider_thumb.png
deleted file mode 100644
index f6fb421..0000000
--- a/chrome/common/extensions/docs/examples/api/fontSettings/images/slider/slider_thumb.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/fontSettings/images/slider/slider_thumb_disabled.png b/chrome/common/extensions/docs/examples/api/fontSettings/images/slider/slider_thumb_disabled.png
deleted file mode 100644
index 5eec71f..0000000
--- a/chrome/common/extensions/docs/examples/api/fontSettings/images/slider/slider_thumb_disabled.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/fontSettings/images/slider/slider_thumb_down.png b/chrome/common/extensions/docs/examples/api/fontSettings/images/slider/slider_thumb_down.png
deleted file mode 100644
index b20d82b5..0000000
--- a/chrome/common/extensions/docs/examples/api/fontSettings/images/slider/slider_thumb_down.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/fontSettings/images/slider/slider_thumb_hover.png b/chrome/common/extensions/docs/examples/api/fontSettings/images/slider/slider_thumb_hover.png
deleted file mode 100644
index 13612251..0000000
--- a/chrome/common/extensions/docs/examples/api/fontSettings/images/slider/slider_thumb_hover.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/fontSettings/images/x-hover.png b/chrome/common/extensions/docs/examples/api/fontSettings/images/x-hover.png
deleted file mode 100644
index 089df18..0000000
--- a/chrome/common/extensions/docs/examples/api/fontSettings/images/x-hover.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/fontSettings/images/x-pressed.png b/chrome/common/extensions/docs/examples/api/fontSettings/images/x-pressed.png
deleted file mode 100644
index 48d12c9..0000000
--- a/chrome/common/extensions/docs/examples/api/fontSettings/images/x-pressed.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/fontSettings/images/x.png b/chrome/common/extensions/docs/examples/api/fontSettings/images/x.png
deleted file mode 100644
index 9e2956d9..0000000
--- a/chrome/common/extensions/docs/examples/api/fontSettings/images/x.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/fontSettings/js/cr.js b/chrome/common/extensions/docs/examples/api/fontSettings/js/cr.js
deleted file mode 100644
index 69141a6..0000000
--- a/chrome/common/extensions/docs/examples/api/fontSettings/js/cr.js
+++ /dev/null
@@ -1,348 +0,0 @@
-// Copyright (c) 2012 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.
-
-/**
- * The global object.
- * @type {!Object}
- * @const
- */
-var global = this;
-
-/** Platform, package, object property, and Event support. **/
-this.cr = (function() {
- 'use strict';
-
- /**
- * Builds an object structure for the provided namespace path,
- * ensuring that names that already exist are not overwritten. For
- * example:
- * "a.b.c" -> a = {};a.b={};a.b.c={};
- * @param {string} name Name of the object that this file defines.
- * @param {*=} opt_object The object to expose at the end of the path.
- * @param {Object=} opt_objectToExportTo The object to add the path to;
- * default is {@code global}.
- * @private
- */
- function exportPath(name, opt_object, opt_objectToExportTo) {
- var parts = name.split('.');
- var cur = opt_objectToExportTo || global;
-
- for (var part; parts.length && (part = parts.shift());) {
- if (!parts.length && opt_object !== undefined) {
- // last part and we have an object; use it
- cur[part] = opt_object;
- } else if (part in cur) {
- cur = cur[part];
- } else {
- cur = cur[part] = {};
- }
- }
- return cur;
- };
-
- /**
- * Fires a property change event on the target.
- * @param {EventTarget} target The target to dispatch the event on.
- * @param {string} propertyName The name of the property that changed.
- * @param {*} newValue The new value for the property.
- * @param {*} oldValue The old value for the property.
- */
- function dispatchPropertyChange(target, propertyName, newValue, oldValue) {
- var e = new Event(propertyName + 'Change');
- e.propertyName = propertyName;
- e.newValue = newValue;
- e.oldValue = oldValue;
- target.dispatchEvent(e);
- }
-
- /**
- * Converts a camelCase javascript property name to a hyphenated-lower-case
- * attribute name.
- * @param {string} jsName The javascript camelCase property name.
- * @return {string} The equivalent hyphenated-lower-case attribute name.
- */
- function getAttributeName(jsName) {
- return jsName.replace(/([A-Z])/g, '-$1').toLowerCase();
- }
-
- /**
- * The kind of property to define in {@code defineProperty}.
- * @enum {number}
- * @const
- */
- var PropertyKind = {
- /**
- * Plain old JS property where the backing data is stored as a "private"
- * field on the object.
- */
- JS: 'js',
-
- /**
- * The property backing data is stored as an attribute on an element.
- */
- ATTR: 'attr',
-
- /**
- * The property backing data is stored as an attribute on an element. If the
- * element has the attribute then the value is true.
- */
- BOOL_ATTR: 'boolAttr'
- };
-
- /**
- * Helper function for defineProperty that returns the getter to use for the
- * property.
- * @param {string} name The name of the property.
- * @param {cr.PropertyKind} kind The kind of the property.
- * @return {function():*} The getter for the property.
- */
- function getGetter(name, kind) {
- switch (kind) {
- case PropertyKind.JS:
- var privateName = name + '_';
- return function() {
- return this[privateName];
- };
- case PropertyKind.ATTR:
- var attributeName = getAttributeName(name);
- return function() {
- return this.getAttribute(attributeName);
- };
- case PropertyKind.BOOL_ATTR:
- var attributeName = getAttributeName(name);
- return function() {
- return this.hasAttribute(attributeName);
- };
- }
- }
-
- /**
- * Helper function for defineProperty that returns the setter of the right
- * kind.
- * @param {string} name The name of the property we are defining the setter
- * for.
- * @param {cr.PropertyKind} kind The kind of property we are getting the
- * setter for.
- * @param {function(*):void} opt_setHook A function to run after the property
- * is set, but before the propertyChange event is fired.
- * @return {function(*):void} The function to use as a setter.
- */
- function getSetter(name, kind, opt_setHook) {
- switch (kind) {
- case PropertyKind.JS:
- var privateName = name + '_';
- return function(value) {
- var oldValue = this[name];
- if (value !== oldValue) {
- this[privateName] = value;
- if (opt_setHook)
- opt_setHook.call(this, value, oldValue);
- dispatchPropertyChange(this, name, value, oldValue);
- }
- };
-
- case PropertyKind.ATTR:
- var attributeName = getAttributeName(name);
- return function(value) {
- var oldValue = this[name];
- if (value !== oldValue) {
- if (value == undefined)
- this.removeAttribute(attributeName);
- else
- this.setAttribute(attributeName, value);
- if (opt_setHook)
- opt_setHook.call(this, value, oldValue);
- dispatchPropertyChange(this, name, value, oldValue);
- }
- };
-
- case PropertyKind.BOOL_ATTR:
- var attributeName = getAttributeName(name);
- return function(value) {
- var oldValue = this[name];
- if (value !== oldValue) {
- if (value)
- this.setAttribute(attributeName, name);
- else
- this.removeAttribute(attributeName);
- if (opt_setHook)
- opt_setHook.call(this, value, oldValue);
- dispatchPropertyChange(this, name, value, oldValue);
- }
- };
- }
- }
-
- /**
- * Defines a property on an object. When the setter changes the value a
- * property change event with the type {@code name + 'Change'} is fired.
- * @param {!Object} obj The object to define the property for.
- * @param {string} name The name of the property.
- * @param {cr.PropertyKind=} opt_kind What kind of underlying storage to use.
- * @param {function(*):void} opt_setHook A function to run after the
- * property is set, but before the propertyChange event is fired.
- */
- function defineProperty(obj, name, opt_kind, opt_setHook) {
- if (typeof obj == 'function')
- obj = obj.prototype;
-
- var kind = opt_kind || PropertyKind.JS;
-
- if (!obj.__lookupGetter__(name))
- obj.__defineGetter__(name, getGetter(name, kind));
-
- if (!obj.__lookupSetter__(name))
- obj.__defineSetter__(name, getSetter(name, kind, opt_setHook));
- }
-
- /**
- * Counter for use with createUid
- */
- var uidCounter = 1;
-
- /**
- * @return {number} A new unique ID.
- */
- function createUid() {
- return uidCounter++;
- }
-
- /**
- * Returns a unique ID for the item. This mutates the item so it needs to be
- * an object
- * @param {!Object} item The item to get the unique ID for.
- * @return {number} The unique ID for the item.
- */
- function getUid(item) {
- if (item.hasOwnProperty('uid'))
- return item.uid;
- return item.uid = createUid();
- }
-
- /**
- * Dispatches a simple event on an event target.
- * @param {!EventTarget} target The event target to dispatch the event on.
- * @param {string} type The type of the event.
- * @param {boolean=} opt_bubbles Whether the event bubbles or not.
- * @param {boolean=} opt_cancelable Whether the default action of the event
- * can be prevented. Default is true.
- * @return {boolean} If any of the listeners called {@code preventDefault}
- * during the dispatch this will return false.
- */
- function dispatchSimpleEvent(target, type, opt_bubbles, opt_cancelable) {
- var e = new Event(type, {
- bubbles: opt_bubbles,
- cancelable: opt_cancelable === undefined || opt_cancelable
- });
- return target.dispatchEvent(e);
- }
-
- /**
- * Calls |fun| and adds all the fields of the returned object to the object
- * named by |name|. For example, cr.define('cr.ui', function() {
- * function List() {
- * ...
- * }
- * function ListItem() {
- * ...
- * }
- * return {
- * List: List,
- * ListItem: ListItem,
- * };
- * });
- * defines the functions cr.ui.List and cr.ui.ListItem.
- * @param {string} name The name of the object that we are adding fields to.
- * @param {!Function} fun The function that will return an object containing
- * the names and values of the new fields.
- */
- function define(name, fun) {
- var obj = exportPath(name);
- var exports = fun();
- for (var propertyName in exports) {
- // Maybe we should check the prototype chain here? The current usage
- // pattern is always using an object literal so we only care about own
- // properties.
- var propertyDescriptor = Object.getOwnPropertyDescriptor(exports,
- propertyName);
- if (propertyDescriptor)
- Object.defineProperty(obj, propertyName, propertyDescriptor);
- }
- }
-
- /**
- * Adds a {@code getInstance} static method that always return the same
- * instance object.
- * @param {!Function} ctor The constructor for the class to add the static
- * method to.
- */
- function addSingletonGetter(ctor) {
- ctor.getInstance = function() {
- return ctor.instance_ || (ctor.instance_ = new ctor());
- };
- }
-
- /**
- * Initialization which must be deferred until run-time.
- */
- function initialize() {
- // If 'document' isn't defined, then we must be being pre-compiled,
- // so set a trap so that we're initialized on first access at run-time.
- if (!global.document) {
- var originalCr = cr;
-
- Object.defineProperty(global, 'cr', {
- get: function() {
- Object.defineProperty(global, 'cr', {value: originalCr});
- originalCr.initialize();
- return originalCr;
- },
- configurable: true
- });
-
- return;
- }
-
- cr.doc = document;
-
- /**
- * Whether we are using a Mac or not.
- */
- cr.isMac = /Mac/.test(navigator.platform);
-
- /**
- * Whether this is on the Windows platform or not.
- */
- cr.isWindows = /Win/.test(navigator.platform);
-
- /**
- * Whether this is on chromeOS or not.
- */
- cr.isChromeOS = /CrOS/.test(navigator.userAgent);
-
- /**
- * Whether this is on vanilla Linux (not chromeOS).
- */
- cr.isLinux = /Linux/.test(navigator.userAgent);
- }
-
- return {
- addSingletonGetter: addSingletonGetter,
- createUid: createUid,
- define: define,
- defineProperty: defineProperty,
- dispatchPropertyChange: dispatchPropertyChange,
- dispatchSimpleEvent: dispatchSimpleEvent,
- getUid: getUid,
- initialize: initialize,
- PropertyKind: PropertyKind
- };
-})();
-
-
-/**
- * TODO(kgr): Move this to another file which is to be loaded last.
- * This will be done as part of future work to make this code pre-compilable.
- */
-cr.initialize();
diff --git a/chrome/common/extensions/docs/examples/api/fontSettings/js/cr/ui.js b/chrome/common/extensions/docs/examples/api/fontSettings/js/cr/ui.js
deleted file mode 100644
index d48d3a8..0000000
--- a/chrome/common/extensions/docs/examples/api/fontSettings/js/cr/ui.js
+++ /dev/null
@@ -1,177 +0,0 @@
-// Copyright (c) 2012 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.
-
-cr.define('cr.ui', function() {
-
- /**
- * Decorates elements as an instance of a class.
- * @param {string|!Element} source The way to find the element(s) to decorate.
- * If this is a string then {@code querySeletorAll} is used to find the
- * elements to decorate.
- * @param {!Function} constr The constructor to decorate with. The constr
- * needs to have a {@code decorate} function.
- */
- function decorate(source, constr) {
- var elements;
- if (typeof source == 'string')
- elements = cr.doc.querySelectorAll(source);
- else
- elements = [source];
-
- for (var i = 0, el; el = elements[i]; i++) {
- if (!(el instanceof constr))
- constr.decorate(el);
- }
- }
-
- /**
- * Helper function for creating new element for define.
- */
- function createElementHelper(tagName, opt_bag) {
- // Allow passing in ownerDocument to create in a different document.
- var doc;
- if (opt_bag && opt_bag.ownerDocument)
- doc = opt_bag.ownerDocument;
- else
- doc = cr.doc;
- return doc.createElement(tagName);
- }
-
- /**
- * Creates the constructor for a UI element class.
- *
- * Usage:
- * <pre>
- * var List = cr.ui.define('list');
- * List.prototype = {
- * __proto__: HTMLUListElement.prototype,
- * decorate: function() {
- * ...
- * },
- * ...
- * };
- * </pre>
- *
- * @param {string|Function} tagNameOrFunction The tagName or
- * function to use for newly created elements. If this is a function it
- * needs to return a new element when called.
- * @return {function(Object=):Element} The constructor function which takes
- * an optional property bag. The function also has a static
- * {@code decorate} method added to it.
- */
- function define(tagNameOrFunction) {
- var createFunction, tagName;
- if (typeof tagNameOrFunction == 'function') {
- createFunction = tagNameOrFunction;
- tagName = '';
- } else {
- createFunction = createElementHelper;
- tagName = tagNameOrFunction;
- }
-
- /**
- * Creates a new UI element constructor.
- * @param {Object=} opt_propertyBag Optional bag of properties to set on the
- * object after created. The property {@code ownerDocument} is special
- * cased and it allows you to create the element in a different
- * document than the default.
- * @constructor
- */
- function f(opt_propertyBag) {
- var el = createFunction(tagName, opt_propertyBag);
- f.decorate(el);
- for (var propertyName in opt_propertyBag) {
- el[propertyName] = opt_propertyBag[propertyName];
- }
- return el;
- }
-
- /**
- * Decorates an element as a UI element class.
- * @param {!Element} el The element to decorate.
- */
- f.decorate = function(el) {
- el.__proto__ = f.prototype;
- el.decorate();
- };
-
- return f;
- }
-
- /**
- * Input elements do not grow and shrink with their content. This is a simple
- * (and not very efficient) way of handling shrinking to content with support
- * for min width and limited by the width of the parent element.
- * @param {HTMLElement} el The element to limit the width for.
- * @param {number} parentEl The parent element that should limit the size.
- * @param {number} min The minimum width.
- * @param {number} opt_scale Optional scale factor to apply to the width.
- */
- function limitInputWidth(el, parentEl, min, opt_scale) {
- // Needs a size larger than borders
- el.style.width = '10px';
- var doc = el.ownerDocument;
- var win = doc.defaultView;
- var computedStyle = win.getComputedStyle(el);
- var parentComputedStyle = win.getComputedStyle(parentEl);
- var rtl = computedStyle.direction == 'rtl';
-
- // To get the max width we get the width of the treeItem minus the position
- // of the input.
- var inputRect = el.getBoundingClientRect(); // box-sizing
- var parentRect = parentEl.getBoundingClientRect();
- var startPos = rtl ? parentRect.right - inputRect.right :
- inputRect.left - parentRect.left;
-
- // Add up border and padding of the input.
- var inner = parseInt(computedStyle.borderLeftWidth, 10) +
- parseInt(computedStyle.paddingLeft, 10) +
- parseInt(computedStyle.paddingRight, 10) +
- parseInt(computedStyle.borderRightWidth, 10);
-
- // We also need to subtract the padding of parent to prevent it to overflow.
- var parentPadding = rtl ? parseInt(parentComputedStyle.paddingLeft, 10) :
- parseInt(parentComputedStyle.paddingRight, 10);
-
- var max = parentEl.clientWidth - startPos - inner - parentPadding;
- if (opt_scale)
- max *= opt_scale;
-
- function limit() {
- if (el.scrollWidth > max) {
- el.style.width = max + 'px';
- } else {
- el.style.width = 0;
- var sw = el.scrollWidth;
- if (sw < min) {
- el.style.width = min + 'px';
- } else {
- el.style.width = sw + 'px';
- }
- }
- }
-
- el.addEventListener('input', limit);
- limit();
- }
-
- /**
- * Takes a number and spits out a value CSS will be happy with. To avoid
- * subpixel layout issues, the value is rounded to the nearest integral value.
- * @param {number} pixels The number of pixels.
- * @return {string} e.g. '16px'.
- */
- function toCssPx(pixels) {
- if (!window.isFinite(pixels))
- console.error('Pixel value is not a number: ' + pixels);
- return Math.round(pixels) + 'px';
- }
-
- return {
- decorate: decorate,
- define: define,
- limitInputWidth: limitInputWidth,
- toCssPx: toCssPx,
- };
-});
diff --git a/chrome/common/extensions/docs/examples/api/fontSettings/js/cr/ui/overlay.js b/chrome/common/extensions/docs/examples/api/fontSettings/js/cr/ui/overlay.js
deleted file mode 100644
index c5fde49..0000000
--- a/chrome/common/extensions/docs/examples/api/fontSettings/js/cr/ui/overlay.js
+++ /dev/null
@@ -1,101 +0,0 @@
-// Copyright (c) 2012 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.
-
-/**
- * @fileoverview Provides dialog-like behaviors for the tracing UI.
- */
-cr.define('cr.ui.overlay', function() {
-
- /**
- * Gets the top, visible overlay. It makes the assumption that if multiple
- * overlays are visible, the last in the byte order is topmost.
- * TODO(estade): rely on aria-visibility instead?
- * @return {HTMLElement} The overlay.
- */
- function getTopOverlay() {
- var overlays = document.querySelectorAll('.overlay:not([hidden])');
- return overlays[overlays.length - 1];
- }
-
- /**
- * Makes initializations which must hook at the document level.
- */
- function globalInitialization() {
- // Close the overlay on escape.
- document.addEventListener('keydown', function(e) {
- if (e.keyCode == 27) { // Escape
- var overlay = getTopOverlay();
- if (!overlay)
- return;
-
- cr.dispatchSimpleEvent(overlay, 'cancelOverlay');
- }
- });
-
- window.addEventListener('resize', setMaxHeightAllPages);
-
- setMaxHeightAllPages();
- }
-
- /**
- * Sets the max-height of all pages in all overlays, based on the window
- * height.
- */
- function setMaxHeightAllPages() {
- var pages = document.querySelectorAll('.overlay .page');
-
- var maxHeight = Math.min(0.9 * window.innerHeight, 640) + 'px';
- for (var i = 0; i < pages.length; i++)
- pages[i].style.maxHeight = maxHeight;
- }
-
- /**
- * Adds behavioral hooks for the given overlay.
- * @param {HTMLElement} overlay The .overlay.
- */
- function setupOverlay(overlay) {
- // Close the overlay on clicking any of the pages' close buttons.
- var closeButtons = overlay.querySelectorAll('.page > .close-button');
- for (var i = 0; i < closeButtons.length; i++) {
- closeButtons[i].addEventListener('click', function(e) {
- cr.dispatchSimpleEvent(overlay, 'cancelOverlay');
- });
- }
-
- // Remove the 'pulse' animation any time the overlay is hidden or shown.
- overlay.__defineSetter__('hidden', function(value) {
- this.classList.remove('pulse');
- if (value)
- this.setAttribute('hidden', true);
- else
- this.removeAttribute('hidden');
- });
- overlay.__defineGetter__('hidden', function() {
- return this.hasAttribute('hidden');
- });
-
- // Shake when the user clicks away.
- overlay.addEventListener('click', function(e) {
- // Only pulse if the overlay was the target of the click.
- if (this != e.target)
- return;
-
- // This may be null while the overlay is closing.
- var overlayPage = this.querySelector('.page:not([hidden])');
- if (overlayPage)
- overlayPage.classList.add('pulse');
- });
- overlay.addEventListener('animationend', function(e) {
- e.target.classList.remove('pulse');
- });
- }
-
- return {
- globalInitialization: globalInitialization,
- setupOverlay: setupOverlay,
- };
-});
-
-document.addEventListener('DOMContentLoaded',
- cr.ui.overlay.globalInitialization);
diff --git a/chrome/common/extensions/docs/examples/api/fontSettings/manifest.json b/chrome/common/extensions/docs/examples/api/fontSettings/manifest.json
deleted file mode 100644
index 2829fecb..0000000
--- a/chrome/common/extensions/docs/examples/api/fontSettings/manifest.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- "name": "Advanced Font Settings",
- "version": "0.67",
- "manifest_version": 2,
- "description": "Customize per-script font settings.",
- "options_page": "options.html",
- "icons": {
- "16": "fonts16.png",
- "128": "fonts128.png"
- },
- "permissions": ["fontSettings"]
-}
diff --git a/chrome/common/extensions/docs/examples/api/fontSettings/options.html b/chrome/common/extensions/docs/examples/api/fontSettings/options.html
deleted file mode 100644
index 3e40b67..0000000
--- a/chrome/common/extensions/docs/examples/api/fontSettings/options.html
+++ /dev/null
@@ -1,302 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<meta charset="utf-8">
-<title>Advanced Font Settings</title>
-<script src="js/cr.js"></script>
-<script src="js/cr/ui.js"></script>
-<script src="js/cr/ui/overlay.js"></script>
-<script src="slider.js"></script>
-<script src="pending_changes.js"></script>
-<script src="options.js"></script>
-<link rel="stylesheet" href="css/chrome_shared.css">
-<link rel="stylesheet" href="css/overlay.css">
-<link rel="stylesheet" href="css/widgets.css">
-<link rel="stylesheet" href="css/uber_shared.css">
-<link rel="stylesheet" href="slider.css">
-<style>
-body.uber-frame {
- margin-inline-start: 18px;
- margin-inline-end: 30px;
-}
-
-body.uber-frame section {
- max-width: 650px;
-}
-
-body.uber-frame section:last-of-type {
- margin-top: 28px;
-}
-
-body.uber-frame header {
- left: 0;
- padding-inline-start: 18px;
- right: 0;
-}
-
-body.uber-frame header > h1 {
- padding-bottom: 16px;
-}
-
-h1 {
- font-size: 16px;
-}
-
-.script-header {
- margin-top: 12px;
-}
-
-h3 {
- margin-bottom: 11px;
- font-size: 14px;
-}
-
-section {
- font-size: 12px;
-}
-
-.bordered {
- border: 1px solid #D9D9D9;
- border-radius: 2px;
-}
-
-.smaller {
- font-size: smaller;
-}
-
-.font-settings-div {
- margin-inline-end: 5px;
- width: 180px;
-}
-
-.font-settings-div:first-of-type {
- width: 138px;
-}
-
-.font-settings-div > :first-child {
- margin-bottom: 10px;
-}
-
-.font-settings-div > * {
- margin-bottom: 14px;
-}
-
-.font-settings-row {
- display: -webkit-flex;
- width: 800px;
-}
-
-.sample-text-div {
- display: -webkit-flex;
- white-space: nowrap;
- width: 100%;
- overflow: hidden;
-}
-
-.sample-text-span {
- margin-top: auto;
- margin-bottom: auto;
- margin-left: 20px;
-}
-
-#overlay-container {
- z-index: 100;
-}
-
-#standardFontSample {
- font-family: standard;
-}
-
-#serifFontSample {
- font-family: serif;
-}
-
-#sansSerifFontSample {
- font-family: sans-serif;
-}
-
-#fixedFontSample {
- font-family: monospace;
-}
-
-#minFontSample {
- font-family: standard;
-}
-
-select {
- width: 100%;
-}
-
-#footer > button {
- padding-inline-start: 9px;
- padding-inline-end: 9px;
-}
-
-#footer > #apply-settings {
- padding-inline-start: 17px;
- padding-inline-end: 17px;
-}
-
-#apply-settings:enabled {
- background-color: #4f7dd6;
- background-image: none;
- border-color: #2a4aac;
- box-shadow: none;
- color: #fbfafb;
- text-shadow: none;
-}
-
-.slider-legend {
- position: relative;
- /* This offset is needed to get the legend to align with the slider. */
- top: -7px;
-}
-
-.slider-container {
- display: inline-block;
- position: relative;
- top: 1px;
- height: 24px;
- width: 88px;
-}
-</style>
-</head>
-<body class="uber-frame">
-<div id="overlay-container" class="overlay" hidden>
- <div id="reset-overlay" class="page">
- <div class="close-button"></div>
- <div id="reset-this-script-overlay-dialog" hidden>
- <h1>Reset</h1>
- <div id="reset-this-script-overlay-dialog-content" class="content-area">
- </div>
- <div class="action-area">
- <div class="button-strip">
- <button id="reset-this-script-cancel">Cancel</button>
- <button id="reset-this-script-ok">Reset</button>
- </div>
- </div>
- </div>
- <div id="reset-all-scripts-overlay-dialog" hidden>
- <h1>Reset</h1>
- <div class="content-area">
- Are you sure you want to reset all settings?
- </div>
- <div class="action-area">
- <div class="button-strip">
- <button id="reset-all-cancel">Cancel</button>
- <button id="reset-all-ok">Reset</button>
- </div>
- </div>
- </div>
- </div>
-</div>
-<div class="page">
- <header style="transform: translateX(0px);">
- <h1>Advanced Font Settings</h1>
- </header>
- <section>
- <h3 class="script-header">Script</h3>
- <div class="font-settings-row">
- <select style="width: 200px" id="scriptList"></select>
- </div>
- </section>
- <section>
- <h3>Proportional fonts</h3>
- <div class="font-settings-row">
- <div class="font-settings-div">
- <div id="defaultFontSizeLabel"></div>
- <div style="width: 100%; margin-bottom: 0">
- <span class="slider-legend smaller">Aa</span>
- <div id="defaultFontSizeSliderContainer" class="slider-container"></div>
- <span class="slider-legend">Aa</span>
- </div>
- </div>
- <div class="font-settings-div">
- <div>Standard</div>
- <div><select id="standardFontList"></select></div>
- </div>
- <div class="font-settings-div">
- <div>Serif</div>
- <div><select id="serifFontList"></select></div>
- </div>
- <div class="font-settings-div">
- <div>Sans-Serif</div>
- <div><select id="sansSerifFontList"></select></div>
- </div>
- </div>
- <div class="bordered" style="position: relative; left: 0; right: 0; height: 160px; width: 702px;">
- <div class="sample-text-div" style="height: 33%">
- <span id='standardFontSample' class="sample-text-span">
- The quick brown fox jumps over the lazy dog.
- </span>
- </div>
- <div class="sample-text-div" style="height: 33%">
- <span id="serifFontSample" class="sample-text-span">
- The quick brown fox jumps over the lazy dog.
- </span>
- </div>
- <div class="sample-text-div" style="height: 33%">
- <span id="sansSerifFontSample" class="sample-text-span">
- The quick brown fox jumps over the lazy dog.
- </span>
- </div>
- </div>
- </section>
- <section>
- <h3>Fixed-width fonts</h3>
- <div class="font-settings-row">
- <div class="font-settings-div">
- <div id="fixedFontSizeLabel"></div>
- <div style="width: 100%; margin-bottom: 0">
- <span class="slider-legend smaller">Aa</span>
- <div id="defaultFixedFontSizeSliderContainer" class="slider-container"></div>
- <span class="slider-legend">Aa</span>
- </div>
- </div>
- <div class="font-settings-div">
- <div>Fixed</div>
- <div><select id="fixedFontList"></select></div>
- </div>
- </div>
- <div class="bordered" style="position: relative; overflow: hidden; left: 0; right: 0; height: 58px; width: 702px;">
- <div class="sample-text-div" style="height: 100%">
- <span id="fixedFontSample" class="sample-text-span">
- The quick brown fox jumps over the lazy dog.
- </span>
- </div>
- </div>
- </section>
- <section>
- <h3>Minimum font size</h3>
- <div class="font-settings-row">
- <div class="font-settings-div">
- <div id="minFontSizeLabel" style="margin-bottom: 8px"></div>
- <div style="width: 100%; margin-bottom: 12px">
- <span class="slider-legend smaller">Aa</span>
- <div id="minFontSizeSliderContainer" class="slider-container"></div>
- <span class="slider-legend">Aa</span>
- </div>
- </div>
- </div>
- <div class="bordered" style="position: relative; overflow: hidden; left: 0; right: 0; height: 58px; width: 702px;">
- <div class="sample-text-div" style="height: 100%">
- <span id="minFontSample" class="sample-text-span">
- The quick brown fox jumps over the lazy dog.
- </span>
- </div>
- </div>
- </section>
- <section id="footer">
- <button id="apply-settings">
- Apply settings
- </button>
- <button id="reset-this-script-button">
- Reset settings for this script
- </button>
- <button id="reset-all-button">
- Reset all settings
- </button>
- </section>
-</div>
-</body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/api/fontSettings/options.js b/chrome/common/extensions/docs/examples/api/fontSettings/options.js
deleted file mode 100644
index 6c57f168..0000000
--- a/chrome/common/extensions/docs/examples/api/fontSettings/options.js
+++ /dev/null
@@ -1,768 +0,0 @@
-// Copyright (c) 2012 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.
-
-'use strict';
-
-/**
- * @fileoverview The Advanced Font Settings Extension implementation.
- */
-
-function $(id) {
- return document.getElementById(id);
-}
-
-/**
- * @namespace
- */
-var advancedFonts = {};
-
-/**
- * The ICU script code for the Common, or global, script, which is used as the
- * fallback when the script is undeclared.
- * @const
- */
-advancedFonts.COMMON_SCRIPT = 'Zyyy';
-
-/**
- * The scripts supported by the Font Settings Extension API.
- * @const
- */
-advancedFonts.scripts = [
- { scriptCode: advancedFonts.COMMON_SCRIPT, scriptName: 'Default'},
- { scriptCode: 'Afak', scriptName: 'Afaka'},
- { scriptCode: 'Arab', scriptName: 'Arabic'},
- { scriptCode: 'Armi', scriptName: 'Imperial Aramaic'},
- { scriptCode: 'Armn', scriptName: 'Armenian'},
- { scriptCode: 'Avst', scriptName: 'Avestan'},
- { scriptCode: 'Bali', scriptName: 'Balinese'},
- { scriptCode: 'Bamu', scriptName: 'Bamum'},
- { scriptCode: 'Bass', scriptName: 'Bassa Vah'},
- { scriptCode: 'Batk', scriptName: 'Batak'},
- { scriptCode: 'Beng', scriptName: 'Bengali'},
- { scriptCode: 'Blis', scriptName: 'Blissymbols'},
- { scriptCode: 'Bopo', scriptName: 'Bopomofo'},
- { scriptCode: 'Brah', scriptName: 'Brahmi'},
- { scriptCode: 'Brai', scriptName: 'Braille'},
- { scriptCode: 'Bugi', scriptName: 'Buginese'},
- { scriptCode: 'Buhd', scriptName: 'Buhid'},
- { scriptCode: 'Cakm', scriptName: 'Chakma'},
- { scriptCode: 'Cans', scriptName: 'Unified Canadian Aboriginal Syllabics'},
- { scriptCode: 'Cari', scriptName: 'Carian'},
- { scriptCode: 'Cham', scriptName: 'Cham'},
- { scriptCode: 'Cher', scriptName: 'Cherokee'},
- { scriptCode: 'Cirt', scriptName: 'Cirth'},
- { scriptCode: 'Copt', scriptName: 'Coptic'},
- { scriptCode: 'Cprt', scriptName: 'Cypriot'},
- { scriptCode: 'Cyrl', scriptName: 'Cyrillic'},
- { scriptCode: 'Cyrs', scriptName: 'Old Church Slavonic Cyrillic'},
- { scriptCode: 'Deva', scriptName: 'Devanagari'},
- { scriptCode: 'Dsrt', scriptName: 'Deseret'},
- { scriptCode: 'Dupl', scriptName: 'Duployan shorthand'},
- { scriptCode: 'Egyd', scriptName: 'Egyptian demotic'},
- { scriptCode: 'Egyh', scriptName: 'Egyptian hieratic'},
- { scriptCode: 'Egyp', scriptName: 'Egyptian hieroglyphs'},
- { scriptCode: 'Elba', scriptName: 'Elbasan'},
- { scriptCode: 'Ethi', scriptName: 'Ethiopic'},
- { scriptCode: 'Geok', scriptName: 'Georgian Khutsuri'},
- { scriptCode: 'Geor', scriptName: 'Georgian'},
- { scriptCode: 'Glag', scriptName: 'Glagolitic'},
- { scriptCode: 'Goth', scriptName: 'Gothic'},
- { scriptCode: 'Gran', scriptName: 'Grantha'},
- { scriptCode: 'Grek', scriptName: 'Greek'},
- { scriptCode: 'Gujr', scriptName: 'Gujarati'},
- { scriptCode: 'Guru', scriptName: 'Gurmukhi'},
- { scriptCode: 'Hang', scriptName: 'Hangul'},
- { scriptCode: 'Hani', scriptName: 'Han'},
- { scriptCode: 'Hano', scriptName: 'Hanunoo'},
- { scriptCode: 'Hans', scriptName: 'Simplified Han'},
- { scriptCode: 'Hant', scriptName: 'Traditional Han'},
- { scriptCode: 'Hebr', scriptName: 'Hebrew'},
- { scriptCode: 'Hluw', scriptName: 'Anatolian Hieroglyphs'},
- { scriptCode: 'Hmng', scriptName: 'Pahawh Hmong'},
- { scriptCode: 'Hung', scriptName: 'Old Hungarian'},
- { scriptCode: 'Inds', scriptName: 'Indus'},
- { scriptCode: 'Ital', scriptName: 'Old Italic'},
- { scriptCode: 'Java', scriptName: 'Javanese'},
- { scriptCode: 'Jpan', scriptName: 'Japanese'},
- { scriptCode: 'Jurc', scriptName: 'Jurchen'},
- { scriptCode: 'Kali', scriptName: 'Kayah Li'},
- { scriptCode: 'Khar', scriptName: 'Kharoshthi'},
- { scriptCode: 'Khmr', scriptName: 'Khmer'},
- { scriptCode: 'Khoj', scriptName: 'Khojki'},
- { scriptCode: 'Knda', scriptName: 'Kannada'},
- { scriptCode: 'Kpel', scriptName: 'Kpelle'},
- { scriptCode: 'Kthi', scriptName: 'Kaithi'},
- { scriptCode: 'Lana', scriptName: 'Lanna'},
- { scriptCode: 'Laoo', scriptName: 'Lao'},
- { scriptCode: 'Latf', scriptName: 'Fraktur Latin'},
- { scriptCode: 'Latg', scriptName: 'Gaelic Latin'},
- { scriptCode: 'Latn', scriptName: 'Latin'},
- { scriptCode: 'Lepc', scriptName: 'Lepcha'},
- { scriptCode: 'Limb', scriptName: 'Limbu'},
- { scriptCode: 'Lina', scriptName: 'Linear A'},
- { scriptCode: 'Linb', scriptName: 'Linear B'},
- { scriptCode: 'Lisu', scriptName: 'Fraser'},
- { scriptCode: 'Loma', scriptName: 'Loma'},
- { scriptCode: 'Lyci', scriptName: 'Lycian'},
- { scriptCode: 'Lydi', scriptName: 'Lydian'},
- { scriptCode: 'Mand', scriptName: 'Mandaean'},
- { scriptCode: 'Mani', scriptName: 'Manichaean'},
- { scriptCode: 'Maya', scriptName: 'Mayan hieroglyphs'},
- { scriptCode: 'Mend', scriptName: 'Mende'},
- { scriptCode: 'Merc', scriptName: 'Meroitic Cursive'},
- { scriptCode: 'Mero', scriptName: 'Meroitic'},
- { scriptCode: 'Mlym', scriptName: 'Malayalam'},
- { scriptCode: 'Mong', scriptName: 'Mongolian'},
- { scriptCode: 'Moon', scriptName: 'Moon'},
- { scriptCode: 'Mroo', scriptName: 'Mro'},
- { scriptCode: 'Mtei', scriptName: 'Meitei Mayek'},
- { scriptCode: 'Mymr', scriptName: 'Myanmar'},
- { scriptCode: 'Narb', scriptName: 'Old North Arabian'},
- { scriptCode: 'Nbat', scriptName: 'Nabataean'},
- { scriptCode: 'Nkgb', scriptName: 'Naxi Geba'},
- { scriptCode: 'Nkoo', scriptName: 'N’Ko'},
- { scriptCode: 'Nshu', scriptName: 'Nüshu'},
- { scriptCode: 'Ogam', scriptName: 'Ogham'},
- { scriptCode: 'Olck', scriptName: 'Ol Chiki'},
- { scriptCode: 'Orkh', scriptName: 'Orkhon'},
- { scriptCode: 'Orya', scriptName: 'Oriya'},
- { scriptCode: 'Osma', scriptName: 'Osmanya'},
- { scriptCode: 'Palm', scriptName: 'Palmyrene'},
- { scriptCode: 'Perm', scriptName: 'Old Permic'},
- { scriptCode: 'Phag', scriptName: 'Phags-pa'},
- { scriptCode: 'Phli', scriptName: 'Inscriptional Pahlavi'},
- { scriptCode: 'Phlp', scriptName: 'Psalter Pahlavi'},
- { scriptCode: 'Phlv', scriptName: 'Book Pahlavi'},
- { scriptCode: 'Phnx', scriptName: 'Phoenician'},
- { scriptCode: 'Plrd', scriptName: 'Pollard Phonetic'},
- { scriptCode: 'Prti', scriptName: 'Inscriptional Parthian'},
- { scriptCode: 'Rjng', scriptName: 'Rejang'},
- { scriptCode: 'Roro', scriptName: 'Rongorongo'},
- { scriptCode: 'Runr', scriptName: 'Runic'},
- { scriptCode: 'Samr', scriptName: 'Samaritan'},
- { scriptCode: 'Sara', scriptName: 'Sarati'},
- { scriptCode: 'Sarb', scriptName: 'Old South Arabian'},
- { scriptCode: 'Saur', scriptName: 'Saurashtra'},
- { scriptCode: 'Sgnw', scriptName: 'SignWriting'},
- { scriptCode: 'Shaw', scriptName: 'Shavian'},
- { scriptCode: 'Shrd', scriptName: 'Sharada'},
- { scriptCode: 'Sind', scriptName: 'Khudawadi'},
- { scriptCode: 'Sinh', scriptName: 'Sinhala'},
- { scriptCode: 'Sora', scriptName: 'Sora Sompeng'},
- { scriptCode: 'Sund', scriptName: 'Sundanese'},
- { scriptCode: 'Sylo', scriptName: 'Syloti Nagri'},
- { scriptCode: 'Syrc', scriptName: 'Syriac'},
- { scriptCode: 'Syre', scriptName: 'Estrangelo Syriac'},
- { scriptCode: 'Syrj', scriptName: 'Western Syriac'},
- { scriptCode: 'Syrn', scriptName: 'Eastern Syriac'},
- { scriptCode: 'Tagb', scriptName: 'Tagbanwa'},
- { scriptCode: 'Takr', scriptName: 'Takri'},
- { scriptCode: 'Tale', scriptName: 'Tai Le'},
- { scriptCode: 'Talu', scriptName: 'New Tai Lue'},
- { scriptCode: 'Taml', scriptName: 'Tamil'},
- { scriptCode: 'Tang', scriptName: 'Tangut'},
- { scriptCode: 'Tavt', scriptName: 'Tai Viet'},
- { scriptCode: 'Telu', scriptName: 'Telugu'},
- { scriptCode: 'Teng', scriptName: 'Tengwar'},
- { scriptCode: 'Tfng', scriptName: 'Tifinagh'},
- { scriptCode: 'Tglg', scriptName: 'Tagalog'},
- { scriptCode: 'Thaa', scriptName: 'Thaana'},
- { scriptCode: 'Thai', scriptName: 'Thai'},
- { scriptCode: 'Tibt', scriptName: 'Tibetan'},
- { scriptCode: 'Tirh', scriptName: 'Tirhuta'},
- { scriptCode: 'Ugar', scriptName: 'Ugaritic'},
- { scriptCode: 'Vaii', scriptName: 'Vai'},
- { scriptCode: 'Visp', scriptName: 'Visible Speech'},
- { scriptCode: 'Wara', scriptName: 'Varang Kshiti'},
- { scriptCode: 'Wole', scriptName: 'Woleai'},
- { scriptCode: 'Xpeo', scriptName: 'Old Persian'},
- { scriptCode: 'Xsux', scriptName: 'Sumero-Akkadian Cuneiform'},
- { scriptCode: 'Yiii', scriptName: 'Yi'},
- { scriptCode: 'Zmth', scriptName: 'Mathematical Notation'},
- { scriptCode: 'Zsym', scriptName: 'Symbols'}
-];
-
-/**
- * The generic font families supported by the Font Settings Extension API.
- * @const
- */
-advancedFonts.FAMILIES =
- ['standard', 'sansserif', 'serif', 'fixed', 'cursive', 'fantasy'];
-
-/**
- * Sample texts.
- * @const
- */
-advancedFonts.SAMPLE_TEXTS = {
- // "Cyrllic script".
- Cyrl: 'Кириллица',
- Hang: '정 참판 양반댁 규수 큰 교자 타고 혼례 치른 날.',
- Hans: '床前明月光,疑是地上霜。举头望明月,低头思故乡。',
- Hant: '床前明月光,疑是地上霜。舉頭望明月,低頭思故鄉。',
- Jpan: '吾輩は猫である。名前はまだ無い。',
- // "Khmer language".
- Khmr: '\u1797\u17B6\u179F\u17B6\u1781\u17D2\u1798\u17C2\u179A',
- Zyyy: 'The quick brown fox jumps over the lazy dog.'
-};
-
-/**
- * Controller of pending changes.
- * @const
- */
-advancedFonts.pendingChanges = new PendingChanges();
-
-/**
- * Map from |genericFamily| to UI controls and data for its font setting.
- */
-advancedFonts.fontSettings = null;
-
-/**
- * Map from |fontSizeKey| to UI controls and data for its font size setting.
- */
-advancedFonts.fontSizeSettings = null;
-
-/**
- * Gets the font size used for |fontSizeKey|, including pending changes. Calls
- * |callback| with the result.
- *
- * @param {string} fontSizeKey The font size setting key. See
- * PendingChanges.getFontSize().
- * @param {function(number, boolean)} callback The callback of form
- * function(size, controllable). |size| is the effective setting,
- * |controllable| is whether the setting can be set.
- */
-advancedFonts.getEffectiveFontSize = function(fontSizeKey, callback) {
- advancedFonts.fontSizeSettings[fontSizeKey].getter({}, function(details) {
- var controllable = advancedFonts.isControllableLevel(
- details.levelOfControl);
- var size = details.pixelSize;
- var pendingFontSize = advancedFonts.pendingChanges.getFontSize(fontSizeKey);
- // If the setting is not controllable, we can have no pending change.
- if (!controllable) {
- if (pendingFontSize != null) {
- advancedFonts.pendingChanges.setFontSize(fontSizeKey, null);
- $('apply-settings').disabled = advancedFonts.pendingChanges.isEmpty();
- pendingFontSize = null;
- }
- }
-
- // If we have a pending change, it overrides the current setting.
- if (pendingFontSize != null)
- size = pendingFontSize;
- callback(size, controllable);
- });
-};
-
-/**
- * Gets the font used for |script| and |genericFamily|, including pending
- * changes. Calls |callback| with the result.
- *
- * @param {string} script The script code.
- * @param {string} genericFamily The generic family.
- * @param {function(string, boolean, string)} callback The callback of form
- * function(font, controllable, effectiveFont). |font| is the setting
- * (pending or not), |controllable| is whether the setting can be set,
- * |effectiveFont| is the font used taking fallback into consideration.
- */
-advancedFonts.getEffectiveFont = function(script, genericFamily, callback) {
- var pendingChanges = advancedFonts.pendingChanges;
- var details = { script: script, genericFamily: genericFamily };
- chrome.fontSettings.getFont(details, function(result) {
- var setting = {};
- setting.font = result.fontId;
- setting.controllable =
- advancedFonts.isControllableLevel(result.levelOfControl);
- var pendingFont =
- pendingChanges.getFont(details.script, details.genericFamily);
- // If the setting is not controllable, we can have no pending change.
- if (!setting.controllable) {
- if (pendingFont != null) {
- pendingChanges.setFont(script, genericFamily, null);
- $('apply-settings').disabled = advancedFonts.pendingChanges.isEmpty();
- pendingFont = null;
- }
- }
-
- // If we have a pending change, it overrides the current setting.
- if (pendingFont != null)
- setting.font = pendingFont;
-
- // If we have a font, we're done.
- if (setting.font) {
- callback(setting.font, setting.controllable, setting.font);
- return;
- }
-
- // If we're still here, we have to fallback to common script, unless this
- // already is common script.
- if (script == advancedFonts.COMMON_SCRIPT) {
- callback('', setting.controllable, '');
- return;
- }
- advancedFonts.getEffectiveFont(
- advancedFonts.COMMON_SCRIPT,
- genericFamily,
- callback.bind(null, setting.font, setting.controllable));
- });
-};
-
-/**
- * Refreshes the UI controls related to a font setting.
- *
- * @param {{fontList: HTMLSelectElement, samples: Array<HTMLElement>}}
- * fontSetting The setting object (see advancedFonts.fontSettings).
- * @param {string} font The value of the font setting.
- * @param {boolean} controllable Whether the font setting can be controlled
- * by this extension.
- * @param {string} effectiveFont The font used, including fallback to Common
- * script.
- */
-advancedFonts.refreshFont = function(
- fontSetting, font, controllable, effectiveFont) {
- for (var i = 0; i < fontSetting.samples.length; ++i)
- fontSetting.samples[i].style.fontFamily = effectiveFont;
- advancedFonts.setSelectedFont(fontSetting.fontList, font);
- fontSetting.fontList.disabled = !controllable;
-};
-
-/**
- * Refreshes the UI controls related to a font size setting.
- *
- * @param {{label: HTMLElement, slider: Slider, samples: Array<HTMLElement>}}
- * fontSizeSetting The setting object (see advancedFonts.fontSizeSettings).
- * @param size The value of the font size setting.
- * @param controllable Whether the setting can be controlled by this extension.
- */
-advancedFonts.refreshFontSize = function(fontSizeSetting, size, controllable) {
- fontSizeSetting.label.textContent = 'Size: ' + size + 'px';
- advancedFonts.setFontSizeSlider(fontSizeSetting.slider, size, controllable);
- for (var i = 0; i < fontSizeSetting.samples.length; ++i)
- fontSizeSetting.samples[i].style.fontSize = size + 'px';
-};
-
-/**
- * Refreshes all UI controls to reflect the current settings, including pending
- * changes.
- */
-advancedFonts.refresh = function() {
- var script = advancedFonts.getSelectedScript();
- var sample;
- if (advancedFonts.SAMPLE_TEXTS[script])
- sample = advancedFonts.SAMPLE_TEXTS[script];
- else
- sample = advancedFonts.SAMPLE_TEXTS[advancedFonts.COMMON_SCRIPT];
- var sampleTexts = document.querySelectorAll('.sample-text-span');
- for (var i = 0; i < sampleTexts.length; i++)
- sampleTexts[i].textContent = sample;
-
- var setting;
- var callback;
- for (var genericFamily in advancedFonts.fontSettings) {
- setting = advancedFonts.fontSettings[genericFamily];
- callback = advancedFonts.refreshFont.bind(null, setting);
- advancedFonts.getEffectiveFont(script, genericFamily, callback);
- }
-
- for (var fontSizeKey in advancedFonts.fontSizeSettings) {
- setting = advancedFonts.fontSizeSettings[fontSizeKey];
- callback = advancedFonts.refreshFontSize.bind(null, setting);
- advancedFonts.getEffectiveFontSize(fontSizeKey, callback);
- }
-
- $('apply-settings').disabled = advancedFonts.pendingChanges.isEmpty();
-};
-
-/**
- * @return {string} The currently selected script code.
- */
-advancedFonts.getSelectedScript = function() {
- var scriptList = $('scriptList');
- return scriptList.options[scriptList.selectedIndex].value;
-};
-
-/**
- * @param {HTMLSelectElement} fontList The <select> containing a list of fonts.
- * @return {string} The currently selected value of |fontList|.
- */
-advancedFonts.getSelectedFont = function(fontList) {
- return fontList.options[fontList.selectedIndex].value;
-};
-
-/**
- * Populates the font lists.
- * @param {Array<{fontId: string, displayName: string>} fonts The list of
- * fonts on the system.
- */
-advancedFonts.populateFontLists = function(fonts) {
- for (var genericFamily in advancedFonts.fontSettings) {
- var list = advancedFonts.fontSettings[genericFamily].fontList;
-
- // Add a special item to indicate fallback to the non-per-script
- // font setting. The Font Settings API uses the empty string to indicate
- // fallback.
- var defaultItem = document.createElement('option');
- defaultItem.value = '';
- defaultItem.text = '(Use default)';
- list.add(defaultItem);
-
- for (var i = 0; i < fonts.length; ++i) {
- var item = document.createElement('option');
- item.value = fonts[i].fontId;
- item.text = fonts[i].displayName;
- list.add(item);
- }
- }
- advancedFonts.refresh();
-};
-
-/**
- * Handles change events on a <select> element for a font setting.
- * @param {string} genericFamily The generic family for the font setting.
- * @param {Event} event The change event.
- */
-advancedFonts.handleFontListChange = function(genericFamily, event) {
- var script = advancedFonts.getSelectedScript();
- var font = advancedFonts.getSelectedFont(event.target);
-
- advancedFonts.pendingChanges.setFont(script, genericFamily, font);
- advancedFonts.refresh();
-};
-
-/**
- * Sets the selected value of |fontList| to |fontId|.
- * @param {HTMLSelectElement} fontList The <select> containing a list of fonts.
- * @param {string} fontId The font to set |fontList|'s selection to.
- */
-advancedFonts.setSelectedFont = function(fontList, fontId) {
- var script = advancedFonts.getSelectedScript();
- var i;
- for (i = 0; i < fontList.length; i++) {
- if (fontId == fontList.options[i].value) {
- fontList.selectedIndex = i;
- break;
- }
- }
- if (i == fontList.length) {
- console.warn("font '" + fontId + "' for " + fontList.id + ' for ' +
- script + ' is not on the system');
- }
-};
-
-/**
- * Handles change events on a font size slider.
- * @param {string} fontSizeKey The key for the font size setting whose slider
- * changed. See PendingChanges.getFont.
- * @param {string} value The new value of the slider.
- */
-advancedFonts.handleFontSizeSliderChange = function(fontSizeKey, value) {
- var pixelSize = parseInt(value);
- if (!isNaN(pixelSize)) {
- advancedFonts.pendingChanges.setFontSize(fontSizeKey, pixelSize);
- advancedFonts.refresh();
- }
-};
-
-/**
- * @param {string} levelOfControl The level of control string for a setting,
- * as returned by the Font Settings Extension API.
- * @return {boolean} True if |levelOfControl| signifies that the extension can
- * control the setting; otherwise, returns false.
- */
-advancedFonts.isControllableLevel = function(levelOfControl) {
- return levelOfControl == 'controllable_by_this_extension' ||
- levelOfControl == 'controlled_by_this_extension';
-};
-
-/*
- * Updates the specified font size slider's value and enabled property.
- * @param {Slider} slider The slider for a font size setting.
- * @param {number} size The value to set the slider to.
- * @param {boolean} enabled Whether to enable or disable the slider.
- */
-advancedFonts.setFontSizeSlider = function(slider, size, enabled) {
- if (slider.getValue() != size)
- slider.setValue(size);
- var inputElement = slider.getInput();
- if (enabled) {
- inputElement.parentNode.classList.remove('disabled');
- inputElement.disabled = false;
- } else {
- inputElement.parentNode.classList.add('disabled');
- inputElement.disabled = true;
- }
-};
-
-/**
- * Initializes the UI control elements related to the font size setting
- * |fontSizeKey| and registers listeners for the user adjusting its slider and
- * the setting changing on the browser-side.
- * @param {string} fontSizeKey The key for font size setting. See
- * PendingChanges.getFont().
- */
-advancedFonts.initFontSizeSetting = function(fontSizeKey) {
- var fontSizeSettings = advancedFonts.fontSizeSettings;
- var setting = fontSizeSettings[fontSizeKey];
- var label = setting.label;
- var samples = setting.samples;
-
- setting.slider = new Slider(
- setting.sliderContainer,
- 0,
- setting.minValue,
- setting.maxValue,
- advancedFonts.handleFontSizeSliderChange.bind(null, fontSizeKey)
- );
-
- var slider = setting.slider;
- setting.getter({}, function(details) {
- var size = details.pixelSize.toString();
- var controllable = advancedFonts.isControllableLevel(
- details.levelOfControl);
- advancedFonts.setFontSizeSlider(slider, size, controllable);
- for (var i = 0; i < samples.length; i++)
- samples[i].style.fontSize = size + 'px';
- });
- fontSizeSettings[fontSizeKey].onChanged.addListener(advancedFonts.refresh);
-};
-
-/**
- * Clears the font settings for the specified script.
- * @param {string} script The script code.
- */
-advancedFonts.clearSettingsForScript = function(script) {
- advancedFonts.pendingChanges.clearOneScript(script);
- for (var i = 0; i < advancedFonts.FAMILIES.length; i++) {
- chrome.fontSettings.clearFont({
- script: script,
- genericFamily: advancedFonts.FAMILIES[i]
- });
- }
-};
-
-/**
- * Clears all font and font size settings.
- */
-advancedFonts.clearAllSettings = function() {
- advancedFonts.pendingChanges.clear();
- for (var i = 0; i < advancedFonts.scripts.length; i++)
- advancedFonts.clearSettingsForScript(advancedFonts.scripts[i].scriptCode);
- chrome.fontSettings.clearDefaultFixedFontSize();
- chrome.fontSettings.clearDefaultFontSize();
- chrome.fontSettings.clearMinimumFontSize();
-};
-
-/**
- * Closes the overlay.
- */
-advancedFonts.closeOverlay = function() {
- $('overlay-container').hidden = true;
-};
-
-/**
- * Initializes apply and reset buttons.
- */
-advancedFonts.initApplyAndResetButtons = function() {
- var applyButton = $('apply-settings');
- applyButton.addEventListener('click', function() {
- advancedFonts.pendingChanges.apply();
- advancedFonts.refresh();
- });
-
- var overlay = $('overlay-container');
- cr.ui.overlay.globalInitialization();
- cr.ui.overlay.setupOverlay(overlay);
- overlay.addEventListener('cancelOverlay', advancedFonts.closeOverlay);
-
- $('reset-this-script-button').onclick = function(event) {
- var scriptList = $('scriptList');
- var scriptName = scriptList.options[scriptList.selectedIndex].text;
- $('reset-this-script-overlay-dialog-content').innerText =
- 'Are you sure you want to reset settings for ' + scriptName +
- ' script?';
-
- $('overlay-container').hidden = false;
- $('reset-this-script-overlay-dialog').hidden = false;
- $('reset-all-scripts-overlay-dialog').hidden = true;
- };
- $('reset-this-script-ok').onclick = function(event) {
- advancedFonts.clearSettingsForScript(advancedFonts.getSelectedScript());
- advancedFonts.closeOverlay();
- advancedFonts.refresh();
- };
- $('reset-this-script-cancel').onclick = advancedFonts.closeOverlay;
-
- $('reset-all-button').onclick = function(event) {
- $('overlay-container').hidden = false;
- $('reset-all-scripts-overlay-dialog').hidden = false;
- $('reset-this-script-overlay-dialog').hidden = true;
- };
- $('reset-all-ok').onclick = function(event) {
- advancedFonts.clearAllSettings();
- advancedFonts.closeOverlay();
- advancedFonts.refresh();
- };
- $('reset-all-cancel').onclick = advancedFonts.closeOverlay;
-};
-
-/**
- * Best guess for system fonts, taken from the IDS_WEB_FONT_FAMILY strings in
- * Chrome.
- * TODO: The font should be localized like Chrome does.
- * @const
- */
-advancedFonts.systemFonts = {
- cros: 'Noto Sans UI, sans-serif',
- linux: 'Ubuntu, sans-serif',
- mac: 'Lucida Grande, sans-serif',
- win: 'Segoe UI, Tahoma, sans-serif',
- unknown: 'sans-serif'
-};
-
-/**
- * @return {string} The platform this extension is running on.
- */
-advancedFonts.getPlatform = function() {
- var ua = window.navigator.appVersion;
- if (ua.indexOf('Win') != -1) return 'win';
- if (ua.indexOf('Mac') != -1) return 'mac';
- if (ua.indexOf('Linux') != -1) return 'linux';
- if (ua.indexOf('CrOS') != -1) return 'cros';
- return 'unknown';
-};
-
-/**
- * Chrome settings tries to use the system font. So does this extension.
- */
-advancedFonts.useSystemFont = function() {
- document.body.style.fontFamily =
- advancedFonts.systemFonts[advancedFonts.getPlatform()];
-};
-
-/**
- * Sorts the list of script codes by scriptName. Someday this extension will
- * have localized script names, so the order will depend on locale.
- */
-advancedFonts.sortScripts = function() {
- var i;
- var scripts = advancedFonts.scripts;
- for (i = 0; i < scripts; ++i) {
- if (scripts[i].scriptCode == advancedFonts.COMMON_SCRIPT)
- break;
- }
- var defaultScript = scripts.splice(i, 1)[0];
-
- scripts.sort(function(a, b) {
- if (a.scriptName > b.scriptName)
- return 1;
- if (a.scriptName < b.scriptName)
- return -1;
- return 0;
- });
-
- scripts.unshift(defaultScript);
-};
-
-/**
- * Initializes UI controls for font settings.
- */
-advancedFonts.initFontControls = function() {
- advancedFonts.fontSettings = {
- standard: {
- fontList: $('standardFontList'),
- samples: [$('standardFontSample'), $('minFontSample')]
- },
- serif: {
- fontList: $('serifFontList'),
- samples: [$('serifFontSample')]
- },
- sansserif: {
- fontList: $('sansSerifFontList'),
- samples: [$('sansSerifFontSample')]
- },
- fixed: {
- fontList: $('fixedFontList'),
- samples: [$('fixedFontSample')]
- }
- };
-
- for (var genericFamily in advancedFonts.fontSettings) {
- var list = advancedFonts.fontSettings[genericFamily].fontList;
- list.addEventListener(
- 'change', advancedFonts.handleFontListChange.bind(list, genericFamily));
- }
- chrome.fontSettings.onFontChanged.addListener(advancedFonts.refresh);
- chrome.fontSettings.getFontList(advancedFonts.populateFontLists);
-};
-
-/**
- * Initializes UI controls for font size settings.
- */
-advancedFonts.initFontSizeControls = function() {
- advancedFonts.fontSizeSettings = {
- defaultFontSize: {
- sliderContainer: $('defaultFontSizeSliderContainer'),
- minValue: 6,
- maxValue: 50,
- samples: [
- $('standardFontSample'), $('serifFontSample'), $('sansSerifFontSample')
- ],
- label: $('defaultFontSizeLabel'),
- getter: chrome.fontSettings.getDefaultFontSize,
- onChanged: chrome.fontSettings.onDefaultFontSizeChanged
- },
- defaultFixedFontSize: {
- sliderContainer: $('defaultFixedFontSizeSliderContainer'),
- minValue: 6,
- maxValue: 50,
- samples: [$('fixedFontSample')],
- label: $('fixedFontSizeLabel'),
- getter: chrome.fontSettings.getDefaultFixedFontSize,
- onChanged: chrome.fontSettings.onDefaultFixedFontSizeChanged
- },
- minFontSize: {
- sliderContainer: $('minFontSizeSliderContainer'),
- minValue: 6,
- maxValue: 24,
- samples: [$('minFontSample')],
- label: $('minFontSizeLabel'),
- getter: chrome.fontSettings.getMinimumFontSize,
- onChanged: chrome.fontSettings.onMinimumFontSizeChanged
- }
- };
-
- for (var fontSizeKey in advancedFonts.fontSizeSettings)
- advancedFonts.initFontSizeSetting(fontSizeKey);
-};
-
-/**
- * Initializes the list of scripts.
- */
-advancedFonts.initScriptList = function() {
- var scriptList = $('scriptList');
- advancedFonts.sortScripts();
- var scripts = advancedFonts.scripts;
- for (var i = 0; i < scripts.length; i++) {
- var script = document.createElement('option');
- script.value = scripts[i].scriptCode;
- script.text = scripts[i].scriptName;
- scriptList.add(script);
- }
- scriptList.selectedIndex = 0;
- scriptList.addEventListener('change', advancedFonts.refresh);
-};
-
-/**
- * Initializes the extension.
- */
-advancedFonts.init = function() {
- advancedFonts.useSystemFont();
-
- advancedFonts.initFontControls();
- advancedFonts.initFontSizeControls();
- advancedFonts.initScriptList();
-
- advancedFonts.initApplyAndResetButtons();
-};
-
-document.addEventListener('DOMContentLoaded', advancedFonts.init);
diff --git a/chrome/common/extensions/docs/examples/api/fontSettings/pending_changes.js b/chrome/common/extensions/docs/examples/api/fontSettings/pending_changes.js
deleted file mode 100644
index be43bb9..0000000
--- a/chrome/common/extensions/docs/examples/api/fontSettings/pending_changes.js
+++ /dev/null
@@ -1,145 +0,0 @@
-// Copyright 2013 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.
-
-'use strict';
-
-/**
- * @fileoverview PendingChanges class tracks changes to be applied when an
- * "Apply Changes" button is clicked.
- */
-
-/**
- * Creates a PendingChanges object with no pending changes.
- *
- * @constructor
- */
-var PendingChanges = function() {
- // Format: pendingFontChanges_.Cyrl.sansserif = "My SansSerif Cyrillic Font"
- this.pendingFontChanges_ = {};
-
- // Format: pendingFontSizeChanges_.defaultFontSize = 12
- this.pendingFontSizeChanges_ = {};
-};
-
-/**
- * Returns the pending font setting change for the specified script and family,
- * or null if it doesn't exist.
- *
- * @param {string} script The script code, like "Cyrl".
- * @param {string} genericFamily The generic family, like "sansserif".
- * @return {?string} The pending font setting, like "My Cyrillic SansSerif Font"
- * or null if it doesn't exist.
- */
-PendingChanges.prototype.getFont = function(script, genericFamily) {
- if (this.pendingFontChanges_[script])
- return this.pendingFontChanges_[script][genericFamily];
- return null;
-};
-
-/**
- * Returns the pending font size setting change, or null if it doesn't exist.
- *
- * @param {string} fontSizeKey The font size setting key. One of
- * 'defaultFontSize', 'defaultFixedFontSize', or 'minFontSize'.
- * @return {?number} The pending font size setting in pixels, or null if it
- * doesn't exist.
- */
-PendingChanges.prototype.getFontSize = function(fontSizeKey) {
- return this.pendingFontSizeChanges_[fontSizeKey];
-};
-
-/**
- * Sets the pending font change for the specified script and family.
- *
- * @param {string} script The script code, like "Cyrl".
- * @param {string} genericFamily The generic family, like "sansserif".
- * @param {?string} font The font to set the setting to, or null to clear it.
- */
-PendingChanges.prototype.setFont = function(script, genericFamily, font) {
- if (!this.pendingFontChanges_[script])
- this.pendingFontChanges_[script] = {};
- if (this.pendingFontChanges_[script][genericFamily] == font)
- return;
- this.pendingFontChanges_[script][genericFamily] = font;
-};
-
-/**
- * Sets the pending font size change.
- *
- * @param {string} fontSizeKey The font size setting key. See
- * getFontSize().
- * @param {number} size The font size to set the setting to.
- */
-PendingChanges.prototype.setFontSize = function(fontSizeKey, size) {
- if (this.pendingFontSizeChanges_[fontSizeKey] == size)
- return;
- this.pendingFontSizeChanges_[fontSizeKey] = size;
-};
-
-/**
- * Commits the pending changes to Chrome. After this function is called, there
- * are no pending changes.
- */
-PendingChanges.prototype.apply = function() {
- for (var script in this.pendingFontChanges_) {
- for (var genericFamily in this.pendingFontChanges_[script]) {
- var fontId = this.pendingFontChanges_[script][genericFamily];
- if (fontId == null)
- continue;
- var details = {};
- details.script = script;
- details.genericFamily = genericFamily;
- details.fontId = fontId;
- chrome.fontSettings.setFont(details);
- }
- }
-
- var size = this.pendingFontSizeChanges_['defaultFontSize'];
- if (size != null)
- chrome.fontSettings.setDefaultFontSize({pixelSize: size});
-
- size = this.pendingFontSizeChanges_['defaultFixedFontSize'];
- if (size != null)
- chrome.fontSettings.setDefaultFixedFontSize({pixelSize: size});
-
- size = this.pendingFontSizeChanges_['minFontSize'];
- if (size != null)
- chrome.fontSettings.setMinimumFontSize({pixelSize: size});
-
- this.clear();
-};
-
-/**
- * Clears the pending font changes for a single script.
- *
- * @param {string} script The script code, like "Cyrl".
- */
-PendingChanges.prototype.clearOneScript = function(script) {
- this.pendingFontChanges_[script] = {};
-};
-
-/**
- * Clears all pending font changes.
- */
-PendingChanges.prototype.clear = function() {
- this.pendingFontChanges_ = {};
- this.pendingFontSizeChanges_ = {};
-};
-
-/**
- * @return {boolean} True if there are no pending changes, otherwise false.
- */
-PendingChanges.prototype.isEmpty = function() {
- for (var script in this.pendingFontChanges_) {
- for (var genericFamily in this.pendingFontChanges_[script]) {
- if (this.pendingFontChanges_[script][genericFamily] != null)
- return false;
- }
- }
- for (var name in this.pendingFontSizeChanges_) {
- if (this.pendingFontSizeChanges_[name] != null)
- return false;
- }
- return true;
-};
diff --git a/chrome/common/extensions/docs/examples/api/fontSettings/slider.css b/chrome/common/extensions/docs/examples/api/fontSettings/slider.css
deleted file mode 100644
index 236054f..0000000
--- a/chrome/common/extensions/docs/examples/api/fontSettings/slider.css
+++ /dev/null
@@ -1,113 +0,0 @@
-/* Copyright 2013 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.
- */
-
-/* Customize the standard input[type='range']. */
-.slider > input[type='range'] {
- -webkit-appearance: none !important; /* Hide the default thumb icon. */
- background: transparent; /* Hide the standard slider bar */
- height: 100%;
- left: -2px; /* Required to align the input element with the parent. */
- position: absolute;
- top: -2px;
- width: 100%;
-}
-
-/* Custom thumb icon. */
-.slider > input[type='range']::-webkit-slider-thumb {
- -webkit-appearance: none;
- background-position: center center;
- background-repeat: no-repeat;
- height: 24px;
- position: relative;
- z-index: 2;
-}
-
-/* Custom slider bar (we hide the standard one). */
-.slider > .bar {
- /* In order to match the horizontal position of the standard slider bar
- left and right must be equal to 1/2 of the thumb icon width. */
- left: 8px;
- right: 8px;
- bottom: 10px;
- pointer-events: none; /* Mouse events pass through to the standard input. */
- position: absolute;
- top: 10px;
- background-image: url(../images/slider/slide_bar_center.png);
- height: 4px;
-}
-
-.slider > .bar > .filled,
-.slider > .bar > .cap {
- position: absolute;
-}
-
-/* The filled portion of the slider bar to the left of the thumb. */
-.slider > .bar > .filled {
- border-left-style: none;
- border-right-style: none;
- left: 0;
- width: 0; /* The element style.width is manipulated from the code. */
-}
-
-.slider > .bar > .cap.right {
- background-image: url(../images/slider/slider_bar_right.png);
- height: 4px;
- width: 4px;
- left: 100%;
-}
-
-.slider > .bar > .filled {
- background-image: url(../images/slider/slide_bar_fill_center.png);
- height: 4px;
-}
-
-.slider > .bar > .cap.left {
- background-image: url(../images/slider/slide_bar_fill_left.png);
- height: 4px;
- width: 4px;
- right: 100%;
-}
-
-.slider.disabled > .bar {
- background-image: url(../images/slider/slide_bar_disabled_center.png);
-}
-
-.slider.disabled > .bar > .filled {
- background-image: url(../images/slider/slide_bar_disabled_center.png);
-}
-
-.slider.disabled > .bar > .cap.left {
- background-image: url(../images/slider/slide_bar_disabled_left.png);
-}
-
-.slider.disabled > .bar > .cap.right {
- background-image: url(../images/slider/slide_bar_disabled_right.png);
-}
-
-.slider.disabled,
-.slider.readonly {
- pointer-events: none;
-}
-
-.slider {
- -webkit-box-flex: 1;
-}
-
-.slider > input[type='range']::-webkit-slider-thumb {
- background-image: url(../images/slider/slider_thumb.png);
- width: 16px;
-}
-
-.slider > input[type='range']::-webkit-slider-thumb:hover {
- background-image: url(../images/slider/slider_thumb_hover.png);
-}
-
-.slider > input[type='range']::-webkit-slider-thumb:active {
- background-image: url(../images/slider/slider_thumb_down.png);
-}
-
-.slider.disabled > input[type='range']::-webkit-slider-thumb {
- background-image: url(../images/slider/slider_thumb_disabled.png);
-}
diff --git a/chrome/common/extensions/docs/examples/api/fontSettings/slider.js b/chrome/common/extensions/docs/examples/api/fontSettings/slider.js
deleted file mode 100644
index ff139dc..0000000
--- a/chrome/common/extensions/docs/examples/api/fontSettings/slider.js
+++ /dev/null
@@ -1,102 +0,0 @@
-// Copyright 2013 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.
-
-'use strict';
-
-/**
- * @fileoverview A Slider control. Based on Chromium's MediaControls.Slider.
- */
-
-/**
- * Creates a slider control.
- *
- * @param {HTMLElement} container The containing div element.
- * @param {number} value Initial value
- * @param {number} min Minimum value
- * @param {number} max Maximum value
- * @param {?function(number)=} opt_onChange Value change handler
- * @constructor
- */
-function Slider(container, value, min, max, opt_onChange) {
- this.container_ = container;
- this.onChange_ = opt_onChange;
-
- var containerDocument = this.container_.ownerDocument;
-
- this.container_.classList.add('slider');
-
- this.input_ = containerDocument.createElement('input');
- this.input_.type = 'range';
- this.input_.min = min;
- this.input_.max = max;
- this.input_.value = value;
- this.container_.appendChild(this.input_);
-
- this.input_.addEventListener(
- 'change', this.onInputChange_.bind(this));
- this.input_.addEventListener(
- 'input', this.onInputChange_.bind(this));
-
- this.bar_ = containerDocument.createElement('div');
- this.bar_.className = 'bar';
- this.container_.appendChild(this.bar_);
-
- this.filled_ = containerDocument.createElement('div');
- this.filled_.className = 'filled';
- this.bar_.appendChild(this.filled_);
-
- var leftCap = containerDocument.createElement('div');
- leftCap.className = 'cap left';
- this.bar_.appendChild(leftCap);
-
- var rightCap = containerDocument.createElement('div');
- rightCap.className = 'cap right';
- this.bar_.appendChild(rightCap);
-
- this.updateFilledWidth_();
-};
-
-/**
- * @return {number} The value of the input control.
- */
-Slider.prototype.getValue = function() {
- return this.input_.value;
-};
-
-/**
- * @param{number} value The value to set the input control to.
- */
-Slider.prototype.setValue = function(value) {
- this.input_.value = value;
- this.updateFilledWidth_();
-};
-
-/**
- * @return {HTMLInputElement} The underlying input control.
- */
-Slider.prototype.getInput = function() {
- return this.input_;
-}
-
-/**
- * Updates the filled portion of the slider to reflect the slider's current
- * value.
- * @private
- */
-Slider.prototype.updateFilledWidth_ = function() {
- var proportion = (this.input_.value - this.input_.min) /
- (this.input_.max - this.input_.min);
- this.filled_.style.width = proportion * 100 + '%';
-};
-
-/**
- * Called when the slider's value changes.
- * @private
- */
-Slider.prototype.onInputChange_ = function() {
- this.updateFilledWidth_();
- if (this.onChange_)
- this.onChange_(this.input_.value);
-};
-
diff --git a/chrome/common/extensions/docs/examples/api/history/historyOverride/history.html b/chrome/common/extensions/docs/examples/api/history/historyOverride/history.html
deleted file mode 100644
index 689b5ef2..0000000
--- a/chrome/common/extensions/docs/examples/api/history/historyOverride/history.html
+++ /dev/null
@@ -1,42 +0,0 @@
-<html>
- <head>
- <title>History</title>
- <link rel="stylesheet" type="text/css" href="style.css"/>
- </head>
- <body>
- <div id="searchBar">
- <h1>History<sup>2</sup></h1>
- <input id="searchInput" type="text" name="search"
- placeholder="Search History">
- <input type="submit" id="searchSubmit" value="Submit">
- <br>
- <br>
- <input type="submit" id="deleteSelected" value="Delete Selected">
- <br>
- <br>
- <input type="submit" id="removeAll" value="Remove All">
- <br>
- <br>
- <input type="submit" id="seeAll" value="See All">
- </div>
- <div id="historyDiv">
- </div>
- <template id="historyTemplate">
- <div class="history">
- <div class="imageDiv">
- <a class="titleLink"></a>
- </div>
- <div class="urlDiv">
- <p class="pageName"></p>
- </div>
- <div class="removeDiv">
- <a>
- <button class="removeButton">Delete</button>
- <input type="checkbox" class="removeCheck"/>
- </a>
- </div>
- </div>
- </template>
- <script src="logic.js"></script>
- </body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/api/history/historyOverride/history128.png b/chrome/common/extensions/docs/examples/api/history/historyOverride/history128.png
deleted file mode 100644
index e53641a..0000000
--- a/chrome/common/extensions/docs/examples/api/history/historyOverride/history128.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/history/historyOverride/history16.png b/chrome/common/extensions/docs/examples/api/history/historyOverride/history16.png
deleted file mode 100644
index cdb6e8a..0000000
--- a/chrome/common/extensions/docs/examples/api/history/historyOverride/history16.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/history/historyOverride/history32.png b/chrome/common/extensions/docs/examples/api/history/historyOverride/history32.png
deleted file mode 100644
index 004630a..0000000
--- a/chrome/common/extensions/docs/examples/api/history/historyOverride/history32.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/history/historyOverride/history48.png b/chrome/common/extensions/docs/examples/api/history/historyOverride/history48.png
deleted file mode 100644
index c16dfe8..0000000
--- a/chrome/common/extensions/docs/examples/api/history/historyOverride/history48.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/history/historyOverride/logic.js b/chrome/common/extensions/docs/examples/api/history/historyOverride/logic.js
deleted file mode 100644
index fc07ddb..0000000
--- a/chrome/common/extensions/docs/examples/api/history/historyOverride/logic.js
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright 2017 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.
-
-const kMillisecondsPerWeek = 1000 * 60 * 60 * 24 * 7;
-const kOneWeekAgo = (new Date).getTime() - kMillisecondsPerWeek;
-let historyDiv = document.getElementById('historyDiv');
-const kColors = ['#4688F1', '#E8453C', '#F9BB2D', '#3AA757'];
-let $ = document.getElementById.bind(document);
-
-function constructHistory(historyItems) {
- let template = $('historyTemplate');
- for (let item of historyItems) {
- let displayDiv = template.content.querySelector("#history, div");
- let randomColor = kColors[Math.floor(Math.random() * kColors.length)];
- displayDiv.style.backgroundColor = randomColor;
- let titleLink = template.content.querySelector('.titleLink, a');
- let pageName = template.content.querySelector('.pageName, p');
- let removeButton = template.content.querySelector('.removeButton, button');
- let checkbox = template.content.querySelector('.removeCheck, input');
- checkbox.setAttribute('value', item.url);
- let favicon = document.createElement('img');
- let host = new URL(item.url).host;
- titleLink.href = item.url;
- favicon.src = 'chrome://favicon/' + item.url;
- titleLink.textContent = host;
- titleLink.appendChild(favicon);
- pageName.innerText = item.title;
- if (item.title === '') {
- pageName.innerText = host;
- }
- var clone = document.importNode(template.content, true);
- clone.querySelector('.removeButton, button')
- .addEventListener('click', function() {
- chrome.history.deleteUrl({url: item.url}, function() {
- location.reload();
- });
- });
- historyDiv.appendChild(clone);
- }
-}
-
-chrome.history.search({
- text: '',
- startTime: kOneWeekAgo,
- maxResults: 99
- }, constructHistory);
-
-$('searchSubmit').onclick = function() {
- historyDiv.innerHTML = " "
- let searchQuery = document.getElementById('searchInput').value
- chrome.history.search({
- text: searchQuery,
- startTime: kOneWeekAgo
- }, constructHistory)
-}
-
-$('deleteSelected').onclick = function() {
- let checkboxes = document.getElementsByTagName('input');
- for (var i =0; i<checkboxes.length; i++) {
- if (checkboxes[i].checked == true) {
- chrome.history.deleteUrl({url: checkboxes[i].value})
- }
- }
- location.reload();
-}
-
-$('removeAll').onclick = function() {
- chrome.history.deleteAll(function() {
- location.reload();
- });
-}
-
-$('seeAll').onclick = function() {
- location.reload();
-}
diff --git a/chrome/common/extensions/docs/examples/api/history/historyOverride/manifest.json b/chrome/common/extensions/docs/examples/api/history/historyOverride/manifest.json
deleted file mode 100644
index bb44e22..0000000
--- a/chrome/common/extensions/docs/examples/api/history/historyOverride/manifest.json
+++ /dev/null
@@ -1,22 +0,0 @@
-{
- "manifest_version": 2,
- "name": "History Override",
- "description": "Overrides the History Page",
- "version": "1.0",
- "chrome_url_overrides" : {
- "history": "history.html"
- },
- "browser_action": {
- "default_title": "History"
- },
- "permissions": [
- "history",
- "chrome://favicon/"
- ],
- "icons": {
- "16": "history16.png",
- "32": "history32.png",
- "48": "history48.png",
- "128": "history128.png"
- }
-}
diff --git a/chrome/common/extensions/docs/examples/api/history/historyOverride/style.css b/chrome/common/extensions/docs/examples/api/history/historyOverride/style.css
deleted file mode 100644
index bc4db0a..0000000
--- a/chrome/common/extensions/docs/examples/api/history/historyOverride/style.css
+++ /dev/null
@@ -1,130 +0,0 @@
-/* Copyright 2017 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.*/
-::-webkit-scrollbar {
- width: 0px; /* remove scrollbar space */
- background: transparent; /* make scrollbar invisible */
-}
-
-#searchBar {
- float: left;
- width: 250px;
- height: auto;
- position: absolute;
- top: 10;
- left: 10;
-}
-
-#historyDiv {
- color: white;
- font-size: 16px;
- max-width: 1020px;
- min-width: 320px;
- max-height: 98vh;
- min-height: 500px;
- position: absolute;
- top: 10;
- left: 260;
- overflow: scroll;
- overflow-x: hidden;
-}
-
-.history {
- float: left;
- margin-right: 10px;
- margin-bottom: 10px;
- width: 300px;
- height: 150px;
- word-wrap: break-word;
- padding: 10px;
- display:inline-block;
-}
-
-.title {
- color: black;
- float: left;
- position: relative;
- left: 15;
- bottom: 15;
-}
-
-img {
- float: left;
- position: relative;
- left: 5;
- top: 2;
- margin-right: 8px;
-}
-
-
-.imageDiv {
- background-color: white;
- width: 310px;
- height: 20px;
- position: relative;
- right: 0;
- overflow-y: hidden;
-}
-
-.removeButton {
- position: relative;
- right: 0;
- bottom: 0;
- height: 30px;
- width: 50px;
- border: none;
- background-color: white;
-}
-
-.urlDiv {
- position: relative;
- right: 0;
- top: -10;
- height: 90px;
- width: 300px;
- overflow-y: hidden;
-}
-
-.removeCheck {
- position: relative;
- left: 230;
- bottom: -15;
- height: 30px;
-}
-
-#searchSubmit {
- height: 30px;
- width: 50px;
- border: none;
- background-color: #3AA757;
-}
-
-#deleteSelected {
- height: 30px;
- width: 185px;
- border: none;
- background-color: #F9BB2D;
-}
-
-#removeAll {
- height: 30px;
- width: 185px;
- border: none;
- background-color: #E8453C;
-}
-
-#seeAll {
- height: 30px;
- width: 185px;
- border: none;
- background-color: #4688F1;
-}
-
-#searchInput {
- height: 30px;
-}
-
-h1 {
- font-size: 50px;
- font-family: Impact, Charcoal, sans-serif;
-}
diff --git a/chrome/common/extensions/docs/examples/api/history/showHistory/clock.png b/chrome/common/extensions/docs/examples/api/history/showHistory/clock.png
deleted file mode 100644
index 8fd573f5..0000000
--- a/chrome/common/extensions/docs/examples/api/history/showHistory/clock.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/history/showHistory/manifest.json b/chrome/common/extensions/docs/examples/api/history/showHistory/manifest.json
deleted file mode 100644
index b4aa6ffe..0000000
--- a/chrome/common/extensions/docs/examples/api/history/showHistory/manifest.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "name": "Typed URL History",
- "version": "1.2",
- "description": "Reads your history, and shows the top ten pages you go to by typing the URL.",
- "permissions": [
- "history"
- ],
- "browser_action": {
- "default_popup": "typedUrls.html",
- "default_icon": "clock.png"
- },
- "manifest_version": 2
-}
diff --git a/chrome/common/extensions/docs/examples/api/history/showHistory/typedUrls.html b/chrome/common/extensions/docs/examples/api/history/showHistory/typedUrls.html
deleted file mode 100644
index 9b8bc71..0000000
--- a/chrome/common/extensions/docs/examples/api/history/showHistory/typedUrls.html
+++ /dev/null
@@ -1,15 +0,0 @@
-<!DOCTYPE HTML>
-<html>
- <head>
- <title>Recently Typed URLs</title>
- <style>
- body {min-width: 250px;}
- </style>
- <script src='typedUrls.js'></script>
- </head>
-
- <body>
- <h2>Recently Typed URLs:</h2>
- <div id="typedUrl_div"></div>
- </body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/api/history/showHistory/typedUrls.js b/chrome/common/extensions/docs/examples/api/history/showHistory/typedUrls.js
deleted file mode 100644
index 204d1ac..0000000
--- a/chrome/common/extensions/docs/examples/api/history/showHistory/typedUrls.js
+++ /dev/null
@@ -1,119 +0,0 @@
-// Copyright (c) 2012 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.
-
-// Event listner for clicks on links in a browser action popup.
-// Open the link in a new tab of the current window.
-function onAnchorClick(event) {
- chrome.tabs.create({
- selected: true,
- url: event.srcElement.href
- });
- return false;
-}
-
-// Given an array of URLs, build a DOM list of those URLs in the
-// browser action popup.
-function buildPopupDom(divName, data) {
- var popupDiv = document.getElementById(divName);
-
- var ul = document.createElement('ul');
- popupDiv.appendChild(ul);
-
- for (var i = 0, ie = data.length; i < ie; ++i) {
- var a = document.createElement('a');
- a.href = data[i];
- a.appendChild(document.createTextNode(data[i]));
- a.addEventListener('click', onAnchorClick);
-
- var li = document.createElement('li');
- li.appendChild(a);
-
- ul.appendChild(li);
- }
-}
-
-// Search history to find up to ten links that a user has typed in,
-// and show those links in a popup.
-function buildTypedUrlList(divName) {
- // To look for history items visited in the last week,
- // subtract a week of microseconds from the current time.
- var microsecondsPerWeek = 1000 * 60 * 60 * 24 * 7;
- var oneWeekAgo = (new Date).getTime() - microsecondsPerWeek;
-
- // Track the number of callbacks from chrome.history.getVisits()
- // that we expect to get. When it reaches zero, we have all results.
- var numRequestsOutstanding = 0;
-
- chrome.history.search({
- 'text': '', // Return every history item....
- 'startTime': oneWeekAgo // that was accessed less than one week ago.
- },
- function(historyItems) {
- // For each history item, get details on all visits.
- for (var i = 0; i < historyItems.length; ++i) {
- var url = historyItems[i].url;
- var processVisitsWithUrl = function(url) {
- // We need the url of the visited item to process the visit.
- // Use a closure to bind the url into the callback's args.
- return function(visitItems) {
- processVisits(url, visitItems);
- };
- };
- chrome.history.getVisits({url: url}, processVisitsWithUrl(url));
- numRequestsOutstanding++;
- }
- if (!numRequestsOutstanding) {
- onAllVisitsProcessed();
- }
- });
-
-
- // Maps URLs to a count of the number of times the user typed that URL into
- // the omnibox.
- var urlToCount = {};
-
- // Callback for chrome.history.getVisits(). Counts the number of
- // times a user visited a URL by typing the address.
- var processVisits = function(url, visitItems) {
- for (var i = 0, ie = visitItems.length; i < ie; ++i) {
- // Ignore items unless the user typed the URL.
- if (visitItems[i].transition != 'typed') {
- continue;
- }
-
- if (!urlToCount[url]) {
- urlToCount[url] = 0;
- }
-
- urlToCount[url]++;
- }
-
- // If this is the final outstanding call to processVisits(),
- // then we have the final results. Use them to build the list
- // of URLs to show in the popup.
- if (!--numRequestsOutstanding) {
- onAllVisitsProcessed();
- }
- };
-
- // This function is called when we have the final list of URls to display.
- var onAllVisitsProcessed = function() {
- // Get the top scorring urls.
- urlArray = [];
- for (var url in urlToCount) {
- urlArray.push(url);
- }
-
- // Sort the URLs by the number of times the user typed them.
- urlArray.sort(function(a, b) {
- return urlToCount[b] - urlToCount[a];
- });
-
- buildPopupDom(divName, urlArray.slice(0, 10));
- };
-}
-
-document.addEventListener('DOMContentLoaded', function () {
- buildTypedUrlList("typedUrl_div");
-});
\ No newline at end of file
diff --git a/chrome/common/extensions/docs/examples/api/i18n/cld/background.js b/chrome/common/extensions/docs/examples/api/i18n/cld/background.js
deleted file mode 100644
index 0c948493..0000000
--- a/chrome/common/extensions/docs/examples/api/i18n/cld/background.js
+++ /dev/null
@@ -1,28 +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.
-
-var selectedId = -1;
-function refreshLanguage() {
- chrome.tabs.detectLanguage(null, function(language) {
- console.log(language);
- if (language == " invalid_language_code")
- language = "???";
- chrome.browserAction.setBadgeText({"text": language, tabId: selectedId});
- });
-}
-
-chrome.tabs.onUpdated.addListener(function(tabId, props) {
- if (props.status == "complete" && tabId == selectedId)
- refreshLanguage();
-});
-
-chrome.tabs.onSelectionChanged.addListener(function(tabId, props) {
- selectedId = tabId;
- refreshLanguage();
-});
-
-chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
- selectedId = tabs[0].id;
- refreshLanguage();
-});
diff --git a/chrome/common/extensions/docs/examples/api/i18n/cld/manifest.json b/chrome/common/extensions/docs/examples/api/i18n/cld/manifest.json
deleted file mode 100644
index 4b242cf..0000000
--- a/chrome/common/extensions/docs/examples/api/i18n/cld/manifest.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- "name": "CLD",
- "description": "Displays the language of a tab",
- "version": "0.3",
- "background": {
- "scripts": ["background.js"]
- },
- "browser_action": {
- "default_name": "Page Language"
- },
- "manifest_version": 2
-}
diff --git a/chrome/common/extensions/docs/examples/api/i18n/detectLanguage/icon.png b/chrome/common/extensions/docs/examples/api/i18n/detectLanguage/icon.png
deleted file mode 100644
index d86677db..0000000
--- a/chrome/common/extensions/docs/examples/api/i18n/detectLanguage/icon.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/i18n/detectLanguage/manifest.json b/chrome/common/extensions/docs/examples/api/i18n/detectLanguage/manifest.json
deleted file mode 100644
index beceb33..0000000
--- a/chrome/common/extensions/docs/examples/api/i18n/detectLanguage/manifest.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- "name": "Detect Language",
- "description": "Detects up to 3 languages and their percentages of the provided string",
- "version": "1.0",
-
- "browser_action": {
- "default_icon": "icon.png",
- "default_popup": "popup.html"
- },
-
- "manifest_version": 2
-}
\ No newline at end of file
diff --git a/chrome/common/extensions/docs/examples/api/i18n/detectLanguage/popup.html b/chrome/common/extensions/docs/examples/api/i18n/detectLanguage/popup.html
deleted file mode 100644
index f017bae..0000000
--- a/chrome/common/extensions/docs/examples/api/i18n/detectLanguage/popup.html
+++ /dev/null
@@ -1,17 +0,0 @@
-<html>
- <head>
- <style>
- body {
- font-family: "Segoe UI", "Lucida Grande", Tahoma, sans-serif;
- font-size: 100%;
- }
- </style>
- <script src="popup.js"></script>
- </head>
- <body>
- <div id="detect_lang">
- <textarea id="text" placeholder="Text to translate" style="padding: 10px; width: 300px;"></textarea>
- <button id="btn-detect">Translate</button>
- </div>
- </body>
-</html>
\ No newline at end of file
diff --git a/chrome/common/extensions/docs/examples/api/i18n/detectLanguage/popup.js b/chrome/common/extensions/docs/examples/api/i18n/detectLanguage/popup.js
deleted file mode 100644
index 1ce8544..0000000
--- a/chrome/common/extensions/docs/examples/api/i18n/detectLanguage/popup.js
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright (c) 2015 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.
-
-document.addEventListener('DOMContentLoaded', function() {
- document.getElementById("btn-detect").addEventListener("click", function() {
- var inputText = document.getElementById("text").value;
- chrome.i18n.detectLanguage(inputText, function(result) {
- var languages = "Languages: \n";
- for (var i = 0; i < result.languages.length; i++) {
- languages += result.languages[i].language + " ";
- languages += result.languages[i].percentage + "\n";
- }
-
- var is_reliable = "\nReliable? \n" + result.isReliable + "\n";
- alert(languages + is_reliable);
- });
- });
-});
diff --git a/chrome/common/extensions/docs/examples/api/i18n/getMessage/_locales/en_US/messages.json b/chrome/common/extensions/docs/examples/api/i18n/getMessage/_locales/en_US/messages.json
deleted file mode 100644
index b33d2f0..0000000
--- a/chrome/common/extensions/docs/examples/api/i18n/getMessage/_locales/en_US/messages.json
+++ /dev/null
@@ -1,27 +0,0 @@
-{
- "chrome_extension_name": {
- "message": "AcceptLanguage"
- },
- "chrome_extension_description": {
- "message": "Returns accept languages of the browser"
- },
- "click_here": {
- "message": "Left click to list acceptLanguages."
- },
- "browser_action_title": {
- "message": "Click Me"
- },
- "chrome_accept_languages": {
- "message": "$CHROME$ accepts $languages$ languages",
- "placeholders": {
- "chrome": {
- "content": "Chrome",
- "example": "Chrome"
- },
- "languages": {
- "content": "$1",
- "example": "en-US,sr,de"
- }
- }
- }
-}
diff --git a/chrome/common/extensions/docs/examples/api/i18n/getMessage/_locales/es/messages.json b/chrome/common/extensions/docs/examples/api/i18n/getMessage/_locales/es/messages.json
deleted file mode 100644
index 0e1a7ef..0000000
--- a/chrome/common/extensions/docs/examples/api/i18n/getMessage/_locales/es/messages.json
+++ /dev/null
@@ -1,27 +0,0 @@
-{
- "chrome_extension_name": {
- "message": "AcceptLanguage"
- },
- "chrome_extension_description": {
- "message": "Devuelve los idiomas aceptados por el navegador"
- },
- "click_here": {
- "message": "Click con botón izquierdo para mostrar la lista de acceptLanguages."
- },
- "browser_action_title": {
- "message": "Haz click aquí"
- },
- "chrome_accept_languages": {
- "message": "$CHROME$ acepta los idiomas $languages$",
- "placeholders": {
- "chrome": {
- "content": "Chrome",
- "example": "Chrome"
- },
- "languages": {
- "content": "$1",
- "example": "en-US,sr,de"
- }
- }
- }
-}
diff --git a/chrome/common/extensions/docs/examples/api/i18n/getMessage/_locales/sr/messages.json b/chrome/common/extensions/docs/examples/api/i18n/getMessage/_locales/sr/messages.json
deleted file mode 100644
index 30bd958..0000000
--- a/chrome/common/extensions/docs/examples/api/i18n/getMessage/_locales/sr/messages.json
+++ /dev/null
@@ -1,24 +0,0 @@
-{
- "chrome_extension_name": {
- "message": "Прихватљиви језици"
- },
- "chrome_extension_description": {
- "message": "Језици које прегледач прихвата"
- },
- "click_here": {
- "message": "Кликните да излистате дозвољене језике."
- },
- "chrome_accept_languages": {
- "message": "$CHROME$ прихвата $languages$ језике.",
- "placeholders": {
- "chrome": {
- "content": "Chrome",
- "example": "Chrome"
- },
- "languages": {
- "content": "$1",
- "example": "en-US,sr,de"
- }
- }
- }
-}
diff --git a/chrome/common/extensions/docs/examples/api/i18n/getMessage/icon.png b/chrome/common/extensions/docs/examples/api/i18n/getMessage/icon.png
deleted file mode 100644
index ea42f3f..0000000
--- a/chrome/common/extensions/docs/examples/api/i18n/getMessage/icon.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/i18n/getMessage/manifest.json b/chrome/common/extensions/docs/examples/api/i18n/getMessage/manifest.json
deleted file mode 100644
index 52997f2..0000000
--- a/chrome/common/extensions/docs/examples/api/i18n/getMessage/manifest.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- "name": "__MSG_chrome_extension_name__",
- "description": "__MSG_chrome_extension_description__",
- "version": "0.2",
- "default_locale": "en_US",
- "browser_action": {
- "default_title": "__MSG_browser_action_title__",
- "default_icon": "icon.png",
- "default_popup": "popup.html"
- },
- "manifest_version": 2
-}
diff --git a/chrome/common/extensions/docs/examples/api/i18n/getMessage/popup.html b/chrome/common/extensions/docs/examples/api/i18n/getMessage/popup.html
deleted file mode 100644
index d765b9d..0000000
--- a/chrome/common/extensions/docs/examples/api/i18n/getMessage/popup.html
+++ /dev/null
@@ -1,22 +0,0 @@
-<!--
-Copyright (c) 2012 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>
- <style>
- body {
- color: black;
- width: 300px;
- }
- </style>
- <script src="popup.js"></script>
- </head>
- <body>
- <div id="accept_lang">
- <span id="languageSpan"></span>
- </div>
- </body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/api/i18n/getMessage/popup.js b/chrome/common/extensions/docs/examples/api/i18n/getMessage/popup.js
deleted file mode 100644
index fd70b6164..0000000
--- a/chrome/common/extensions/docs/examples/api/i18n/getMessage/popup.js
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright (c) 2012 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.
-
-function setChildTextNode(elementId, text) {
- document.getElementById(elementId).innerText = text;
-}
-
-function init() {
- setChildTextNode('languageSpan', chrome.i18n.getMessage("click_here"));
-}
-
-function getAcceptLanguages() {
- chrome.i18n.getAcceptLanguages(function(languageList) {
- var languages = languageList.join(",");
- setChildTextNode('languageSpan',
- chrome.i18n.getMessage("chrome_accept_languages", languages));
- })
-}
-
-document.addEventListener('DOMContentLoaded', function() {
- document.querySelector('#accept_lang').addEventListener(
- 'click', getAcceptLanguages);
- init();
-});
diff --git a/chrome/common/extensions/docs/examples/api/i18n/localizedHostedApp/_locales/de/messages.json b/chrome/common/extensions/docs/examples/api/i18n/localizedHostedApp/_locales/de/messages.json
deleted file mode 100644
index 0d8e2f7..0000000
--- a/chrome/common/extensions/docs/examples/api/i18n/localizedHostedApp/_locales/de/messages.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "application_title": {
- "message": "Eine lokalisierte gehostete Beispielanwendung"
- },
- "application_description": {
- "message": "Hier steht eine Beschreibung der Applikation, die im Web Store auftauchen wird."
- }
-}
diff --git a/chrome/common/extensions/docs/examples/api/i18n/localizedHostedApp/_locales/en/messages.json b/chrome/common/extensions/docs/examples/api/i18n/localizedHostedApp/_locales/en/messages.json
deleted file mode 100644
index ed87abf..0000000
--- a/chrome/common/extensions/docs/examples/api/i18n/localizedHostedApp/_locales/en/messages.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "application_title": {
- "message": "Minimal Localized Hosted App",
- "description": "The title of the application, displayed in the web store."
- },
- "application_description": {
- "message": "This is the minimal set of data required to upload a localized hosted application to the web store.",
- "description": "The description of the application, displayed in the web store."
- }
-}
diff --git a/chrome/common/extensions/docs/examples/api/i18n/localizedHostedApp/icon128.png b/chrome/common/extensions/docs/examples/api/i18n/localizedHostedApp/icon128.png
deleted file mode 100644
index 0b36c4c..0000000
--- a/chrome/common/extensions/docs/examples/api/i18n/localizedHostedApp/icon128.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/i18n/localizedHostedApp/manifest.json b/chrome/common/extensions/docs/examples/api/i18n/localizedHostedApp/manifest.json
deleted file mode 100644
index 9cb94fd..0000000
--- a/chrome/common/extensions/docs/examples/api/i18n/localizedHostedApp/manifest.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "name": "__MSG_application_title__",
- "description": "__MSG_application_description__",
- "version": "0.2",
- "default_locale": "en",
- "app": {
- "launch": {
- "web_url": "http://example.com/"
- }
- },
- "icons": {
- "128": "icon128.png"
- },
- "manifest_version": 2
-}
diff --git a/chrome/common/extensions/docs/examples/api/idle/idle_simple/background.js b/chrome/common/extensions/docs/examples/api/idle/idle_simple/background.js
deleted file mode 100644
index c25e0ab3..0000000
--- a/chrome/common/extensions/docs/examples/api/idle/idle_simple/background.js
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright (c) 2010 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.
-
-var history_log = [];
-
-/**
-* Stores a state every time an "active" event is sent, up to 20 items.
-*/
-chrome.idle.onStateChanged.addListener(function(newstate) {
- var time = new Date();
- if (history_log.length >= 20) {
- history_log.pop();
- }
- history_log.unshift({'state':newstate, 'time':time});
-});
-
-/**
-* Opens history.html when the browser action is clicked.
-* Used window.open because I didn't want the tabs permission.
-*/
-chrome.browserAction.onClicked.addListener(function() {
- window.open('history.html', 'testwindow', 'width=700,height=600');
-});
diff --git a/chrome/common/extensions/docs/examples/api/idle/idle_simple/history.html b/chrome/common/extensions/docs/examples/api/idle/idle_simple/history.html
deleted file mode 100644
index c8061c560..0000000
--- a/chrome/common/extensions/docs/examples/api/idle/idle_simple/history.html
+++ /dev/null
@@ -1,38 +0,0 @@
-<!DOCTYPE html>
-<!--
- * Copyright (c) 2010 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>
- <style>
- body {
- width: 100%;
- font: 13px Arial;
- }
- </style>
- <script src="history.js"></script>
- </head>
- <body>
- <h1>Idle API Demonstration</h1>
- <h2>Current state</h2>
- <p>
- Idle threshold:
- <select id="idle-threshold">
- <option selected value="15">15</option>
- <option value="30">30</option>
- <option value="60">60</option>
- </select>
- <p>
- <code>chrome.idle.queryState(<strong id="idle-set-threshold"></strong>, ...);</code> -
- <span id="idle-state"></span>
- </p>
- <p>
- Last state change: <span id="idle-laststate"></span>
- </p>
-
- <h2>Idle changes:</h2>
- <ul id='idle-history'></ul>
- </body>
-</html>
\ No newline at end of file
diff --git a/chrome/common/extensions/docs/examples/api/idle/idle_simple/history.js b/chrome/common/extensions/docs/examples/api/idle/idle_simple/history.js
deleted file mode 100644
index 814c7cb..0000000
--- a/chrome/common/extensions/docs/examples/api/idle/idle_simple/history.js
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright (c) 2012 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.
-
-/**
- * Convert a state and time into a nice styled chunk of HTML.
- */
-function renderState(state, time) {
- var now = new Date().getTime();
- var diff = Math.round((time.getTime() - now) / 1000);
- var str = (diff == 0) ?
- "now" :
- Math.abs(diff) + " seconds " + (diff > 0 ? "from now" : "ago");
- var col = (state == "active") ?
- "#009900" :
- "#990000";
- return "<b style='color: " + col + "'>" + state + "</b> " + str;
-};
-
-/**
- * Creates DOM and injects a rendered state into the page.
- */
-function renderItem(state, time, parent) {
- var dom_item = document.createElement('li');
- dom_item.innerHTML = renderState(state, time);
- parent.appendChild(dom_item);
-};
-
-// Store previous state so we can show deltas. This is important
-// because the API currently doesn't fire idle messages, and we'd
-// like to keep track of last time we went idle.
-var laststate = null;
-var laststatetime = null;
-
-/**
- * Checks the current state of the browser.
- */
-function checkState() {
- threshold = parseInt(document.querySelector('#idle-threshold').value);
- var dom_threshold = document.querySelector('#idle-set-threshold');
- dom_threshold.innerText = threshold;
-
- // Request the state based off of the user-supplied threshold.
- chrome.idle.queryState(threshold, function(state) {
- var time = new Date();
- if (laststate != state) {
- laststate = state;
- laststatetime = time;
- }
-
- // Keep rendering results so we get a nice "seconds elapsed" view.
- var dom_result = document.querySelector('#idle-state');
- dom_result.innerHTML = renderState(state, time);
- var dom_laststate = document.querySelector('#idle-laststate');
- dom_laststate.innerHTML = renderState(laststate, laststatetime);
- });
-};
-
-var dom_history = document.querySelector('#idle-history');
-
-/**
- * Render the data gathered by the background page - should show a log
- * of "active" states. No events are fired upon idle.
- */
-function renderHistory() {
- dom_history.innerHTML = "";
- var history_log = chrome.extension.getBackgroundPage().history_log;
- for (var i = 0; i < history_log.length; i++) {
- var data = history_log[i];
- renderItem(data['state'], data['time'], dom_history);
- }
-};
-
-
-document.addEventListener('DOMContentLoaded', function() {
- // Check every second (even though this is overkill - minimum idle
- // threshold is 15 seconds) so that the numbers appear to be counting up.
- checkState();
- window.setInterval(checkState, 1000);
-
- // Check every second (see above).
- renderHistory();
- window.setInterval(renderHistory, 1000);
-});
diff --git a/chrome/common/extensions/docs/examples/api/idle/idle_simple/manifest.json b/chrome/common/extensions/docs/examples/api/idle/idle_simple/manifest.json
deleted file mode 100644
index b6fba2a..0000000
--- a/chrome/common/extensions/docs/examples/api/idle/idle_simple/manifest.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
- "name" : "Idle - Simple Example",
- "version" : "1.0.1",
- "description" : "Demonstrates the Idle API",
- "background" : {
- "scripts": ["background.js"]
- },
- "permissions" : [ "idle" ],
- "browser_action" : {
- "default_icon" : "sample-19.png"
- },
- "icons" : {
- "16" : "sample-16.png",
- "48" : "sample-48.png",
- "128" : "sample-128.png"
- },
- "manifest_version": 2
-}
diff --git a/chrome/common/extensions/docs/examples/api/idle/idle_simple/sample-128.png b/chrome/common/extensions/docs/examples/api/idle/idle_simple/sample-128.png
deleted file mode 100644
index 96be429..0000000
--- a/chrome/common/extensions/docs/examples/api/idle/idle_simple/sample-128.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/idle/idle_simple/sample-16.png b/chrome/common/extensions/docs/examples/api/idle/idle_simple/sample-16.png
deleted file mode 100644
index 5308fc9..0000000
--- a/chrome/common/extensions/docs/examples/api/idle/idle_simple/sample-16.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/idle/idle_simple/sample-19.png b/chrome/common/extensions/docs/examples/api/idle/idle_simple/sample-19.png
deleted file mode 100644
index 108b2a7..0000000
--- a/chrome/common/extensions/docs/examples/api/idle/idle_simple/sample-19.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/idle/idle_simple/sample-48.png b/chrome/common/extensions/docs/examples/api/idle/idle_simple/sample-48.png
deleted file mode 100644
index a732e383..0000000
--- a/chrome/common/extensions/docs/examples/api/idle/idle_simple/sample-48.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/input.ime/basic/icon.png b/chrome/common/extensions/docs/examples/api/input.ime/basic/icon.png
deleted file mode 100644
index d86677db..0000000
--- a/chrome/common/extensions/docs/examples/api/input.ime/basic/icon.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/input.ime/basic/main.js b/chrome/common/extensions/docs/examples/api/input.ime/basic/main.js
deleted file mode 100644
index fdff7cef..0000000
--- a/chrome/common/extensions/docs/examples/api/input.ime/basic/main.js
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2013 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.
-
-var ime_api = chrome.input.ime;
-
-var context_id = -1;
-
-console.log("Initializing IME");
-
-ime_api.onFocus.addListener(function(context) {
- console.log('onFocus:' + context.contextID);
- context_id = context.contextID;
-});
-ime_api.onBlur.addListener(function(contextID) {
- console.log('onBlur:' + contextID);
- context_id = -1;
-});
-
-ime_api.onActivate.addListener(function(engineID) {
- console.log('onActivate:' + engineID);
-});
-ime_api.onDeactivated.addListener(function(engineID) {
- console.log('onDeactivated:' + engineID);
-});
-
-ime_api.onKeyEvent.addListener(
-function(engineID, keyData) {
- console.log('onKeyEvent:' + keyData.key + " context: " + context_id);
- if (keyData.type == "keydown" && keyData.key.match(/^[a-z]$/)) {
- chrome.input.ime.commitText({"contextID": context_id,
- "text": keyData.key.toUpperCase()});
- return true;
- }
-
- return false
-});
diff --git a/chrome/common/extensions/docs/examples/api/input.ime/basic/manifest.json b/chrome/common/extensions/docs/examples/api/input.ime/basic/manifest.json
deleted file mode 100644
index b0a06d7e..0000000
--- a/chrome/common/extensions/docs/examples/api/input.ime/basic/manifest.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
- "name": "Test IME",
- "version": "1.0",
- "manifest_version": 2,
- "description": "A simple IME that converts all keystrokes to upper case.",
- "background": {
- "scripts": ["main.js"]
- },
- "permissions": [
- "input"
- ],
- "input_components": [
- {
- "name": "Test IME",
- "id": "test",
- "language": "en-US", // The primary language this IME is used for
- "layouts": ["us::eng"] // The supported keyboard layouts for this IME
- }
- ]
-}
diff --git a/chrome/common/extensions/docs/examples/api/messaging/timer/clock.png b/chrome/common/extensions/docs/examples/api/messaging/timer/clock.png
deleted file mode 100644
index 35324c5..0000000
--- a/chrome/common/extensions/docs/examples/api/messaging/timer/clock.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/messaging/timer/manifest.json b/chrome/common/extensions/docs/examples/api/messaging/timer/manifest.json
deleted file mode 100644
index 76d6907..0000000
--- a/chrome/common/extensions/docs/examples/api/messaging/timer/manifest.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- "name": "Message Timer",
- "version": "1.3",
- "description": "Times how long it takes to send a message to a content script and back.",
- "content_scripts": [
- {
- "matches": ["http://*/*", "https://*/*"],
- "js": ["page.js"]
- }
- ],
- "browser_action": {
- "default_title": "Time to current page",
- "default_icon": "clock.png",
- "default_popup": "popup.html"
- },
- "manifest_version": 2
-}
diff --git a/chrome/common/extensions/docs/examples/api/messaging/timer/page.js b/chrome/common/extensions/docs/examples/api/messaging/timer/page.js
deleted file mode 100644
index 29f518e1..0000000
--- a/chrome/common/extensions/docs/examples/api/messaging/timer/page.js
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright (c) 2013 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.
-
-chrome.runtime.onConnect.addListener(function(port) {
- port.onMessage.addListener(function(msg) {
- port.postMessage({counter: msg.counter+1});
- });
-});
-
-chrome.runtime.onMessage.addListener(
- function(request, sender, sendResponse) {
- sendResponse({counter: request.counter+1});
- });
diff --git a/chrome/common/extensions/docs/examples/api/messaging/timer/popup.html b/chrome/common/extensions/docs/examples/api/messaging/timer/popup.html
deleted file mode 100644
index 2931321..0000000
--- a/chrome/common/extensions/docs/examples/api/messaging/timer/popup.html
+++ /dev/null
@@ -1,25 +0,0 @@
-<head>
-<style>
-tr {
- white-space: nowrap;
-}
-.results {
- text-align: right;
- min-width: 6em;
- color: black;
-}
-</style>
-<script src="popup.js"></script>
-</head>
-<body>
-<table>
- <tr>
- <td><button id="testMessage">Measure sendMessage</button></td>
- <td id="resultsRequest" class="results">(results)</td>
- </tr>
- <tr>
- <td><button id="testConnect">Measure postMessage</button></td>
- <td id="resultsConnect" class="results">(results)</td>
- </tr>
-</table>
-</body>
diff --git a/chrome/common/extensions/docs/examples/api/messaging/timer/popup.js b/chrome/common/extensions/docs/examples/api/messaging/timer/popup.js
deleted file mode 100644
index 8f50354..0000000
--- a/chrome/common/extensions/docs/examples/api/messaging/timer/popup.js
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright (c) 2012 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.
-
-function setChildTextNode(elementId, text) {
- document.getElementById(elementId).innerText = text;
-}
-
-// Tests the roundtrip time of sendMessage().
-function testMessage() {
- setChildTextNode("resultsRequest", "running...");
-
- chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
- var timer = new chrome.Interval();
- timer.start();
- var tab = tabs[0];
- chrome.tabs.sendMessage(tab.id, {counter: 1}, function handler(response) {
- if (response.counter < 1000) {
- chrome.tabs.sendMessage(tab.id, {counter: response.counter}, handler);
- } else {
- timer.stop();
- var usec = Math.round(timer.microseconds() / response.counter);
- setChildTextNode("resultsRequest", usec + "usec");
- }
- });
- });
-}
-
-// Tests the roundtrip time of Port.postMessage() after opening a channel.
-function testConnect() {
- setChildTextNode("resultsConnect", "running...");
-
- chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
- var timer = new chrome.Interval();
- timer.start();
-
- var port = chrome.tabs.connect(tabs[0].id);
- port.postMessage({counter: 1});
- port.onMessage.addListener(function getResp(response) {
- if (response.counter < 1000) {
- port.postMessage({counter: response.counter});
- } else {
- timer.stop();
- var usec = Math.round(timer.microseconds() / response.counter);
- setChildTextNode("resultsConnect", usec + "usec");
- }
- });
- });
-}
-
-(function(){
- if (!chrome.benchmarking) {
- alert("Warning: Looks like you forgot to run chrome with " +
- " --enable-benchmarking set.");
- return;
- }
- document.addEventListener('DOMContentLoaded', function() {
- document.querySelector('#testMessage').addEventListener(
- 'click', testMessage);
- document.querySelector('#testConnect').addEventListener(
- 'click', testConnect);
- });
-})();
diff --git a/chrome/common/extensions/docs/examples/api/nativeMessaging/README.txt b/chrome/common/extensions/docs/examples/api/nativeMessaging/README.txt
deleted file mode 100644
index c0269460..0000000
--- a/chrome/common/extensions/docs/examples/api/nativeMessaging/README.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-This directory contains an example of chrome application that uses native
-messaging API that allows to communicate with a native application.
-
-In order for this example to work you must first install the native messaging
-host from the host directory.
-
-To install the host:
-
-On Windows:
- Run install_host.bat script in the host directory.
- This script installs the native messaging host for the current user, by
- creating a registry key
- HKEY_CURRENT_USER\SOFTWARE\Google\Chrome\NativeMessagingHosts\com.google.chrome.example.echo
- and setting its default value to the full path to
- host\com.google.chrome.example.echo-win.json .
- If you want to install the native messaging host for all users, change HKCU to
- HKLM.
- Note that you need to have python installed.
-
-On Mac and Linux:
- Run install_host.sh script in the host directory:
- host/install_host.sh
- By default the host is installed only for the user who runs the script, but if
- you run it with admin privileges (i.e. 'sudo host/install_host.sh'), then the
- host will be installed for all users. You can later use host/uninstall_host.sh
- to uninstall the host.
diff --git a/chrome/common/extensions/docs/examples/api/nativeMessaging/app/icon-128.png b/chrome/common/extensions/docs/examples/api/nativeMessaging/app/icon-128.png
deleted file mode 100644
index c3bd2fd48..0000000
--- a/chrome/common/extensions/docs/examples/api/nativeMessaging/app/icon-128.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/nativeMessaging/app/main.html b/chrome/common/extensions/docs/examples/api/nativeMessaging/app/main.html
deleted file mode 100644
index 445b876..0000000
--- a/chrome/common/extensions/docs/examples/api/nativeMessaging/app/main.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE html>
-<!--
- * Copyright 2013 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 src='./main.js'></script>
- </head>
- <body>
- <button id='connect-button'>Connect</button>
- <input id='input-text' type='text' />
- <button id='send-message-button'>Send</button>
- <div id='response'></div>
- </body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/api/nativeMessaging/app/main.js b/chrome/common/extensions/docs/examples/api/nativeMessaging/app/main.js
deleted file mode 100644
index 618268a..0000000
--- a/chrome/common/extensions/docs/examples/api/nativeMessaging/app/main.js
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 2013 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.
-
-var port = null;
-
-var getKeys = function(obj){
- var keys = [];
- for(var key in obj){
- keys.push(key);
- }
- return keys;
-}
-
-
-function appendMessage(text) {
- document.getElementById('response').innerHTML += "<p>" + text + "</p>";
-}
-
-function updateUiState() {
- if (port) {
- document.getElementById('connect-button').style.display = 'none';
- document.getElementById('input-text').style.display = 'block';
- document.getElementById('send-message-button').style.display = 'block';
- } else {
- document.getElementById('connect-button').style.display = 'block';
- document.getElementById('input-text').style.display = 'none';
- document.getElementById('send-message-button').style.display = 'none';
- }
-}
-
-function sendNativeMessage() {
- message = {"text": document.getElementById('input-text').value};
- port.postMessage(message);
- appendMessage("Sent message: <b>" + JSON.stringify(message) + "</b>");
-}
-
-function onNativeMessage(message) {
- appendMessage("Received message: <b>" + JSON.stringify(message) + "</b>");
-}
-
-function onDisconnected() {
- appendMessage("Failed to connect: " + chrome.runtime.lastError.message);
- port = null;
- updateUiState();
-}
-
-function connect() {
- var hostName = "com.google.chrome.example.echo";
- appendMessage("Connecting to native messaging host <b>" + hostName + "</b>")
- port = chrome.runtime.connectNative(hostName);
- port.onMessage.addListener(onNativeMessage);
- port.onDisconnect.addListener(onDisconnected);
- updateUiState();
-}
-
-document.addEventListener('DOMContentLoaded', function () {
- document.getElementById('connect-button').addEventListener(
- 'click', connect);
- document.getElementById('send-message-button').addEventListener(
- 'click', sendNativeMessage);
- updateUiState();
-});
diff --git a/chrome/common/extensions/docs/examples/api/nativeMessaging/app/manifest.json b/chrome/common/extensions/docs/examples/api/nativeMessaging/app/manifest.json
deleted file mode 100644
index a339e11..0000000
--- a/chrome/common/extensions/docs/examples/api/nativeMessaging/app/manifest.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- // Extension ID: knldjmfmopnpolahpmmgbagdohdnhkik
- "key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDcBHwzDvyBQ6bDppkIs9MP4ksKqCMyXQ/A52JivHZKh4YO/9vJsT3oaYhSpDCE9RPocOEQvwsHsFReW2nUEc6OLLyoCFFxIb7KkLGsmfakkut/fFdNJYh0xOTbSN8YvLWcqph09XAY2Y/f0AL7vfO1cuCqtkMt8hFrBGWxDdf9CQIDAQAB",
- "name": "Native Messaging Example",
- "version": "1.0",
- "manifest_version": 2,
- "description": "Send a message to a native application.",
- "app": {
- "launch": {
- "local_path": "main.html"
- }
- },
- "icons": {
- "128": "icon-128.png"
- },
- "permissions": [
- "nativeMessaging"
- ]
-}
diff --git a/chrome/common/extensions/docs/examples/api/nativeMessaging/host/com.google.chrome.example.echo-win.json b/chrome/common/extensions/docs/examples/api/nativeMessaging/host/com.google.chrome.example.echo-win.json
deleted file mode 100644
index 84e5448..0000000
--- a/chrome/common/extensions/docs/examples/api/nativeMessaging/host/com.google.chrome.example.echo-win.json
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2013 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.
-
-{
- "name": "com.google.chrome.example.echo",
- "description": "Chrome Native Messaging API Example Host",
- "path": "native-messaging-example-host.bat",
- "type": "stdio",
- "allowed_origins": [
- "chrome-extension://knldjmfmopnpolahpmmgbagdohdnhkik/"
- ]
-}
diff --git a/chrome/common/extensions/docs/examples/api/nativeMessaging/host/com.google.chrome.example.echo.json b/chrome/common/extensions/docs/examples/api/nativeMessaging/host/com.google.chrome.example.echo.json
deleted file mode 100644
index dfeae04..0000000
--- a/chrome/common/extensions/docs/examples/api/nativeMessaging/host/com.google.chrome.example.echo.json
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2013 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.
-
-{
- "name": "com.google.chrome.example.echo",
- "description": "Chrome Native Messaging API Example Host",
- "path": "HOST_PATH",
- "type": "stdio",
- "allowed_origins": [
- "chrome-extension://knldjmfmopnpolahpmmgbagdohdnhkik/"
- ]
-}
diff --git a/chrome/common/extensions/docs/examples/api/nativeMessaging/host/install_host.bat b/chrome/common/extensions/docs/examples/api/nativeMessaging/host/install_host.bat
deleted file mode 100755
index 8b88ab8..0000000
--- a/chrome/common/extensions/docs/examples/api/nativeMessaging/host/install_host.bat
+++ /dev/null
@@ -1,7 +0,0 @@
-:: Copyright 2014 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.
-
-:: Change HKCU to HKLM if you want to install globally.
-:: %~dp0 is the directory containing this bat script and ends with a backslash.
-REG ADD "HKCU\Software\Google\Chrome\NativeMessagingHosts\com.google.chrome.example.echo" /ve /t REG_SZ /d "%~dp0com.google.chrome.example.echo-win.json" /f
diff --git a/chrome/common/extensions/docs/examples/api/nativeMessaging/host/install_host.sh b/chrome/common/extensions/docs/examples/api/nativeMessaging/host/install_host.sh
deleted file mode 100755
index f968c37..0000000
--- a/chrome/common/extensions/docs/examples/api/nativeMessaging/host/install_host.sh
+++ /dev/null
@@ -1,39 +0,0 @@
-#!/bin/sh
-# Copyright 2013 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.
-
-set -e
-
-DIR="$( cd "$( dirname "$0" )" && pwd )"
-if [ "$(uname -s)" = "Darwin" ]; then
- if [ "$(whoami)" = "root" ]; then
- TARGET_DIR="/Library/Google/Chrome/NativeMessagingHosts"
- else
- TARGET_DIR="$HOME/Library/Application Support/Google/Chrome/NativeMessagingHosts"
- fi
-else
- if [ "$(whoami)" = "root" ]; then
- TARGET_DIR="/etc/opt/chrome/native-messaging-hosts"
- else
- TARGET_DIR="$HOME/.config/google-chrome/NativeMessagingHosts"
- fi
-fi
-
-HOST_NAME=com.google.chrome.example.echo
-
-# Create directory to store native messaging host.
-mkdir -p "$TARGET_DIR"
-
-# Copy native messaging host manifest.
-cp "$DIR/$HOST_NAME.json" "$TARGET_DIR"
-
-# Update host path in the manifest.
-HOST_PATH=$DIR/native-messaging-example-host
-ESCAPED_HOST_PATH=${HOST_PATH////\\/}
-sed -i -e "s/HOST_PATH/$ESCAPED_HOST_PATH/" "$TARGET_DIR/$HOST_NAME.json"
-
-# Set permissions for the manifest so that all users can read it.
-chmod o+r "$TARGET_DIR/$HOST_NAME.json"
-
-echo "Native messaging host $HOST_NAME has been installed."
diff --git a/chrome/common/extensions/docs/examples/api/nativeMessaging/host/native-messaging-example-host b/chrome/common/extensions/docs/examples/api/nativeMessaging/host/native-messaging-example-host
deleted file mode 100755
index 8c94ed8..0000000
--- a/chrome/common/extensions/docs/examples/api/nativeMessaging/host/native-messaging-example-host
+++ /dev/null
@@ -1,128 +0,0 @@
-#!/usr/bin/env python
-# Copyright (c) 2012 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.
-
-# A simple native messaging host. Shows a Tkinter dialog with incoming messages
-# that also allows to send message back to the webapp.
-
-import struct
-import sys
-import threading
-import Queue
-
-try:
- import Tkinter
- import tkMessageBox
-except ImportError:
- Tkinter = None
-
-# On Windows, the default I/O mode is O_TEXT. Set this to O_BINARY
-# to avoid unwanted modifications of the input/output streams.
-if sys.platform == "win32":
- import os, msvcrt
- msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY)
- msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
-
-# Helper function that sends a message to the webapp.
-def send_message(message):
- # Write message size.
- sys.stdout.write(struct.pack('I', len(message)))
- # Write the message itself.
- sys.stdout.write(message)
- sys.stdout.flush()
-
-# Thread that reads messages from the webapp.
-def read_thread_func(queue):
- message_number = 0
- while 1:
- # Read the message length (first 4 bytes).
- text_length_bytes = sys.stdin.read(4)
-
- if len(text_length_bytes) == 0:
- if queue:
- queue.put(None)
- sys.exit(0)
-
- # Unpack message length as 4 byte integer.
- text_length = struct.unpack('i', text_length_bytes)[0]
-
- # Read the text (JSON object) of the message.
- text = sys.stdin.read(text_length).decode('utf-8')
-
- if queue:
- queue.put(text)
- else:
- # In headless mode just send an echo message back.
- send_message('{"echo": %s}' % text)
-
-if Tkinter:
- class NativeMessagingWindow(Tkinter.Frame):
- def __init__(self, queue):
- self.queue = queue
-
- Tkinter.Frame.__init__(self)
- self.pack()
-
- self.text = Tkinter.Text(self)
- self.text.grid(row=0, column=0, padx=10, pady=10, columnspan=2)
- self.text.config(state=Tkinter.DISABLED, height=10, width=40)
-
- self.messageContent = Tkinter.StringVar()
- self.sendEntry = Tkinter.Entry(self, textvariable=self.messageContent)
- self.sendEntry.grid(row=1, column=0, padx=10, pady=10)
-
- self.sendButton = Tkinter.Button(self, text="Send", command=self.onSend)
- self.sendButton.grid(row=1, column=1, padx=10, pady=10)
-
- self.after(100, self.processMessages)
-
- def processMessages(self):
- while not self.queue.empty():
- message = self.queue.get_nowait()
- if message == None:
- self.quit()
- return
- self.log("Received %s" % message)
-
- self.after(100, self.processMessages)
-
- def onSend(self):
- text = '{"text": "' + self.messageContent.get() + '"}'
- self.log('Sending %s' % text)
- try:
- send_message(text)
- except IOError:
- tkMessageBox.showinfo('Native Messaging Example',
- 'Failed to send message.')
- sys.exit(1)
-
- def log(self, message):
- self.text.config(state=Tkinter.NORMAL)
- self.text.insert(Tkinter.END, message + "\n")
- self.text.config(state=Tkinter.DISABLED)
-
-
-def Main():
- if not Tkinter:
- send_message('"Tkinter python module wasn\'t found. Running in headless ' +
- 'mode. Please consider installing Tkinter."')
- read_thread_func(None)
- sys.exit(0)
-
- queue = Queue.Queue()
-
- main_window = NativeMessagingWindow(queue)
- main_window.master.title('Native Messaging Example')
-
- thread = threading.Thread(target=read_thread_func, args=(queue,))
- thread.daemon = True
- thread.start()
-
- main_window.mainloop()
-
- sys.exit(0)
-
-
-if __name__ == '__main__':
- Main()
diff --git a/chrome/common/extensions/docs/examples/api/nativeMessaging/host/native-messaging-example-host.bat b/chrome/common/extensions/docs/examples/api/nativeMessaging/host/native-messaging-example-host.bat
deleted file mode 100755
index 430179e..0000000
--- a/chrome/common/extensions/docs/examples/api/nativeMessaging/host/native-messaging-example-host.bat
+++ /dev/null
@@ -1,6 +0,0 @@
-@echo off
-:: Copyright (c) 2013 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.
-
-python "%~dp0/native-messaging-example-host" %*
diff --git a/chrome/common/extensions/docs/examples/api/nativeMessaging/host/uninstall_host.bat b/chrome/common/extensions/docs/examples/api/nativeMessaging/host/uninstall_host.bat
deleted file mode 100755
index 5c2631f..0000000
--- a/chrome/common/extensions/docs/examples/api/nativeMessaging/host/uninstall_host.bat
+++ /dev/null
@@ -1,7 +0,0 @@
-:: Copyright 2014 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.
-
-:: Deletes the entry created by install_host.bat
-REG DELETE "HKCU\Software\Google\Chrome\NativeMessagingHosts\com.google.chrome.example.echo" /f
-REG DELETE "HKLM\Software\Google\Chrome\NativeMessagingHosts\com.google.chrome.example.echo" /f
diff --git a/chrome/common/extensions/docs/examples/api/nativeMessaging/host/uninstall_host.sh b/chrome/common/extensions/docs/examples/api/nativeMessaging/host/uninstall_host.sh
deleted file mode 100755
index bed4776..0000000
--- a/chrome/common/extensions/docs/examples/api/nativeMessaging/host/uninstall_host.sh
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/bin/sh
-# Copyright 2013 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.
-
-set -e
-
-if [ "$(uname -s)" = "Darwin" ]; then
- if [ "$(whoami)" = "root" ]; then
- TARGET_DIR="/Library/Google/Chrome/NativeMessagingHosts"
- else
- TARGET_DIR="$HOME/Library/Application Support/Google/Chrome/NativeMessagingHosts"
- fi
-else
- if [ "$(whoami)" = "root" ]; then
- TARGET_DIR="/etc/opt/chrome/native-messaging-hosts"
- else
- TARGET_DIR="$HOME/.config/google-chrome/NativeMessagingHosts"
- fi
-fi
-
-HOST_NAME=com.google.chrome.example.echo
-rm "$TARGET_DIR/com.google.chrome.example.echo.json"
-echo "Native messaging host $HOST_NAME has been uninstalled."
diff --git a/chrome/common/extensions/docs/examples/api/notifications/128.png b/chrome/common/extensions/docs/examples/api/notifications/128.png
deleted file mode 100644
index 181ee31..0000000
--- a/chrome/common/extensions/docs/examples/api/notifications/128.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/notifications/16.png b/chrome/common/extensions/docs/examples/api/notifications/16.png
deleted file mode 100644
index 4f24553..0000000
--- a/chrome/common/extensions/docs/examples/api/notifications/16.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/notifications/48.png b/chrome/common/extensions/docs/examples/api/notifications/48.png
deleted file mode 100644
index 2ad14f9..0000000
--- a/chrome/common/extensions/docs/examples/api/notifications/48.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/notifications/64.png b/chrome/common/extensions/docs/examples/api/notifications/64.png
deleted file mode 100644
index 61ec9592..0000000
--- a/chrome/common/extensions/docs/examples/api/notifications/64.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/notifications/background.js b/chrome/common/extensions/docs/examples/api/notifications/background.js
deleted file mode 100644
index cbe9d53..0000000
--- a/chrome/common/extensions/docs/examples/api/notifications/background.js
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright (c) 2011 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.
-
-/*
- Displays a notification with the current time. Requires "notifications"
- permission in the manifest file (or calling
- "Notification.requestPermission" beforehand).
-*/
-function show() {
- var time = /(..)(:..)/.exec(new Date()); // The prettyprinted time.
- var hour = time[1] % 12 || 12; // The prettyprinted hour.
- var period = time[1] < 12 ? 'a.m.' : 'p.m.'; // The period of the day.
- new Notification(hour + time[2] + ' ' + period, {
- icon: '48.png',
- body: 'Time to make the toast.'
- });
-}
-
-// Conditionally initialize the options.
-if (!localStorage.isInitialized) {
- localStorage.isActivated = true; // The display activation.
- localStorage.frequency = 1; // The display frequency, in minutes.
- localStorage.isInitialized = true; // The option initialization.
-}
-
-// Test for notification support.
-if (window.Notification) {
- // While activated, show notifications at the display frequency.
- if (JSON.parse(localStorage.isActivated)) { show(); }
-
- var interval = 0; // The display interval, in minutes.
-
- setInterval(function() {
- interval++;
-
- if (
- JSON.parse(localStorage.isActivated) &&
- localStorage.frequency <= interval
- ) {
- show();
- interval = 0;
- }
- }, 60000);
-}
diff --git a/chrome/common/extensions/docs/examples/api/notifications/manifest.json b/chrome/common/extensions/docs/examples/api/notifications/manifest.json
deleted file mode 100644
index 1f77d635..0000000
--- a/chrome/common/extensions/docs/examples/api/notifications/manifest.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
- "name": "Notification Demo",
- "version": "1.1",
- "description":
- "Shows off desktop notifications, which are \"toast\" windows that pop up on the desktop.",
- "icons": {"16": "16.png", "48": "48.png", "128": "128.png"},
- "permissions": [
- "notifications"
- ],
- "options_page": "options.html",
- "background": { "scripts": ["background.js"] },
- "manifest_version": 2,
-
- // crbug.com/134315
- "web_accessible_resources": [
- "48.png"
- ]
-}
diff --git a/chrome/common/extensions/docs/examples/api/notifications/options.html b/chrome/common/extensions/docs/examples/api/notifications/options.html
deleted file mode 100644
index df61b379..0000000
--- a/chrome/common/extensions/docs/examples/api/notifications/options.html
+++ /dev/null
@@ -1,41 +0,0 @@
-<!--
- Copyright (c) 2012 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.
-
- Brian Kennish <bkennish@chromium.org>
-
- An option page for configuring notifications.
--->
-<!doctype html>
-<html>
- <head>
- <title>Notification Demo</title>
- <link href="style.css" rel="stylesheet" type="text/css">
- <script src="options.js"></script>
- </head>
- <body>
- <h1>
- <img src="64.png" alt="Toast">
- Notification Demo
- </h1>
- <h2>Options</h2>
- <form id="options">
- <input type="checkbox" name="isActivated" checked>
- Display a notification every
- <select name="frequency">
- <option>1</option>
- <option>2</option>
- <option>3</option>
- <option>4</option>
- <option>5</option>
- <option>10</option>
- <option>15</option>
- <option>20</option>
- <option>25</option>
- <option>30</option>
- </select>
- minute(s).
- </form>
- </body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/api/notifications/options.js b/chrome/common/extensions/docs/examples/api/notifications/options.js
deleted file mode 100644
index 9f5e6a2..0000000
--- a/chrome/common/extensions/docs/examples/api/notifications/options.js
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (c) 2011 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.
-
-/*
- Grays out or [whatever the opposite of graying out is called] the option
- field.
-*/
-function ghost(isDeactivated) {
- options.style.color = isDeactivated ? 'graytext' : 'black';
- // The label color.
- options.frequency.disabled = isDeactivated; // The control manipulability.
-}
-
-window.addEventListener('load', function() {
- // Initialize the option controls.
- options.isActivated.checked = JSON.parse(localStorage.isActivated);
- // The display activation.
- options.frequency.value = localStorage.frequency;
- // The display frequency, in minutes.
-
- if (!options.isActivated.checked) { ghost(true); }
-
- // Set the display activation and frequency.
- options.isActivated.onchange = function() {
- localStorage.isActivated = options.isActivated.checked;
- ghost(!options.isActivated.checked);
- };
-
- options.frequency.onchange = function() {
- localStorage.frequency = options.frequency.value;
- };
-});
diff --git a/chrome/common/extensions/docs/examples/api/notifications/style.css b/chrome/common/extensions/docs/examples/api/notifications/style.css
deleted file mode 100644
index 7a5de73..0000000
--- a/chrome/common/extensions/docs/examples/api/notifications/style.css
+++ /dev/null
@@ -1,25 +0,0 @@
-/**
- * Copyright (c) 2011 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.
- */
-
-/* Clone the look and feel of "chrome://" pages. */
-body {
- margin: 10px;
- font: 84% Arial, sans-serif
-}
-
-h1 { font-size: 156% }
-
-h1 img {
- margin: 1px 5px 0 1px;
- vertical-align: middle
-}
-
-h2 {
- border-top: 1px solid #9cc2ef;
- background-color: #ebeff9;
- padding: 3px 5px;
- font-size: 100%
-}
diff --git a/chrome/common/extensions/docs/examples/api/omnibox/newtab_search/background.js b/chrome/common/extensions/docs/examples/api/omnibox/newtab_search/background.js
deleted file mode 100644
index 83d69f4..0000000
--- a/chrome/common/extensions/docs/examples/api/omnibox/newtab_search/background.js
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2017 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.
-
-// This event is fired with the user accepts the input in the omnibox.
-chrome.omnibox.onInputEntered.addListener(
- function(text) {
- // Encode user input for special characters , / ? : @ & = + $ #
- var newURL = 'https://www.google.com/search?q=' + encodeURIComponent(text);
- chrome.tabs.create({ url: newURL });
- });
diff --git a/chrome/common/extensions/docs/examples/api/omnibox/newtab_search/manifest.json b/chrome/common/extensions/docs/examples/api/omnibox/newtab_search/manifest.json
deleted file mode 100644
index 5d1c2ff..0000000
--- a/chrome/common/extensions/docs/examples/api/omnibox/newtab_search/manifest.json
+++ /dev/null
@@ -1,23 +0,0 @@
-{
- "name": "Omnibox New Tab Search",
- "description": "Type 'nt' plus a search term into the Omnibox to open search in new tab.",
- "version": "1.0",
- "background": {
- "scripts": ["background.js"],
- "persistent": false
- },
- "omnibox": { "keyword" : "nt" },
- "manifest_version": 2,
- "browser_action": {
- "default_icon": {
- "16": "newtab_search16.png",
- "32": "newtab_search32.png"
- }
- },
- "icons": {
- "16": "newtab_search16.png",
- "32": "newtab_search32.png",
- "48": "newtab_search48.png",
- "128": "newtab_search128.png"
- }
-}
diff --git a/chrome/common/extensions/docs/examples/api/omnibox/newtab_search/newtab_search128.png b/chrome/common/extensions/docs/examples/api/omnibox/newtab_search/newtab_search128.png
deleted file mode 100644
index d4b8637..0000000
--- a/chrome/common/extensions/docs/examples/api/omnibox/newtab_search/newtab_search128.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/omnibox/newtab_search/newtab_search16.png b/chrome/common/extensions/docs/examples/api/omnibox/newtab_search/newtab_search16.png
deleted file mode 100644
index 09c8ae2..0000000
--- a/chrome/common/extensions/docs/examples/api/omnibox/newtab_search/newtab_search16.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/omnibox/newtab_search/newtab_search32.png b/chrome/common/extensions/docs/examples/api/omnibox/newtab_search/newtab_search32.png
deleted file mode 100644
index 17a435a..0000000
--- a/chrome/common/extensions/docs/examples/api/omnibox/newtab_search/newtab_search32.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/omnibox/newtab_search/newtab_search48.png b/chrome/common/extensions/docs/examples/api/omnibox/newtab_search/newtab_search48.png
deleted file mode 100644
index 5678cec..0000000
--- a/chrome/common/extensions/docs/examples/api/omnibox/newtab_search/newtab_search48.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/omnibox/simple-example/background.js b/chrome/common/extensions/docs/examples/api/omnibox/simple-example/background.js
deleted file mode 100644
index 35808c9..0000000
--- a/chrome/common/extensions/docs/examples/api/omnibox/simple-example/background.js
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright (c) 2012 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.
-
-'use strict';
-
-// This event is fired each time the user updates the text in the omnibox,
-// as long as the extension's keyword mode is still active.
-chrome.omnibox.onInputChanged.addListener(
- function(text, suggest) {
- console.log('inputChanged: ' + text);
- suggest([
- {content: text + " one", description: "the first one"},
- {content: text + " number two", description: "the second entry"}
- ]);
- });
-
-// This event is fired with the user accepts the input in the omnibox.
-chrome.omnibox.onInputEntered.addListener(
- function(text) {
- console.log('inputEntered: ' + text);
- alert('You just typed "' + text + '"');
- });
diff --git a/chrome/common/extensions/docs/examples/api/omnibox/simple-example/manifest.json b/chrome/common/extensions/docs/examples/api/omnibox/simple-example/manifest.json
deleted file mode 100644
index eafc95a..0000000
--- a/chrome/common/extensions/docs/examples/api/omnibox/simple-example/manifest.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "name": "Omnibox Example",
- "description" : "To use, type 'omnix' plus a search term into the Omnibox.",
- "version": "1.1",
- "background": {
- "scripts": ["background.js"],
- "persistent": false
- },
- "omnibox": { "keyword" : "omnix" },
- "manifest_version": 2
-}
diff --git a/chrome/common/extensions/docs/examples/api/override/blank_ntp/blank.html b/chrome/common/extensions/docs/examples/api/override/blank_ntp/blank.html
deleted file mode 100644
index 87cf3ed..0000000
--- a/chrome/common/extensions/docs/examples/api/override/blank_ntp/blank.html
+++ /dev/null
@@ -1,19 +0,0 @@
-<html>
- <head>
- <title>Blank New Tab</title>
- <style>
- div {
- color: #cccccc;
- vertical-align: 50%;
- text-align: center;
- font-family: sans-serif;
- font-size: 300%;
- }
- </style>
- </head>
- <body>
- <div style="height:40%"></div>
- <div>Blank New Tab™</div>
- </body>
-</html>
-
diff --git a/chrome/common/extensions/docs/examples/api/override/blank_ntp/manifest.json b/chrome/common/extensions/docs/examples/api/override/blank_ntp/manifest.json
deleted file mode 100644
index 9efcc231..0000000
--- a/chrome/common/extensions/docs/examples/api/override/blank_ntp/manifest.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "name": "Blank new tab page",
- "description": "Override the new tab page with a blank one",
- "version": "0.2",
- "incognito": "split",
- "chrome_url_overrides": {
- "newtab": "blank.html"
- },
- "manifest_version": 2
-}
diff --git a/chrome/common/extensions/docs/examples/api/override/override_igoogle/manifest.json b/chrome/common/extensions/docs/examples/api/override/override_igoogle/manifest.json
deleted file mode 100644
index 927faa3..0000000
--- a/chrome/common/extensions/docs/examples/api/override/override_igoogle/manifest.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "name": "iGoogle new tab page",
- "description": "Override the new tab page with iGoogle",
- "version": "0.2",
- "chrome_url_overrides": {
- "newtab": "redirect.html"
- },
- "manifest_version": 2
-}
diff --git a/chrome/common/extensions/docs/examples/api/override/override_igoogle/redirect.html b/chrome/common/extensions/docs/examples/api/override/override_igoogle/redirect.html
deleted file mode 100644
index 35117f48..0000000
--- a/chrome/common/extensions/docs/examples/api/override/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/common/extensions/docs/examples/api/pageAction/pageaction_by_content/background.js b/chrome/common/extensions/docs/examples/api/pageAction/pageaction_by_content/background.js
deleted file mode 100644
index 30005da..0000000
--- a/chrome/common/extensions/docs/examples/api/pageAction/pageaction_by_content/background.js
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright (c) 2012 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.
-
-// Update the declarative rules on install or upgrade.
-chrome.runtime.onInstalled.addListener(function() {
- chrome.declarativeContent.onPageChanged.removeRules(undefined, function() {
- chrome.declarativeContent.onPageChanged.addRules([{
- conditions: [
- // When a page contains a <video> tag...
- new chrome.declarativeContent.PageStateMatcher({
- css: ["video"]
- })
- ],
- // ... show the page action.
- actions: [new chrome.declarativeContent.ShowPageAction() ]
- }]);
- });
-});
diff --git a/chrome/common/extensions/docs/examples/api/pageAction/pageaction_by_content/manifest.json b/chrome/common/extensions/docs/examples/api/pageAction/pageaction_by_content/manifest.json
deleted file mode 100644
index 79134a72..0000000
--- a/chrome/common/extensions/docs/examples/api/pageAction/pageaction_by_content/manifest.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
- "name" : "Page action by content",
- "version" : "1.1",
- "description" : "Shows a page action for HTML pages containing a video",
- "background" : {
- "scripts": ["background.js"],
- "persistent": false
- },
- "page_action" :
- {
- "default_icon" : "video-19.png",
- "default_title" : "There's a <video> in this page!"
- },
- "permissions": [ "declarativeContent" ],
- "icons" : {
- "48" : "video-48.png",
- "128" : "video-128.png"
- },
- "manifest_version": 2
-}
diff --git a/chrome/common/extensions/docs/examples/api/pageAction/pageaction_by_content/video-128.png b/chrome/common/extensions/docs/examples/api/pageAction/pageaction_by_content/video-128.png
deleted file mode 100644
index c16dea2..0000000
--- a/chrome/common/extensions/docs/examples/api/pageAction/pageaction_by_content/video-128.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/pageAction/pageaction_by_content/video-19.png b/chrome/common/extensions/docs/examples/api/pageAction/pageaction_by_content/video-19.png
deleted file mode 100644
index 2f5caf1..0000000
--- a/chrome/common/extensions/docs/examples/api/pageAction/pageaction_by_content/video-19.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/pageAction/pageaction_by_content/video-48.png b/chrome/common/extensions/docs/examples/api/pageAction/pageaction_by_content/video-48.png
deleted file mode 100644
index 0a06c37..0000000
--- a/chrome/common/extensions/docs/examples/api/pageAction/pageaction_by_content/video-48.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/pageAction/pageaction_by_url/background.js b/chrome/common/extensions/docs/examples/api/pageAction/pageaction_by_url/background.js
deleted file mode 100644
index bdc7433..0000000
--- a/chrome/common/extensions/docs/examples/api/pageAction/pageaction_by_url/background.js
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright (c) 2011 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.
-
-// When the extension is installed or upgraded ...
-chrome.runtime.onInstalled.addListener(function() {
- // Replace all rules ...
- chrome.declarativeContent.onPageChanged.removeRules(undefined, function() {
- // With a new rule ...
- chrome.declarativeContent.onPageChanged.addRules([
- {
- // That fires when a page's URL contains a 'g' ...
- conditions: [
- new chrome.declarativeContent.PageStateMatcher({
- pageUrl: { urlContains: 'g' },
- })
- ],
- // And shows the extension's page action.
- actions: [ new chrome.declarativeContent.ShowPageAction() ]
- }
- ]);
- });
-});
diff --git a/chrome/common/extensions/docs/examples/api/pageAction/pageaction_by_url/icon-128.png b/chrome/common/extensions/docs/examples/api/pageAction/pageaction_by_url/icon-128.png
deleted file mode 100644
index 27b35c4..0000000
--- a/chrome/common/extensions/docs/examples/api/pageAction/pageaction_by_url/icon-128.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/pageAction/pageaction_by_url/icon-19.png b/chrome/common/extensions/docs/examples/api/pageAction/pageaction_by_url/icon-19.png
deleted file mode 100644
index 6dc2d13..0000000
--- a/chrome/common/extensions/docs/examples/api/pageAction/pageaction_by_url/icon-19.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/pageAction/pageaction_by_url/icon-48.png b/chrome/common/extensions/docs/examples/api/pageAction/pageaction_by_url/icon-48.png
deleted file mode 100644
index 9af987c6..0000000
--- a/chrome/common/extensions/docs/examples/api/pageAction/pageaction_by_url/icon-48.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/pageAction/pageaction_by_url/manifest.json b/chrome/common/extensions/docs/examples/api/pageAction/pageaction_by_url/manifest.json
deleted file mode 100644
index 5c20902f..0000000
--- a/chrome/common/extensions/docs/examples/api/pageAction/pageaction_by_url/manifest.json
+++ /dev/null
@@ -1,22 +0,0 @@
-{
- "name": "Page action by URL",
- "version": "1.0",
- "description": "Shows a page action for urls which have the letter 'g' in them.",
- "background": {
- "scripts": ["background.js"],
- "persistent": false
- },
- "page_action" :
- {
- "default_icon" : "icon-19.png",
- "default_title" : "There's a 'G' in this URL!"
- },
- "permissions" : [
- "declarativeContent"
- ],
- "icons" : {
- "48" : "icon-48.png",
- "128" : "icon-128.png"
- },
- "manifest_version": 2
-}
diff --git a/chrome/common/extensions/docs/examples/api/pageAction/set_icon/background.html b/chrome/common/extensions/docs/examples/api/pageAction/set_icon/background.html
deleted file mode 100644
index 58ecd28..0000000
--- a/chrome/common/extensions/docs/examples/api/pageAction/set_icon/background.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<html>
-<head>
-<script src="background.js"></script>
-</head>
-<body>
-<canvas id="canvas" width="19" height="19"></canvas>
-</body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/api/pageAction/set_icon/background.js b/chrome/common/extensions/docs/examples/api/pageAction/set_icon/background.js
deleted file mode 100644
index f2e59ce..0000000
--- a/chrome/common/extensions/docs/examples/api/pageAction/set_icon/background.js
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright (c) 2012 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.
-
-var lastTabId = 0;
-var tab_clicks = {};
-
-chrome.tabs.onSelectionChanged.addListener(function(tabId) {
- lastTabId = tabId;
- chrome.pageAction.show(lastTabId);
-});
-
-chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
- lastTabId = tabs[0].id;
- chrome.pageAction.show(lastTabId);
-});
-
-// Called when the user clicks on the page action.
-chrome.pageAction.onClicked.addListener(function(tab) {
- var clicks = tab_clicks[tab.id] || 0;
- chrome.pageAction.setIcon({path: "icon" + (clicks + 1) + ".png",
- tabId: tab.id});
- if (clicks % 2) {
- chrome.pageAction.show(tab.id);
- } else {
- chrome.pageAction.hide(tab.id);
- setTimeout(function() { chrome.pageAction.show(tab.id); }, 200);
- }
- chrome.pageAction.setTitle({title: "click:" + clicks, tabId: tab.id});
-
- // We only have 2 icons, but cycle through 3 icons to test the
- // out-of-bounds index bug.
- clicks++;
- if (clicks > 3)
- clicks = 0;
- tab_clicks[tab.id] = clicks;
-});
-
-var i = 0;
-window.setInterval(function() {
- var clicks = tab_clicks[lastTabId] || 0;
-
- // 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);
-}
diff --git a/chrome/common/extensions/docs/examples/api/pageAction/set_icon/icon1.png b/chrome/common/extensions/docs/examples/api/pageAction/set_icon/icon1.png
deleted file mode 100644
index ea42f3f..0000000
--- a/chrome/common/extensions/docs/examples/api/pageAction/set_icon/icon1.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/pageAction/set_icon/icon2.png b/chrome/common/extensions/docs/examples/api/pageAction/set_icon/icon2.png
deleted file mode 100644
index da75c5f..0000000
--- a/chrome/common/extensions/docs/examples/api/pageAction/set_icon/icon2.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/pageAction/set_icon/manifest.json b/chrome/common/extensions/docs/examples/api/pageAction/set_icon/manifest.json
deleted file mode 100644
index 115b8d0..0000000
--- a/chrome/common/extensions/docs/examples/api/pageAction/set_icon/manifest.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- "name": "Animated Page Action",
- "description": "This extension adds an animated browser action to the toolbar.",
- "version": "1.2",
- "background": {
- "page": "background.html"
- },
- "page_action": {
- "default_title": "First icon"
- },
- "manifest_version": 2
-}
diff --git a/chrome/common/extensions/docs/examples/api/permissions/extension-questions.crx b/chrome/common/extensions/docs/examples/api/permissions/extension-questions.crx
deleted file mode 100644
index 9737b18e..0000000
--- a/chrome/common/extensions/docs/examples/api/permissions/extension-questions.crx
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/permissions/extension-questions/images/icon.png b/chrome/common/extensions/docs/examples/api/permissions/extension-questions/images/icon.png
deleted file mode 100644
index 66a3be1..0000000
--- a/chrome/common/extensions/docs/examples/api/permissions/extension-questions/images/icon.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/permissions/extension-questions/manifest.json b/chrome/common/extensions/docs/examples/api/permissions/extension-questions/manifest.json
deleted file mode 100644
index 2d8647ed..0000000
--- a/chrome/common/extensions/docs/examples/api/permissions/extension-questions/manifest.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- "name": "Top Chrome Extension Questions",
- "version": "0.3",
- "description": "Sample demonstration of the optional permissions API.",
- "icons": {
- "128": "images/icon.png",
- "48": "images/icon.png",
- "16": "images/icon.png"
- },
- "browser_action": {
- "default_icon": "images/icon.png",
- "default_popup": "popup.html"
- },
- "options_page": "options.html",
- "optional_permissions": ["http://api.stackoverflow.com/"],
- "manifest_version": 2
-}
diff --git a/chrome/common/extensions/docs/examples/api/permissions/extension-questions/options.html b/chrome/common/extensions/docs/examples/api/permissions/extension-questions/options.html
deleted file mode 100644
index 7fa0aae..0000000
--- a/chrome/common/extensions/docs/examples/api/permissions/extension-questions/options.html
+++ /dev/null
@@ -1,14 +0,0 @@
-<!doctype html>
-<head>
- <style>
- #status { font-weight: bold; }
- </style>
-</head>
-<body>
- <button id="enable">Grant Permission</button>
- <button id="disable">Revoke Permission</button>
- <p>
- Stack Overflow permission status: <span id="status"></span>
- <script src="options.js"></script>
- </p>
-</body>
diff --git a/chrome/common/extensions/docs/examples/api/permissions/extension-questions/options.js b/chrome/common/extensions/docs/examples/api/permissions/extension-questions/options.js
deleted file mode 100644
index 9ff8f7e2..0000000
--- a/chrome/common/extensions/docs/examples/api/permissions/extension-questions/options.js
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright (c) 2011 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.
-
-var PERMISSIONS = {origins: ['http://api.stackoverflow.com/']};
-var YES = 'ENABLED';
-var NO = 'DISABLED';
-
-var $status = document.querySelector('#status');
-chrome.permissions.onAdded.addListener(function(permissions) {
- $status.innerText = YES;
-});
-chrome.permissions.onRemoved.addListener(function(permissions) {
- $status.innerText = NO;
-});
-chrome.permissions.contains(PERMISSIONS, function(contains) {
- $status.innerText = contains ? YES : NO;
-});
-
-document.querySelector('button#enable').addEventListener('click', function() {
- chrome.permissions.contains(PERMISSIONS, function(allowed) {
- if (allowed) {
- alert('You already have SO host permission!');
- } else {
- chrome.permissions.request(PERMISSIONS, function(result) {
- if (result) {
- console.log('SO host permission granted!' +
- 'Open the browser action again.');
- }
- });
- }
- });
-});
-
-document.querySelector('button#disable').addEventListener('click', function() {
- chrome.permissions.contains(PERMISSIONS, function(allowed) {
- if (allowed) {
- chrome.permissions.remove(PERMISSIONS, function(result) {
- console.log('Revoked SO host permission.');
- });
- } else {
- alert('No SO host permission found.');
- }
- });
-});
-
diff --git a/chrome/common/extensions/docs/examples/api/permissions/extension-questions/popup.html b/chrome/common/extensions/docs/examples/api/permissions/extension-questions/popup.html
deleted file mode 100644
index 43fc6b0..0000000
--- a/chrome/common/extensions/docs/examples/api/permissions/extension-questions/popup.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<!doctype html>
-<head>
- <style>
- body { width: 300px; }
- </style>
-</head>
-<body>
- <h3 id="title"></h3>
- <ul id="results"></ul>
- <script src="popup.js"></script>
-</body>
diff --git a/chrome/common/extensions/docs/examples/api/permissions/extension-questions/popup.js b/chrome/common/extensions/docs/examples/api/permissions/extension-questions/popup.js
deleted file mode 100644
index 46c74d9..0000000
--- a/chrome/common/extensions/docs/examples/api/permissions/extension-questions/popup.js
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright (c) 2011 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.
-
-var PERMISSIONS = {origins: ['http://api.stackoverflow.com/']};
-var URL = 'http://api.stackoverflow.com/1.1/questions?max=10&sort=votes&tagged=google-chrome-extension';
-var ROOT = 'http://stackoverflow.com';
-
-chrome.permissions.contains(PERMISSIONS, function(result) {
- if (!result) {
- // Open options page to request permissions.
- document.querySelector('#title').innerText =
- 'Requires Stack Overflow permission';
- chrome.tabs.create({url: 'options.html'});
- } else {
- // Make the request to SO.
- makeRequest(function(data) {
- // Render the results.
- renderQuestions(JSON.parse(data));
- });
- }
-});
-
-function makeRequest(callback) {
- var xhr = new XMLHttpRequest();
- xhr.open('GET', URL);
- xhr.addEventListener('load', function(e) {
- var result = xhr.responseText;
- callback(result);
- });
- xhr.send();
-}
-
-function renderQuestions(data) {
- var $results = document.querySelector('#results');
- var questions = data.questions;
- for (var i = 0; i < Math.min(10, questions.length); i++) {
- var question = questions[i];
- var $question = document.createElement('li');
- var url = ROOT + question.question_answers_url;
- $question.innerHTML = '<a href="' + url + '" target="_blank">' +
- question.title + '</a>';
- results.appendChild($question);
- }
- // Update title too.
- document.querySelector('#title').innerText = 'Top Chrome Extension Questions';
-}
diff --git a/chrome/common/extensions/docs/examples/api/power/_locales/en/messages.json b/chrome/common/extensions/docs/examples/api/power/_locales/en/messages.json
deleted file mode 100644
index ef50944..0000000
--- a/chrome/common/extensions/docs/examples/api/power/_locales/en/messages.json
+++ /dev/null
@@ -1,22 +0,0 @@
-{
- "extensionName": {
- "message": "Keep Awake",
- "description": "Extension name."
- },
- "extensionDescription": {
- "message": "Override system power-saving settings.",
- "description": "Extension description."
- },
- "disabledTitle": {
- "message": "Default power-saving settings",
- "description": "Browser action title when disabled."
- },
- "displayTitle": {
- "message": "Screen will be kept on",
- "description": "Browser action title when preventing screen-off."
- },
- "systemTitle": {
- "message": "System will stay awake",
- "description": "Browser action title when preventing system sleep."
- }
-}
diff --git a/chrome/common/extensions/docs/examples/api/power/background.js b/chrome/common/extensions/docs/examples/api/power/background.js
deleted file mode 100644
index 5fd9083..0000000
--- a/chrome/common/extensions/docs/examples/api/power/background.js
+++ /dev/null
@@ -1,101 +0,0 @@
-// Copyright (c) 2013 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.
-
-/**
- * States that the extension can be in.
- */
-var StateEnum = {
- DISABLED: 'disabled',
- DISPLAY: 'display',
- SYSTEM: 'system'
-};
-
-/**
- * Key used for storing the current state in {localStorage}.
- */
-var STATE_KEY = 'state';
-
-/**
- * Loads the locally-saved state asynchronously.
- * @param {function} callback Callback invoked with the loaded {StateEnum}.
- */
-function loadSavedState(callback) {
- chrome.storage.local.get(STATE_KEY, function(items) {
- var savedState = items[STATE_KEY];
- for (var key in StateEnum) {
- if (savedState == StateEnum[key]) {
- callback(savedState);
- return;
- }
- }
- callback(StateEnum.DISABLED);
- });
-}
-
-/**
- * Switches to a new state.
- * @param {string} newState New {StateEnum} to use.
- */
-function setState(newState) {
- var imagePrefix = 'night';
- var title = '';
-
- switch (newState) {
- case StateEnum.DISABLED:
- chrome.power.releaseKeepAwake();
- imagePrefix = 'night';
- title = chrome.i18n.getMessage('disabledTitle');
- break;
- case StateEnum.DISPLAY:
- chrome.power.requestKeepAwake('display');
- imagePrefix = 'day';
- title = chrome.i18n.getMessage('displayTitle');
- break;
- case StateEnum.SYSTEM:
- chrome.power.requestKeepAwake('system');
- imagePrefix = 'sunset';
- title = chrome.i18n.getMessage('systemTitle');
- break;
- default:
- throw 'Invalid state "' + newState + '"';
- }
-
- var items = {};
- items[STATE_KEY] = newState;
- chrome.storage.local.set(items);
-
- chrome.browserAction.setIcon({
- path: {
- '19': 'images/' + imagePrefix + '-19.png',
- '38': 'images/' + imagePrefix + '-38.png'
- }
- });
- chrome.browserAction.setTitle({title: title});
-}
-
-chrome.browserAction.onClicked.addListener(function() {
- loadSavedState(function(state) {
- switch (state) {
- case StateEnum.DISABLED:
- setState(StateEnum.DISPLAY);
- break;
- case StateEnum.DISPLAY:
- setState(StateEnum.SYSTEM);
- break;
- case StateEnum.SYSTEM:
- setState(StateEnum.DISABLED);
- break;
- default:
- throw 'Invalid state "' + state + '"';
- }
- });
-});
-
-chrome.runtime.onStartup.addListener(function() {
- loadSavedState(function(state) { setState(state); });
-});
-
-chrome.runtime.onInstalled.addListener(function(details) {
- loadSavedState(function(state) { setState(state); });
-});
diff --git a/chrome/common/extensions/docs/examples/api/power/images/day-19.png b/chrome/common/extensions/docs/examples/api/power/images/day-19.png
deleted file mode 100644
index 09d2305..0000000
--- a/chrome/common/extensions/docs/examples/api/power/images/day-19.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/power/images/day-38.png b/chrome/common/extensions/docs/examples/api/power/images/day-38.png
deleted file mode 100644
index ec5eec9b..0000000
--- a/chrome/common/extensions/docs/examples/api/power/images/day-38.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/power/images/icon-128.png b/chrome/common/extensions/docs/examples/api/power/images/icon-128.png
deleted file mode 100644
index ec35e41..0000000
--- a/chrome/common/extensions/docs/examples/api/power/images/icon-128.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/power/images/icon-16.png b/chrome/common/extensions/docs/examples/api/power/images/icon-16.png
deleted file mode 100644
index 0755f7c..0000000
--- a/chrome/common/extensions/docs/examples/api/power/images/icon-16.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/power/images/icon-48.png b/chrome/common/extensions/docs/examples/api/power/images/icon-48.png
deleted file mode 100644
index 272390d5..0000000
--- a/chrome/common/extensions/docs/examples/api/power/images/icon-48.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/power/images/night-19.png b/chrome/common/extensions/docs/examples/api/power/images/night-19.png
deleted file mode 100644
index 949b2d65..0000000
--- a/chrome/common/extensions/docs/examples/api/power/images/night-19.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/power/images/night-38.png b/chrome/common/extensions/docs/examples/api/power/images/night-38.png
deleted file mode 100644
index b891f77..0000000
--- a/chrome/common/extensions/docs/examples/api/power/images/night-38.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/power/images/sunset-19.png b/chrome/common/extensions/docs/examples/api/power/images/sunset-19.png
deleted file mode 100644
index ce5af806..0000000
--- a/chrome/common/extensions/docs/examples/api/power/images/sunset-19.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/power/images/sunset-38.png b/chrome/common/extensions/docs/examples/api/power/images/sunset-38.png
deleted file mode 100644
index 3510341..0000000
--- a/chrome/common/extensions/docs/examples/api/power/images/sunset-38.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/power/manifest.json b/chrome/common/extensions/docs/examples/api/power/manifest.json
deleted file mode 100644
index dd90842..0000000
--- a/chrome/common/extensions/docs/examples/api/power/manifest.json
+++ /dev/null
@@ -1,30 +0,0 @@
-{
- "manifest_version": 2,
-
- "name": "__MSG_extensionName__",
- "description": "__MSG_extensionDescription__",
- "version": "1.9",
- "icons": {
- "16": "images/icon-16.png",
- "48": "images/icon-48.png",
- "128": "images/icon-128.png"
- },
-
- "permissions": [
- "power",
- "storage"
- ],
- "browser_action": {
- "default_title": "__MSG_disabledTitle__",
- "default_icon": {
- "19": "images/night-19.png",
- "38": "images/night-38.png"
- }
- },
- "background": {
- "scripts": ["background.js"],
- "persistent": false
- },
-
- "default_locale": "en"
-}
diff --git a/chrome/common/extensions/docs/examples/api/preferences/allowThirdPartyCookies/advicedog.jpg b/chrome/common/extensions/docs/examples/api/preferences/allowThirdPartyCookies/advicedog.jpg
deleted file mode 100644
index 9274fbd..0000000
--- a/chrome/common/extensions/docs/examples/api/preferences/allowThirdPartyCookies/advicedog.jpg
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/preferences/allowThirdPartyCookies/manifest.json b/chrome/common/extensions/docs/examples/api/preferences/allowThirdPartyCookies/manifest.json
deleted file mode 100644
index 2511406..0000000
--- a/chrome/common/extensions/docs/examples/api/preferences/allowThirdPartyCookies/manifest.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "name" : "Block/allow third-party cookies API example extension",
- "version" : "0.1",
- "description" : "Sample extension which demonstrates how to access a preference.",
- "permissions": [ "privacy" ],
- "browser_action": {
- "default_icon": "advicedog.jpg",
- "default_popup": "popup.html"
- },
- "manifest_version": 2
-}
diff --git a/chrome/common/extensions/docs/examples/api/preferences/allowThirdPartyCookies/popup.css b/chrome/common/extensions/docs/examples/api/preferences/allowThirdPartyCookies/popup.css
deleted file mode 100644
index 3e715ba..0000000
--- a/chrome/common/extensions/docs/examples/api/preferences/allowThirdPartyCookies/popup.css
+++ /dev/null
@@ -1,13 +0,0 @@
-/**
- * Copyright (c) 2011 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.
- */
-
-#container {
- width: 300px;
-}
-
-#incognito {
- display: none;
-}
diff --git a/chrome/common/extensions/docs/examples/api/preferences/allowThirdPartyCookies/popup.html b/chrome/common/extensions/docs/examples/api/preferences/allowThirdPartyCookies/popup.html
deleted file mode 100644
index 37dccec..0000000
--- a/chrome/common/extensions/docs/examples/api/preferences/allowThirdPartyCookies/popup.html
+++ /dev/null
@@ -1,25 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
- <link href="popup.css" rel="stylesheet" type="text/css">
- <script src="popup.js"></script>
-</head>
-<body>
-
-<div id="container">
- <input type="checkbox" id="regularValue" />
- Allow third-party sites to set cookies
- <div id="incognito">
- <input type="checkbox" id="useSeparateIncognitoSettings" />
- Use separate setting for incognito mode:
- <br>
- <input type="checkbox" id="incognitoValue" disabled="disabled"/>
- Allow third-party sites to set cookies in incognito sessions
- </div>
- <div id="incognito-forbidden">
- Select "Allow in incognito" to access incognito preferences
- </div>
-</div>
-
-</body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/api/preferences/allowThirdPartyCookies/popup.js b/chrome/common/extensions/docs/examples/api/preferences/allowThirdPartyCookies/popup.js
deleted file mode 100644
index ce25b11..0000000
--- a/chrome/common/extensions/docs/examples/api/preferences/allowThirdPartyCookies/popup.js
+++ /dev/null
@@ -1,127 +0,0 @@
-// Copyright (c) 2012 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.
-
-
-var pref = chrome.privacy.websites.thirdPartyCookiesAllowed;
-
-function $(id) {
- return document.getElementById(id);
-}
-
-/**
- * Returns whether the |levelOfControl| means that the extension can change the
- * preference value.
- *
- * @param levelOfControl{string}
- */
-function settingIsControllable(levelOfControl) {
- return (levelOfControl == 'controllable_by_this_extension' ||
- levelOfControl == 'controlled_by_this_extension');
-}
-
-/**
- * Updates the UI to reflect the state of the preference.
- *
- * @param settings{object} A settings object, as returned from |get()| or the
- * |onchange| event.
- */
-function updateUI(settings) {
- var disableUI = !settingIsControllable(settings.levelOfControl);
- document.getElementById('regularValue').disabled = disableUI;
- document.getElementById('useSeparateIncognitoSettings').disabled = disableUI;
- if (settings.hasOwnProperty('incognitoSpecific')) {
- var hasIncognitoValue = settings.incognitoSpecific;
- document.getElementById('useSeparateIncognitoSettings').checked =
- hasIncognitoValue;
- document.getElementById('incognitoValue').disabled =
- disableUI || !hasIncognitoValue;
- document.getElementById('incognitoValue').checked = settings.value;
- } else {
- document.getElementById('regularValue').checked = settings.value;
- }
-}
-
-/**
- * Wrapper for |updateUI| which is used as callback for the |get()| method and
- * which logs the result.
- * If there was an error getting the preference, does nothing.
- *
- * @param settings{object} A settings object, as returned from |get()|.
- */
-function updateUIFromGet(settings) {
- if (settings) {
- console.log('pref.get result:' + JSON.stringify(settings));
- updateUI(settings);
- }
-}
-
-/**
- * Wrapper for |updateUI| which is used as handler for the |onchange| event
- * and which logs the result.
- *
- * @param settings{object} A settings object, as returned from the |onchange|
- * event.
- */
-function updateUIFromOnChange(settings) {
- console.log('pref.onChange event:' + JSON.stringify(settings));
- updateUI(settings);
-}
-
-/*
- * Initializes the UI.
- */
-function init() {
- chrome.extension.isAllowedIncognitoAccess(function(allowed) {
- if (allowed) {
- pref.get({'incognito': true}, updateUIFromGet);
- $('incognito').style.display = 'block';
- $('incognito-forbidden').style.display = 'none';
- }
- });
- pref.get({}, updateUIFromGet);
- pref.onChange.addListener(updateUIFromOnChange);
-
- $('regularValue').addEventListener('click', function () {
- setPrefValue(this.checked, false);
- });
- $('useSeparateIncognitoSettings').addEventListener('click', function () {
- setUseSeparateIncognitoSettings(this.checked);
- });
- $('incognitoValue').addEventListener('click', function () {
- setPrefValue(this.checked, true);
- });
-}
-
-/**
- * Called from the UI to change the preference value.
- *
- * @param enabled{boolean} The new preference value.
- * @param incognito{boolean} Whether the value is specific to incognito mode.
- */
-function setPrefValue(enabled, incognito) {
- var scope = incognito ? 'incognito_session_only' : 'regular';
- pref.set({'value': enabled, 'scope': scope});
-}
-
-/**
- * Called from the UI to change whether to use separate settings for
- * incognito mode.
- *
- * @param value{boolean} whether to use separate settings for
- * incognito mode.
- */
-function setUseSeparateIncognitoSettings(value) {
- if (!value) {
- pref.clear({'incognito': true});
- } else {
- // Explicitly set the value for incognito mode.
- pref.get({'incognito': true}, function(settings) {
- pref.set({'incognito': true, 'value': settings.value});
- });
- }
- document.getElementById('incognitoValue').disabled = !value;
-}
-
-// Call `init` to kick things off.
-document.addEventListener('DOMContentLoaded', init);
diff --git a/chrome/common/extensions/docs/examples/api/preferences/enableReferrer/advicedog.jpg b/chrome/common/extensions/docs/examples/api/preferences/enableReferrer/advicedog.jpg
deleted file mode 100644
index 9274fbd..0000000
--- a/chrome/common/extensions/docs/examples/api/preferences/enableReferrer/advicedog.jpg
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/preferences/enableReferrer/manifest.json b/chrome/common/extensions/docs/examples/api/preferences/enableReferrer/manifest.json
deleted file mode 100644
index c72e895..0000000
--- a/chrome/common/extensions/docs/examples/api/preferences/enableReferrer/manifest.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "name" : "Block/allow referrer API example extension",
- "version" : "0.1",
- "description" : "Sample extension which demonstrates how to access a preference.",
- "permissions": [ "privacy" ],
- "browser_action": {
- "default_icon": "advicedog.jpg",
- "default_popup": "popup.html"
- },
- "manifest_version": 2
-}
diff --git a/chrome/common/extensions/docs/examples/api/preferences/enableReferrer/popup.css b/chrome/common/extensions/docs/examples/api/preferences/enableReferrer/popup.css
deleted file mode 100644
index 3e715ba..0000000
--- a/chrome/common/extensions/docs/examples/api/preferences/enableReferrer/popup.css
+++ /dev/null
@@ -1,13 +0,0 @@
-/**
- * Copyright (c) 2011 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.
- */
-
-#container {
- width: 300px;
-}
-
-#incognito {
- display: none;
-}
diff --git a/chrome/common/extensions/docs/examples/api/preferences/enableReferrer/popup.html b/chrome/common/extensions/docs/examples/api/preferences/enableReferrer/popup.html
deleted file mode 100644
index 7f94699c..0000000
--- a/chrome/common/extensions/docs/examples/api/preferences/enableReferrer/popup.html
+++ /dev/null
@@ -1,25 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
- <link href="popup.css" rel="stylesheet" type="text/css">
- <script src="popup.js"></script>
-</head>
-<body>
-
-<div id="container">
- <input type="checkbox" id="regularValue" />
- Enable referrers
- <div id="incognito">
- <input type="checkbox" id="useSeparateIncognitoSettings" />
- Use separate setting for incognito mode:
- <br>
- <input type="checkbox" id="incognitoValue" disabled="disabled"/>
- Enable referrers in incognito sessions
- </div>
- <div id="incognito-forbidden">
- Select "Allow in incognito" to access incognito preferences
- </div>
-</div>
-
-</body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/api/preferences/enableReferrer/popup.js b/chrome/common/extensions/docs/examples/api/preferences/enableReferrer/popup.js
deleted file mode 100644
index 72bb9e4..0000000
--- a/chrome/common/extensions/docs/examples/api/preferences/enableReferrer/popup.js
+++ /dev/null
@@ -1,127 +0,0 @@
-// Copyright (c) 2012 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.
-
-
-var pref = chrome.privacy.websites.referrersEnabled;
-
-function $(id) {
- return document.getElementById(id);
-}
-
-/**
- * Returns whether the |levelOfControl| means that the extension can change the
- * preference value.
- *
- * @param levelOfControl{string}
- */
-function settingIsControllable(levelOfControl) {
- return (levelOfControl == 'controllable_by_this_extension' ||
- levelOfControl == 'controlled_by_this_extension');
-}
-
-/**
- * Updates the UI to reflect the state of the preference.
- *
- * @param settings{object} A settings object, as returned from |get()| or the
- * |onchange| event.
- */
-function updateUI(settings) {
- var disableUI = !settingIsControllable(settings.levelOfControl);
- document.getElementById('regularValue').disabled = disableUI;
- document.getElementById('useSeparateIncognitoSettings').disabled = disableUI;
- if (settings.hasOwnProperty('incognitoSpecific')) {
- var hasIncognitoValue = settings.incognitoSpecific;
- document.getElementById('useSeparateIncognitoSettings').checked =
- hasIncognitoValue;
- document.getElementById('incognitoValue').disabled =
- disableUI || !hasIncognitoValue;
- document.getElementById('incognitoValue').checked = settings.value;
- } else {
- document.getElementById('regularValue').checked = settings.value;
- }
-}
-
-/**
- * Wrapper for |updateUI| which is used as callback for the |get()| method and
- * which logs the result.
- * If there was an error getting the preference, does nothing.
- *
- * @param settings{object} A settings object, as returned from |get()|.
- */
-function updateUIFromGet(settings) {
- if (settings) {
- console.log('pref.get result:' + JSON.stringify(settings));
- updateUI(settings);
- }
-}
-
-/**
- * Wrapper for |updateUI| which is used as handler for the |onchange| event
- * and which logs the result.
- *
- * @param settings{object} A settings object, as returned from the |onchange|
- * event.
- */
-function updateUIFromOnChange(settings) {
- console.log('pref.onChange event:' + JSON.stringify(settings));
- updateUI(settings);
-}
-
-/*
- * Initializes the UI.
- */
-function init() {
- chrome.extension.isAllowedIncognitoAccess(function(allowed) {
- if (allowed) {
- pref.get({'incognito': true}, updateUIFromGet);
- $('incognito').style.display = 'block';
- $('incognito-forbidden').style.display = 'none';
- }
- });
- pref.get({}, updateUIFromGet);
- pref.onChange.addListener(updateUIFromOnChange);
-
- $('regularValue').addEventListener('click', function () {
- setPrefValue(this.checked, false);
- });
- $('useSeparateIncognitoSettings').addEventListener('click', function () {
- setUseSeparateIncognitoSettings(this.checked);
- });
- $('incognitoValue').addEventListener('click', function () {
- setPrefValue(this.checked, true);
- });
-}
-
-/**
- * Called from the UI to change the preference value.
- *
- * @param enabled{boolean} The new preference value.
- * @param incognito{boolean} Whether the value is specific to incognito mode.
- */
-function setPrefValue(enabled, incognito) {
- var scope = incognito ? 'incognito_session_only' : 'regular';
- pref.set({'value': enabled, 'scope': scope});
-}
-
-/**
- * Called from the UI to change whether to use separate settings for
- * incognito mode.
- *
- * @param value{boolean} whether to use separate settings for
- * incognito mode.
- */
-function setUseSeparateIncognitoSettings(value) {
- if (!value) {
- pref.clear({'incognito': true});
- } else {
- // Explicitly set the value for incognito mode.
- pref.get({'incognito': true}, function(settings) {
- pref.set({'incognito': true, 'value': settings.value});
- });
- }
- document.getElementById('incognitoValue').disabled = !value;
-}
-
-// Call `init` to kick things off.
-document.addEventListener('DOMContentLoaded', init);
diff --git a/chrome/common/extensions/docs/examples/api/printing/icons/icon.png b/chrome/common/extensions/docs/examples/api/printing/icons/icon.png
deleted file mode 100644
index 19057a5..0000000
--- a/chrome/common/extensions/docs/examples/api/printing/icons/icon.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/printing/icons/icon128.png b/chrome/common/extensions/docs/examples/api/printing/icons/icon128.png
deleted file mode 100644
index 13a19d6d..0000000
--- a/chrome/common/extensions/docs/examples/api/printing/icons/icon128.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/printing/icons/icon16.png b/chrome/common/extensions/docs/examples/api/printing/icons/icon16.png
deleted file mode 100644
index 7591630c..0000000
--- a/chrome/common/extensions/docs/examples/api/printing/icons/icon16.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/printing/icons/icon48.png b/chrome/common/extensions/docs/examples/api/printing/icons/icon48.png
deleted file mode 100644
index f51b2ff24..0000000
--- a/chrome/common/extensions/docs/examples/api/printing/icons/icon48.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/printing/manifest.json b/chrome/common/extensions/docs/examples/api/printing/manifest.json
deleted file mode 100644
index e47664fe..0000000
--- a/chrome/common/extensions/docs/examples/api/printing/manifest.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
- "name": "Print Extension",
- "version": "1.0",
- "description": "Sends print job directly to the printers installed on the Chromebook",
- "permissions": [
- "printing"
- ],
- "browser_action": {
- "default_popup": "printers.html",
- "default_icon": "icons/icon.png"
- },
- "icons": {
- "16": "icons/icon16.png",
- "48": "icons/icon48.png",
- "128": "icons/icon128.png"
- },
- "manifest_version": 2
-}
diff --git a/chrome/common/extensions/docs/examples/api/printing/printers.css b/chrome/common/extensions/docs/examples/api/printing/printers.css
deleted file mode 100644
index e97ffda6..0000000
--- a/chrome/common/extensions/docs/examples/api/printing/printers.css
+++ /dev/null
@@ -1,18 +0,0 @@
-/**
- * Copyright 2020 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.
- */
-
-table, th, td, tr {
- border: 1px solid black;
-}
-
-table {
- width: 100%;
- border-collapse: collapse;
-}
-
-div {
- overflow: auto;
-}
diff --git a/chrome/common/extensions/docs/examples/api/printing/printers.html b/chrome/common/extensions/docs/examples/api/printing/printers.html
deleted file mode 100644
index 3654aff2..0000000
--- a/chrome/common/extensions/docs/examples/api/printing/printers.html
+++ /dev/null
@@ -1,35 +0,0 @@
-<!--
- * Copyright 2020 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.
--->
-<!DOCTYPE HTML>
-<html>
- <head>
- <title>Printers</title>
- <link href="printers.css" rel="stylesheet" type="text/css">
- <script src="printers.js"></script>
- </head>
-
- <body>
- <h2>Printers:</h2>
- <div id="printers">
- <table id="printersTable">
- <thead>
- <tr>
- <th>Id</th>
- <th>Name</th>
- <th>Description</th>
- <th>URI</th>
- <th>Source</th>
- <th>Default</th>
- <th>Recently used</th>
- <th>Capabilities</th>
- <th>Status</th>
- <th>Print</th>
- </tr>
- </thead>
- </table>
- </div>
- </body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/api/printing/printers.js b/chrome/common/extensions/docs/examples/api/printing/printers.js
deleted file mode 100644
index 2462665..0000000
--- a/chrome/common/extensions/docs/examples/api/printing/printers.js
+++ /dev/null
@@ -1,99 +0,0 @@
-// Copyright 2020 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.
-
-function onPrintButtonClicked(printerId, dpi) {
- var ticket = {
- version: '1.0',
- print: {
- color: {type: 'STANDARD_MONOCHROME'},
- duplex: {type: 'NO_DUPLEX'},
- page_orientation: {type: 'LANDSCAPE'},
- copies: {copies: 1},
- dpi: {horizontal_dpi: dpi.horizontal_dpi, vertical_dpi: dpi.vertical_dpi},
- media_size: {
- width_microns: 210000,
- height_microns: 297000,
- vendor_id: 'iso_a4_210x297mm'
- },
- collate: {collate: false}
- }
- };
-
- fetch('test.pdf')
- .then(response => response.arrayBuffer())
- .then(arrayBuffer => {
- const request = {
- job: {
- printerId: printerId,
- title: 'test job',
- ticket: ticket,
- contentType: 'application/pdf',
- document: new Blob(
- [new Uint8Array(arrayBuffer)], {type: 'application/pdf'})
- }
- };
- chrome.printing.submitJob(request, (response) => {
- if (response !== undefined) {
- console.log(response.status);
- }
- if (chrome.runtime.lastError !== undefined) {
- console.log(chrome.runtime.lastError.message);
- }
- });
- });
-}
-
-function createPrintButton(onClicked) {
- const button = document.createElement('button');
- button.innerHTML = 'Print';
- button.onclick = onClicked;
- return button;
-}
-
-function createPrintersTable() {
- chrome.printing.getPrinters(function(printers) {
- const tbody = document.createElement('tbody');
-
- for (let i = 0; i < printers.length; ++i) {
- const printer = printers[i];
- chrome.printing.getPrinterInfo(printer.id, function(response) {
- const columnValues = [
- printer.id,
- printer.name,
- printer.description,
- printer.uri,
- printer.source,
- printer.isDefault,
- printer.recentlyUsedRank,
- JSON.stringify(response.capabilities),
- response.status,
- ];
-
- let tr = document.createElement('tr');
- for (const columnValue of columnValues) {
- const td = document.createElement('td');
- td.appendChild(document.createTextNode(columnValue));
- td.setAttribute('align', 'center');
- tr.appendChild(td);
- }
-
- const printTd = document.createElement('td');
- printTd.appendChild(createPrintButton(function() {
- onPrintButtonClicked(
- printer.id, response.capabilities.printer.dpi.option[0]);
- }));
- tr.appendChild(printTd);
-
- tbody.appendChild(tr);
- });
- }
-
- const table = document.getElementById('printersTable');
- table.appendChild(tbody);
- });
-}
-
-document.addEventListener('DOMContentLoaded', function() {
- createPrintersTable();
-});
diff --git a/chrome/common/extensions/docs/examples/api/printing/test.pdf b/chrome/common/extensions/docs/examples/api/printing/test.pdf
deleted file mode 100644
index 7bad251b..0000000
--- a/chrome/common/extensions/docs/examples/api/printing/test.pdf
+++ /dev/null
@@ -1,50 +0,0 @@
-%PDF-1.7
-% ò¤ô
-1 0 obj <<
- /Type /Catalog
- /Pages 2 0 R
->>
-endobj
-2 0 obj <<
- /Type /Pages
- /MediaBox [ 0 0 200 300 ]
- /Count 1
- /Kids [ 3 0 R ]
->>
-endobj
-3 0 obj <<
- /Type /Page
- /Parent 2 0 R
- /Contents 4 0 R
->>
-endobj
-4 0 obj <<
->>
-stream
-q
-0 0 0 rg
-0 290 10 10 re B*
-10 150 50 30 re B*
-0 0 1 rg
-190 290 10 10 re B*
-70 232 50 30 re B*
-0 1 0 rg
-190 0 10 10 re B*
-130 150 50 30 re B*
-1 0 0 rg
-0 0 10 10 re B*
-70 67 50 30 re B*
-Q
-endstream
-endobj
-xref
-0 5
-0000000000 65535 f
-0000000015 00000 n
-0000000068 00000 n
-0000000161 00000 n
-0000000230 00000 n
-trailer<< /Root 1 0 R /Size 5 >>
-startxref
-456
-%%EOF
diff --git a/chrome/common/extensions/docs/examples/api/printingMetrics/background.js b/chrome/common/extensions/docs/examples/api/printingMetrics/background.js
deleted file mode 100644
index 283a841..0000000
--- a/chrome/common/extensions/docs/examples/api/printingMetrics/background.js
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2019 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.
-
-chrome.printingMetrics.onPrintJobFinished.addListener(function(printJob) {
- chrome.storage.local.get('printJobs', function(result) {
- let printJobs = result.printJobs || 0;
- printJobs++;
- chrome.browserAction.setBadgeText({text: printJobs.toString()});
- chrome.storage.local.set({printJobs: printJobs});
- });
-});
diff --git a/chrome/common/extensions/docs/examples/api/printingMetrics/manifest.json b/chrome/common/extensions/docs/examples/api/printingMetrics/manifest.json
deleted file mode 100644
index 8890532..0000000
--- a/chrome/common/extensions/docs/examples/api/printingMetrics/manifest.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
- "name": "Print Job History",
- "version": "1.0",
- "description": "Reads your print history and displays the recent print jobs.",
- "permissions": [
- "printingMetrics",
- "storage"
- ],
- "browser_action": {
- "default_popup": "print_jobs.html",
- "default_icon": "print.png"
- },
- "background": {
- "scripts": [
- "background.js"
- ],
- "persistent": false
- },
- "manifest_version": 2
-}
diff --git a/chrome/common/extensions/docs/examples/api/printingMetrics/print.png b/chrome/common/extensions/docs/examples/api/printingMetrics/print.png
deleted file mode 100644
index 19057a5..0000000
--- a/chrome/common/extensions/docs/examples/api/printingMetrics/print.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/printingMetrics/print_jobs.css b/chrome/common/extensions/docs/examples/api/printingMetrics/print_jobs.css
deleted file mode 100644
index fb9e350..0000000
--- a/chrome/common/extensions/docs/examples/api/printingMetrics/print_jobs.css
+++ /dev/null
@@ -1,18 +0,0 @@
-/**
- * Copyright 2019 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.
- */
-
-table, th, td, tr {
- border: 1px solid black;
-}
-
-table {
- width: 100%;
- border-collapse: collapse;
-}
-
-div {
- overflow: auto;
-}
diff --git a/chrome/common/extensions/docs/examples/api/printingMetrics/print_jobs.html b/chrome/common/extensions/docs/examples/api/printingMetrics/print_jobs.html
deleted file mode 100644
index 6341d68..0000000
--- a/chrome/common/extensions/docs/examples/api/printingMetrics/print_jobs.html
+++ /dev/null
@@ -1,41 +0,0 @@
-<!--
- * Copyright 2019 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.
--->
-<!DOCTYPE HTML>
-<html>
- <head>
- <title>Recent print jobs</title>
- <link href="print_jobs.css" rel="stylesheet" type="text/css">
- <script src="print_jobs.js"></script>
- </head>
-
- <body>
- <h2>Recent print jobs:</h2>
- <div id="printJobs">
- <table id="printJobsTable">
- <thead>
- <tr>
- <th rowspan="2">Title</th>
- <th rowspan="2">Status</th>
- <th rowspan="2">Time</th>
- <th rowspan="2">Number of pages</th>
- <th colspan="3">Printer</th>
- <th colspan="5">Settings</th>
- </tr>
- <tr>
- <th>Name</th>
- <th>URI</th>
- <th>Source</th>
- <th>Color</th>
- <th>Duplex</th>
- <th>Paper width</th>
- <th>Paper height</th>
- <th>Copies</th>
- </tr>
- </thead>
- </table>
- </div>
- </body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/api/printingMetrics/print_jobs.js b/chrome/common/extensions/docs/examples/api/printingMetrics/print_jobs.js
deleted file mode 100644
index dee293a..0000000
--- a/chrome/common/extensions/docs/examples/api/printingMetrics/print_jobs.js
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2019 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.
-
-function showPrintJobTable() {
- chrome.printingMetrics.getPrintJobs(function(printJobs) {
- const tbody = document.createElement('tbody');
-
- for (let i = 0; i < printJobs.length; ++i) {
- const columnValues = [
- printJobs[i].title, printJobs[i].status,
- new Date(printJobs[i].completionTime), printJobs[i].numberOfPages,
- printJobs[i].printer.name, printJobs[i].printer.uri,
- printJobs[i].printer.source, printJobs[i].settings.color,
- printJobs[i].settings.duplex, printJobs[i].settings.mediaSize.width,
- printJobs[i].settings.mediaSize.height, printJobs[i].settings.copies
- ];
-
- let tr = document.createElement('tr');
- for (columnValue of columnValues) {
- const td = document.createElement('td');
- td.appendChild(document.createTextNode(columnValue));
- td.setAttribute('align', 'center');
- tr.appendChild(td);
- }
- tbody.appendChild(tr);
- }
-
- const table = document.getElementById('printJobsTable');
- table.appendChild(tbody);
- });
-}
-
-document.addEventListener('DOMContentLoaded', function() {
- showPrintJobTable();
-});
diff --git a/chrome/common/extensions/docs/examples/api/processes/process_monitor/icon.png b/chrome/common/extensions/docs/examples/api/processes/process_monitor/icon.png
deleted file mode 100644
index ea42f3f..0000000
--- a/chrome/common/extensions/docs/examples/api/processes/process_monitor/icon.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/processes/process_monitor/manifest.json b/chrome/common/extensions/docs/examples/api/processes/process_monitor/manifest.json
deleted file mode 100644
index 2c1836a..0000000
--- a/chrome/common/extensions/docs/examples/api/processes/process_monitor/manifest.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "name": "Process Monitor",
- "version": "1.2",
- "description": "Adds a browser action that monitors resource usage of all browser processes.",
- "permissions": [
- "processes"
- ],
- "browser_action": {
- "default_title": "Process Monitor",
- "default_icon": "icon.png",
- "default_popup": "popup.html"
- },
- "manifest_version": 2
-}
diff --git a/chrome/common/extensions/docs/examples/api/processes/process_monitor/popup.html b/chrome/common/extensions/docs/examples/api/processes/process_monitor/popup.html
deleted file mode 100644
index 27caa29..0000000
--- a/chrome/common/extensions/docs/examples/api/processes/process_monitor/popup.html
+++ /dev/null
@@ -1,33 +0,0 @@
-<html>
-<head>
-<script src="popup.js"></script>
-<style>
-body {
- overflow: hidden;
- margin: 0px;
- padding: 0px;
- background: white;
-}
-
-div:first-child {
- margin-top: 0px;
-}
-
-div, td {
- padding: 1px 3px;
- font-family: sans-serif;
- font-size: 10pt;
- margin-top: 1px;
- white-space: nowrap;
-}
-</style>
-</head>
-<body>
-<div id="title"><b>Process Monitor</b></div>
-<div id="process-list"><i>Loading...</i></div>
-<div id="buttons">
- <input type="button" value="End Process" id="killProcess" />
-</div>
-</div>
-</body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/api/processes/process_monitor/popup.js b/chrome/common/extensions/docs/examples/api/processes/process_monitor/popup.js
deleted file mode 100644
index 8e4d46b2..0000000
--- a/chrome/common/extensions/docs/examples/api/processes/process_monitor/popup.js
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright (c) 2012 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.
-
-// Shows an updating list of process statistics.
-function init() {
- chrome.processes.onUpdatedWithMemory.addListener(
- function(processes) {
- var table = "<table>\n" +
- "<tr><td><b>Process</b></td>" +
- "<td>OS ID</td>" +
- "<td>Title</td>" +
- "<td>Type</td>" +
- "<td>Tabs</td>" +
- "<td>CPU</td>" +
- "<td>Network</td>" +
- "<td>Private Memory</td>" +
- "<td>JS Memory</td>" +
- "<td></td>" +
- "</tr>\n";
- for (pid in processes) {
- table = displayProcessInfo(processes[pid], table);
- }
- table += "</table>\n";
- var div = document.getElementById("process-list");
- div.innerHTML = table;
- });
-
- document.getElementById("killProcess").onclick = function () {
- var procId = parseInt(prompt("Enter process ID"));
- chrome.processes.terminate(procId);
- }
-}
-
-function displayProcessInfo(process, table) {
- // Format network string like task manager
- var network = process.network;
- if (network > 1024) {
- network = (network / 1024).toFixed(1) + " kB/s";
- } else if (network > 0) {
- network += " B/s";
- } else if (network == -1) {
- network = "N/A";
- }
-
- table +=
- "<tr><td>" + process.id + "</td>" +
- "<td>" + process.osProcessId + "</td>" +
- "<td>" + process.title + "</td>" +
- "<td>" + process.type + "</td>" +
- "<td>" + process.tabs + "</td>" +
- "<td>" + process.cpu + "</td>" +
- "<td>" + network + "</td>";
-
- if ("privateMemory" in process) {
- table += "<td>" + (process.privateMemory / 1024) + "K</td>";
- } else {
- table += "<td>N/A</td>";
- }
- if ("jsMemoryAllocated" in process) {
- var allocated = process.jsMemoryAllocated / 1024;
- var used = process.jsMemoryUsed / 1024;
- table += "<td>" + allocated.toFixed(2) + "K (" + used.toFixed(2) +
- "K live)</td>";
- } else {
- table += "<td>N/A</td>";
- }
-
- table +=
- "<td></td>" +
- "</tr>\n";
- return table;
-}
-
-document.addEventListener('DOMContentLoaded', init);
diff --git a/chrome/common/extensions/docs/examples/api/processes/show_tabs/icon.png b/chrome/common/extensions/docs/examples/api/processes/show_tabs/icon.png
deleted file mode 100644
index ea42f3f..0000000
--- a/chrome/common/extensions/docs/examples/api/processes/show_tabs/icon.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/processes/show_tabs/manifest.json b/chrome/common/extensions/docs/examples/api/processes/show_tabs/manifest.json
deleted file mode 100644
index bdbdb1e..0000000
--- a/chrome/common/extensions/docs/examples/api/processes/show_tabs/manifest.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "name": "Show Tabs in Process",
- "version": "1.0",
- "description": "Adds a browser action showing which tabs share the current tab's process.",
- "permissions": [
- "processes", "tabs", "chrome://favicon/*"
- ],
- "browser_action": {
- "default_title": "Show Tabs in this Process",
- "default_icon": "icon.png",
- "default_popup": "popup.html"
- },
- "manifest_version": 2
-}
diff --git a/chrome/common/extensions/docs/examples/api/processes/show_tabs/popup.css b/chrome/common/extensions/docs/examples/api/processes/show_tabs/popup.css
deleted file mode 100644
index 31e15e18..0000000
--- a/chrome/common/extensions/docs/examples/api/processes/show_tabs/popup.css
+++ /dev/null
@@ -1,25 +0,0 @@
-/**
- * Copyright (c) 2011 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.
- */
-
-body {
- overflow: hidden;
- margin: 0px;
- padding: 0px;
- background: white;
- width: 400px;
-}
-
-div:first-child {
- margin-top: 0px;
-}
-
-div {
- padding: 1px 3px;
- font-family: sans-serif;
- font-size: 10pt;
- width: 400px;
- margin-top: 1px;
-}
diff --git a/chrome/common/extensions/docs/examples/api/processes/show_tabs/popup.html b/chrome/common/extensions/docs/examples/api/processes/show_tabs/popup.html
deleted file mode 100644
index d8133454..0000000
--- a/chrome/common/extensions/docs/examples/api/processes/show_tabs/popup.html
+++ /dev/null
@@ -1,12 +0,0 @@
-<!doctype html>
-<html>
- <head>
- <title>Popup</title>
- <link href="popup.css" rel="stylesheet" type="text/css">
- <script src="popup.js"></script>
- </head>
- <body>
- <div id="title"></div>
- <div id="tab-list"></div>
- </body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/api/processes/show_tabs/popup.js b/chrome/common/extensions/docs/examples/api/processes/show_tabs/popup.js
deleted file mode 100644
index 429d226..0000000
--- a/chrome/common/extensions/docs/examples/api/processes/show_tabs/popup.js
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright (c) 2011 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.
-
-// Show a list of all tabs in the same process as this one.
-function init() {
- chrome.windows.getCurrent({populate: true}, function(currentWindow) {
- chrome.tabs.query({currentWindow: true, active: true}, function(tabs) {
- var current = currentWindow.tabs.filter(function(tab) {
- return tab.active;
- })[0];
- chrome.processes.getProcessIdForTab(current.id,
- function(pid) {
- var outputDiv = document.getElementById("tab-list");
- var titleDiv = document.getElementById("title");
- titleDiv.innerHTML = "<b>Tabs in Process " + pid + ":</b>";
- displayTabInfo(currentWindow.id, current, outputDiv);
- displaySameProcessTabs(current, pid, outputDiv);
- }
- );
-
- });
- });
-}
-
-function displaySameProcessTabs(selectedTab, processId, outputDiv) {
- // Loop over all windows and their tabs
- var tabs = [];
- chrome.windows.getAll({ populate: true }, function(windowList) {
- for (var i = 0; i < windowList.length; i++) {
- for (var j = 0; j < windowList[i].tabs.length; j++) {
- var tab = windowList[i].tabs[j];
- if (tab.id != selectedTab.id) {
- tabs.push(tab);
- }
- }
- }
-
- // Display tab in list if it is in the same process
- tabs.forEach(function(tab) {
- chrome.processes.getProcessIdForTab(tab.id,
- function(pid) {
- if (pid == processId) {
- displayTabInfo(tab.windowId, tab, outputDiv);
- }
- }
- );
- });
- });
-}
-
-// Print a link to a given tab
-function displayTabInfo(windowId, tab, outputDiv) {
- if (tab.favIconUrl != undefined) {
- outputDiv.innerHTML += "<img src='chrome://favicon/" + tab.url + "'>\n";
- }
- outputDiv.innerHTML +=
- "<b><a href='#' onclick='showTab(window, " + windowId + ", " + tab.id +
- ")'>" + tab.title + "</a></b><br>\n" +
- "<i>" + tab.url + "</i><br>\n";
-}
-
-// Bring the selected tab to the front
-function showTab(origWindow, windowId, tabId) {
- // TODO: Bring the window to the front. (See http://crbug.com/31434)
- //chrome.windows.update(windowId, {focused: true});
- chrome.tabs.update(tabId, { selected: true });
- origWindow.close();
-}
-
-// Kick things off.
-document.addEventListener('DOMContentLoaded', init);
diff --git a/chrome/common/extensions/docs/examples/api/storage/stylizr/icon.png b/chrome/common/extensions/docs/examples/api/storage/stylizr/icon.png
deleted file mode 100644
index 30098be0e..0000000
--- a/chrome/common/extensions/docs/examples/api/storage/stylizr/icon.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/storage/stylizr/manifest.json b/chrome/common/extensions/docs/examples/api/storage/stylizr/manifest.json
deleted file mode 100644
index 1c0b9ce..0000000
--- a/chrome/common/extensions/docs/examples/api/storage/stylizr/manifest.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
- "name": "Stylizr",
- "description": "Spruce up your pages with custom CSS.",
- "version": "1.0",
-
- "permissions": [
- "activeTab",
- "storage"
- ],
-
- "options_page": "options.html",
-
- "browser_action": {
- "default_icon": "icon.png",
- "default_title": "Stylize!",
- "default_popup": "popup.html"
- },
-
- "manifest_version": 2
-}
diff --git a/chrome/common/extensions/docs/examples/api/storage/stylizr/options.html b/chrome/common/extensions/docs/examples/api/storage/stylizr/options.html
deleted file mode 100644
index 108e661..0000000
--- a/chrome/common/extensions/docs/examples/api/storage/stylizr/options.html
+++ /dev/null
@@ -1,42 +0,0 @@
-<!doctype html>
-<html>
- <head>
- <title>Stylizr</title>
- <style>
- body {
- font-family: sans-serif;
- }
- label {
- display: block;
- }
- textarea {
- font-family: monospace;
- }
- .message {
- height: 20px;
- background: #eee;
- padding: 5px;
- }
- </style>
- </head>
- <body>
- <div class="message"></div>
- <h3>Stylizr Instructions</h3>
-
- <ol>
- <li>Write CSS in this textarea and save</li>
- <li>Navigate to some page</li>
- <li>Click the browser action icon <img src="icon.png" /></li>
- <li>Hey presto! CSS is injected!</li>
- </ol>
-
- <textarea name="style_url" id="style_url" cols=80 rows=24
- placeholder="eg: * { font-size: 110%; }"></textarea>
-
- <br/>
- <button class="submit">Save</button>
- <button class="reset">Reset</button>
-
- <script src="options.js"></script>
- </body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/api/storage/stylizr/options.js b/chrome/common/extensions/docs/examples/api/storage/stylizr/options.js
deleted file mode 100644
index a687c5f..0000000
--- a/chrome/common/extensions/docs/examples/api/storage/stylizr/options.js
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright (c) 2012 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.
-
-// Store CSS data in the "local" storage area.
-//
-// Usually we try to store settings in the "sync" area since a lot of the time
-// it will be a better user experience for settings to automatically sync
-// between browsers.
-//
-// However, "sync" is expensive with a strict quota (both in storage space and
-// bandwidth) so data that may be as large and updated as frequently as the CSS
-// may not be suitable.
-var storage = chrome.storage.local;
-
-// Get at the DOM controls used in the sample.
-var resetButton = document.querySelector('button.reset');
-var submitButton = document.querySelector('button.submit');
-var textarea = document.querySelector('textarea');
-
-// Load any CSS that may have previously been saved.
-loadChanges();
-
-submitButton.addEventListener('click', saveChanges);
-resetButton.addEventListener('click', reset);
-
-function saveChanges() {
- // Get the current CSS snippet from the form.
- var cssCode = textarea.value;
- // Check that there's some code there.
- if (!cssCode) {
- message('Error: No CSS specified');
- return;
- }
- // Save it using the Chrome extension storage API.
- storage.set({'css': cssCode}, function() {
- // Notify that we saved.
- message('Settings saved');
- });
-}
-
-function loadChanges() {
- storage.get('css', function(items) {
- // To avoid checking items.css we could specify storage.get({css: ''}) to
- // return a default value of '' if there is no css value yet.
- if (items.css) {
- textarea.value = items.css;
- message('Loaded saved CSS.');
- }
- });
-}
-
-function reset() {
- // Remove the saved value from storage. storage.clear would achieve the same
- // thing.
- storage.remove('css', function(items) {
- message('Reset stored CSS');
- });
- // Refresh the text area.
- textarea.value = '';
-}
-
-function message(msg) {
- var message = document.querySelector('.message');
- message.innerText = msg;
- setTimeout(function() {
- message.innerText = '';
- }, 3000);
-}
diff --git a/chrome/common/extensions/docs/examples/api/storage/stylizr/popup.html b/chrome/common/extensions/docs/examples/api/storage/stylizr/popup.html
deleted file mode 100644
index 02b597d..0000000
--- a/chrome/common/extensions/docs/examples/api/storage/stylizr/popup.html
+++ /dev/null
@@ -1,16 +0,0 @@
-<!doctype html>
-<html>
- <head>
- <title>Stylizr</title>
- <style>
- body {
- font-family: sans-serif;
- width: 200px;
- }
- </style>
- </head>
- <body>
- <div id="message"></div>
- <script src="popup.js"></script>
- </body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/api/storage/stylizr/popup.js b/chrome/common/extensions/docs/examples/api/storage/stylizr/popup.js
deleted file mode 100644
index 4b44751..0000000
--- a/chrome/common/extensions/docs/examples/api/storage/stylizr/popup.js
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) 2012 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.
-
-// Store CSS data in the "local" storage area.
-//
-// See note in options.js for rationale on why not to use "sync".
-var storage = chrome.storage.local;
-
-var message = document.querySelector('#message');
-
-// Check if there is CSS specified.
-storage.get('css', function(items) {
- console.log(items);
- // If there is CSS specified, inject it into the page.
- if (items.css) {
- chrome.tabs.insertCSS({code: items.css}, function() {
- if (chrome.runtime.lastError) {
- message.innerText = 'Not allowed to inject CSS into special page.';
- } else {
- message.innerText = 'Injected style!';
- }
- });
- } else {
- var optionsUrl = chrome.extension.getURL('options.html');
- message.innerHTML = 'Set a style in the <a target="_blank" href="' +
- optionsUrl + '">options page</a> first.';
- }
-});
-
diff --git a/chrome/common/extensions/docs/examples/api/tabCapture/eventPage.js b/chrome/common/extensions/docs/examples/api/tabCapture/eventPage.js
deleted file mode 100644
index fcde1bc..0000000
--- a/chrome/common/extensions/docs/examples/api/tabCapture/eventPage.js
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright 2016 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.
-
-// The window (tab) opened and navigated to receiver.html.
-var receiver = null;
-
-// Open a new window of receiver.html when browser action icon is clicked.
-function playCapturedStream(stream) {
- if (!stream) {
- console.error('Error starting tab capture: ' +
- (chrome.runtime.lastError.message || 'UNKNOWN'));
- return;
- }
- if (receiver != null) {
- receiver.close();
- }
- receiver = window.open('receiver.html');
- receiver.currentStream = stream;
-}
-
-function testCapture() {
- console.log('Test with method capture().');
- chrome.tabCapture.capture({
- video: true, audio: true,
- videoConstraints: {
- mandatory: {
- // If minWidth/Height have the same aspect ratio (e.g., 16:9) as
- // maxWidth/Height, the implementation will letterbox/pillarbox as
- // needed. Otherwise, set minWidth/Height to 0 to allow output video
- // to be of any arbitrary size.
- minWidth: 16,
- minHeight: 9,
- maxWidth: 854,
- maxHeight: 480,
- maxFrameRate: 60, // Note: Frame rate is variable (0 <= x <= 60).
- },
- },
- },
- function(stream) {
- playCapturedStream(stream);
- });
-}
-
-function testGetMediaStreamId() {
- console.log('Test with method getMediaStreamId().');
- chrome.tabCapture.getMediaStreamId(function(streamId) {
- if (typeof streamId !== 'string') {
- console.error('Failed to get media stream id: ' +
- (chrome.runtime.lastError.message || 'UNKNOWN'));
- return;
- }
-
- navigator.webkitGetUserMedia({
- audio:false,
- video: {
- mandatory:{
- chromeMediaSource:'tab', // The media source must be 'tab' here.
- chromeMediaSourceId:streamId
- }
- }
- },
- function(stream){
- playCapturedStream(stream);
- },
- function(error){
- console.error(error);
- })
- });
-}
-
-chrome.browserAction.onClicked.addListener(function(tab) {
- // Retrieve the test option to test each method respectively.
- // The captured stream will have different resolution for each test.
- chrome.storage.local.get(['tabCaptureMethod'], function(result) {
- if (result.tabCaptureMethod == 'streamId') {
- testGetMediaStreamId();
- } else {
- testCapture();
- }
- });
-});
diff --git a/chrome/common/extensions/docs/examples/api/tabCapture/icon.png b/chrome/common/extensions/docs/examples/api/tabCapture/icon.png
deleted file mode 100644
index a49189cf..0000000
--- a/chrome/common/extensions/docs/examples/api/tabCapture/icon.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/tabCapture/manifest.json b/chrome/common/extensions/docs/examples/api/tabCapture/manifest.json
deleted file mode 100644
index 777e1e2..0000000
--- a/chrome/common/extensions/docs/examples/api/tabCapture/manifest.json
+++ /dev/null
@@ -1,22 +0,0 @@
-{
- "name": "Tab Capture Example",
- "description": "Capture a tab and play in a <video> element in a separate tab.",
- "version": "1",
- "manifest_version": 2,
- "background": {
- "scripts": ["eventPage.js"],
- "persistent": false
- },
- "browser_action": {
- "default_icon": "icon.png"
- },
- "options_ui": {
- "page": "options.html",
- "open_in_tab": false
- },
- "permissions": [
- "storage",
- "tabs",
- "tabCapture"
- ]
-}
diff --git a/chrome/common/extensions/docs/examples/api/tabCapture/options.html b/chrome/common/extensions/docs/examples/api/tabCapture/options.html
deleted file mode 100644
index f385c6d..0000000
--- a/chrome/common/extensions/docs/examples/api/tabCapture/options.html
+++ /dev/null
@@ -1,19 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head><title>tabCapture Sample Options</title></head>
-<body>
-
-Test tabCapture method:
-<form name="methodForm">
- <input type="radio" name="method" id="capture"
- value="capture" style="margin-top: 5px"> capture()<br>
- <input type="radio" name="method" id="streamId"
- value="streamId" style="margin-top: 5px"> getMediaSteamId()<br>
-</form>
-
-<button id="save" style="margin-top: 10px">Save</button>
-<div id="status" style="margin-top: 5px"></div>
-
-<script src="options.js"></script>
-</body>
-</html>
\ No newline at end of file
diff --git a/chrome/common/extensions/docs/examples/api/tabCapture/options.js b/chrome/common/extensions/docs/examples/api/tabCapture/options.js
deleted file mode 100644
index 575cbbac..0000000
--- a/chrome/common/extensions/docs/examples/api/tabCapture/options.js
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2018 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.
-
-// Restore the option last saved.
-window.onload = function() {
- chrome.storage.local.get(['tabCaptureMethod'], function(result) {
- if (result.tabCaptureMethod == 'streamId') {
- document.getElementById('streamId').checked = true;
- } else {
- document.getElementById('capture').checked = true;
- }
- });
-}
-
-// Save option locally.
-function saveOption(){
- var value = document.querySelector('input[name="method"]:checked').value;
- chrome.storage.local.set({'tabCaptureMethod': value}, function() {
- var status = document.getElementById('status');
- status.textContent = "Option saved.";
- setTimeout(function() {status.textContent = '';}, 750);
- });
-}
-
-document.getElementById('save').addEventListener('click', saveOption);
\ No newline at end of file
diff --git a/chrome/common/extensions/docs/examples/api/tabCapture/receiver.html b/chrome/common/extensions/docs/examples/api/tabCapture/receiver.html
deleted file mode 100644
index 214e823..0000000
--- a/chrome/common/extensions/docs/examples/api/tabCapture/receiver.html
+++ /dev/null
@@ -1,26 +0,0 @@
-<html>
- <head>
- <style>
- body {
- align-items: center;
- background-color: #224;
- display: flex;
- justify-content: center;
- margin: none;
- padding: none;
- }
-
- body.shutdown {
- background-color: #422;
- }
-
- body.shutdown #player {
- display: none;
- }
- </style>
- </head>
- <body>
- <video id="player"></video>
- <script src="receiver.js"></script>
- </body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/api/tabCapture/receiver.js b/chrome/common/extensions/docs/examples/api/tabCapture/receiver.js
deleted file mode 100644
index 3ea7b40..0000000
--- a/chrome/common/extensions/docs/examples/api/tabCapture/receiver.js
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2016 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.
-
-// Note: |window.currentStream| was set in background.js.
-
-// Stop video play-out, stop the MediaStreamTracks, and set style class to
-// "shutdown".
-function shutdownReceiver() {
- if (!window.currentStream) {
- return;
- }
-
- var player = document.getElementById('player');
- player.srcObject = null;
- var tracks = window.currentStream.getTracks();
- for (var i = 0; i < tracks.length; ++i) {
- tracks[i].stop();
- }
- window.currentStream = null;
-
- document.body.className = 'shutdown';
-}
-
-window.addEventListener('load', function() {
- // Start video play-out of the captured audio/video MediaStream once the page
- // has loaded.
- var player = document.getElementById('player');
- player.addEventListener('canplay', function() {
- this.volume = 0.75;
- this.muted = false;
- this.play();
- });
- player.setAttribute('controls', '1');
- player.srcObject = window.currentStream;
-
- // Add onended event listeners. This detects when tab capture was shut down by
- // closing the tab being captured.
- var tracks = window.currentStream.getTracks();
- for (var i = 0; i < tracks.length; ++i) {
- tracks[i].addEventListener('ended', function() {
- console.log('MediaStreamTrack[' + i + '] ended, shutting down...');
- shutdownReceiver();
- });
- }
-});
-
-// Shutdown when the receiver page is closed.
-window.addEventListener('beforeunload', shutdownReceiver);
diff --git a/chrome/common/extensions/docs/examples/api/tabs/inspector/background.js b/chrome/common/extensions/docs/examples/api/tabs/inspector/background.js
deleted file mode 100644
index a58a0036..0000000
--- a/chrome/common/extensions/docs/examples/api/tabs/inspector/background.js
+++ /dev/null
@@ -1,7 +0,0 @@
-// Copyright (c) 2012 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.
-
-chrome.browserAction.onClicked.addListener(function(tab) {
- chrome.tabs.create({url:chrome.extension.getURL("tabs_api.html")});
-});
diff --git a/chrome/common/extensions/docs/examples/api/tabs/inspector/jstemplate_compiled.js b/chrome/common/extensions/docs/examples/api/tabs/inspector/jstemplate_compiled.js
deleted file mode 100644
index 2f62b316..0000000
--- a/chrome/common/extensions/docs/examples/api/tabs/inspector/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/common/extensions/docs/examples/api/tabs/inspector/manifest.json b/chrome/common/extensions/docs/examples/api/tabs/inspector/manifest.json
deleted file mode 100644
index 68b7728e..0000000
--- a/chrome/common/extensions/docs/examples/api/tabs/inspector/manifest.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "name": "Tab Inspector",
- "description": "Utility for working with the extension tabs api",
- "version": "0.3",
- "permissions": ["tabs"],
- "background": {
- "persistent": false,
- "scripts": ["background.js"]
- },
- "browser_action": {
- "default_title": "show tab inspector"
- },
- "manifest_version": 2
-}
diff --git a/chrome/common/extensions/docs/examples/api/tabs/inspector/tabs_api.html b/chrome/common/extensions/docs/examples/api/tabs/inspector/tabs_api.html
deleted file mode 100644
index d58f8d8..0000000
--- a/chrome/common/extensions/docs/examples/api/tabs/inspector/tabs_api.html
+++ /dev/null
@@ -1,105 +0,0 @@
-<html>
-<head>
-<script src="jstemplate_compiled.js" type="text/javascript"></script>
-<script src="tabs_api.js"></script>
-</head>
- <body>
- <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/common/extensions/docs/examples/api/tabs/inspector/tabs_api.js b/chrome/common/extensions/docs/examples/api/tabs/inspector/tabs_api.js
deleted file mode 100644
index a14e260a..0000000
--- a/chrome/common/extensions/docs/examples/api/tabs/inspector/tabs_api.js
+++ /dev/null
@@ -1,305 +0,0 @@
-// Copyright (c) 2012 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.
-
-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) {
- document.getElementById('log')
- .appendChild(document.createElement('div'))
- .innerText = "> " + logLine;
-}
-
-function clearLog() {
- document.getElementById('log').innerText = '';
-}
-
-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.query({active: true, currentWindow: true} function(tabs) {
- var input = new JsExprContext(tabs[0]);
- var output = document.getElementById('tab_' + tabs[0].id);
- jstProcess(input, output);
- appendToLog(
- 'selected tab refreshed -- tabId: ' + tabs[0].id +
- ' url:' + tabs[0].url);
- });
-}
-
-document.addEventListener('DOMContentLoaded', function() {
- bootStrap();
-});
\ No newline at end of file
diff --git a/chrome/common/extensions/docs/examples/api/tabs/pin/README b/chrome/common/extensions/docs/examples/api/tabs/pin/README
deleted file mode 100644
index d9d5c65..0000000
--- a/chrome/common/extensions/docs/examples/api/tabs/pin/README
+++ /dev/null
@@ -1,2 +0,0 @@
-Demo Chrome Extension that uses the Tab Pinning API. Enables a new keyboard
-shortcut (Ctrl + Shift + P) to toggle pinning and unpinning of the current tab.
diff --git a/chrome/common/extensions/docs/examples/api/tabs/pin/background.js b/chrome/common/extensions/docs/examples/api/tabs/pin/background.js
deleted file mode 100644
index 13d87cf7..0000000
--- a/chrome/common/extensions/docs/examples/api/tabs/pin/background.js
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright (c) 2012 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.
-
-chrome.commands.onCommand.addListener(function(command) {
- if (command == "toggle-pin") {
- // Get the currently selected tab
- chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
- // Toggle the pinned status
- var current = tabs[0]
- chrome.tabs.update(current.id, {'pinned': !current.pinned});
- });
- }
-});
diff --git a/chrome/common/extensions/docs/examples/api/tabs/pin/manifest.json b/chrome/common/extensions/docs/examples/api/tabs/pin/manifest.json
deleted file mode 100644
index 3154c8c..0000000
--- a/chrome/common/extensions/docs/examples/api/tabs/pin/manifest.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
- "name": "Keyboard Pin",
- "version": "0.3",
- "description": "Creates a keyboard shortcut (Alt + Shift + P) to toggle the pinned state of the currently selected tab",
- "background": {
- "persistent": false,
- "scripts": ["background.js"]
- },
- "commands": {
- "toggle-pin": {
- "suggested_key": { "default": "Alt+Shift+P" },
- "description": "Toggle tab pin"
- }
- },
- "manifest_version": 2
-}
diff --git a/chrome/common/extensions/docs/examples/api/tabs/screenshot/background.js b/chrome/common/extensions/docs/examples/api/tabs/screenshot/background.js
deleted file mode 100644
index 7f9b7bce..0000000
--- a/chrome/common/extensions/docs/examples/api/tabs/screenshot/background.js
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright (c) 2012 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.
-
-// To make sure we can uniquely identify each screenshot tab, add an id as a
-// query param to the url that displays the screenshot.
-// Note: It's OK that this is a global variable (and not in localStorage),
-// because the event page will stay open as long as any screenshot tabs are
-// open.
-var id = 100;
-
-// Listen for a click on the camera icon. On that click, take a screenshot.
-chrome.browserAction.onClicked.addListener(function() {
-
- chrome.tabs.captureVisibleTab(function(screenshotUrl) {
- var viewTabUrl = chrome.extension.getURL('screenshot.html?id=' + id++)
- var targetId = null;
-
- chrome.tabs.onUpdated.addListener(function listener(tabId, changedProps) {
- // We are waiting for the tab we opened to finish loading.
- // Check that 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 getting called when onUpdated events fire.
- chrome.tabs.onUpdated.removeListener(listener);
-
- // Look through all views to find the window which will display
- // the screenshot. The url of the tab which will display the
- // screenshot includes a query parameter with a unique id, which
- // ensures that exactly one view will have the matching URL.
- var views = chrome.extension.getViews();
- for (var i = 0; i < views.length; i++) {
- var view = views[i];
- if (view.location.href == viewTabUrl) {
- view.setScreenshotUrl(screenshotUrl);
- break;
- }
- }
- });
-
- chrome.tabs.create({url: viewTabUrl}, function(tab) {
- targetId = tab.id;
- });
- });
-});
diff --git a/chrome/common/extensions/docs/examples/api/tabs/screenshot/camera.png b/chrome/common/extensions/docs/examples/api/tabs/screenshot/camera.png
deleted file mode 100644
index 37c5c04..0000000
--- a/chrome/common/extensions/docs/examples/api/tabs/screenshot/camera.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/tabs/screenshot/manifest.json b/chrome/common/extensions/docs/examples/api/tabs/screenshot/manifest.json
deleted file mode 100644
index 2fae69d..0000000
--- a/chrome/common/extensions/docs/examples/api/tabs/screenshot/manifest.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- "name": "Test Screenshot Extension",
- "version": "1.3",
- "description": "Demonstrate screenshot functionality in the chrome.tabs api.",
- "background": {
- "persistent": false,
- "scripts": ["background.js"]
- },
- "browser_action": {
- "default_icon": "camera.png",
- "default_title": "Take a screen shot!"
- },
- "permissions": [
- "activeTab"
- ],
- "manifest_version": 2
-}
diff --git a/chrome/common/extensions/docs/examples/api/tabs/screenshot/screenshot.html b/chrome/common/extensions/docs/examples/api/tabs/screenshot/screenshot.html
deleted file mode 100644
index 46d7e4d4..0000000
--- a/chrome/common/extensions/docs/examples/api/tabs/screenshot/screenshot.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<html>
-<script src="screenshot.js"></script>
-<body>
- Image here:
- <p>
- <img id="target" src="white.png" height="480">
- <p>
- End image
- </body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/api/tabs/screenshot/screenshot.js b/chrome/common/extensions/docs/examples/api/tabs/screenshot/screenshot.js
deleted file mode 100644
index cf83d334..0000000
--- a/chrome/common/extensions/docs/examples/api/tabs/screenshot/screenshot.js
+++ /dev/null
@@ -1,7 +0,0 @@
-// Copyright (c) 2011 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.
-
-function setScreenshotUrl(url) {
- document.getElementById('target').src = url;
-}
diff --git a/chrome/common/extensions/docs/examples/api/tabs/screenshot/white.png b/chrome/common/extensions/docs/examples/api/tabs/screenshot/white.png
deleted file mode 100644
index 52b9a9f..0000000
--- a/chrome/common/extensions/docs/examples/api/tabs/screenshot/white.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/tabs/zoom/README b/chrome/common/extensions/docs/examples/api/tabs/zoom/README
deleted file mode 100644
index caa44686..0000000
--- a/chrome/common/extensions/docs/examples/api/tabs/zoom/README
+++ /dev/null
@@ -1,2 +0,0 @@
-Demo Chrome Extension that uses the Tab Zoom API. Demonstrates manipulation of
-tab zoom levels and zoom modes and use of zoom-change event listeners.
diff --git a/chrome/common/extensions/docs/examples/api/tabs/zoom/background.js b/chrome/common/extensions/docs/examples/api/tabs/zoom/background.js
deleted file mode 100644
index d2c5234..0000000
--- a/chrome/common/extensions/docs/examples/api/tabs/zoom/background.js
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2014 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.
-
-/**
- * @fileoverview In this extension, the background page demonstrates how to
- * listen for zoom change events.
-*/
-
-function zoomChangeListener(zoomChangeInfo) {
- var settings_str = "mode:" + zoomChangeInfo.zoomSettings.mode +
- ", scope:" + zoomChangeInfo.zoomSettings.scope;
-
- console.log('[ZoomDemoExtension] zoomChangeListener(tab=' +
- zoomChangeInfo.tabId + ', new=' +
- zoomChangeInfo.newZoomFactor + ', old=' +
- zoomChangeInfo.oldZoomFactor + ', ' +
- settings_str + ')');
-}
-
-chrome.tabs.onZoomChange.addListener(zoomChangeListener);
diff --git a/chrome/common/extensions/docs/examples/api/tabs/zoom/manifest.json b/chrome/common/extensions/docs/examples/api/tabs/zoom/manifest.json
deleted file mode 100644
index 51db85b..0000000
--- a/chrome/common/extensions/docs/examples/api/tabs/zoom/manifest.json
+++ /dev/null
@@ -1,24 +0,0 @@
-{
- "manifest_version": 2,
-
- "name": "Tabs Zoom API Demo",
- "description": "This extension allows the user to explore features of the new tabs zoom api.",
-
- "version": "0.1",
-
- "icons": {
- "16": "zoom16.png",
- "48": "zoom48.png"
- },
-
- "background": {
- "scripts": ["background.js"],
- "persistent": false
- },
-
- "browser_action": {
- "default_icon": "zoom19.png",
- "default_title": "Zoom Extension Demo",
- "default_popup": "popup.html"
- }
-}
diff --git a/chrome/common/extensions/docs/examples/api/tabs/zoom/popup.html b/chrome/common/extensions/docs/examples/api/tabs/zoom/popup.html
deleted file mode 100644
index 8b7f276..0000000
--- a/chrome/common/extensions/docs/examples/api/tabs/zoom/popup.html
+++ /dev/null
@@ -1,55 +0,0 @@
-<!doctype html>
-<html>
- <head>
- <title>Tab Zoom Extension</title>
- <style>
- body {
- width: 150px;
- overflow-x: hidden;
- color: #ffff00;
- background-color: #186464;
- }
-
- img {
- margin: 5px;
- border: 2px solid black;
- vertical-align: middle;
- width: 19px;
- height: 19px;
- }
- </style>
- <script src="popup.js"></script>
- </head>
- <body>
- <div style="text-align: center">
- <table style="margin: 0px auto">
- <tr>
- <td><button type="button" id="decreaseButton">-</button></td>
- <td><div style="width: 50px; border-style: solid; border-width: 1px"
- id="displayDiv">100%</div></td>
- <td><button type="button" id="increaseButton">+</button></td>
- </td>
- </table>
- <button type="button" id="defaultButton">Reset to Default</button>
- <div id="defaultLabel"></div>
- </div>
- <p>
- <div style="border-width: 2px; border-style: solid; border-color: #7f0000; padding: 2px">
- <form style="border-width: 2px; border-style: solid; border-color: #7f0000">
- <b>Mode:</b><br>
- <input type="radio" name="modeRadio" value="automatic">automatic<br>
- <input type="radio" name="modeRadio" value="manual">manual<br>
- <input type="radio" name="modeRadio" value="disabled">disabled
- </form><br>
- <form style="border-width: 2px; border-style: solid; border-color: #7f0000">
- <b>Scope:</b><br>
- <input type="radio" name="scopeRadio" value="per-origin">per-origin<br>
- <input type="radio" name="scopeRadio" value="per-tab">per-tab
- </form>
- <button type="button" id="setModeButton">Set Zoom Settings</button>
- </div>
- <p>
- <button type="button" id="closeButton">Close</button>
- </body>
-</html>
-
diff --git a/chrome/common/extensions/docs/examples/api/tabs/zoom/popup.js b/chrome/common/extensions/docs/examples/api/tabs/zoom/popup.js
deleted file mode 100644
index c680d5d..0000000
--- a/chrome/common/extensions/docs/examples/api/tabs/zoom/popup.js
+++ /dev/null
@@ -1,141 +0,0 @@
-// Copyright 2014 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.
-
-/**
- * @fileoverview This code supports the popup behaviour of the extension, and
- * demonstrates how to:
- *
- * 1) Set the zoom for a tab using tabs.setZoom()
- * 2) Read the current zoom of a tab using tabs.getZoom()
- * 3) Set the zoom mode of a tab using tabs.setZoomSettings()
- * 4) Read the current zoom mode of a tab using
- * tabs.getZoomSettings()
- *
- * It also demonstrates using a zoom change listener to update the
- * contents of a control.
- */
-
-zoomStep = 1.1;
-tabId = -1;
-
-function displayZoomLevel(level) {
- var percentZoom = parseFloat(level) * 100;
- var zoom_percent_str = percentZoom.toFixed(1) + '%';
-
- document.getElementById('displayDiv').textContent = zoom_percent_str;
-}
-
-document.addEventListener('DOMContentLoaded', function() {
- // Find the tabId of the current (active) tab. We could just omit the tabId
- // parameter in the function calls below, and they would act on the current
- // tab by default, but for the purposes of this demo we will always use the
- // API with an explicit tabId to demonstrate its use.
- chrome.tabs.query({active: true}, function (tabs) {
- if (tabs.length > 1)
- console.log(
- '[ZoomDemoExtension] Query unexpectedly returned more than 1 tab.');
- tabId = tabs[0].id;
-
- chrome.tabs.getZoomSettings(tabId, function(zoomSettings) {
- var modeRadios = document.getElementsByName('modeRadio');
- for (var i = 0; i < modeRadios.length; i++) {
- if (modeRadios[i].value == zoomSettings.mode)
- modeRadios[i].checked = true;
- }
-
- var scopeRadios = document.getElementsByName('scopeRadio');
- for (var i = 0; i < scopeRadios.length; i++) {
- if (scopeRadios[i].value == zoomSettings.scope)
- scopeRadios[i].checked = true;
- }
-
- var percentDefaultZoom =
- parseFloat(zoomSettings.defaultZoomFactor) * 100;
- document.getElementById('defaultLabel').textContent =
- 'Default: ' + percentDefaultZoom.toFixed(1) + '%';
- });
-
- chrome.tabs.getZoom(tabId, displayZoomLevel);
- });
-
- document.getElementById('increaseButton').onclick = doZoomIn;
- document.getElementById('decreaseButton').onclick = doZoomOut;
- document.getElementById('defaultButton').onclick = doZoomDefault;
- document.getElementById('setModeButton').onclick = doSetMode;
- document.getElementById('closeButton').onclick = doClose;
-});
-
-function zoomChangeListener(zoomChangeInfo) {
- displayZoomLevel(zoomChangeInfo.newZoomFactor);
-}
-
-chrome.tabs.onZoomChange.addListener(zoomChangeListener);
-
-function changeZoomByFactorDelta(factorDelta) {
- if (tabId == -1)
- return;
-
- chrome.tabs.getZoom(tabId, function(zoomFactor) {
- var newZoomFactor = factorDelta * zoomFactor;
- chrome.tabs.setZoom(tabId, newZoomFactor, function() {
- if (chrome.runtime.lastError)
- console.log('[ZoomDemoExtension] ' + chrome.runtime.lastError.message);
- });
- });
-}
-
-function doZoomIn() {
- changeZoomByFactorDelta(zoomStep);
-}
-
-function doZoomOut() {
- changeZoomByFactorDelta(1.0/zoomStep);
-}
-
-function doZoomDefault() {
- if (tabId == -1)
- return;
-
- chrome.tabs.setZoom(tabId, 0, function() {
- if (chrome.runtime.lastError)
- console.log('[ZoomDemoExtension] ' + chrome.runtime.lastError.message);
- });
-}
-
-function doSetMode() {
- if (tabId == -1)
- return;
-
- var modeVal;
- var modeRadios = document.getElementsByName('modeRadio');
- for (var i = 0; i < modeRadios.length; i++) {
- if (modeRadios[i].checked)
- modeVal = modeRadios[i].value;
- }
-
- var scopeVal;
- var scopeRadios = document.getElementsByName('scopeRadio');
- for (var i = 0; i < scopeRadios.length; i++) {
- if (scopeRadios[i].checked)
- scopeVal = scopeRadios[i].value;
- }
-
- if (!modeVal || !scopeVal) {
- console.log(
- '[ZoomDemoExtension] Must specify values for both mode & scope.');
- return;
- }
-
- chrome.tabs.setZoomSettings(tabId, { mode: modeVal, scope: scopeVal },
- function() {
- if (chrome.runtime.lastError) {
- console.log('[ZoomDemoExtension] doSetMode() error: ' +
- chrome.runtime.lastError.message);
- }
- });
-}
-
-function doClose() {
- self.close();
-}
diff --git a/chrome/common/extensions/docs/examples/api/tabs/zoom/zoom16.png b/chrome/common/extensions/docs/examples/api/tabs/zoom/zoom16.png
deleted file mode 100644
index d1bdbdd..0000000
--- a/chrome/common/extensions/docs/examples/api/tabs/zoom/zoom16.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/tabs/zoom/zoom19.png b/chrome/common/extensions/docs/examples/api/tabs/zoom/zoom19.png
deleted file mode 100644
index 9f22ce22..0000000
--- a/chrome/common/extensions/docs/examples/api/tabs/zoom/zoom19.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/tabs/zoom/zoom48.png b/chrome/common/extensions/docs/examples/api/tabs/zoom/zoom48.png
deleted file mode 100644
index 8a4663a9..0000000
--- a/chrome/common/extensions/docs/examples/api/tabs/zoom/zoom48.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/topsites/basic/icon.png b/chrome/common/extensions/docs/examples/api/topsites/basic/icon.png
deleted file mode 100644
index ea42f3f..0000000
--- a/chrome/common/extensions/docs/examples/api/topsites/basic/icon.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/topsites/basic/manifest.json b/chrome/common/extensions/docs/examples/api/topsites/basic/manifest.json
deleted file mode 100644
index c042c09..0000000
--- a/chrome/common/extensions/docs/examples/api/topsites/basic/manifest.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "name": "Top Sites",
- "version": "1.2",
- "description": "Shows the top sites in a browser action",
- "permissions": ["topSites"],
- "browser_action": {
- "default_icon": "icon.png",
- "default_popup": "popup.html"
- },
- "manifest_version": 2
-}
diff --git a/chrome/common/extensions/docs/examples/api/topsites/basic/popup.html b/chrome/common/extensions/docs/examples/api/topsites/basic/popup.html
deleted file mode 100644
index 12473076..0000000
--- a/chrome/common/extensions/docs/examples/api/topsites/basic/popup.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<!DOCTYPE HTML>
-<html>
- <body>
- <h2>Most Visited:</h2>
- <div id='mostVisited_div'></div>
- <script src='popup.js'></script>
- </body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/api/topsites/basic/popup.js b/chrome/common/extensions/docs/examples/api/topsites/basic/popup.js
deleted file mode 100644
index 5f6761dc..0000000
--- a/chrome/common/extensions/docs/examples/api/topsites/basic/popup.js
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2013 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.
-
-// Event listener for clicks on links in a browser action popup.
-// Open the link in a new tab of the current window.
-function onAnchorClick(event) {
- chrome.tabs.create({ url: event.srcElement.href });
- return false;
-}
-
-// Given an array of URLs, build a DOM list of these URLs in the
-// browser action popup.
-function buildPopupDom(mostVisitedURLs) {
- var popupDiv = document.getElementById('mostVisited_div');
- var ol = popupDiv.appendChild(document.createElement('ol'));
-
- for (var i = 0; i < mostVisitedURLs.length; i++) {
- var li = ol.appendChild(document.createElement('li'));
- var a = li.appendChild(document.createElement('a'));
- a.href = mostVisitedURLs[i].url;
- a.appendChild(document.createTextNode(mostVisitedURLs[i].title));
- a.addEventListener('click', onAnchorClick);
- }
-}
-
-chrome.topSites.get(buildPopupDom);
diff --git a/chrome/common/extensions/docs/examples/api/topsites/magic8ball/manifest.json b/chrome/common/extensions/docs/examples/api/topsites/magic8ball/manifest.json
deleted file mode 100644
index 84f12ac..0000000
--- a/chrome/common/extensions/docs/examples/api/topsites/magic8ball/manifest.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "name": "NTP prototyping extension",
- "version": "1.1",
- "description": "extension to prototype new NTP designs",
- "chrome_url_overrides" : {
- "newtab": "newTab.html"
- },
- "permissions": [
- "topSites",
- "chrome://favicon/"
- ],
- "manifest_version": 2
-}
diff --git a/chrome/common/extensions/docs/examples/api/topsites/magic8ball/newTab.css b/chrome/common/extensions/docs/examples/api/topsites/magic8ball/newTab.css
deleted file mode 100644
index 6c070fb8..0000000
--- a/chrome/common/extensions/docs/examples/api/topsites/magic8ball/newTab.css
+++ /dev/null
@@ -1,28 +0,0 @@
-/* Copyright (c) 2012 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 {
- background-color: #ddd;
-}
-
-#spacer {
- height: 200px;
-}
-
-#title {
- color: #555;
- font-weight: bold;
- height: 200px;
- vertical-align: middle;
-}
-
-#mostVisitedThumb {
- background-repeat: no-repeat;
- height: 200px;
- margin-left: 20px;
- padding-left: 20px;
- vertical-align: middle;
- width: 212px;
-}
diff --git a/chrome/common/extensions/docs/examples/api/topsites/magic8ball/newTab.html b/chrome/common/extensions/docs/examples/api/topsites/magic8ball/newTab.html
deleted file mode 100644
index 4539728a..0000000
--- a/chrome/common/extensions/docs/examples/api/topsites/magic8ball/newTab.html
+++ /dev/null
@@ -1,25 +0,0 @@
-<!DOCTYPE html>
-<!--
- * Copyright (c) 2010 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>
-<meta charset="utf-8">
-<script src="newTab.js"></script>
-<link rel="stylesheet" href="newTab.css">
-
-<title>New 8ball</title>
-
-<body>
- <center>
- <div id="spacer"></div>
- <span id='title'>Magic 8 ball says to visit</span>
- <a id='mostVisitedThumb'>
- <span></span>
- </a>
- </center>
-</body>
-
-</html>
diff --git a/chrome/common/extensions/docs/examples/api/topsites/magic8ball/newTab.js b/chrome/common/extensions/docs/examples/api/topsites/magic8ball/newTab.js
deleted file mode 100644
index 69ffad6..0000000
--- a/chrome/common/extensions/docs/examples/api/topsites/magic8ball/newTab.js
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright (c) 2012 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.
-
-function $(id) {
- return document.getElementById(id);
-}
-
-function thumbnailsGotten(data) {
- var eightBallWindow = $('mostVisitedThumb');
- var rand = Math.floor(Math.random() * data.length);
- eightBallWindow.href = data[rand].url;
- eightBallWindow.textContent = data[rand].title;
- eightBallWindow.style.backgroundImage = 'url(chrome://favicon/' +
- data[rand].url + ')';
-}
-
-window.onload = function() {
- chrome.topSites.get(thumbnailsGotten);
-}
diff --git a/chrome/common/extensions/docs/examples/api/ttsEngine/console_tts_engine/console_tts_engine.html b/chrome/common/extensions/docs/examples/api/ttsEngine/console_tts_engine/console_tts_engine.html
deleted file mode 100644
index f142127..0000000
--- a/chrome/common/extensions/docs/examples/api/ttsEngine/console_tts_engine/console_tts_engine.html
+++ /dev/null
@@ -1,47 +0,0 @@
-<html>
-<head>
- <title>Console TTS Engine</title>
- <style>
- body {
- font-family: arial, helvetica, sans-serif;
- }
- table {
- text-align: center;
- padding: 10px;
- }
- #text {
- text-align: left;
- padding: 4px;
- border: 1px solid #aaa;
- width: 99%;
- min-height: 100px;
- overflow: auto;
- }
- </style>
- <script type="text/javascript">
- function clearText() {
- document.getElementById("text").innerHTML = "";
- }
- </script>
-</head>
-<body>
- <table>
- <tr>
- <th>Voice Name</th>
- <th>Language</th>
- <th>Rate</th>
- <th>Pitch</th>
- <th>Volume</th>
- </tr>
- <tr>
- <td id="voiceName"></td>
- <td id="lang"></td>
- <td id="rate"></td>
- <td id="pitch"></td>
- <td id="volume"></td>
- </tr>
- </table>
- <button onclick="clearText()">Clear</button>
- <p id="text"></p>
-</body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/api/ttsEngine/console_tts_engine/console_tts_engine.js b/chrome/common/extensions/docs/examples/api/ttsEngine/console_tts_engine/console_tts_engine.js
deleted file mode 100644
index 0d607e43..0000000
--- a/chrome/common/extensions/docs/examples/api/ttsEngine/console_tts_engine/console_tts_engine.js
+++ /dev/null
@@ -1,114 +0,0 @@
-// Copyright (c) 2012 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.
-
-var timeoutId;
-var ttsId = -1;
-var ttsWindow;
-var milliseconds;
-var curOptions;
-
-function areNewOptions(options) {
- var properties = ['voiceName', 'lang', 'rate', 'pitch', 'volume'];
-
- for (var i = 0; i < properties.length; ++i) {
- if (options[properties[i]] != curOptions[properties[i]]) {
- return true;
- }
- }
-
- return false;
-}
-
-function getTtsElement(element) {
- return ttsWindow.document.getElementById(element);
-}
-
-function appendText(text) {
- getTtsElement("text").innerHTML += text;
-}
-
-function logOptions() {
- getTtsElement("voiceName").innerHTML = curOptions.voiceName;
- getTtsElement("lang").innerHTML = curOptions.lang;
- getTtsElement("rate").innerHTML = curOptions.rate;
- getTtsElement("pitch").innerHTML = curOptions.pitch;
- getTtsElement("volume").innerHTML = curOptions.volume;
-}
-
-function logUtterance(utterance, index, sendTtsEvent) {
- if (index == utterance.length) {
- sendTtsEvent({'type': 'end', 'charIndex': utterance.length});
- return;
- }
-
- appendText(utterance[index]);
-
- if (utterance[index] == ' ') {
- sendTtsEvent({'type': 'word', 'charIndex': index});
- }
- else if (utterance[index] == '.' ||
- utterance[index] == '?' ||
- utterance[index] == '!') {
- sendTtsEvent({'type': 'sentence', 'charIndex': index});
- }
-
- timeoutId = setTimeout(function() {
- logUtterance(utterance, ++index, sendTtsEvent)
- }, milliseconds);
-}
-
-var speakListener = function(utterance, options, sendTtsEvent) {
- clearTimeout(timeoutId);
-
- sendTtsEvent({'type': 'start', 'charIndex': 0});
-
- if (ttsId == -1) {
- // Create a new window that overlaps the bottom 40% of the current window
- chrome.windows.getCurrent(function(curWindow) {
- chrome.windows.create(
- {"url": "console_tts_engine.html",
- "focused": false,
- "top": Math.round(curWindow.top + 6/10 * curWindow.height),
- "left": curWindow.left,
- "width": curWindow.width,
- "height": Math.round(4/10 * curWindow.height)},
- function(newWindow) {
- ttsId = newWindow.id;
- ttsWindow = chrome.extension.getViews({"windowId": ttsId})[0];
-
- curOptions = options;
- logOptions();
-
- // Fastest timeout == 1 ms (@ options.rate = 10.0)
- milliseconds = 10 / curOptions.rate;
- logUtterance(utterance, 0, sendTtsEvent);
- }
- );
- });
- } else {
- if (areNewOptions(options)) {
- curOptions = options;
- logOptions();
-
- milliseconds = 10 / curOptions.rate;
- }
-
- logUtterance(utterance, 0, sendTtsEvent);
- }
-
-};
-
-var stopListener = function() {
- clearTimeout(timeoutId);
-};
-
-var removedListener = function(windowId, removeInfo) {
- if (ttsId == windowId) {
- ttsId = -1;
- }
-}
-
-chrome.ttsEngine.onSpeak.addListener(speakListener);
-chrome.ttsEngine.onStop.addListener(stopListener);
-chrome.windows.onRemoved.addListener(removedListener);
diff --git a/chrome/common/extensions/docs/examples/api/ttsEngine/console_tts_engine/manifest.json b/chrome/common/extensions/docs/examples/api/ttsEngine/console_tts_engine/manifest.json
deleted file mode 100644
index 35be832..0000000
--- a/chrome/common/extensions/docs/examples/api/ttsEngine/console_tts_engine/manifest.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- "name": "Console TTS Engine",
- "manifest_version": 2,
- "version": "2.1",
- "description": "A \"silent\" TTS engine that prints text to a small window rather than synthesizing speech.",
- "permissions": ["ttsEngine", "tabs"],
- "background": {
- "persistent": false,
- "scripts": ["console_tts_engine.js"]
- },
- "tts_engine": {
- "voices": [
- {
- "voice_name": "Console",
- "event_types": ["start", "word", "sentence", "end"]
- }
- ]
- }
-}
diff --git a/chrome/common/extensions/docs/examples/api/water_alarm_notification/background.js b/chrome/common/extensions/docs/examples/api/water_alarm_notification/background.js
deleted file mode 100644
index f3fb248..0000000
--- a/chrome/common/extensions/docs/examples/api/water_alarm_notification/background.js
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2017 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.
-'use strict';
-
-chrome.alarms.onAlarm.addListener(function() {
- chrome.browserAction.setBadgeText({text: ''});
- chrome.notifications.create({
- type: 'basic',
- iconUrl: 'stay_hydrated.png',
- title: 'Time to Hydrate',
- message: 'Everyday I\'m Guzzlin\'!',
- buttons: [
- {title: 'Keep it Flowing.'}
- ],
- priority: 0});
-});
-
-chrome.notifications.onButtonClicked.addListener(function() {
- chrome.storage.sync.get(['minutes'], function(item) {
- chrome.browserAction.setBadgeText({text: 'ON'});
- chrome.alarms.create({delayInMinutes: item.minutes});
- });
-});
diff --git a/chrome/common/extensions/docs/examples/api/water_alarm_notification/drink_water128.png b/chrome/common/extensions/docs/examples/api/water_alarm_notification/drink_water128.png
deleted file mode 100644
index e669740..0000000
--- a/chrome/common/extensions/docs/examples/api/water_alarm_notification/drink_water128.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/water_alarm_notification/drink_water16.png b/chrome/common/extensions/docs/examples/api/water_alarm_notification/drink_water16.png
deleted file mode 100644
index 831d708..0000000
--- a/chrome/common/extensions/docs/examples/api/water_alarm_notification/drink_water16.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/water_alarm_notification/drink_water32.png b/chrome/common/extensions/docs/examples/api/water_alarm_notification/drink_water32.png
deleted file mode 100644
index a12983c0..0000000
--- a/chrome/common/extensions/docs/examples/api/water_alarm_notification/drink_water32.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/water_alarm_notification/drink_water48.png b/chrome/common/extensions/docs/examples/api/water_alarm_notification/drink_water48.png
deleted file mode 100644
index 0af36a5..0000000
--- a/chrome/common/extensions/docs/examples/api/water_alarm_notification/drink_water48.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/water_alarm_notification/manifest.json b/chrome/common/extensions/docs/examples/api/water_alarm_notification/manifest.json
deleted file mode 100644
index a4832da..0000000
--- a/chrome/common/extensions/docs/examples/api/water_alarm_notification/manifest.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
- "name": "Drink Water Event Popup",
- "description": "Demonstrates usage and features of the event page by reminding user to drink water",
- "version": "1.0",
- "manifest_version": 2,
- "permissions": ["alarms", "notifications", "storage"],
- "background": {
- "scripts": ["background.js"],
- "persistent": false
- },
- "browser_action": {
- "default_title": "Drink Water Event",
- "default_popup": "popup.html"
- },
- "icons": {
- "16": "drink_water16.png",
- "32": "drink_water32.png",
- "48": "drink_water48.png",
- "128": "drink_water128.png"
- }
-}
diff --git a/chrome/common/extensions/docs/examples/api/water_alarm_notification/popup.html b/chrome/common/extensions/docs/examples/api/water_alarm_notification/popup.html
deleted file mode 100644
index e792182..0000000
--- a/chrome/common/extensions/docs/examples/api/water_alarm_notification/popup.html
+++ /dev/null
@@ -1,44 +0,0 @@
-<!-- Copyright 2017 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>
- <title>Water Popup</title>
- <style>
- body {
- text-align: center;
- }
-
- #hydrateImage {
- width: 100px;
- margin: 5px;
- }
-
- button {
- margin: 5px;
- outline: none;
- }
-
- button:hover {
- outline: #80DEEA dotted thick;
- }
- </style>
- <!--
- - JavaScript and HTML must be in separate files: see our Content Security
- - Policy documentation[1] for details and explanation.
- -
- - [1]: https://developer.chrome.com/extensions/contentSecurityPolicy
- -->
- </head>
- <body>
- <img src='./stay_hydrated.png' id='hydrateImage'>
- <!-- An Alarm delay of less than the minimum 1 minute will fire
- in approximately 1 minute incriments if released -->
- <button id='sampleSecond' value='0.1'>Sample Second</button>
- <button id='15min' value='15'>15 Minutes</button>
- <button id='30min' value='30'>30 Minutes</button>
- <button id='cancelAlarm'>Cancel Alarm</button>
- <!-- link to non-persistent background script -->
- <script src="popup.js"></script>
- </body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/api/water_alarm_notification/popup.js b/chrome/common/extensions/docs/examples/api/water_alarm_notification/popup.js
deleted file mode 100644
index 2d18c12..0000000
--- a/chrome/common/extensions/docs/examples/api/water_alarm_notification/popup.js
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2017 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.
-'use strict';
-
-function setAlarm(event) {
- let minutes = parseFloat(event.target.value);
- chrome.browserAction.setBadgeText({text: 'ON'});
- chrome.alarms.create({delayInMinutes: minutes});
- chrome.storage.sync.set({minutes: minutes});
- window.close();
-}
-
-function clearAlarm() {
- chrome.browserAction.setBadgeText({text: ''});
- chrome.alarms.clearAll();
- window.close();
-}
-
-//An Alarm delay of less than the minimum 1 minute will fire
-// in approximately 1 minute incriments if released
-document.getElementById('sampleSecond').addEventListener('click', setAlarm);
-document.getElementById('15min').addEventListener('click', setAlarm);
-document.getElementById('30min').addEventListener('click', setAlarm);
-document.getElementById('cancelAlarm').addEventListener('click', clearAlarm);
diff --git a/chrome/common/extensions/docs/examples/api/water_alarm_notification/stay_hydrated.png b/chrome/common/extensions/docs/examples/api/water_alarm_notification/stay_hydrated.png
deleted file mode 100644
index c44deee..0000000
--- a/chrome/common/extensions/docs/examples/api/water_alarm_notification/stay_hydrated.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/webNavigation/basic/_locales/en/messages.json b/chrome/common/extensions/docs/examples/api/webNavigation/basic/_locales/en/messages.json
deleted file mode 100644
index e639880..0000000
--- a/chrome/common/extensions/docs/examples/api/webNavigation/basic/_locales/en/messages.json
+++ /dev/null
@@ -1,52 +0,0 @@
-{
- "extName": {
- "message": "WebNavigation Tech Demo",
- "description": "The extension name."
- },
- "extDescription": {
- "message": "Demonstration of the WebNavigation extension API.",
- "description": "The extension description."
- },
-
- "navigationDescription": {
- "message": ", requested $NUM$ times. Loaded in an average of $LOAD$ miliseconds.",
- "description": "The message posted in the popup for each stored navigation.",
- "placeholders": {
- "NUM": {
- "content": "$1",
- "example": "4 (The number of times this URL was accessed.)"
- },
- "LOAD": {
- "content": "$2",
- "example": "12.345 (The average load time in miliseconds.)"
- }
- }
- },
-
- "inHandler": {
- "message": "In webNavigation[`%s`] handler: %o",
- "description": "Notification displayed for each webNavigation event."
- },
-
- "inHandlerError": {
- "message": "In webNavigation[`%s`] handler: No data!",
- "description": "Notification displayed in a webNavigation event handler without data!"
- },
-
- "errorCommittedWithoutPending": {
- "message": "Wha? `onCommitted` for `%s` called, though it's not pending: %o",
- "description": "Error logged when `onCommitted` is triggered on a non-pending request."
- },
- "errorCompletedWithoutPending": {
- "message": "Wha? `onCompleted` for `%s` called, though it's not pending: %o",
- "description": "Error logged when `onCompleted` is triggered on a non-pending request."
- },
- "errorErrorOccurredWithoutPending": {
- "message": "Wha? `onErrorOccurred` for `%s` called, though it's not pending: %o",
- "description": "Error logged when `onErrorOccurred` is triggered on a non-pending request."
- },
- "errorCommittedWithoutPending": {
- "message": "Wha? `onCompleted` for `%s` called, though it's not pending: %o",
- "description": "Error logged when `onCompleted` is triggered on a non-pending request."
- }
-}
diff --git a/chrome/common/extensions/docs/examples/api/webNavigation/basic/background.js b/chrome/common/extensions/docs/examples/api/webNavigation/basic/background.js
deleted file mode 100644
index a056515..0000000
--- a/chrome/common/extensions/docs/examples/api/webNavigation/basic/background.js
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright (c) 2012 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.
-
-/**
- * @filedescription Initializes the extension's background page.
- */
-
-var nav = new NavigationCollector();
-
-var eventList = ['onBeforeNavigate', 'onCreatedNavigationTarget',
- 'onCommitted', 'onCompleted', 'onDOMContentLoaded',
- 'onErrorOccurred', 'onReferenceFragmentUpdated', 'onTabReplaced',
- 'onHistoryStateUpdated'];
-
-eventList.forEach(function(e) {
- chrome.webNavigation[e].addListener(function(data) {
- if (typeof data)
- console.log(chrome.i18n.getMessage('inHandler'), e, data);
- else
- console.error(chrome.i18n.getMessage('inHandlerError'), e);
- });
-});
-
-// Reset the navigation state on startup. We only want to collect data within a
-// session.
-chrome.runtime.onStartup.addListener(function() {
- nav.resetDataStorage();
-});
diff --git a/chrome/common/extensions/docs/examples/api/webNavigation/basic/icon.png b/chrome/common/extensions/docs/examples/api/webNavigation/basic/icon.png
deleted file mode 100644
index d86677db..0000000
--- a/chrome/common/extensions/docs/examples/api/webNavigation/basic/icon.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/webNavigation/basic/manifest.json b/chrome/common/extensions/docs/examples/api/webNavigation/basic/manifest.json
deleted file mode 100644
index 2c0d435..0000000
--- a/chrome/common/extensions/docs/examples/api/webNavigation/basic/manifest.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
- "name": "__MSG_extName__",
- "version": "0.2",
- "description": "__MSG_extDescription__",
- "default_locale": "en",
- "background": {
- "persistent": false,
- "scripts": ["navigation_collector.js", "background.js"]
- },
- "browser_action": {
- "default_icon": "icon.png",
- "default_popup": "popup.html"
- },
- "permissions": [
- "webNavigation", "storage"
- ],
- "manifest_version": 2
-}
diff --git a/chrome/common/extensions/docs/examples/api/webNavigation/basic/navigation_collector.js b/chrome/common/extensions/docs/examples/api/webNavigation/basic/navigation_collector.js
deleted file mode 100644
index 56faa35b..0000000
--- a/chrome/common/extensions/docs/examples/api/webNavigation/basic/navigation_collector.js
+++ /dev/null
@@ -1,500 +0,0 @@
-// Copyright (c) 2012 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.
-
-/**
- * Implements the NavigationCollector object that powers the extension.
- *
- * @author mkwst@google.com (Mike West)
- */
-
-/**
- * Collects navigation events, and provides a list of successful requests
- * that you can do interesting things with. Calling the constructor will
- * automatically bind handlers to the relevant webnavigation API events,
- * and to a `getMostRequestedUrls` extension message for internal
- * communication between background pages and popups.
- *
- * @constructor
- */
-function NavigationCollector() {
- /**
- * A list of currently pending requests, implemented as a hash of each
- * request's tab ID, frame ID, and URL in order to ensure uniqueness.
- *
- * @type {Object<string, {start: number}>}
- * @private
- */
- this.pending_ = {};
-
- /**
- * A list of completed requests, implemented as a hash of each
- * request's tab ID, frame ID, and URL in order to ensure uniqueness.
- *
- * @type {Object<string, Array<NavigationCollector.Request>>}
- * @private
- */
- this.completed_ = {};
-
- /**
- * A list of requests that errored off, implemented as a hash of each
- * request's tab ID, frame ID, and URL in order to ensure uniqueness.
- *
- * @type {Object<string, Array<NavigationCollector.Request>>}
- * @private
- */
- this.errored_ = {};
-
- // Bind handlers to the 'webNavigation' events that we're interested
- // in handling in order to build up a complete picture of the whole
- // navigation event.
- chrome.webNavigation.onCreatedNavigationTarget.addListener(
- this.onCreatedNavigationTargetListener_.bind(this));
- chrome.webNavigation.onBeforeNavigate.addListener(
- this.onBeforeNavigateListener_.bind(this));
- chrome.webNavigation.onCompleted.addListener(
- this.onCompletedListener_.bind(this));
- chrome.webNavigation.onCommitted.addListener(
- this.onCommittedListener_.bind(this));
- chrome.webNavigation.onErrorOccurred.addListener(
- this.onErrorOccurredListener_.bind(this));
- chrome.webNavigation.onReferenceFragmentUpdated.addListener(
- this.onReferenceFragmentUpdatedListener_.bind(this));
- chrome.webNavigation.onHistoryStateUpdated.addListener(
- this.onHistoryStateUpdatedListener_.bind(this));
-
- // Bind handler to extension messages for communication from popup.
- chrome.runtime.onMessage.addListener(this.onMessageListener_.bind(this));
-
- this.loadDataStorage_();
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-/**
- * The possible transition types that explain how the navigation event
- * was generated (i.e. "The user clicked on a link." or "The user submitted
- * a form").
- *
- * @see http://code.google.com/chrome/extensions/trunk/history.html
- * @enum {string}
- */
-NavigationCollector.NavigationType = {
- AUTO_BOOKMARK: 'auto_bookmark',
- AUTO_SUBFRAME: 'auto_subframe',
- FORM_SUBMIT: 'form_submit',
- GENERATED: 'generated',
- KEYWORD: 'keyword',
- KEYWORD_GENERATED: 'keyword_generated',
- LINK: 'link',
- MANUAL_SUBFRAME: 'manual_subframe',
- RELOAD: 'reload',
- START_PAGE: 'start_page',
- TYPED: 'typed'
-};
-
-/**
- * The possible transition qualifiers:
- *
- * * CLIENT_REDIRECT: Redirects caused by JavaScript, or a refresh meta tag
- * on a page.
- *
- * * SERVER_REDIRECT: Redirected by the server via a 301/302 response.
- *
- * * FORWARD_BACK: User used the forward or back buttons to navigate through
- * their browsing history.
- *
- * @enum {string}
- */
-NavigationCollector.NavigationQualifier = {
- CLIENT_REDIRECT: 'client_redirect',
- FORWARD_BACK: 'forward_back',
- SERVER_REDIRECT: 'server_redirect'
-};
-
-/**
- * @typedef {{url: string, transitionType: NavigationCollector.NavigationType,
- * transitionQualifier: Array<NavigationCollector.NavigationQualifier>,
- * openedInNewTab: boolean, source: {frameId: ?number, tabId: ?number},
- * duration: number}}
- */
-NavigationCollector.Request;
-
-///////////////////////////////////////////////////////////////////////////////
-
-NavigationCollector.prototype = {
- /**
- * Returns a somewhat unique ID for a given WebNavigation request.
- *
- * @param {!{tabId: ?number, frameId: ?number}} data Information
- * about the navigation event we'd like an ID for.
- * @return {!string} ID created by combining the source tab ID and frame ID
- * (or target tab/frame IDs if there's no source), as the API ensures
- * that these will be unique across a single navigation event.
- * @private
- */
- parseId_: function(data) {
- return data.tabId + '-' + (data.frameId ? data.frameId : 0);
- },
-
-
- /**
- * Creates an empty entry in the pending array if one doesn't already exist,
- * and prepopulates the errored and completed arrays for ease of insertion
- * later.
- *
- * @param {!string} id The request's ID, as produced by parseId_.
- * @param {!string} url The request's URL.
- */
- prepareDataStorage_: function(id, url) {
- this.pending_[id] = this.pending_[id] || {
- openedInNewTab: false,
- source: {
- frameId: null,
- tabId: null
- },
- start: null,
- transitionQualifiers: [],
- transitionType: null
- };
- this.completed_[url] = this.completed_[url] || [];
- this.errored_[url] = this.errored_[url] || [];
- },
-
-
- /**
- * Retrieves our saved data from storage.
- * @private
- */
- loadDataStorage_: function() {
- chrome.storage.local.get({
- "completed": {},
- "errored": {},
- }, function(storage) {
- this.completed_ = storage.completed;
- this.errored_ = storage.errored;
- }.bind(this));
- },
-
-
- /**
- * Persists our state to the storage API.
- * @private
- */
- saveDataStorage_: function() {
- chrome.storage.local.set({
- "completed": this.completed_,
- "errored": this.errored_,
- });
- },
-
-
- /**
- * Resets our saved state to empty.
- */
- resetDataStorage: function() {
- this.completed_ = {};
- this.errored_ = {};
- this.saveDataStorage_();
- // Load again, in case there is an outstanding storage.get request. This
- // one will reload the newly-cleared data.
- this.loadDataStorage_();
- },
-
-
- /**
- * Handler for the 'onCreatedNavigationTarget' event. Updates the
- * pending request with a source frame/tab, and notes that it was opened in a
- * new tab.
- *
- * Pushes the request onto the
- * 'pending_' object, and stores it for later use.
- *
- * @param {!Object} data The event data generated for this request.
- * @private
- */
- onCreatedNavigationTargetListener_: function(data) {
- var id = this.parseId_(data);
- this.prepareDataStorage_(id, data.url);
- this.pending_[id].openedInNewTab = data.tabId;
- this.pending_[id].source = {
- tabId: data.sourceTabId,
- frameId: data.sourceFrameId
- };
- this.pending_[id].start = data.timeStamp;
- },
-
-
- /**
- * Handler for the 'onBeforeNavigate' event. Pushes the request onto the
- * 'pending_' object, and stores it for later use.
- *
- * @param {!Object} data The event data generated for this request.
- * @private
- */
- onBeforeNavigateListener_: function(data) {
- var id = this.parseId_(data);
- this.prepareDataStorage_(id, data.url);
- this.pending_[id].start = this.pending_[id].start || data.timeStamp;
- },
-
-
- /**
- * Handler for the 'onCommitted' event. Updates the pending request with
- * transition information.
- *
- * Pushes the request onto the
- * 'pending_' object, and stores it for later use.
- *
- * @param {!Object} data The event data generated for this request.
- * @private
- */
- onCommittedListener_: function(data) {
- var id = this.parseId_(data);
- if (!this.pending_[id]) {
- console.warn(
- chrome.i18n.getMessage('errorCommittedWithoutPending'),
- data.url,
- data);
- } else {
- this.prepareDataStorage_(id, data.url);
- this.pending_[id].transitionType = data.transitionType;
- this.pending_[id].transitionQualifiers =
- data.transitionQualifiers;
- }
- },
-
-
- /**
- * Handler for the 'onReferenceFragmentUpdated' event. Updates the pending
- * request with transition information.
- *
- * Pushes the request onto the
- * 'pending_' object, and stores it for later use.
- *
- * @param {!Object} data The event data generated for this request.
- * @private
- */
- onReferenceFragmentUpdatedListener_: function(data) {
- var id = this.parseId_(data);
- if (!this.pending_[id]) {
- this.completed_[data.url] = this.completed_[data.url] || [];
- this.completed_[data.url].push({
- duration: 0,
- openedInNewWindow: false,
- source: {
- frameId: null,
- tabId: null
- },
- transitionQualifiers: data.transitionQualifiers,
- transitionType: data.transitionType,
- url: data.url
- });
- this.saveDataStorage_();
- } else {
- this.prepareDataStorage_(id, data.url);
- this.pending_[id].transitionType = data.transitionType;
- this.pending_[id].transitionQualifiers =
- data.transitionQualifiers;
- }
- },
-
-
- /**
- * Handler for the 'onHistoryStateUpdated' event. Updates the pending
- * request with transition information.
- *
- * Pushes the request onto the
- * 'pending_' object, and stores it for later use.
- *
- * @param {!Object} data The event data generated for this request.
- * @private
- */
- onHistoryStateUpdatedListener_: function(data) {
- var id = this.parseId_(data);
- if (!this.pending_[id]) {
- this.completed_[data.url] = this.completed_[data.url] || [];
- this.completed_[data.url].push({
- duration: 0,
- openedInNewWindow: false,
- source: {
- frameId: null,
- tabId: null
- },
- transitionQualifiers: data.transitionQualifiers,
- transitionType: data.transitionType,
- url: data.url
- });
- this.saveDataStorage_();
- } else {
- this.prepareDataStorage_(id, data.url);
- this.pending_[id].transitionType = data.transitionType;
- this.pending_[id].transitionQualifiers =
- data.transitionQualifiers;
- }
- },
-
-
- /**
- * Handler for the 'onCompleted` event. Pulls the request's data from the
- * 'pending_' object, combines it with the completed event's data, and pushes
- * a new NavigationCollector.Request object onto 'completed_'.
- *
- * @param {!Object} data The event data generated for this request.
- * @private
- */
- onCompletedListener_: function(data) {
- var id = this.parseId_(data);
- if (!this.pending_[id]) {
- console.warn(
- chrome.i18n.getMessage('errorCompletedWithoutPending'),
- data.url,
- data);
- } else {
- this.completed_[data.url].push({
- duration: (data.timeStamp - this.pending_[id].start),
- openedInNewWindow: this.pending_[id].openedInNewWindow,
- source: this.pending_[id].source,
- transitionQualifiers: this.pending_[id].transitionQualifiers,
- transitionType: this.pending_[id].transitionType,
- url: data.url
- });
- delete this.pending_[id];
- this.saveDataStorage_();
- }
- },
-
-
- /**
- * Handler for the 'onErrorOccurred` event. Pulls the request's data from the
- * 'pending_' object, combines it with the completed event's data, and pushes
- * a new NavigationCollector.Request object onto 'errored_'.
- *
- * @param {!Object} data The event data generated for this request.
- * @private
- */
- onErrorOccurredListener_: function(data) {
- var id = this.parseId_(data);
- if (!this.pending_[id]) {
- console.error(
- chrome.i18n.getMessage('errorErrorOccurredWithoutPending'),
- data.url,
- data);
- } else {
- this.prepareDataStorage_(id, data.url);
- this.errored_[data.url].push({
- duration: (data.timeStamp - this.pending_[id].start),
- openedInNewWindow: this.pending_[id].openedInNewWindow,
- source: this.pending_[id].source,
- transitionQualifiers: this.pending_[id].transitionQualifiers,
- transitionType: this.pending_[id].transitionType,
- url: data.url
- });
- delete this.pending_[id];
- this.saveDataStorage_();
- }
- },
-
- /**
- * Handle messages from the popup.
- *
- * @param {!{type:string}} message The external message to answer.
- * @param {!MessageSender} sender Info about the script context that sent
- * the message.
- * @param {!function} sendResponse Function to call to send a response.
- * @private
- */
- onMessageListener_: function(message, sender, sendResponse) {
- if (message.type === 'getMostRequestedUrls')
- sendResponse({result: this.getMostRequestedUrls(message.num)});
- else
- sendResponse({});
- },
-
-///////////////////////////////////////////////////////////////////////////////
-
- /**
- * @return {Object<string, NavigationCollector.Request>} The complete list of
- * successful navigation requests.
- */
- get completed() {
- return this.completed_;
- },
-
-
- /**
- * @return {Object<string, Navigationcollector.Request>} The complete list of
- * unsuccessful navigation requests.
- */
- get errored() {
- return this.errored_;
- },
-
-
- /**
- * Get a list of the X most requested URLs.
- *
- * @param {number=} num The number of successful navigation requests to
- * return. If 0 is passed in, or the argument left off entirely, all
- * successful requests are returned.
- * @return {Object<string, NavigationCollector.Request>} The list of
- * successful navigation requests, sorted in decending order of frequency.
- */
- getMostRequestedUrls: function(num) {
- return this.getMostFrequentUrls_(this.completed, num);
- },
-
-
- /**
- * Get a list of the X most errored URLs.
- *
- * @param {number=} num The number of unsuccessful navigation requests to
- * return. If 0 is passed in, or the argument left off entirely, all
- * successful requests are returned.
- * @return {Object<string, NavigationCollector.Request>} The list of
- * unsuccessful navigation requests, sorted in decending order
- * of frequency.
- */
- getMostErroredUrls: function(num) {
- return this.getMostErroredUrls_(this.errored, num);
- },
-
-
- /**
- * Get a list of the most frequent URLs in a list.
- *
- * @param {NavigationCollector.Request} list A list of URLs to parse.
- * @param {number=} num The number of navigation requests to return. If
- * 0 is passed in, or the argument left off entirely, all requests
- * are returned.
- * @return {Object<string, NavigationCollector.Request>} The list of
- * navigation requests, sorted in decending order of frequency.
- * @private
- */
- getMostFrequentUrls_: function(list, num) {
- var result = [];
- var avg;
- // Convert the 'completed_' object to an array.
- for (var x in list) {
- avg = 0;
- if (list.hasOwnProperty(x) && list[x].length) {
- list[x].forEach(function(o) {
- avg += o.duration;
- });
- avg = avg / list[x].length;
- result.push({
- url: x,
- numRequests: list[x].length,
- requestList: list[x],
- average: avg
- });
- }
- }
- // Sort the array.
- result.sort(function(a, b) {
- return b.numRequests - a.numRequests;
- });
- // Return the requested number of results.
- return num ? result.slice(0, num) : result;
- }
-};
diff --git a/chrome/common/extensions/docs/examples/api/webNavigation/basic/popup.css b/chrome/common/extensions/docs/examples/api/webNavigation/basic/popup.css
deleted file mode 100644
index e5512260..0000000
--- a/chrome/common/extensions/docs/examples/api/webNavigation/basic/popup.css
+++ /dev/null
@@ -1,63 +0,0 @@
-/**
- * Copyright (c) 2011 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.
- */
-
-
-body {
- margin: 5px 10px 10px;
-}
-
-h1 {
- color: #53637D;
- font: 26px/1.2 Helvetica, sans-serif;
- font-size: 200%;
- margin: 0;
- padding-bottom: 4px;
- text-shadow: white 0 1px 2px;
-}
-
-body > section {
- border-radius: 5px;
- background: -webkit-linear-gradient(rgba(234, 238, 243, 0.2), #EAEEF3),
- -webkit-linear-gradient(
- left, #EAEEF3, #EAEEF3 97%, #D3D7DB);
- font: 14px/1 Arial,Sans Serif;
- padding: 10px;
- width: 563px;
- max-height: 400px;
- overflow-y: auto;
- box-shadow: inset 0px 2px 5px rgba(0,0,0,0.5);
-}
-
-body > section > ol {
- padding: 0;
- margin: 0;
- list-style: none inside;
-}
-
-body > section > ol > li {
- position: relative;
- margin: 0.5em 0 0.5em 40px;
-}
-
-code {
- word-wrap: break-word;
- background: rgba(255,255,0, 0.5);
-}
-
-em {
- position: absolute;
- top: 0px;
- left: -40px;
- width: 30px;
- text-align: right;
- font: 30px/1 Helvetica, sans-serif;
- font-weight: 700;
-}
-
-p {
- min-height: 30px;
- line-height: 1.2;
-}
diff --git a/chrome/common/extensions/docs/examples/api/webNavigation/basic/popup.html b/chrome/common/extensions/docs/examples/api/webNavigation/basic/popup.html
deleted file mode 100644
index 1f518020..0000000
--- a/chrome/common/extensions/docs/examples/api/webNavigation/basic/popup.html
+++ /dev/null
@@ -1,17 +0,0 @@
-<!doctype html>
-<!--
- * Copyright (c) 2011 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>
- <title>WebNavigation Tech Demo Popup</title>
- <link href="popup.css" rel="stylesheet" type="text/css">
- </head>
- <body>
- <h1>Most Requested URLs</h1>
- <section></section>
- <script src="popup.js"></script>
- </body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/api/webNavigation/basic/popup.js b/chrome/common/extensions/docs/examples/api/webNavigation/basic/popup.js
deleted file mode 100644
index ccb3243..0000000
--- a/chrome/common/extensions/docs/examples/api/webNavigation/basic/popup.js
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (c) 2011 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.
-
-/**
- * @filedescription Initializes the extension's popup page.
- */
-
-chrome.runtime.sendMessage(
- {'type': 'getMostRequestedUrls'},
- function generateList(response) {
- var section = document.querySelector('body>section');
- var results = response.result;
- var ol = document.createElement('ol');
- var li, p, em, code, text;
- var i;
- for (i = 0; i < results.length; i++ ) {
- li = document.createElement('li');
- p = document.createElement('p');
- em = document.createElement('em');
- em.textContent = i + 1;
- code = document.createElement('code');
- code.textContent = results[i].url;
- text = document.createTextNode(
- chrome.i18n.getMessage('navigationDescription',
- [results[i].numRequests,
- results[i].average]));
- p.appendChild(em);
- p.appendChild(code);
- p.appendChild(text);
- li.appendChild(p);
- ol.appendChild(li);
- }
- section.innerHTML = '';
- section.appendChild(ol);
- });
diff --git a/chrome/common/extensions/docs/examples/api/webview/capturevisibleregion/display.html b/chrome/common/extensions/docs/examples/api/webview/capturevisibleregion/display.html
deleted file mode 100644
index 2dfdc4f3..0000000
--- a/chrome/common/extensions/docs/examples/api/webview/capturevisibleregion/display.html
+++ /dev/null
@@ -1,14 +0,0 @@
-<!DOCTYPE html>
-<html>
- <head>
- <title>Display Screenshot</title>
- <style type="text/css">
-body {
- background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==');
- margin: 0;
-}
- </style>
- </head>
- <body>
- </body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/api/webview/capturevisibleregion/main.js b/chrome/common/extensions/docs/examples/api/webview/capturevisibleregion/main.js
deleted file mode 100644
index 91816208..0000000
--- a/chrome/common/extensions/docs/examples/api/webview/capturevisibleregion/main.js
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) 2016 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.
-
-chrome.app.runtime.onLaunched.addListener(function() {
- chrome.app.window.create('test.html', {
- innerBounds: {
- 'width': 1280,
- 'height': 800
- }
- });
-});
diff --git a/chrome/common/extensions/docs/examples/api/webview/capturevisibleregion/manifest.json b/chrome/common/extensions/docs/examples/api/webview/capturevisibleregion/manifest.json
deleted file mode 100644
index 6b27ec4..0000000
--- a/chrome/common/extensions/docs/examples/api/webview/capturevisibleregion/manifest.json
+++ /dev/null
@@ -1,22 +0,0 @@
-{
- "manifest_version": 2,
- "name": "Webview transparency",
- "description": "Sample of the webview.captureVisibleRegion api",
- "version": "1",
- "app": {
- "background": {
- "scripts": ["main.js"]
- }
- },
- "permissions": [
- "webview"
- ],
- "webview": {
- "partitions": [
- {
- "name": "partition",
- "accessible_resources": [ "test2.html" ]
- }
- ]
- }
-}
diff --git a/chrome/common/extensions/docs/examples/api/webview/capturevisibleregion/test.html b/chrome/common/extensions/docs/examples/api/webview/capturevisibleregion/test.html
deleted file mode 100644
index b5d498048..0000000
--- a/chrome/common/extensions/docs/examples/api/webview/capturevisibleregion/test.html
+++ /dev/null
@@ -1,25 +0,0 @@
-<!DOCTYPE html>
-<html>
- <head>
- <script src="test.js"></script>
-<style type="text/css">
-.ib {
- position: relative;
- display: inline-block;
-}
-.controls {
- margin: 4px;
- position: absolute;
- right: 0px;
- top: 0px;
-}
-</style>
- </head>
- <body bgColor='teal'>
- <br>
- <button id="add_wv">Add webview</button>
- <button id="delete_wv">Delete webview</button>
- <span><input type="checkbox" id="transparent" checked="checked"><label for="transparent">Transparent</label></span>
- <br>
- </body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/api/webview/capturevisibleregion/test.js b/chrome/common/extensions/docs/examples/api/webview/capturevisibleregion/test.js
deleted file mode 100644
index c5a92c9..0000000
--- a/chrome/common/extensions/docs/examples/api/webview/capturevisibleregion/test.js
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright (c) 2016 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.
-
-document.addEventListener('DOMContentLoaded', function() {
-
- var deleteNode = function(node) {
- node.parentNode.removeChild(node);
- };
-
- var deleteAWebview = function() {
- deleteNode(document.querySelector('.ib'));
- };
-
- var findContainer = function(node) {
- var container = node;
- while (container && !container.classList.contains('ib')) {
- container = container.parentElement;
- }
- return container;
- };
-
- var handleDelete = function(event) {
- var container = findContainer(event.target);
- if (container) {
- deleteNode(container);
- }
- };
-
- var viewScreenshot = function(wv) {
- return function(data) {
- chrome.app.window.create('display.html', {
- innerBounds: { width: wv.clientWidth, height: wv.clientHeight }
- },
- function(aw) {
- var d = aw.contentWindow.document;
- d.addEventListener('DOMContentLoaded', function() {
- var img = d.createElement('img');
- img.src = data;
- d.body.appendChild(img);
- });
- });
- };
- };
-
- var handleScreenshot = function(event) {
- var container = findContainer(event.target);
- var wv = container.querySelector('webview');
- wv.captureVisibleRegion({format:'png'}, viewScreenshot(wv));
- };
-
- var getControls = (function() {
- var controls = document.createElement('div');
- controls.className = 'controls';
- controls.innerHTML = '<button id="screenshot">Screenshot</button>' +
- '<button id="delete">Delete webview</button>';
-
- return function() {
- var c = controls.cloneNode(true);
- c.querySelector('#delete').addEventListener('click', handleDelete);
- c.querySelector('#screenshot').
- addEventListener('click', handleScreenshot);
- return c;
- };
- })();
-
- var createWebview = (function(){
- var id = 0;
- return function() {
- var wv = document.createElement('webview');
- wv.partition = "partition";
- wv.src = 'test2.html';
- wv.allowtransparency = document.getElementById('transparent').checked;
- wv.style.width = "640px";
- wv.style.height = "480px";
-
- var container = document.createElement('div');
- container.id = 'wvid0' + id;
- id++;
-
- container.className = 'ib';
-
- container.appendChild(wv);
- container.appendChild(getControls());
- return container;
- };
- })();
-
- document.getElementById('delete_wv').
- addEventListener('click', deleteAWebview);
- document.getElementById('add_wv').
- addEventListener('click', function() {
- document.body.appendChild(createWebview());
- });
-});
diff --git a/chrome/common/extensions/docs/examples/api/webview/capturevisibleregion/test2.html b/chrome/common/extensions/docs/examples/api/webview/capturevisibleregion/test2.html
deleted file mode 100644
index 6d31d82..0000000
--- a/chrome/common/extensions/docs/examples/api/webview/capturevisibleregion/test2.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<!DOCTYPE html>
-<html>
- <head></head>
- <body>
- Hello world!
-
- <button id="newwindow" onclick="window.open('http://www.google.com/');">newwindow</button>
- </body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/api/webview/comm_demo_app/app.js b/chrome/common/extensions/docs/examples/api/webview/comm_demo_app/app.js
deleted file mode 100644
index 0b473f0e..0000000
--- a/chrome/common/extensions/docs/examples/api/webview/comm_demo_app/app.js
+++ /dev/null
@@ -1,165 +0,0 @@
-// Copyright 2018 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.
-
-'use strict;'
-
-const kWhitelistedExtensionId = 'dpicdiinminmigempanoghnpckmkfepi';
-const kExtensionIds = [kWhitelistedExtensionId];
-
-let portMap = {};
-let webview = null;
-
-let initScripts = [];
-
-function createWebView(initScripts) {
- let container = document.getElementById('webview-container');
- webview = document.createElement('webview');
- webview.partition = 'partition';
- webview.style = 'width: 640px; height: 400px';
-
- webview.addContentScripts([{
- // The value of |embedder| in the script below will persist, and can be
- // used by content script injected into the guest any time to send data
- // back to us.
- name: 'embedderVar',
- matches: ['<all_urls>'],
- js: {code: 'var embedder = null;\n'},
- all_frames: true,
- run_at: 'document_start'
- }]);
- webview.addContentScripts(initScripts);
-
- webview.addEventListener('contentload', function() {
- webview.executeScript({
- code: 'window.addEventListener(\'message\', function(e){\n' +
- ' if (e.data != \'connect\')\n' +
- ' return;\n' +
- ' console.log(\'msg = \' + e.data);\n' +
- ' embedder = e.source;\n' +
- ' embedder.postMessage(JSON.stringify({\n' +
- ' \'ext_id\' : \'0\',\n' +
- ' \'msg\' : \'Hello from guest!\'}), \'*\');\n' +
- '});'
- });
- // Here we aren't enforcing any particular origin on the guest, but we
- // could if security needs required it.
- webview.contentWindow.postMessage('connect', '*');
- });
-
- addEventListener('message', function(e) {
- if (e.source != webview.contentWindow)
- return;
-
- let data;
- try {
- data = JSON.parse(e.data);
- } catch (err) {
- console.warn('invalid JSON format for incoming message: ' + err.message);
- }
-
- if (!data) {
- console.warn('Malformed message: ' + e.data);
- return;
- }
-
- if (data.extensionId) {
- if (!data.extensionId in portMap) {
- console.warn('Message for unknown extension: ' + data.extensionId);
- return;
- }
- if (!data.request) {
- console.warn('malformed messgae (no request):' + e.data);
- return;
- }
- // Relay this to the appropriate extension.
- // If the app wants to monitor messages from injected code, this is one
- // place to do it.
- console.log('Request: ' + data.request + ' => ' + data.extensionId);
- portMap[data.extensionId].postMessage({request: data.request});
- } else {
- if (!data.msg) {
- console.warn('malformed message (no msg): ' + e.data);
- }
- console.log('Message for us: ' + data.msg);
- }
- });
-
- webview.src = 'http://example.com';
- container.appendChild(webview);
-}
-
-function connectToExtension(extensionId) {
- let port;
- try {
- port = chrome.runtime.connect(extensionId);
- } catch (e) {
- console.error('Could not connect to extension: ' + e.message);
- return;
- }
- // Save port in map.
- portMap[extensionId] = port;
- port.onDisconnect.addListener(() => {
- delete portMap[extensionId];
- });
-
- let initPromise = new Promise((resolve, reject) => {
- port.onMessage.addListener(function(msg) {
- // Perhaps check here to make sure |msg.code| exists.
- console.log('Incoming from extension: ' + msg.name + ' -> ' + msg.code);
- if (msg.name == 'ext_getInitScripts') {
- initScripts.push({
- name: 'initScripts-' + extensionId,
- matches: ['<all_urls>'],
- js: {code: msg.code},
- run_at: 'document_start'
- });
- resolve();
- } else {
- webview.executeScript({code: msg.code});
- }
- });
- setTimeout(function() {
- reject('Timeout waiting for initScripts from ' + extensionId);
- }, 5000);
- });
-
- port.postMessage({request: 'getInitScripts'});
-
- return initPromise;
-}
-
-function setUpExtensionHandlers() {
- let port = portMap[kWhitelistedExtensionId];
- // Some examples of UI in the app requesting services from the guest.
- // The replies from the extension are injected into the guest and executed
- // via the port.onMessage handler declared above.
- document.getElementById('magnify_button')
- .addEventListener('click', function() {
- port.postMessage({request: 'magnify'});
- });
- document.getElementById('background_button')
- .addEventListener('click', function() {
- port.postMessage({request: 'setBackground'});
- });
- document.getElementById('add_div_button')
- .addEventListener('click', function() {
- port.postMessage({request: 'addDiv'});
- });
- document.getElementById('iframe_dataurl_button')
- .addEventListener('click', function() {
- port.postMessage({request: 'iFrameDataURL'});
- });
-}
-
-document.addEventListener('DOMContentLoaded', function() {
- promises = [];
- for (let extensionId of kExtensionIds)
- promises.push(connectToExtension(extensionId));
-
- setUpExtensionHandlers();
-
- Promise.all(promises).then(function() {
- createWebView(initScripts);
- });
-});
diff --git a/chrome/common/extensions/docs/examples/api/webview/comm_demo_app/main.js b/chrome/common/extensions/docs/examples/api/webview/comm_demo_app/main.js
deleted file mode 100644
index c512efa1..0000000
--- a/chrome/common/extensions/docs/examples/api/webview/comm_demo_app/main.js
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2018 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.
-
-chrome.app.runtime.onLaunched.addListener(function() {
- chrome.app.window.create('test.html', {
- innerBounds: {
- 'width': 1000,
- 'height': 800
- }
- });
-});
diff --git a/chrome/common/extensions/docs/examples/api/webview/comm_demo_app/manifest.json b/chrome/common/extensions/docs/examples/api/webview/comm_demo_app/manifest.json
deleted file mode 100644
index 340d5901..0000000
--- a/chrome/common/extensions/docs/examples/api/webview/comm_demo_app/manifest.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- "manifest_version": 2,
- "name": "WebView Extension Communications Demo: App",
- "version": "1",
- "app": {
- "background": {
- "scripts": ["main.js"]
- }
- },
- "permissions": ["webview"],
- "webview": {
- "partitions": [
- {
- "name": "partition",
- "accessible_resources": [""]
- }
- ]
- }
-}
diff --git a/chrome/common/extensions/docs/examples/api/webview/comm_demo_app/test.html b/chrome/common/extensions/docs/examples/api/webview/comm_demo_app/test.html
deleted file mode 100644
index afb3b38..0000000
--- a/chrome/common/extensions/docs/examples/api/webview/comm_demo_app/test.html
+++ /dev/null
@@ -1,16 +0,0 @@
-<!DOCTYPE html>
-<head>
- <script src="app.js"></script>
-</head>
-<html>
- <body bgColor='teal'>
- <div id='webview-container'>
- </div>
- <input type=button value="Magnify" id=magnify_button>
- <input type=button value="Background" id=background_button>
- <input type=button value="Add Div" id=add_div_button>
- <input type=button value="Scripting Data URL in IFrame"
- id=iframe_dataurl_button>
- <p>Try typing 'm' in the guest window above.</p>
- <body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/api/webview/comm_demo_ext/background.js b/chrome/common/extensions/docs/examples/api/webview/comm_demo_ext/background.js
deleted file mode 100644
index f42e0bb..0000000
--- a/chrome/common/extensions/docs/examples/api/webview/comm_demo_ext/background.js
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright 2018 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.
-
-'use strict;'
-
-// Define globals.
-
-// This DataURI image will allow us to demonstrate injecting non-html content
-// into a guest.
-var chromiumLogoDataURI = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAABHNCSVQICAgIfAhkiAAACmlJREFUaIG9mmtsXMd1x39n5i53yeVDlESRlERaVEXKqmq7iZW6lZyoTtzYQhuraGK7RSCnTZAoMGw0Sd0U/UQILfqhddqkeRQN0CA2EjT1AwjSvFzYUOyEslzZkS1XimW2jiTqRVkiKT72de/M6Ye7S652l8sl7fgAF7t75szM/3/mzMyZuSu8DTI8fLzpDaKhqWl3y5wGv0UgN0XebiJyqwCsmEnv3Rk1/mizFF5MJd0LZ58+9tpLL+0P32rfstKKu4cPBmuijp1Xr6b+IkqYuwqhLhRqtX2lKhEI1uW/m05Of+kHX3j6OTjgV4Jj2QSGh483/Twb7btaCP4xikz7InirlLVstKgMrL/anJj7y86x9COPP769sBw8yyLwh391bM+VTPDvTqVjKXDLIVASQzjREczs+/E/7/pho5gaIrDvH15JX7iQeCIbmjvjjqvhVGkaCKPKZkq/kzbzVI//v488/rV7ZpfCtiSBP/mbE4Nnx8PDXpKrFzr61RIAsBpeSSXP7Tr4pT0n6+GrS2Dv8NGdk5cTP3UmMFVgKnp/uwkAOHFujZ5733/9yx2HFsO4KIG9w6/unJwMRryC1jB7JwgAiFFaE+d3PvPF25+vhbMmgbs/f2zrhRk9oUHCQJXz35EQWqijROLdajn968989fdfryyvQnf38MHWsVl3yEtg1AuoorXXmXdMAjV2xvWN/N6+R9OVZVUExt/sfFJ8sDoeG0VVEaW2e4rSCL236gKVYO1sy/VPUBE11xD4+NenPtmcNh9EHd57UA8SD2NpHtQKn1+VVI58ZFrvvPX+g3eU6+bZDB/UYOwXMzNQSB1/6QSSaMNIgBqLIIiAR5GKaVN7E1PwjriGr2lXM94b2Pysj6ZeeP37XTx7ILqGwP5vzt3nQnlEgIunT3DpQg6TaAMTzJtJyVoWSJR30p5y7L6phZu3trCpJ8GqtEWA2axj/Eqe18fmOP5GhlwBjAhiBESwIhijgMFYwRiDFJcPkfi3CQQRwVqDBHzir+/d9I15Ao89pvapK5kJCaQdQDTklZFnkaa1ELTHcWZK0Sbz+EvgUwnHvb/bzt5dbTTZGqtW2ffIKUdOZHj++CyIjdszgjFgioSMEQJjMVYQK1gTgxfAWAPOTX7mw91rREQDgMNz2feUwAOoJBjYuo1fvjaKEQM2jWrMVqQUmTGLnk5leF8vfV0BChw9IxwaFUbH4cpc3GlnqzLYDbcOKjf2we/ckGbouhT/eWiO2azEo2ENQWCwgSGwBimCjruJnVYiIU10fvuZ7A7gSAAwE+pny8MCoG1tL02pU4ThDEoCE6QAwWtpHii9ncLf7++lM20Ym4R//YnhjUvVc+TStHBpGkZGhS3rlP23eTasstx7WxvfO5InHyYWvCzxxikmBm4k9pUUQ1cMCMJ0pJ8BPirDBzU4N5qdz+bLeYTZKV576RiaSILtwJgmMIIgJBPwxfu76esK+J+zwsNPCYWoxo5dpYGkVR7ao2zfoFzNKD86WvTyvKfjevEcAVNkYErgjBCGBR2/oyMwM2cKm8s7UV14EskO2le3gQshmkU1nC/749va6OsKGJtkWeBRyEfCwz8Szk1BR4twQ79ircEGgg0M1hqChCWwhsBaTBB/2sAQBJaEMTSnmuX6w7l+M+v9jlr9AKgIGwe3gYvAezTMIC6kowX27mpFicOmYfBlko+Erx80KHD9BkNzwhPYeA6YhCkSiudDovjdSqw31mCNoGJuNt7pogQATJCid/N1gAMc3mXZfWOKJmt4+YxUxXxd8BUFo+PCsbOCNbCxi9jrxmCL3i59GmsWlt2ypryTHSYK/Y6lvNW1vj/egX28Kb17awqAQ6MrB19SjZyM21jfIYgxmCD2rpGF5XqxRqNIf9uot79Wslns8VgGtw/GqYVXBnqSAIyOrxx8SU4W22hrAVjeuV6RAWOksLYR41THGppaEuAdq1otEK/zS2JcpKCknii2kQwU9TUI1EnLhXy3cSrRkugBMGzZtpV4LpQaWBiluigbUy9bvEpkAsulRivYZCud69qZmnUo8Q67qDSIck1r/JmP4jmwVBvlKueazhv1croq6GvVKq7/6wcG+OXZLACD3csHX1m0tTvWTGdBpDqPqieG8JzxRg4vBrgWITFJRi/HHd062MC5cYmiXUOx9vKMLGlcqbKBPWSs8vPFu6wtoxNtFELlxj5lyzpdaH2Z4Id64IaNivPCxau2vnEtkfCoUY1ebNB8XmYLlp/8r+YF2H+bJ2nrHzdrlaYS8OndDgGOjxXI+6Bun7XayOfDI6Z/vOPUco6JJUDP/qIpeXEaNqyCh/YoyaCBm4oy8J/f4+nthItXQk5NpupWqg0+p+dv7zxrDhwQ75Vv19vIak2HQiQ8MhIwk4PtG5S//YhnsDgh60XTUA/83R85tq1XpuYcz50sEARN9RnXECPBowdEvAB8/MuXd2hTy5HGqy9IV7vysZ0R3e1x/8fOCiMnhZPjC5vUmtZ4tdk1pNywMb4eOHc54smRSbZs6a/LeDFO2Wz4m5++I/1K6apB7vtK5pJtkoZ25UppCuD92zzvHfI01ZkPAPkQnnk1yw8PT/Ded/XQ1ta6bPC+EL75px9o6Z4/UiKi9msTD0DqOyshUIjgx68aRkYNN230bF3v6W2HdCqGMJsTzk85jp/O8+Jojpm5iKG+9hWBB3AUPiWSVii7lbj7MbXpK9PnxSTWrYREpcwfZ4lzwHx2GheGeHU0kWf3jl6SiVTNuvXAh4Xo0tgHmnsPiHgou9h6/B5x1hXufjvAlzJvV3qcQ9UVr4sc2wbaVgQewPnsXSXw1xAA+LcHup4r5HNPvBXg1Re2ivch3gvqHZ1pZeO61bXrL9F+oRD+x/4PrnmhXFeVfARtV/f5MGw4wSs/Q9cUr/EI+AjnHdcPdFQnbQ2Ad4XwwtmJU/dV6qtaeuTPBnJ5M7vDF/KusqwcbF3Q8/aK1zjPV1X6uxKs6+yotlsCvM/nwqlc7j0H7ql+AVgz/fvO/RvGLHM3e+8bBluTgFecd/EIhCFDm1Y1dP95DXj1hC7zrs/9wZpztcoXzV+/8eDGVySau1ELuaqRWBI44Oe9H4GP2HZdC+lU6hqbRjwfZqd+41N39hxfzKZuAv7NB7tfzQfZgTCTv9gI6HJQWryh9j6iOaH0bei4xnYpCbPhhcl8OFAPPCxBAOJwmggub8rn5p5cDHAlIC3GvfOKho5t/c0kg0RDXldVMpm5x8auntq0WNiUy7JedN/38Nj7okT6yUQytXjKoeC9w0ceFxVY3Zzllu3dVN691pK5fP5Nn5ve+8CHNtR8oVdLlnWGe/ShvufCnz3dk81M3xuFmYlaNqrxiuOdw4V5BvvblgRfyMxezs5MfXj89tae5YCHt/BnD1TlY1848+7QJv/cJ+xHk0HaqCrqPN55fJinf62yfXNnzbDJZGYV9FthPvdPD961/mURWdFlxcoJlMnwsJrRVWc24e3NKsEtuSi7Q1xu867NbetaOlsiCnrBWn/OGfO8cf7lQjT335c/dN3p8pRgpfL/IYD7eLJbZAcAAAAASUVORK5CYII=';
-
-var iframeDataURL =
- 'data:text/html,' +
- '<html>' +
- ' <head>' +
- ' <script>' +
- ' document.addEventListener("DOMContentLoaded", function(){' +
- ' document.getElementById("target").innerText = "Fred.";' +
- ' });' +
- ' </script>' +
- ' </head>' +
- ' <body>' +
- ' <h1>Data URL IFrame</h1>' +
- ' <img src="' + chromiumLogoDataURI + '"><br>' +
- ' <p>A data-url based iframe that has scripts.</p>' +
- ' <p id="target"></p>' +
- ' </body>' +
- '</html>';
-
-let handlers = {};
-
-handlers['magnify'] =
- 'els = document.getElementsByTagName(\'div\'); ' +
- 'for (i = 0; i < els.length; i++) {' +
- ' els[i].style.fontSize = "200%";' +
- '}'
-
-handlers['setBackground'] =
- 'document.body.style.backgroundColor=\'pink\';';
-
-handlers['addDiv'] =
- 'el = document.createElement(\'div\'); ' +
- 'el.innerText = \'Greetings from the extension!\'; ' +
- 'document.body.appendChild(el);';
-
-handlers['iFrameDataURL'] =
- 'el = document.createElement(\'iframe\');\n' +
- 'document.body.appendChild(el);\n' +
- 'el.src = \'' + iframeDataURL + '\';';
-
-handlers['getInitScripts'] =
- 'window.addEventListener(\'keypress\', function(e){\n' +
- ' console.log(\'keypress!!\');\n' +
- ' if (!embedder)\n' +
- ' return;\n' +
- ' if (e.keyCode == 109)\n' +
- ' embedder.postMessage(JSON.stringify({\n' +
- ' \'extensionId\' : \'' + chrome.runtime.id + '\',\n' +
- ' \'request\' : \'magnify\'}), \'*\');\n' +
- '});';
-
-chrome.runtime.onConnectExternal.addListener(function(port) {
- port.onMessage.addListener((msg) => {
- if (!handlers.hasOwnProperty(msg.request)) {
- console.error('Unknown request: ' + msg.request);
- return;
- }
- port.postMessage({code: handlers[msg.request], name: 'ext_' + msg.request});
- });
-});
diff --git a/chrome/common/extensions/docs/examples/api/webview/comm_demo_ext/manifest.json b/chrome/common/extensions/docs/examples/api/webview/comm_demo_ext/manifest.json
deleted file mode 100644
index 0869009..0000000
--- a/chrome/common/extensions/docs/examples/api/webview/comm_demo_ext/manifest.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "manifest_version": 2,
-
- "name": "WebView Extension Communications Demo: Extension",
- "description": "Provides content scripts to an app hosting a WebView.",
- "version": "1.0",
-
- "background": {
- "scripts": ["background.js"]
- },
- "permissions": [
- ]
-}
diff --git a/chrome/common/extensions/docs/examples/api/windows/merge_windows/NOTICE b/chrome/common/extensions/docs/examples/api/windows/merge_windows/NOTICE
deleted file mode 100644
index d86114b..0000000
--- a/chrome/common/extensions/docs/examples/api/windows/merge_windows/NOTICE
+++ /dev/null
@@ -1,2 +0,0 @@
-This extension uses icons based on the famfamfam silk series.
-http://www.famfamfam.com/lab/icons/silk/
\ No newline at end of file
diff --git a/chrome/common/extensions/docs/examples/api/windows/merge_windows/arrow_in.png b/chrome/common/extensions/docs/examples/api/windows/merge_windows/arrow_in.png
deleted file mode 100644
index f0da7b15..0000000
--- a/chrome/common/extensions/docs/examples/api/windows/merge_windows/arrow_in.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/windows/merge_windows/background.js b/chrome/common/extensions/docs/examples/api/windows/merge_windows/background.js
deleted file mode 100644
index e9789210..0000000
--- a/chrome/common/extensions/docs/examples/api/windows/merge_windows/background.js
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright (c) 2011 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.
-
-var targetWindow = null;
-var tabCount = 0;
-
-function start(tab) {
- chrome.windows.getCurrent(getWindows);
-}
-
-function getWindows(win) {
- targetWindow = win;
- chrome.tabs.getAllInWindow(targetWindow.id, getTabs);
-}
-
-function getTabs(tabs) {
- tabCount = tabs.length;
- // We require all the tab information to be populated.
- chrome.windows.getAll({"populate" : true}, moveTabs);
-}
-
-function moveTabs(windows) {
- var numWindows = windows.length;
- var tabPosition = tabCount;
-
- for (var i = 0; i < numWindows; i++) {
- var win = windows[i];
-
- if (targetWindow.id != win.id) {
- var numTabs = win.tabs.length;
-
- for (var j = 0; j < numTabs; j++) {
- var tab = win.tabs[j];
- // Move the tab into the window that triggered the browser action.
- chrome.tabs.move(tab.id,
- {"windowId": targetWindow.id, "index": tabPosition});
- tabPosition++;
- }
- }
- }
-}
-
-// Set up a click handler so that we can merge all the windows.
-chrome.browserAction.onClicked.addListener(start);
diff --git a/chrome/common/extensions/docs/examples/api/windows/merge_windows/manifest.json b/chrome/common/extensions/docs/examples/api/windows/merge_windows/manifest.json
deleted file mode 100644
index b5b51737..0000000
--- a/chrome/common/extensions/docs/examples/api/windows/merge_windows/manifest.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
- "name": "Merge Windows",
- "version": "1.0.2",
- "description": "Merges all of the browser's windows into the current window",
- "icons": {
- "48": "merge_windows_48.png",
- "128": "merge_windows_128.png"
- },
- "background": {
- "persistent": false,
- "scripts": ["background.js"]
- },
- "browser_action": {
- "default_icon": "arrow_in.png",
- "default_title": "Merge Windows"
- },
- "manifest_version": 2
-}
diff --git a/chrome/common/extensions/docs/examples/api/windows/merge_windows/merge_windows_128.png b/chrome/common/extensions/docs/examples/api/windows/merge_windows/merge_windows_128.png
deleted file mode 100644
index a37b606..0000000
--- a/chrome/common/extensions/docs/examples/api/windows/merge_windows/merge_windows_128.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/windows/merge_windows/merge_windows_48.png b/chrome/common/extensions/docs/examples/api/windows/merge_windows/merge_windows_48.png
deleted file mode 100644
index 3542c6a..0000000
--- a/chrome/common/extensions/docs/examples/api/windows/merge_windows/merge_windows_48.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/apps/background-simple/README b/chrome/common/extensions/docs/examples/apps/background-simple/README
deleted file mode 100644
index dc74c5a6..0000000
--- a/chrome/common/extensions/docs/examples/apps/background-simple/README
+++ /dev/null
@@ -1,19 +0,0 @@
-This example demonstrates background window functionality in a hosted app.
-To run the app, you first need to edit it and install it:
-
-1. Put index.html and background.html in a directory where the HTTP server
- can find them.
-
-2. Edit manifest.json. Search for SOME_, replacing the text with URLs
- pointing to the launch page (index.html) and to the directory where
- index.html and background.html live.
-
-3. Install the app from manifest.json. You can use the Load unpacked extension
- button on the chrome://extensions page.
-
-Once the app is installed, you can launch it by clicking its icon on the
-New Tab page.
-
-For more information, see the documentation:
-
- http://code.google.com/chrome/apps/docs/developers_guide.html
diff --git a/chrome/common/extensions/docs/examples/apps/background-simple/background.html b/chrome/common/extensions/docs/examples/apps/background-simple/background.html
deleted file mode 100644
index 7095d3f..0000000
--- a/chrome/common/extensions/docs/examples/apps/background-simple/background.html
+++ /dev/null
@@ -1,13 +0,0 @@
-<!DOCTYPE html>
-<!--
- * 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>
- <script>
- new Notification("Simple Background App", {
- body: "A background window has been created"
- });
- </script>
-</html>
diff --git a/chrome/common/extensions/docs/examples/apps/background-simple/index.html b/chrome/common/extensions/docs/examples/apps/background-simple/index.html
deleted file mode 100644
index 025c8a6..0000000
--- a/chrome/common/extensions/docs/examples/apps/background-simple/index.html
+++ /dev/null
@@ -1,53 +0,0 @@
-<!DOCTYPE html>
-<!--
- * 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>
- <title>Simple Background App</title>
- <style>
- .hidden { display: none; }
- #unsupported { color: #d00; }
- </style>
- </head>
- <body>
- <h1>Simple Background App</h1>
- <p id="supported" class="hidden">
- <button id="openBackgroundWindow">Open background window</button>
- <button id="closeBackgroundWindow">Close background window</button>
- </p>
- <p id="unsupported" class="hidden">
- You are not using Chrome or have not installed the application for this
- page.
- </p>
- <script src="index.js"></script>
- <p>
- This app displays a notification
- whenever its background window is created.
- Background windows and this app are described in the
- <a href="http://code.google.com/chrome/apps/docs/developers_guide.html">apps documentation</a>.
- </p>
- <p>
- The generic source code is available for
- <a href="http://code.google.com/chrome/extensions/trunk/examples/apps/background-simple.zip">download</a>.
- The
- <a href="https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/docs/examples/apps/background-simple/README">README</a>
- tells you how to modify the code.
- </p>
- <p>
- If you just want to run a version of this app that's already on the web,
- here's how:
- </p>
- <ol>
- <li>
- <a href="http://background-simple.appspot.com/app.crx">Install the app</a>
- from background-simple.appspot.com.
- </li>
- <li>
- Launch Simple Background App from the New Tab page.
- </li>
- </ol>
- </body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/apps/background-simple/index.js b/chrome/common/extensions/docs/examples/apps/background-simple/index.js
deleted file mode 100644
index 970810c..0000000
--- a/chrome/common/extensions/docs/examples/apps/background-simple/index.js
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (c) 2012 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.
-
-// Check for support
-if (window.chrome && window.chrome.app && window.chrome.app.isInstalled) {
- document.getElementById('supported').className = '';
-} else {
- document.getElementById('unsupported').className = '';
-}
-var bgWinUrl = "background.html#yay";
-var bgWinName = "bgNotifier";
-
-function openBackgroundWindow() {
- window.open(bgWinUrl, bgWinName, "background");
-}
-
-function closeBackgroundWindow() {
- var w = window.open(bgWinUrl, bgWinName, "background");
- w.close();
-}
-
-document.addEventListener('DOMContentLoaded', function() {
- document.querySelector('#openBackgroundWindow').addEventListener(
- 'click', openBackgroundWindow);
- document.querySelector('#closeBackgroundWindow').addEventListener(
- 'click', closeBackgroundWindow);
-});
\ No newline at end of file
diff --git a/chrome/common/extensions/docs/examples/apps/background-simple/manifest.json b/chrome/common/extensions/docs/examples/apps/background-simple/manifest.json
deleted file mode 100644
index 0861384..0000000
--- a/chrome/common/extensions/docs/examples/apps/background-simple/manifest.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- "name": "Simple Background App",
- "version": "0.2",
- "app": {
- "urls": [ "http://SOME_SITE_WITHOUT_PORT_NUMBERS/SOME_PATH/" ],
- "launch": {
- "web_url": "http://SOME_SITE/SOME_PATH/index.html"
- }
- },
- "permissions": ["background", "notifications"],
- "manifest_version": 2
-}
diff --git a/chrome/common/extensions/docs/examples/apps/calculator/LICENSE b/chrome/common/extensions/docs/examples/apps/calculator/LICENSE
deleted file mode 100644
index e6c0d72..0000000
--- a/chrome/common/extensions/docs/examples/apps/calculator/LICENSE
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/chrome/common/extensions/docs/examples/apps/hello-java/HelloLicenseServlet.java b/chrome/common/extensions/docs/examples/apps/hello-java/HelloLicenseServlet.java
deleted file mode 100644
index 059f8ad..0000000
--- a/chrome/common/extensions/docs/examples/apps/hello-java/HelloLicenseServlet.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (c) 2012 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.
- *
- * The "Hello world!" of the Chrome Web Store Licensing API, in Java. This
- * program logs the user in with OpenID, fetches their license state with OAuth,
- * and prints one of these greetings as appropriate:
- *
- * 1. Hello *no* license!
- * 2. Hello *free trial* license!
- * 3. Hello *full* license!
- *
- * Brian Kennish <bkennish@chromium.org>
- */
-package com.example;
-
-import com.google.appengine.api.users.*;
-import com.google.appengine.repackaged.org.json.JSONObject;
-
-import java.io.*;
-import java.net.*;
-import java.util.HashSet;
-
-import javax.servlet.http.*;
-
-import oauth.signpost.OAuthConsumer;
-import oauth.signpost.basic.DefaultOAuthConsumer;
-
-/* A Google App Engine servlet. */
-@SuppressWarnings("serial")
-public class HelloLicenseServlet extends HttpServlet {
- /* TODO: The app ID from the Chrome Developer Dashboard. */
- public static final String APP_ID = "[INSERT APP ID HERE]";
-
- /* TODO: The token from the Chrome Developer Dashboard. */
- private static final String TOKEN = "[INSERT TOKEN HERE]";
-
- /* TODO: The token secret from the Chrome Developer Dashboard. */
- private static final String TOKEN_SECRET = "[INSERT TOKEN SECRET HERE]";
-
- /*
- * The license server URL, where %s are placeholders for app and
- * user IDs
- */
- public static final String SERVER_URL =
- "https://www.googleapis.com/chromewebstore/v1/licenses/%s/%s";
-
- /* The consumer key. */
- public static final String CONSUMER_KEY = "anonymous";
-
- /* The consumer secret. */
- public static final String CONSUMER_SECRET = CONSUMER_KEY;
-
- /* Handles "GET" requests. */
- public void doGet(HttpServletRequest request, HttpServletResponse response)
- throws IOException {
- response.setContentType("text/html; charset=UTF-8");
- UserService userService = UserServiceFactory.getUserService();
- PrintWriter output = response.getWriter();
- String url = request.getRequestURI();
-
- if (userService.isUserLoggedIn()) {
- // Provide a logout path.
- User user = userService.getCurrentUser();
- output.printf(
- "<strong>%s</strong> | <a href=\"%s\">Sign out</a><br><br>",
- user.getEmail(),
- userService.createLogoutURL(url)
- );
-
- try {
- // Send a signed request for the user's license state.
- OAuthConsumer oauth =
- new DefaultOAuthConsumer(CONSUMER_KEY, CONSUMER_SECRET);
- oauth.setTokenWithSecret(TOKEN, TOKEN_SECRET);
- URLConnection http =
- new URL(
- String.format(
- SERVER_URL,
- APP_ID,
- URLEncoder.encode(user.getFederatedIdentity(), "UTF-8")
- )
- ).openConnection();
- oauth.sign(http);
- http.connect();
-
- // Convert the response from the license server to a string.
- BufferedReader input =
- new BufferedReader(new InputStreamReader(http.getInputStream()));
- String file = "";
- for (String line; (line = input.readLine()) != null; file += line);
- input.close();
-
- // Parse the string as JSON and display the license state.
- JSONObject json = new JSONObject(file);
- output.printf(
- "Hello <strong>%s</strong> license!",
- "YES".equals(json.get("result")) ?
- "FULL".equals(json.get("accessLevel")) ? "full" : "free trial" :
- "no"
- );
- } catch (Exception exception) {
- // Dump any error.
- output.printf("Oops! <strong>%s</strong>", exception.getMessage());
- }
- } else { // The user isn't logged in.
- // Prompt for login.
- output.printf(
- "<a href=\"%s\">Sign in</a>",
- userService.createLoginURL(
- url,
- null,
- "https://www.google.com/accounts/o8/id",
- new HashSet<String>()
- )
- );
- }
- }
-}
diff --git a/chrome/common/extensions/docs/examples/apps/hello-java/README b/chrome/common/extensions/docs/examples/apps/hello-java/README
deleted file mode 100644
index 11ef20c7..0000000
--- a/chrome/common/extensions/docs/examples/apps/hello-java/README
+++ /dev/null
@@ -1,10 +0,0 @@
-See the documentation at
- http://code.google.com/chrome/webstore/docs/get_started.html
-for instructions on how to use these files.
-
-"HelloLicenseServlet.java" contains all the code you need to talk to the Chrome
-Web Store Licensing API.
-
-"workspace" contains a complete Eclipse project, "HelloLicense", which you can
-import and deploy to Google App Engine after updating
-"HelloLicenseServlet.java".
diff --git a/chrome/common/extensions/docs/examples/apps/hello-php/NOTICE b/chrome/common/extensions/docs/examples/apps/hello-php/NOTICE
deleted file mode 100644
index 261a4094..0000000
--- a/chrome/common/extensions/docs/examples/apps/hello-php/NOTICE
+++ /dev/null
@@ -1,97 +0,0 @@
-======================================================================
-./popuplib.js (PopupManager):
-======================================================================
-
-// Copyright 2009 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-======================================================================
-./index.php JS templating engine:
-======================================================================
-
-The MIT License
-
-Copyright (c) 2010 John Resig
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-
-======================================================================
-./lib/oauth/ is licensed as follows
- (Cf. ../lib/oauth/LICENSE.txt):
-======================================================================
-
-The MIT License
-
-Copyright (c) 2007 Andy Smith
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-
-======================================================================
-./lib/lightopenid/ is licensed as follows
- (Cf. ../lib/lightopenid/openid.php):
-======================================================================
-
-The MIT License
-
-Copyright (c) 2010, Mewp
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
diff --git a/chrome/common/extensions/docs/examples/apps/hello-php/README b/chrome/common/extensions/docs/examples/apps/hello-php/README
deleted file mode 100644
index c6566e9..0000000
--- a/chrome/common/extensions/docs/examples/apps/hello-php/README
+++ /dev/null
@@ -1,9 +0,0 @@
-See the documentation at
- http://code.google.com/chrome/webstore/docs/get_started.html
-for instructions on how to use these files.
-
-"lib" contains the necessary OAuth and OpenID libraries to talk to the Chrome
-Web Store Licensing API and Google's OpenID endpoint.
-
-To "index.php", replace APP_ID, TOKEN, and TOKEN_SECRET with your app's id, your
-developer OAuth access token, and its token secret, respectively.
diff --git a/chrome/common/extensions/docs/examples/apps/hello-php/index.php b/chrome/common/extensions/docs/examples/apps/hello-php/index.php
deleted file mode 100644
index 8b0d3cf..0000000
--- a/chrome/common/extensions/docs/examples/apps/hello-php/index.php
+++ /dev/null
@@ -1,288 +0,0 @@
-<?php
-/**
- * Copyright (c) 2012 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.
- *
- * A "Hello world!" for the Chrome Web Store Licensing API, in PHP. This
- * program logs the user in with Google's Federated Login API (OpenID), fetches
- * their license state with OAuth, and prints one of these greetings as
- * appropriate:
- *
- * 1. This user has FREE_TRIAL access to this application ( appId: 1 )
- * 2. This user has FULL access to this application ( appId: 1 )
- * 3. This user has NO access to this application ( appId: 1 )
- *
- * This code makes use of a popup ui extension to the OpenID protocol. Instead
- * of the user being redirected to the Google login page, a popup window opens
- * to the login page, keeping the user on the main application page. See
- * popuplib.js
- *
- * Eric Bidelman <ericbidelman@chromium.org>
- */
-
-session_start();
-
-require_once 'lib/oauth/OAuth.php';
-require_once 'lib/lightopenid/openid.php';
-
-// Full URL of the current application is running under.
-$scheme = (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] != 'on') ? 'http' :
- 'https';
-$selfUrl = "$scheme://{$_SERVER['HTTP_HOST']}{$_SERVER['PHP_SELF']}";
-
-
-/**
- * Wrapper class to make calls to the Chrome Web Store License Server.
- */
-class LicenseServerClient {
-
- const LICENSE_SERVER_HOST = 'https://www.googleapis.com';
- const CONSUMER_KEY = 'anonymous';
- const CONSUMER_SECRET = 'anonymous';
- const APP_ID = '1'; // Change to the correct id of your application.
- const TOKEN = '[REPLACE THIS WITH YOUR OAUTH TOKEN]';
- const TOKEN_SECRET = '[REPLACE THIS WITH YOUR OAUTH TOKEN SECRET]';
- public $consumer;
- public $token;
- public $signatureMethod;
-
- public function __construct() {
- $this->consumer = new OAuthConsumer(
- self::CONSUMER_KEY, self::CONSUMER_SECRET, NULL);
- $this->token = new OAuthToken(self::TOKEN, self::TOKEN_SECRET);
- $this->signatureMethod = new OAuthSignatureMethod_HMAC_SHA1();
- }
-
- /**
- * Makes an HTTP GET request to the specified URL.
- *
- * @param string $url Full URL of the resource to access
- * @param string $request OAuthRequest containing the signed request to make.
- * @param array $extraHeaders (optional) Array of headers.
- * @param bool $returnResponseHeaders True if resp headers should be returned.
- * @return string Response body from the server.
- */
- protected function send_signed_get($request, $extraHeaders=NULL,
- $returnRequestHeaders=false,
- $returnResponseHeaders=false) {
- $url = explode('?', $request->to_url());
- $curl = curl_init($url[0]);
- curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
- curl_setopt($curl, CURLOPT_FAILONERROR, false);
- curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
-
- // Return request headers in the response.
- curl_setopt($curl, CURLINFO_HEADER_OUT, $returnRequestHeaders);
-
- // Return response headers in the response?
- if ($returnResponseHeaders) {
- curl_setopt($curl, CURLOPT_HEADER, true);
- }
-
- $headers = array($request->to_header());
- if (is_array($extraHeaders)) {
- $headers = array_merge($headers, $extraHeaders);
- }
- curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
-
- // Execute the request. If an error occurs fill the response body with it.
- $response = curl_exec($curl);
- if (!$response) {
- $response = curl_error($curl);
- }
-
- // Add server's response headers to our response body
- $response = curl_getinfo($curl, CURLINFO_HEADER_OUT) . $response;
-
- curl_close($curl);
-
- return $response;
- }
-
- public function checkLicense($userId) {
- $url = self::LICENSE_SERVER_HOST . '/chromewebstore/v1/licenses/' .
- self::APP_ID . '/' . urlencode($userId);
-
- $request = OAuthRequest::from_consumer_and_token(
- $this->consumer, $this->token, 'GET', $url, array());
-
- $request->sign_request($this->signatureMethod, $this->consumer,
- $this->token);
-
- return $this->send_signed_get($request);
- }
-}
-
-try {
- $openid = new LightOpenID();
- $userId = $openid->identity;
- if (!isset($_GET['openid_mode'])) {
- // This section performs the OpenID dance with the normal redirect. Use it
- // if you want an alternative to the popup UI.
- if (isset($_GET['login'])) {
- $openid->identity = 'https://www.google.com/accounts/o8/id';
- $openid->required = array('namePerson/first', 'namePerson/last',
- 'contact/email');
- header('Location: ' . $openid->authUrl());
- }
- } else if ($_GET['openid_mode'] == 'cancel') {
- echo 'User has canceled authentication!';
- } else {
- $userId = $openid->validate() ? $openid->identity : '';
- $_SESSION['userId'] = $userId;
- $attributes = $openid->getAttributes();
- $_SESSION['attributes'] = $attributes;
- }
-} catch(ErrorException $e) {
- echo $e->getMessage();
- exit;
-}
-
-if (isset($_REQUEST['popup']) && !isset($_SESSION['redirect_to'])) {
- $_SESSION['redirect_to'] = $selfUrl;
- echo '<script type = "text/javascript">window.close();</script>';
- exit;
-} else if (isset($_SESSION['redirect_to'])) {
- $redirect = $_SESSION['redirect_to'];
- unset($_SESSION['redirect_to']);
- header('Location: ' . $redirect);
-} else if (isset($_REQUEST['queryLicenseServer'])) {
- $ls = new LicenseServerClient();
- echo $ls->checkLicense($_REQUEST['user_id']);
- exit;
-} else if (isset($_GET['logout'])) {
- unset($_SESSION['attributes']);
- unset($_SESSION['userId']);
- header('Location: ' . $selfUrl);
-}
-?>
-
-<!DOCTYPE html>
-<html>
- <head>
- <meta charset="utf-8" />
- <link href="main.css" type="text/css" rel="stylesheet" />
- <script type="text/javascript" src="popuplib.js"></script>
- <script type="text/html" id="ls_tmpl">
- <div id="access-level">
- <% if (result.toLowerCase() == 'yes') { %>
- This user has <span class="<%= accessLevel.toLowerCase() %>"><%= accessLevel %></span> access to this application ( appId: <%= appId %> )
- <% } else { %>
- This user has <span class="<%= result.toLowerCase() %>"><%= result %></span> access to this application ( appId: <%= appId %> )
- <% } %>
- </div>
- </script>
- </head>
- <body>
- <nav>
- <?php if (!isset($_SESSION['userId'])): ?>
- <a href="javascript:" onclick="openPopup(450, 500, this);">Sign in</a>
- <?php else: ?>
- <span>Welcome <?php echo @$_SESSION['attributes']['namePerson/first'] ?> <?php echo @$_SESSION['attributes']['namePerson/last'] ?> ( <?php echo $_SESSION['attributes']['contact/email'] ?> )</span>
- <a href="?logout">Sign out</a>
- <?php endif; ?>
- </nav>
- <?php if (isset($_SESSION['attributes'])): ?>
- <div id="container">
- <form action="<?php echo "$selfUrl?queryLicenseServer" ?>" onsubmit="return queryLicenseServer(this);">
- <input type="hidden" id="user_id" name="user_id" value="<?php echo $_SESSION['userId'] ?>" />
- <input type="submit" value="Check user's access" />
- </form>
- <div id="license-server-response"></div>
- </div>
- <?php endif; ?>
- <script>
- // Simple JavaScript Templating
- // John Resig - http://ejohn.org/ - MIT Licensed
- (function(){
- var cache = {};
-
- this.tmpl = function tmpl(str, data){
- // Figure out if we're getting a template, or if we need to
- // load the template - and be sure to cache the result.
- var fn = !/\W/.test(str) ?
- cache[str] = cache[str] ||
- tmpl(document.getElementById(str).innerHTML) :
-
- // Generate a reusable function that will serve as a template
- // generator (and which will be cached).
- new Function("obj",
- "var p=[],print=function(){p.push.apply(p,arguments);};" +
-
- // Introduce the data as local variables using with(){}
- "with(obj){p.push('" +
-
- // Convert the template into pure JavaScript
- str
- .replace(/[\r\t\n]/g, " ")
- .split("<%").join("\t")
- .replace(/((^|%>)[^\t]*)'/g, "$1\r")
- .replace(/\t=(.*?)%>/g, "',$1,'")
- .split("\t").join("');")
- .split("%>").join("p.push('")
- .split("\r").join("\\'")
- + "');}return p.join('');");
-
- // Provide some basic currying to the user
- return data ? fn( data ) : fn;
- };
- })();
-
- function queryLicenseServer(form) {
- var userId = form.user_id.value;
-
- if (!userId) {
- alert('No OpenID specified!');
- return false;
- }
-
- var req = new XMLHttpRequest();
- req.onreadystatechange = function(e) {
- if (this.readyState == 4) {
- var resp = JSON.parse(this.responseText);
- var el = document.getElementById('license-server-response');
- if (resp.error) {
- el.innerHTML = ['<div class="error">Error ', resp.error.code,
- ': ', resp.error.message, '</div>'].join('');
- } else {
- el.innerHTML = tmpl('ls_tmpl', resp);
- }
- }
- };
- var url =
- [form.action, '&user_id=', encodeURIComponent(userId)].join('');
- req.open('GET', url, true);
- req.send(null);
-
- return false;
- }
-
- function openPopup(w, h, link) {
- var extensions = {
- 'openid.ns.ext1': 'http://openid.net/srv/ax/1.0',
- 'openid.ext1.mode': 'fetch_request',
- 'openid.ext1.type.email': 'http://axschema.org/contact/email',
- 'openid.ext1.type.first': 'http://axschema.org/namePerson/first',
- 'openid.ext1.type.last': 'http://axschema.org/namePerson/last',
- 'openid.ext1.required': 'email,first,last',
- 'openid.ui.icon': 'true'
- };
-
- var googleOpener = popupManager.createPopupOpener({
- opEndpoint: 'https://www.google.com/accounts/o8/ud',
- returnToUrl: '<?php echo "$selfUrl?popup=true" ?>',
- onCloseHandler: function() {
- window.location = '<?php echo $selfUrl ?>';
- },
- shouldEncodeUrls: false,
- extensions: extensions
- });
- link.parentNode.appendChild(
- document.createTextNode('Authenticating...'));
- link.parentNode.removeChild(link);
- googleOpener.popup(w, h);
- }
- </script>
- </body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/apps/hello-php/lib/lightopenid/openid.php b/chrome/common/extensions/docs/examples/apps/hello-php/lib/lightopenid/openid.php
deleted file mode 100644
index 4fa6cdc..0000000
--- a/chrome/common/extensions/docs/examples/apps/hello-php/lib/lightopenid/openid.php
+++ /dev/null
@@ -1,563 +0,0 @@
-<?php
-/**
- * This class provides a simple interface for OpenID (1.1 and 2.0) authentication.
- * Supports Yadis discovery.
- * The authentication process is stateless/dumb.
- *
- * Usage:
- * Sign-on with OpenID is a two step process:
- * Step one is authentication with the provider:
- * <code>
- * $openid = new LightOpenID;
- * $openid->identity = 'ID supplied by user';
- * header('Location: ' . $openid->authUrl());
- * </code>
- * The provider then sends various parameters via GET, one of them is openid_mode.
- * Step two is verification:
- * <code>
- * if ($this->data['openid_mode']) {
- * $openid = new LightOpenID;
- * echo $openid->validate() ? 'Logged in.' : 'Failed';
- * }
- * </code>
- *
- * Optionally, you can set $returnUrl and $realm (or $trustRoot, which is an alias).
- * The default values for those are:
- * $openid->realm = (!empty($_SERVER['HTTPS']) ? 'https' : 'http') . '://' . $_SERVER['HTTP_HOST'];
- * $openid->returnUrl = $openid->realm . $_SERVER['REQUEST_URI'];
- * If you don't know their meaning, refer to any openid tutorial, or specification. Or just guess.
- *
- * AX and SREG extensions are supported.
- * To use them, specify $openid->required and/or $openid->optional.
- * These are arrays, with values being AX schema paths (the 'path' part of the URL).
- * For example:
- * $openid->required = array('namePerson/friendly', 'contact/email');
- * $openid->optional = array('namePerson/first');
- * If the server supports only SREG or OpenID 1.1, these are automaticaly
- * mapped to SREG names, so that user doesn't have to know anything about the server.
- *
- * To get the values, use $openid->getAttributes().
- *
- *
- * The library depends on curl, and requires PHP 5.
- * @author Mewp
- * @copyright Copyright (c) 2010, Mewp
- * @license http://www.opensource.org/licenses/mit-license.php MIT
- */
-class LightOpenID
-{
- public $returnUrl
- , $required = array()
- , $optional = array();
- private $identity, $claimed_id;
- protected $server, $version, $trustRoot, $aliases, $identifier_select = false
- , $ax = false, $sreg = false, $data;
- static protected $ax_to_sreg = array(
- 'namePerson/friendly' => 'nickname',
- 'contact/email' => 'email',
- 'namePerson' => 'fullname',
- 'birthDate' => 'dob',
- 'person/gender' => 'gender',
- 'contact/postalCode/home' => 'postcode',
- 'contact/country/home' => 'country',
- 'pref/language' => 'language',
- 'pref/timezone' => 'timezone',
- );
-
- function __construct()
- {
- $this->trustRoot = (!empty($_SERVER['HTTPS']) ? 'https' : 'http') . '://' . $_SERVER['HTTP_HOST'];
- $this->returnUrl = $this->trustRoot . $_SERVER['REQUEST_URI'];
-
- if (!function_exists('curl_exec')) {
- throw new ErrorException('Curl extension is required.');
- }
-
- $this->data = $_POST + $_GET; # OPs may send data as POST or GET.
- }
-
- function __set($name, $value)
- {
- switch ($name) {
- case 'identity':
- if (strlen($value = trim($value))) {
- if (preg_match('#^xri:/*#i', $value, $m)) {
- $value = substr($value, strlen($m[0]));
- } elseif (!preg_match('/^(?:[=@+\$!\(]|https?:)/i', $value)) {
- $value = "http://$value";
- }
- if (preg_match('#^https?://[^/]+$#i', $value, $m)) {
- $value .= '/';
- }
- }
- $this->$name = $this->claimed_id = $value;
- break;
- case 'trustRoot':
- case 'realm':
- $this->trustRoot = trim($value);
- }
- }
-
- function __get($name)
- {
- switch ($name) {
- case 'identity':
- # We return claimed_id instead of identity,
- # because the developer should see the claimed identifier,
- # i.e. what they set as identity, not the op-local identifier (which is what we verify)
- return $this->claimed_id;
- case 'trustRoot':
- case 'realm':
- return $this->trustRoot;
- }
- }
-
- protected function request($url, $method='GET', $params=array())
- {
- $params = http_build_query($params, '', '&');
- $curl = curl_init($url . ($method == 'GET' && $params ? '?' . $params : ''));
- curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
- curl_setopt($curl, CURLOPT_HEADER, false);
- curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
- curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
- if ($method == 'POST') {
- curl_setopt($curl, CURLOPT_POST, true);
- curl_setopt($curl, CURLOPT_POSTFIELDS, $params);
- } elseif ($method == 'HEAD') {
- curl_setopt($curl, CURLOPT_HEADER, true);
- curl_setopt($curl, CURLOPT_NOBODY, true);
- } else {
- curl_setopt($curl, CURLOPT_HTTPGET, true);
- }
- $response = curl_exec($curl);
-
- if (curl_errno($curl)) {
- throw new ErrorException(curl_error($curl), curl_errno($curl));
- }
-
- return $response;
- }
-
- protected function build_url($url, $parts)
- {
- if (isset($url['query'], $parts['query'])) {
- $parts['query'] = $url['query'] . '&' . $parts['query'];
- }
-
- $url = $parts + $url;
- $url = $url['scheme'] . '://'
- . (empty($url['username'])?''
- :(empty($url['password'])? "{$url['username']}@"
- :"{$url['username']}:{$url['password']}@"))
- . $url['host']
- . (empty($url['port'])?'':":{$url['port']}")
- . (empty($url['path'])?'':$url['path'])
- . (empty($url['query'])?'':"?{$url['query']}")
- . (empty($url['fragment'])?'':":{$url['fragment']}");
- return $url;
- }
-
- /**
- * Helper function used to scan for <meta>/<link> tags and extract information
- * from them
- */
- protected function htmlTag($content, $tag, $attrName, $attrValue, $valueName)
- {
- preg_match_all("#<{$tag}[^>]*$attrName=['\"].*?$attrValue.*?['\"][^>]*$valueName=['\"](.+?)['\"][^>]*/?>#i", $content, $matches1);
- preg_match_all("#<{$tag}[^>]*$valueName=['\"](.+?)['\"][^>]*$attrName=['\"].*?$attrValue.*?['\"][^>]*/?>#i", $content, $matches2);
-
- $result = array_merge($matches1[1], $matches2[1]);
- return empty($result)?false:$result[0];
- }
-
- /**
- * Performs Yadis and HTML discovery. Normally not used.
- * @param $url Identity URL.
- * @return String OP Endpoint (i.e. OpenID provider address).
- * @throws ErrorException
- */
- function discover($url)
- {
- if (!$url) throw new ErrorException('No identity supplied.');
- # Use xri.net proxy to resolve i-name identities
- if (!preg_match('#^https?:#', $url)) {
- $url = "https://xri.net/$url";
- }
-
- # We save the original url in case of Yadis discovery failure.
- # It can happen when we'll be lead to an XRDS document
- # which does not have any OpenID2 services.
- $originalUrl = $url;
-
- # A flag to disable yadis discovery in case of failure in headers.
- $yadis = true;
-
- # We'll jump a maximum of 5 times, to avoid endless redirections.
- for ($i = 0; $i < 5; $i ++) {
- if ($yadis) {
- $headers = explode("\n",$this->request($url, 'HEAD'));
-
- $next = false;
- foreach ($headers as $header) {
- if (preg_match('#X-XRDS-Location\s*:\s*(.*)#', $header, $m)) {
- $url = $this->build_url(parse_url($url), parse_url(trim($m[1])));
- $next = true;
- }
-
- if (preg_match('#Content-Type\s*:\s*application/xrds\+xml#i', $header)) {
- # Found an XRDS document, now let's find the server, and optionally delegate.
- $content = $this->request($url, 'GET');
-
- # OpenID 2
- # We ignore it for MyOpenID, as it breaks sreg if using OpenID 2.0
- $ns = preg_quote('http://specs.openid.net/auth/2.0/');
- if (preg_match('#<Service.*?>(.*)<Type>\s*'.$ns.'(.*?)\s*</Type>(.*)</Service>#s', $content, $m)) {
- $content = ' ' . $m[1] . $m[3]; # The space is added, so that strpos doesn't return 0.
- if ($m[2] == 'server') $this->identifier_select = true;
-
- preg_match('#<URI.*?>(.*)</URI>#', $content, $server);
- preg_match('#<(Local|Canonical)ID>(.*)</\1ID>#', $content, $delegate);
- if (empty($server)) {
- return false;
- }
- # Does the server advertise support for either AX or SREG?
- $this->ax = (bool) strpos($content, '<Type>http://openid.net/srv/ax/1.0</Type>');
- $this->sreg = strpos($content, '<Type>http://openid.net/sreg/1.0</Type>')
- || strpos($content, '<Type>http://openid.net/extensions/sreg/1.1</Type>');
-
- $server = $server[1];
- if (isset($delegate[2])) $this->identity = trim($delegate[2]);
- $this->version = 2;
-
- $this->server = $server;
- return $server;
- }
-
- # OpenID 1.1
- $ns = preg_quote('http://openid.net/signon/1.1');
- if (preg_match('#<Service.*?>(.*)<Type>\s*'.$ns.'\s*</Type>(.*)</Service>#s', $content, $m)) {
- $content = ' ' . $m[1] . $m[2];
-
- preg_match('#<URI.*?>(.*)</URI>#', $content, $server);
- preg_match('#<.*?Delegate>(.*)</.*?Delegate>#', $content, $delegate);
- if (empty($server)) {
- return false;
- }
- # AX can be used only with OpenID 2.0, so checking only SREG
- $this->sreg = strpos($content, '<Type>http://openid.net/sreg/1.0</Type>')
- || strpos($content, '<Type>http://openid.net/extensions/sreg/1.1</Type>');
-
- $server = $server[1];
- if (isset($delegate[1])) $this->identity = $delegate[1];
- $this->version = 1;
-
- $this->server = $server;
- return $server;
- }
-
- $next = true;
- $yadis = false;
- $url = $originalUrl;
- $content = null;
- break;
- }
- }
- if ($next) continue;
-
- # There are no relevant information in headers, so we search the body.
- $content = $this->request($url, 'GET');
- if ($location = $this->htmlTag($content, 'meta', 'http-equiv', 'X-XRDS-Location', 'value')) {
- $url = $this->build_url(parse_url($url), parse_url($location));
- continue;
- }
- }
-
- if (!$content) $content = $this->request($url, 'GET');
-
- # At this point, the YADIS Discovery has failed, so we'll switch
- # to openid2 HTML discovery, then fallback to openid 1.1 discovery.
- $server = $this->htmlTag($content, 'link', 'rel', 'openid2.provider', 'href');
- $delegate = $this->htmlTag($content, 'link', 'rel', 'openid2.local_id', 'href');
- $this->version = 2;
-
- if (!$server) {
- # The same with openid 1.1
- $server = $this->htmlTag($content, 'link', 'rel', 'openid.server', 'href');
- $delegate = $this->htmlTag($content, 'link', 'rel', 'openid.delegate', 'href');
- $this->version = 1;
- }
-
- if ($server) {
- # We found an OpenID2 OP Endpoint
- if ($delegate) {
- # We have also found an OP-Local ID.
- $this->identity = $delegate;
- }
- $this->server = $server;
- return $server;
- }
-
- throw new ErrorException('No servers found!');
- }
- throw new ErrorException('Endless redirection!');
- }
-
- protected function sregParams()
- {
- $params = array();
- # We always use SREG 1.1, even if the server is advertising only support for 1.0.
- # That's because it's fully backwards compatibile with 1.0, and some providers
- # advertise 1.0 even if they accept only 1.1. One such provider is myopenid.com
- $params['openid.ns.sreg'] = 'http://openid.net/extensions/sreg/1.1';
- if ($this->required) {
- $params['openid.sreg.required'] = array();
- foreach ($this->required as $required) {
- if (!isset(self::$ax_to_sreg[$required])) continue;
- $params['openid.sreg.required'][] = self::$ax_to_sreg[$required];
- }
- $params['openid.sreg.required'] = implode(',', $params['openid.sreg.required']);
- }
-
- if ($this->optional) {
- $params['openid.sreg.optional'] = array();
- foreach ($this->optional as $optional) {
- if (!isset(self::$ax_to_sreg[$optional])) continue;
- $params['openid.sreg.optional'][] = self::$ax_to_sreg[$optional];
- }
- $params['openid.sreg.optional'] = implode(',', $params['openid.sreg.optional']);
- }
- return $params;
- }
- protected function axParams()
- {
- $params = array();
- if ($this->required || $this->optional) {
- $params['openid.ns.ax'] = 'http://openid.net/srv/ax/1.0';
- $params['openid.ax.mode'] = 'fetch_request';
- $this->aliases = array();
- $counts = array();
- $required = array();
- $optional = array();
- foreach (array('required','optional') as $type) {
- foreach ($this->$type as $alias => $field) {
- if (is_int($alias)) $alias = strtr($field, '/', '_');
- $this->aliases[$alias] = 'http://axschema.org/' . $field;
- if (empty($counts[$alias])) $counts[$alias] = 0;
- $counts[$alias] += 1;
- ${$type}[] = $alias;
- }
- }
- foreach ($this->aliases as $alias => $ns) {
- $params['openid.ax.type.' . $alias] = $ns;
- }
- foreach ($counts as $alias => $count) {
- if ($count == 1) continue;
- $params['openid.ax.count.' . $alias] = $count;
- }
-
- # Don't send empty ax.requied and ax.if_available.
- # Google and possibly other providers refuse to support ax when one of these is empty.
- if($required) {
- $params['openid.ax.required'] = implode(',', $required);
- }
- if($optional) {
- $params['openid.ax.if_available'] = implode(',', $optional);
- }
- }
- return $params;
- }
-
- protected function authUrl_v1()
- {
- $returnUrl = $this->returnUrl;
- # If we have an openid.delegate that is different from our claimed id,
- # we need to somehow preserve the claimed id between requests.
- # The simplest way is to just send it along with the return_to url.
- if($this->identity != $this->claimed_id) {
- $returnUrl .= (strpos($returnUrl, '?') ? '&' : '?') . 'openid.claimed_id=' . $this->claimed_id;
- }
-
- $params = array(
- 'openid.return_to' => $returnUrl,
- 'openid.mode' => 'checkid_setup',
- 'openid.identity' => $this->identity,
- 'openid.trust_root' => $this->trustRoot,
- ) + $this->sregParams();
-
- return $this->build_url(parse_url($this->server)
- , array('query' => http_build_query($params, '', '&')));
- }
-
- protected function authUrl_v2($identifier_select)
- {
- $params = array(
- 'openid.ns' => 'http://specs.openid.net/auth/2.0',
- 'openid.mode' => 'checkid_setup',
- 'openid.return_to' => $this->returnUrl,
- 'openid.realm' => $this->trustRoot,
- );
- if ($this->ax) {
- $params += $this->axParams();
- }
- if ($this->sreg) {
- $params += $this->sregParams();
- }
- if (!$this->ax && !$this->sreg) {
- # If OP doesn't advertise either SREG, nor AX, let's send them both
- # in worst case we don't get anything in return.
- $params += $this->axParams() + $this->sregParams();
- }
-
- if ($identifier_select) {
- $params['openid.identity'] = $params['openid.claimed_id']
- = 'http://specs.openid.net/auth/2.0/identifier_select';
- } else {
- $params['openid.identity'] = $this->identity;
- $params['openid.claimed_id'] = $this->claimed_id;
- }
-
- return $this->build_url(parse_url($this->server)
- , array('query' => http_build_query($params, '', '&')));
- }
-
- /**
- * Returns authentication url. Usually, you want to redirect your user to it.
- * @return String The authentication url.
- * @param String $select_identifier Whether to request OP to select identity for an user in OpenID 2. Does not affect OpenID 1.
- * @throws ErrorException
- */
- function authUrl($identifier_select = null)
- {
- if (!$this->server) $this->discover($this->identity);
-
- if ($this->version == 2) {
- if ($identifier_select === null) {
- return $this->authUrl_v2($this->identifier_select);
- }
- return $this->authUrl_v2($identifier_select);
- }
- return $this->authUrl_v1();
- }
-
- /**
- * Performs OpenID verification with the OP.
- * @return Bool Whether the verification was successful.
- * @throws ErrorException
- */
- function validate()
- {
- $this->claimed_id = isset($this->data['openid_claimed_id'])?$this->data['openid_claimed_id']:$this->data['openid_identity'];
- $params = array(
- 'openid.assoc_handle' => $this->data['openid_assoc_handle'],
- 'openid.signed' => $this->data['openid_signed'],
- 'openid.sig' => $this->data['openid_sig'],
- );
-
- if (isset($this->data['openid_op_endpoint'])) {
- # We're dealing with an OpenID 2.0 server, so let's set an ns
- # Even though we should know location of the endpoint,
- # we still need to verify it by discovery, so $server is not set here
- $params['openid.ns'] = 'http://specs.openid.net/auth/2.0';
- }
- $server = $this->discover($this->data['openid_identity']);
-
- foreach (explode(',', $this->data['openid_signed']) as $item) {
- # Checking whether magic_quotes_gpc is turned on, because
- # the function may fail if it is. For example, when fetching
- # AX namePerson, it might containg an apostrophe, which will be escaped.
- # In such case, validation would fail, since we'd send different data than OP
- # wants to verify. stripslashes() should solve that problem, but we can't
- # use it when magic_quotes is off.
- $value = $this->data['openid_' . str_replace('.','_',$item)];
- $params['openid.' . $item] = get_magic_quotes_gpc() ? stripslashes($value) : $value;
- }
-
- $params['openid.mode'] = 'check_authentication';
-
- $response = $this->request($server, 'POST', $params);
-
- return preg_match('/is_valid\s*:\s*true/i', $response);
- }
- protected function getAxAttributes()
- {
- $alias = null;
- if (isset($this->data['openid_ns_ax'])
- && $this->data['openid_ns_ax'] != 'http://openid.net/srv/ax/1.0'
- ) { # It's the most likely case, so we'll check it before
- $alias = 'ax';
- } else {
- # 'ax' prefix is either undefined, or points to another extension,
- # so we search for another prefix
- foreach ($this->data as $key => $val) {
- if (substr($key, 0, strlen('openid_ns_')) == 'openid_ns_'
- && $val == 'http://openid.net/srv/ax/1.0'
- ) {
- $alias = substr($key, strlen('openid_ns_'));
- break;
- }
- }
- }
- if (!$alias) {
- # An alias for AX schema has not been found,
- # so there is no AX data in the OP's response
- return array();
- }
-
- foreach ($this->data as $key => $value) {
- $keyMatch = 'openid_' . $alias . '_value_';
- if (substr($key, 0, strlen($keyMatch)) != $keyMatch) {
- continue;
- }
- $key = substr($key, strlen($keyMatch));
- if (!isset($this->data['openid_' . $alias . '_type_' . $key])) {
- # OP is breaking the spec by returning a field without
- # associated ns. This shouldn't happen, but it's better
- # to check, than cause an E_NOTICE.
- continue;
- }
- $key = substr($this->data['openid_' . $alias . '_type_' . $key],
- strlen('http://axschema.org/'));
- $attributes[$key] = $value;
- }
- # Found the AX attributes, so no need to scan for SREG.
- return $attributes;
- }
- protected function getSregAttributes()
- {
- $attributes = array();
- $sreg_to_ax = array_flip(self::$ax_to_sreg);
- foreach ($this->data as $key => $value) {
- $keyMatch = 'openid_sreg_';
- if (substr($key, 0, strlen($keyMatch)) != $keyMatch) {
- continue;
- }
- $key = substr($key, strlen($keyMatch));
- if (!isset($sreg_to_ax[$key])) {
- # The field name isn't part of the SREG spec, so we ignore it.
- continue;
- }
- $attributes[$sreg_to_ax[$key]] = $value;
- }
- return $attributes;
- }
- /**
- * Gets AX/SREG attributes provided by OP. should be used only after successful validaton.
- * Note that it does not guarantee that any of the required/optional parameters will be present,
- * or that there will be no other attributes besides those specified.
- * In other words. OP may provide whatever information it wants to.
- * * SREG names will be mapped to AX names.
- * * @return Array Array of attributes with keys being the AX schema names, e.g. 'contact/email'
- * @see http://www.axschema.org/types/
- */
- function getAttributes()
- {
- $attributes;
- if (isset($this->data['openid_ns'])
- && $this->data['openid_ns'] == 'http://specs.openid.net/auth/2.0'
- ) { # OpenID 2.0
- # We search for both AX and SREG attributes, with AX taking precedence.
- return $this->getAxAttributes() + $this->getSregAttributes();
- }
- return $this->getSregAttributes();
- }
-}
diff --git a/chrome/common/extensions/docs/examples/apps/hello-php/lib/oauth/CHANGELOG.txt b/chrome/common/extensions/docs/examples/apps/hello-php/lib/oauth/CHANGELOG.txt
deleted file mode 100644
index b12ff1c5..0000000
--- a/chrome/common/extensions/docs/examples/apps/hello-php/lib/oauth/CHANGELOG.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-== 2008.08.04 ==
-* Added LICENSE.txt file with MIT license, copyright owner is perhaps
- dubious however.
-== 2008.07.22 ==
-* Change to encoding to fix last change to encoding of spaces
-== 2008.07.15 ==
-* Another change to encoding per
- http://groups.google.com/group/oauth/browse_thread/thread/d39931d39b4af4bd
-* A change to port handling to better deal with https and the like per
- http://groups.google.com/group/oauth/browse_thread/thread/1b203a51d9590226
-* Fixed a small bug per
- http://code.google.com/p/oauth/issues/detail?id=26
-* Added missing base_string debug info when using RSA-SHA1
-* Increased size of example endpoint input field and added note about
- query strings
diff --git a/chrome/common/extensions/docs/examples/apps/hello-php/lib/oauth/LICENSE.txt b/chrome/common/extensions/docs/examples/apps/hello-php/lib/oauth/LICENSE.txt
deleted file mode 100644
index 89f0591..0000000
--- a/chrome/common/extensions/docs/examples/apps/hello-php/lib/oauth/LICENSE.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-The MIT License
-
-Copyright (c) 2007 Andy Smith
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-
diff --git a/chrome/common/extensions/docs/examples/apps/hello-php/lib/oauth/OAuth.php b/chrome/common/extensions/docs/examples/apps/hello-php/lib/oauth/OAuth.php
deleted file mode 100644
index d32db32..0000000
--- a/chrome/common/extensions/docs/examples/apps/hello-php/lib/oauth/OAuth.php
+++ /dev/null
@@ -1,879 +0,0 @@
-<?php
-// vim: foldmethod=marker
-
-/* Generic exception class
- */
-class OAuthException extends Exception {
- // pass
-}
-
-class OAuthConsumer {
- public $key;
- public $secret;
-
- function __construct($key, $secret, $callback_url=NULL) {
- $this->key = $key;
- $this->secret = $secret;
- $this->callback_url = $callback_url;
- }
-
- function __toString() {
- return "OAuthConsumer[key=$this->key,secret=$this->secret]";
- }
-}
-
-class OAuthToken {
- // access tokens and request tokens
- public $key;
- public $secret;
-
- /**
- * key = the token
- * secret = the token secret
- */
- function __construct($key, $secret) {
- $this->key = $key;
- $this->secret = $secret;
- }
-
- /**
- * generates the basic string serialization of a token that a server
- * would respond to request_token and access_token calls with
- */
- function to_string() {
- return "oauth_token=" .
- OAuthUtil::urlencode_rfc3986($this->key) .
- "&oauth_token_secret=" .
- OAuthUtil::urlencode_rfc3986($this->secret);
- }
-
- function __toString() {
- return $this->to_string();
- }
-}
-
-/**
- * A class for implementing a Signature Method
- * See section 9 ("Signing Requests") in the spec
- */
-abstract class OAuthSignatureMethod {
- /**
- * Needs to return the name of the Signature Method (ie HMAC-SHA1)
- * @return string
- */
- abstract public function get_name();
-
- /**
- * Build up the signature
- * NOTE: The output of this function MUST NOT be urlencoded.
- * the encoding is handled in OAuthRequest when the final
- * request is serialized
- * @param OAuthRequest $request
- * @param OAuthConsumer $consumer
- * @param OAuthToken $token
- * @return string
- */
- abstract public function build_signature($request, $consumer, $token);
-
- /**
- * Verifies that a given signature is correct
- * @param OAuthRequest $request
- * @param OAuthConsumer $consumer
- * @param OAuthToken $token
- * @param string $signature
- * @return bool
- */
- public function check_signature($request, $consumer, $token, $signature) {
- $built = $this->build_signature($request, $consumer, $token);
- return $built == $signature;
- }
-}
-
-/**
- * The HMAC-SHA1 signature method uses the HMAC-SHA1 signature algorithm as defined in [RFC2104]
- * where the Signature Base String is the text and the key is the concatenated values (each first
- * encoded per Parameter Encoding) of the Consumer Secret and Token Secret, separated by an '&'
- * character (ASCII code 38) even if empty.
- * - Chapter 9.2 ("HMAC-SHA1")
- */
-class OAuthSignatureMethod_HMAC_SHA1 extends OAuthSignatureMethod {
- function get_name() {
- return "HMAC-SHA1";
- }
-
- public function build_signature($request, $consumer, $token) {
- $base_string = $request->get_signature_base_string();
- $request->base_string = $base_string;
-
- $key_parts = array(
- $consumer->secret,
- ($token) ? $token->secret : ""
- );
-
- $key_parts = OAuthUtil::urlencode_rfc3986($key_parts);
- $key = implode('&', $key_parts);
-
- return base64_encode(hash_hmac('sha1', $base_string, $key, true));
- }
-}
-
-/**
- * The PLAINTEXT method does not provide any security protection and SHOULD only be used
- * over a secure channel such as HTTPS. It does not use the Signature Base String.
- * - Chapter 9.4 ("PLAINTEXT")
- */
-class OAuthSignatureMethod_PLAINTEXT extends OAuthSignatureMethod {
- public function get_name() {
- return "PLAINTEXT";
- }
-
- /**
- * oauth_signature is set to the concatenated encoded values of the Consumer Secret and
- * Token Secret, separated by a '&' character (ASCII code 38), even if either secret is
- * empty. The result MUST be encoded again.
- * - Chapter 9.4.1 ("Generating Signatures")
- *
- * Please note that the second encoding MUST NOT happen in the SignatureMethod, as
- * OAuthRequest handles this!
- */
- public function build_signature($request, $consumer, $token) {
- $key_parts = array(
- $consumer->secret,
- ($token) ? $token->secret : ""
- );
-
- $key_parts = OAuthUtil::urlencode_rfc3986($key_parts);
- $key = implode('&', $key_parts);
- $request->base_string = $key;
-
- return $key;
- }
-}
-
-/**
- * The RSA-SHA1 signature method uses the RSASSA-PKCS1-v1_5 signature algorithm as defined in
- * [RFC3447] section 8.2 (more simply known as PKCS#1), using SHA-1 as the hash function for
- * EMSA-PKCS1-v1_5. It is assumed that the Consumer has provided its RSA public key in a
- * verified way to the Service Provider, in a manner which is beyond the scope of this
- * specification.
- * - Chapter 9.3 ("RSA-SHA1")
- */
-abstract class OAuthSignatureMethod_RSA_SHA1 extends OAuthSignatureMethod {
- public function get_name() {
- return "RSA-SHA1";
- }
-
- // Up to the SP to implement this lookup of keys. Possible ideas are:
- // (1) do a lookup in a table of trusted certs keyed off of consumer
- // (2) fetch via http using a url provided by the requester
- // (3) some sort of specific discovery code based on request
- //
- // Either way should return a string representation of the certificate
- protected abstract function fetch_public_cert(&$request);
-
- // Up to the SP to implement this lookup of keys. Possible ideas are:
- // (1) do a lookup in a table of trusted certs keyed off of consumer
- //
- // Either way should return a string representation of the certificate
- protected abstract function fetch_private_cert(&$request);
-
- public function build_signature($request, $consumer, $token) {
- $base_string = $request->get_signature_base_string();
- $request->base_string = $base_string;
-
- // Fetch the private key cert based on the request
- $cert = $this->fetch_private_cert($request);
-
- // Pull the private key ID from the certificate
- $privatekeyid = openssl_get_privatekey($cert);
-
- // Sign using the key
- $ok = openssl_sign($base_string, $signature, $privatekeyid);
-
- // Release the key resource
- openssl_free_key($privatekeyid);
-
- return base64_encode($signature);
- }
-
- public function check_signature($request, $consumer, $token, $signature) {
- $decoded_sig = base64_decode($signature);
-
- $base_string = $request->get_signature_base_string();
-
- // Fetch the public key cert based on the request
- $cert = $this->fetch_public_cert($request);
-
- // Pull the public key ID from the certificate
- $publickeyid = openssl_get_publickey($cert);
-
- // Check the computed signature against the one passed in the query
- $ok = openssl_verify($base_string, $decoded_sig, $publickeyid);
-
- // Release the key resource
- openssl_free_key($publickeyid);
-
- return $ok == 1;
- }
-}
-
-class OAuthRequest {
- protected $parameters;
- protected $http_method;
- protected $http_url;
- // for debug purposes
- public $base_string;
- public static $version = '1.0';
- public static $POST_INPUT = 'php://input';
-
- function __construct($http_method, $http_url, $parameters=NULL) {
- $parameters = ($parameters) ? $parameters : array();
- $parameters = array_merge( OAuthUtil::parse_parameters(parse_url($http_url, PHP_URL_QUERY)), $parameters);
- $this->parameters = $parameters;
- $this->http_method = $http_method;
- $this->http_url = $http_url;
- }
-
-
- /**
- * attempt to build up a request from what was passed to the server
- */
- public static function from_request($http_method=NULL, $http_url=NULL, $parameters=NULL) {
- $scheme = (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] != "on")
- ? 'http'
- : 'https';
- $http_url = ($http_url) ? $http_url : $scheme .
- '://' . $_SERVER['HTTP_HOST'] .
- ':' .
- $_SERVER['SERVER_PORT'] .
- $_SERVER['REQUEST_URI'];
- $http_method = ($http_method) ? $http_method : $_SERVER['REQUEST_METHOD'];
-
- // We weren't handed any parameters, so let's find the ones relevant to
- // this request.
- // If you run XML-RPC or similar you should use this to provide your own
- // parsed parameter-list
- if (!$parameters) {
- // Find request headers
- $request_headers = OAuthUtil::get_headers();
-
- // Parse the query-string to find GET parameters
- $parameters = OAuthUtil::parse_parameters($_SERVER['QUERY_STRING']);
-
- // It's a POST request of the proper content-type, so parse POST
- // parameters and add those overriding any duplicates from GET
- if ($http_method == "POST"
- && isset($request_headers['Content-Type'])
- && strstr($request_headers['Content-Type'],
- 'application/x-www-form-urlencoded')
- ) {
- $post_data = OAuthUtil::parse_parameters(
- file_get_contents(self::$POST_INPUT)
- );
- $parameters = array_merge($parameters, $post_data);
- }
-
- // We have a Authorization-header with OAuth data. Parse the header
- // and add those overriding any duplicates from GET or POST
- if (isset($request_headers['Authorization']) && substr($request_headers['Authorization'], 0, 6) == 'OAuth ') {
- $header_parameters = OAuthUtil::split_header(
- $request_headers['Authorization']
- );
- $parameters = array_merge($parameters, $header_parameters);
- }
-
- }
-
- return new OAuthRequest($http_method, $http_url, $parameters);
- }
-
- /**
- * pretty much a helper function to set up the request
- */
- public static function from_consumer_and_token($consumer, $token, $http_method, $http_url, $parameters=NULL) {
- $parameters = ($parameters) ? $parameters : array();
- $defaults = array("oauth_version" => OAuthRequest::$version,
- "oauth_nonce" => OAuthRequest::generate_nonce(),
- "oauth_timestamp" => OAuthRequest::generate_timestamp(),
- "oauth_consumer_key" => $consumer->key);
- if ($token)
- $defaults['oauth_token'] = $token->key;
-
- $parameters = array_merge($defaults, $parameters);
-
- return new OAuthRequest($http_method, $http_url, $parameters);
- }
-
- public function set_parameter($name, $value, $allow_duplicates = true) {
- if ($allow_duplicates && isset($this->parameters[$name])) {
- // We have already added parameter(s) with this name, so add to the list
- if (is_scalar($this->parameters[$name])) {
- // This is the first duplicate, so transform scalar (string)
- // into an array so we can add the duplicates
- $this->parameters[$name] = array($this->parameters[$name]);
- }
-
- $this->parameters[$name][] = $value;
- } else {
- $this->parameters[$name] = $value;
- }
- }
-
- public function get_parameter($name) {
- return isset($this->parameters[$name]) ? $this->parameters[$name] : null;
- }
-
- public function get_parameters() {
- return $this->parameters;
- }
-
- public function unset_parameter($name) {
- unset($this->parameters[$name]);
- }
-
- /**
- * The request parameters, sorted and concatenated into a normalized string.
- * @return string
- */
- public function get_signable_parameters() {
- // Grab all parameters
- $params = $this->parameters;
-
- // Remove oauth_signature if present
- // Ref: Spec: 9.1.1 ("The oauth_signature parameter MUST be excluded.")
- if (isset($params['oauth_signature'])) {
- unset($params['oauth_signature']);
- }
-
- return OAuthUtil::build_http_query($params);
- }
-
- /**
- * Returns the base string of this request
- *
- * The base string defined as the method, the url
- * and the parameters (normalized), each urlencoded
- * and the concated with &.
- */
- public function get_signature_base_string() {
- $parts = array(
- $this->get_normalized_http_method(),
- $this->get_normalized_http_url(),
- $this->get_signable_parameters()
- );
-
- $parts = OAuthUtil::urlencode_rfc3986($parts);
-
- return implode('&', $parts);
- }
-
- /**
- * just uppercases the http method
- */
- public function get_normalized_http_method() {
- return strtoupper($this->http_method);
- }
-
- /**
- * parses the url and rebuilds it to be
- * scheme://host/path
- */
- public function get_normalized_http_url() {
- $parts = parse_url($this->http_url);
-
- $scheme = (isset($parts['scheme'])) ? $parts['scheme'] : 'http';
- $port = (isset($parts['port'])) ? $parts['port'] : (($scheme == 'https') ? '443' : '80');
- $host = (isset($parts['host'])) ? $parts['host'] : '';
- $path = (isset($parts['path'])) ? $parts['path'] : '';
-
- if (($scheme == 'https' && $port != '443')
- || ($scheme == 'http' && $port != '80')) {
- $host = "$host:$port";
- }
- return "$scheme://$host$path";
- }
-
- /**
- * builds a url usable for a GET request
- */
- public function to_url() {
- $post_data = $this->to_postdata();
- $out = $this->get_normalized_http_url();
- if ($post_data) {
- $out .= '?'.$post_data;
- }
- return $out;
- }
-
- /**
- * builds the data one would send in a POST request
- */
- public function to_postdata() {
- return OAuthUtil::build_http_query($this->parameters);
- }
-
- /**
- * builds the Authorization: header
- */
- public function to_header($realm=null) {
- $first = true;
- if($realm) {
- $out = 'Authorization: OAuth realm="' . OAuthUtil::urlencode_rfc3986($realm) . '"';
- $first = false;
- } else
- $out = 'Authorization: OAuth';
-
- $total = array();
- foreach ($this->parameters as $k => $v) {
- if (substr($k, 0, 5) != "oauth") continue;
- if (is_array($v)) {
- throw new OAuthException('Arrays not supported in headers');
- }
- $out .= ($first) ? ' ' : ',';
- $out .= OAuthUtil::urlencode_rfc3986($k) .
- '="' .
- OAuthUtil::urlencode_rfc3986($v) .
- '"';
- $first = false;
- }
- return $out;
- }
-
- public function __toString() {
- return $this->to_url();
- }
-
-
- public function sign_request($signature_method, $consumer, $token) {
- $this->set_parameter(
- "oauth_signature_method",
- $signature_method->get_name(),
- false
- );
- $signature = $this->build_signature($signature_method, $consumer, $token);
- $this->set_parameter("oauth_signature", $signature, false);
- }
-
- public function build_signature($signature_method, $consumer, $token) {
- $signature = $signature_method->build_signature($this, $consumer, $token);
- return $signature;
- }
-
- /**
- * util function: current timestamp
- */
- private static function generate_timestamp() {
- return time();
- }
-
- /**
- * util function: current nonce
- */
- private static function generate_nonce() {
- $mt = microtime();
- $rand = mt_rand();
-
- return md5($mt . $rand); // md5s look nicer than numbers
- }
-}
-
-class OAuthServer {
- protected $timestamp_threshold = 300; // in seconds, five minutes
- protected $version = '1.0'; // hi blaine
- protected $signature_methods = array();
-
- protected $data_store;
-
- function __construct($data_store) {
- $this->data_store = $data_store;
- }
-
- public function add_signature_method($signature_method) {
- $this->signature_methods[$signature_method->get_name()] =
- $signature_method;
- }
-
- // high level functions
-
- /**
- * process a request_token request
- * returns the request token on success
- */
- public function fetch_request_token(&$request) {
- $this->get_version($request);
-
- $consumer = $this->get_consumer($request);
-
- // no token required for the initial token request
- $token = NULL;
-
- $this->check_signature($request, $consumer, $token);
-
- // Rev A change
- $callback = $request->get_parameter('oauth_callback');
- $new_token = $this->data_store->new_request_token($consumer, $callback);
-
- return $new_token;
- }
-
- /**
- * process an access_token request
- * returns the access token on success
- */
- public function fetch_access_token(&$request) {
- $this->get_version($request);
-
- $consumer = $this->get_consumer($request);
-
- // requires authorized request token
- $token = $this->get_token($request, $consumer, "request");
-
- $this->check_signature($request, $consumer, $token);
-
- // Rev A change
- $verifier = $request->get_parameter('oauth_verifier');
- $new_token = $this->data_store->new_access_token($token, $consumer, $verifier);
-
- return $new_token;
- }
-
- /**
- * verify an api call, checks all the parameters
- */
- public function verify_request(&$request) {
- $this->get_version($request);
- $consumer = $this->get_consumer($request);
- $token = $this->get_token($request, $consumer, "access");
- $this->check_signature($request, $consumer, $token);
- return array($consumer, $token);
- }
-
- // Internals from here
- /**
- * version 1
- */
- private function get_version(&$request) {
- $version = $request->get_parameter("oauth_version");
- if (!$version) {
- // Service Providers MUST assume the protocol version to be 1.0 if this parameter is not present.
- // Chapter 7.0 ("Accessing Protected Ressources")
- $version = '1.0';
- }
- if ($version !== $this->version) {
- throw new OAuthException("OAuth version '$version' not supported");
- }
- return $version;
- }
-
- /**
- * figure out the signature with some defaults
- */
- private function get_signature_method($request) {
- $signature_method = $request instanceof OAuthRequest
- ? $request->get_parameter("oauth_signature_method")
- : NULL;
-
- if (!$signature_method) {
- // According to chapter 7 ("Accessing Protected Ressources") the signature-method
- // parameter is required, and we can't just fallback to PLAINTEXT
- throw new OAuthException('No signature method parameter. This parameter is required');
- }
-
- if (!in_array($signature_method,
- array_keys($this->signature_methods))) {
- throw new OAuthException(
- "Signature method '$signature_method' not supported " .
- "try one of the following: " .
- implode(", ", array_keys($this->signature_methods))
- );
- }
- return $this->signature_methods[$signature_method];
- }
-
- /**
- * try to find the consumer for the provided request's consumer key
- */
- private function get_consumer($request) {
- $consumer_key = $request instanceof OAuthRequest
- ? $request->get_parameter("oauth_consumer_key")
- : NULL;
-
- if (!$consumer_key) {
- throw new OAuthException("Invalid consumer key");
- }
-
- $consumer = $this->data_store->lookup_consumer($consumer_key);
- if (!$consumer) {
- throw new OAuthException("Invalid consumer");
- }
-
- return $consumer;
- }
-
- /**
- * try to find the token for the provided request's token key
- */
- private function get_token($request, $consumer, $token_type="access") {
- $token_field = $request instanceof OAuthRequest
- ? $request->get_parameter('oauth_token')
- : NULL;
-
- $token = $this->data_store->lookup_token(
- $consumer, $token_type, $token_field
- );
- if (!$token) {
- throw new OAuthException("Invalid $token_type token: $token_field");
- }
- return $token;
- }
-
- /**
- * all-in-one function to check the signature on a request
- * should guess the signature method appropriately
- */
- private function check_signature($request, $consumer, $token) {
- // this should probably be in a different method
- $timestamp = $request instanceof OAuthRequest
- ? $request->get_parameter('oauth_timestamp')
- : NULL;
- $nonce = $request instanceof OAuthRequest
- ? $request->get_parameter('oauth_nonce')
- : NULL;
-
- $this->check_timestamp($timestamp);
- $this->check_nonce($consumer, $token, $nonce, $timestamp);
-
- $signature_method = $this->get_signature_method($request);
-
- $signature = $request->get_parameter('oauth_signature');
- $valid_sig = $signature_method->check_signature(
- $request,
- $consumer,
- $token,
- $signature
- );
-
- if (!$valid_sig) {
- throw new OAuthException("Invalid signature");
- }
- }
-
- /**
- * check that the timestamp is new enough
- */
- private function check_timestamp($timestamp) {
- if( ! $timestamp )
- throw new OAuthException(
- 'Missing timestamp parameter. The parameter is required'
- );
-
- // verify that timestamp is recentish
- $now = time();
- if (abs($now - $timestamp) > $this->timestamp_threshold) {
- throw new OAuthException(
- "Expired timestamp, yours $timestamp, ours $now"
- );
- }
- }
-
- /**
- * check that the nonce is not repeated
- */
- private function check_nonce($consumer, $token, $nonce, $timestamp) {
- if( ! $nonce )
- throw new OAuthException(
- 'Missing nonce parameter. The parameter is required'
- );
-
- // verify that the nonce is uniqueish
- $found = $this->data_store->lookup_nonce(
- $consumer,
- $token,
- $nonce,
- $timestamp
- );
- if ($found) {
- throw new OAuthException("Nonce already used: $nonce");
- }
- }
-
-}
-
-class OAuthDataStore {
- function lookup_consumer($consumer_key) {
- // implement me
- }
-
- function lookup_token($consumer, $token_type, $token) {
- // implement me
- }
-
- function lookup_nonce($consumer, $token, $nonce, $timestamp) {
- // implement me
- }
-
- function new_request_token($consumer, $callback = null) {
- // return a new token attached to this consumer
- }
-
- function new_access_token($token, $consumer, $verifier = null) {
- // return a new access token attached to this consumer
- // for the user associated with this token if the request token
- // is authorized
- // should also invalidate the request token
- }
-
-}
-
-class OAuthUtil {
- public static function urlencode_rfc3986($input) {
- if (is_array($input)) {
- return array_map(array('OAuthUtil', 'urlencode_rfc3986'), $input);
- } else if (is_scalar($input)) {
- return str_replace(
- '+',
- ' ',
- str_replace('%7E', '~', rawurlencode($input))
- );
- } else {
- return '';
- }
-}
-
-
- // This decode function isn't taking into consideration the above
- // modifications to the encoding process. However, this method doesn't
- // seem to be used anywhere so leaving it as is.
- public static function urldecode_rfc3986($string) {
- return urldecode($string);
- }
-
- // Utility function for turning the Authorization: header into
- // parameters, has to do some unescaping
- // Can filter out any non-oauth parameters if needed (default behaviour)
- // May 28th, 2010 - method updated to tjerk.meesters for a speed improvement.
- // see http://code.google.com/p/oauth/issues/detail?id=163
- public static function split_header($header, $only_allow_oauth_parameters = true) {
- $params = array();
- if (preg_match_all('/('.($only_allow_oauth_parameters ? 'oauth_' : '').'[a-z_-]*)=(:?"([^"]*)"|([^,]*))/', $header, $matches)) {
- foreach ($matches[1] as $i => $h) {
- $params[$h] = OAuthUtil::urldecode_rfc3986(empty($matches[3][$i]) ? $matches[4][$i] : $matches[3][$i]);
- }
- if (isset($params['realm'])) {
- unset($params['realm']);
- }
- }
- return $params;
- }
-
- // helper to try to sort out headers for people who aren't running apache
- public static function get_headers() {
- if (function_exists('apache_request_headers')) {
- // we need this to get the actual Authorization: header
- // because apache tends to tell us it doesn't exist
- $headers = apache_request_headers();
-
- // sanitize the output of apache_request_headers because
- // we always want the keys to be Cased-Like-This and arh()
- // returns the headers in the same case as they are in the
- // request
- $out = array();
- foreach ($headers AS $key => $value) {
- $key = str_replace(
- " ",
- "-",
- ucwords(strtolower(str_replace("-", " ", $key)))
- );
- $out[$key] = $value;
- }
- } else {
- // otherwise we don't have apache and are just going to have to hope
- // that $_SERVER actually contains what we need
- $out = array();
- if( isset($_SERVER['CONTENT_TYPE']) )
- $out['Content-Type'] = $_SERVER['CONTENT_TYPE'];
- if( isset($_ENV['CONTENT_TYPE']) )
- $out['Content-Type'] = $_ENV['CONTENT_TYPE'];
-
- foreach ($_SERVER as $key => $value) {
- if (substr($key, 0, 5) == "HTTP_") {
- // this is chaos, basically it is just there to capitalize the first
- // letter of every word that is not an initial HTTP and strip HTTP
- // code from przemek
- $key = str_replace(
- " ",
- "-",
- ucwords(strtolower(str_replace("_", " ", substr($key, 5))))
- );
- $out[$key] = $value;
- }
- }
- }
- return $out;
- }
-
- // This function takes a input like a=b&a=c&d=e and returns the parsed
- // parameters like this
- // array('a' => array('b','c'), 'd' => 'e')
- public static function parse_parameters( $input ) {
- if (!isset($input) || !$input) return array();
-
- $pairs = explode('&', $input);
-
- $parsed_parameters = array();
- foreach ($pairs as $pair) {
- $split = explode('=', $pair, 2);
- $parameter = OAuthUtil::urldecode_rfc3986($split[0]);
- $value = isset($split[1]) ? OAuthUtil::urldecode_rfc3986($split[1]) : '';
-
- if (isset($parsed_parameters[$parameter])) {
- // We have already received parameter(s) with this name, so add to the list
- // of parameters with this name
-
- if (is_scalar($parsed_parameters[$parameter])) {
- // This is the first duplicate, so transform scalar (string) into an array
- // so we can add the duplicates
- $parsed_parameters[$parameter] = array($parsed_parameters[$parameter]);
- }
-
- $parsed_parameters[$parameter][] = $value;
- } else {
- $parsed_parameters[$parameter] = $value;
- }
- }
- return $parsed_parameters;
- }
-
- public static function build_http_query($params) {
- if (!$params) return '';
-
- // Urlencode both keys and values
- $keys = OAuthUtil::urlencode_rfc3986(array_keys($params));
- $values = OAuthUtil::urlencode_rfc3986(array_values($params));
- $params = array_combine($keys, $values);
-
- // Parameters are sorted by name, using lexicographical byte value ordering.
- // Ref: Spec: 9.1.1 (1)
- uksort($params, 'strcmp');
-
- $pairs = array();
- foreach ($params as $parameter => $value) {
- if (is_array($value)) {
- // If two or more parameters share the same name, they are sorted by their value
- // Ref: Spec: 9.1.1 (1)
- // June 12th, 2010 - changed to sort because of issue 164 by hidetaka
- sort($value, SORT_STRING);
- foreach ($value as $duplicate_value) {
- $pairs[] = $parameter . '=' . $duplicate_value;
- }
- } else {
- $pairs[] = $parameter . '=' . $value;
- }
- }
- // For each parameter, the name is separated from the corresponding value by an '=' character (ASCII code 61)
- // Each name-value pair is separated by an '&' character (ASCII code 38)
- return implode('&', $pairs);
- }
-}
-
-?>
diff --git a/chrome/common/extensions/docs/examples/apps/hello-php/main.css b/chrome/common/extensions/docs/examples/apps/hello-php/main.css
deleted file mode 100644
index 109547df..0000000
--- a/chrome/common/extensions/docs/examples/apps/hello-php/main.css
+++ /dev/null
@@ -1,89 +0,0 @@
-body {
- font-family: Arial, Verdana, san-serif;
- font-size: 11pt;
- color: #666;
- margin: 0;
-}
-
-nav {
- display: block; /* for older browsers */
- text-align: right;
- margin-bottom: 10px;
- padding: 10px;
- border-bottom: 1px solid #C6D2EB;
- background: -moz-linear-gradient(#fff, #EEF1F9 60%, #EEF1F9);
- background: -webkit-linear-gradient(#fff, #EEF1F9 60%, #EEF1F9);
- text-shadow: 1px 1px 1px #fff;
-}
-
-nav span {
- float: left;
- font-weight: bold;
-}
-
-a {
- color: #2F58A4;
- text-decoration: none;
-}
-
-a:hover {
- text-decoration: underline;
-}
-
-form {
- margin: 0;
-}
-
-input[type='text'] {
- padding: 3px;
-}
-
-li {
- list-style: none;
-}
-
-.error {
- margin: 10px 0 10px;
- padding: 10px;
- text-align: center;
- border: 1px solid red;
- color: red;
- font-weight: bold;
- background-color: #ffffcc;
- -moz-border-radius: 5px;
- border-radius: 5px;
- text-shadow: 2px 2px 2px #ccc;
-}
-
-#container {
- margin-top: 10px;
- padding: 10px;
-}
-
-#access-level {
- text-align: center;
- padding: 15px;
- border: 1px dotted #C6D2EB;
- font-size: 12pt;
- -moz-border-radius: 15px;
- border-radius: 15px;
- width: 550px;
- margin-left: auto;
- margin-right: auto;
-}
-
-#license-server-response span {
- font-weight: bold;
-}
-
-#license-server-response span.full {
- color: green;
-}
-
-#license-server-response span.free_trial {
- color: orange;
-}
-
-#license-server-response span.no {
- color: red;
-}
diff --git a/chrome/common/extensions/docs/examples/apps/hello-php/popuplib.js b/chrome/common/extensions/docs/examples/apps/hello-php/popuplib.js
deleted file mode 100644
index 4b0fd408..0000000
--- a/chrome/common/extensions/docs/examples/apps/hello-php/popuplib.js
+++ /dev/null
@@ -1,279 +0,0 @@
-// Copyright 2009 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-
-// PopupManager is a library to facilitate integration with OpenID
-// identity providers (OP)s that support a pop-up authentication interface.
-// To create a popup window, you first construct a popupOpener customized
-// for your site and a particular identity provider, E.g.:
-//
-// var googleOpener = popupManager.createOpener(openidParams);
-//
-// where 'openidParams' are customized for Google in this instance.
-// (typically you just change the openidpoint, the version number
-// (the openid.ns parameter) and the extensions based on what
-// the OP supports.
-// OpenID libraries can often discover these properties
-// automatically from the location of an XRD document.
-//
-// Then, you can either directly call
-// googleOpener.popup(width, height), where 'width' and 'height' are your choices
-// for popup size, or you can display a button 'Sign in with Google' and set the
-//..'onclick' handler of the button to googleOpener.popup()
-
-var popupManager = {};
-
-// Library constants
-
-popupManager.constants = {
- 'darkCover' : 'popupManager_darkCover_div',
- 'darkCoverStyle' : ['position:absolute;',
- 'top:0px;',
- 'left:0px;',
- 'padding-right:0px;',
- 'padding-bottom:0px;',
- 'background-color:#000000;',
- 'opacity:0.5;', //standard-compliant browsers
- '-moz-opacity:0.5;', // old Mozilla
- 'filter:alpha(opacity=0.5);', // IE
- 'z-index:10000;',
- 'width:100%;',
- 'height:100%;'
- ].join(''),
- 'openidSpec' : {
- 'identifier_select' : 'http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0%2Fidentifier_select',
- 'namespace2' : 'http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0'
- } };
-
-// Computes the size of the window contents. Returns a pair of
-// coordinates [width, height] which can be [0, 0] if it was not possible
-// to compute the values.
-popupManager.getWindowInnerSize = function() {
- var width = 0;
- var height = 0;
- var elem = null;
- if ('innerWidth' in window) {
- // For non-IE
- width = window.innerWidth;
- height = window.innerHeight;
- } else {
- // For IE,
- if (('BackCompat' === window.document.compatMode)
- && ('body' in window.document)) {
- elem = window.document.body;
- } else if ('documentElement' in window.document) {
- elem = window.document.documentElement;
- }
- if (elem !== null) {
- width = elem.offsetWidth;
- height = elem.offsetHeight;
- }
- }
- return [width, height];
-};
-
-// Computes the coordinates of the parent window.
-// Gets the coordinates of the parent frame
-popupManager.getParentCoords = function() {
- var width = 0;
- var height = 0;
- if ('screenLeft' in window) {
- // IE-compatible variants
- width = window.screenLeft;
- height = window.screenTop;
- } else if ('screenX' in window) {
- // Firefox-compatible
- width = window.screenX;
- height = window.screenY;
- }
- return [width, height];
-};
-
-// Computes the coordinates of the new window, so as to center it
-// over the parent frame
-popupManager.getCenteredCoords = function(width, height) {
- var parentSize = this.getWindowInnerSize();
- var parentPos = this.getParentCoords();
- var xPos = parentPos[0] +
- Math.max(0, Math.floor((parentSize[0] - width) / 2));
- var yPos = parentPos[1] +
- Math.max(0, Math.floor((parentSize[1] - height) / 2));
- return [xPos, yPos];
-};
-
-// A utility class, implements an onOpenHandler that darkens the screen
-// by overlaying it with a semi-transparent black layer. To use, ensure that
-// no screen element has a z-index at or above 10000.
-// This layer will be suppressed automatically after the screen closes.
-//
-// Note: If you want to perform other operations before opening the popup, but
-// also would like the screen to darken, you can define a custom handler
-// as such:
-// var myOnOpenHandler = function(inputs) {
-// .. do something
-// popupManager.darkenScreen();
-// .. something else
-// };
-// Then you pass myOnOpenHandler as input to the opener, as in:
-// var openidParams = {};
-// openidParams.onOpenHandler = myOnOpenHandler;
-// ... other customizations
-// var myOpener = popupManager.createOpener(openidParams);
-popupManager.darkenScreen = function() {
- var darkCover = window.document.getElementById(window.popupManager.constants['darkCover']);
- if (!darkCover) {
- darkCover = window.document.createElement('div');
- darkCover['id'] = window.popupManager.constants['darkCover'];
- darkCover.setAttribute('style', window.popupManager.constants['darkCoverStyle']);
- window.document.body.appendChild(darkCover);
- }
- darkCover.style.visibility = 'visible';
-};
-
-// Returns a an object that can open a popup window customized for an OP & RP.
-// to use you call var opener = popupManager.cretePopupOpener(openidParams);
-// and then you can assign the 'onclick' handler of a button to
-// opener.popup(width, height), where width and height are the values of the popup size;
-//
-// To use it, you would typically have code such as:
-// var myLoginCheckFunction = ... some AJAXy call or page refresh operation
-// that will cause the user to see the logged-in experience in the current page.
-// var openidParams = { realm : 'openid.realm', returnToUrl : 'openid.return_to',
-// opEndpoint : 'openid.op_endpoint', onCloseHandler : myLoginCheckFunction,
-// shouldEncodeUrls : 'true' (default) or 'false', extensions : myOpenIDExtensions };
-//
-// Here extensions include any OpenID extensions that you support. For instance,
-// if you support Attribute Exchange v.1.0, you can say:
-// (Example for attribute exchange request for email and name,
-// assuming that shouldEncodeUrls = 'true':)
-// var myOpenIDExtensions = {
-// 'openid.ax.ns' : 'http://openid.net/srv/ax/1.0',
-// 'openid.ax.type.email' : 'http://axschema.org/contact/email',
-// 'openid.ax.type.name1' : 'http://axschema.org/namePerson/first',
-// 'openid.ax.type.name2' : 'http://axschema.org/namePerson/last',
-// 'openid.ax.required' : 'email,name1,name2' };
-// Note that the 'ui' namespace is reserved by this library for the OpenID
-// UI extension, and that the mode 'popup' is automatically applied.
-// If you wish to make use of the 'language' feature of the OpenID UI extension
-// simply add the following entry (example assumes the language requested
-// is Swiss French:
-// var my OpenIDExtensions = {
-// ... // other extension parameters
-// 'openid.ui.language' : 'fr_CH',
-// ... };
-popupManager.createPopupOpener = (function(openidParams) {
- var interval_ = null;
- var popupWindow_ = null;
- var that = this;
- var shouldEscape_ = ('shouldEncodeUrls' in openidParams) ? openidParams.shouldEncodeUrls : true;
- var encodeIfRequested_ = function(url) {
- return (shouldEscape_ ? encodeURIComponent(url) : url);
- };
- var identifier_ = ('identifier' in openidParams) ? encodeIfRequested_(openidParams.identifier) :
- this.constants.openidSpec.identifier_select;
- var identity_ = ('identity' in openidParams) ? encodeIfRequested_(openidParams.identity) :
- this.constants.openidSpec.identifier_select;
- var openidNs_ = ('namespace' in openidParams) ? encodeIfRequested_(openidParams.namespace) :
- this.constants.openidSpec.namespace2;
- var onOpenHandler_ = (('onOpenHandler' in openidParams) &&
- ('function' === typeof(openidParams.onOpenHandler))) ?
- openidParams.onOpenHandler : this.darkenScreen;
- var onCloseHandler_ = (('onCloseHandler' in openidParams) &&
- ('function' === typeof(openidParams.onCloseHandler))) ?
- openidParams.onCloseHandler : null;
- var returnToUrl_ = ('returnToUrl' in openidParams) ? openidParams.returnToUrl : null;
- var realm_ = ('realm' in openidParams) ? openidParams.realm : null;
- var endpoint_ = ('opEndpoint' in openidParams) ? openidParams.opEndpoint : null;
- var extensions_ = ('extensions' in openidParams) ? openidParams.extensions : null;
-
- // processes key value pairs, escaping any input;
- var keyValueConcat_ = function(keyValuePairs) {
- var result = "";
- for (key in keyValuePairs) {
- result += ['&', key, '=', encodeIfRequested_(keyValuePairs[key])].join('');
- }
- return result;
- };
-
- //Assembles the OpenID request from customizable parameters
- var buildUrlToOpen_ = function() {
- var connector = '&';
- var encodedUrl = null;
- var urlToOpen = null;
- if ((null === endpoint_) || (null === returnToUrl_)) {
- return;
- }
- if (endpoint_.indexOf('?') === -1) {
- connector = '?';
- }
- encodedUrl = encodeIfRequested_(returnToUrl_);
- urlToOpen = [ endpoint_, connector,
- 'openid.ns=', openidNs_,
- '&openid.mode=checkid_setup',
- '&openid.claimed_id=', identifier_,
- '&openid.identity=', identity_,
- '&openid.return_to=', encodedUrl ].join('');
- if (realm_ !== null) {
- urlToOpen += "&openid.realm=" + encodeIfRequested_(realm_);
- }
- if (extensions_ !== null) {
- urlToOpen += keyValueConcat_(extensions_);
- }
- urlToOpen += '&openid.ns.ui=' + encodeURIComponent(
- 'http://specs.openid.net/extensions/ui/1.0');
- urlToOpen += '&openid.ui.mode=popup';
- return urlToOpen;
- };
-
- // Tests that the popup window has closed
- var isPopupClosed_ = function() {
- return (!popupWindow_ || popupWindow_.closed);
- };
-
- // Check to perform at each execution of the timed loop. It also triggers
- // the action that follows the closing of the popup
- var waitForPopupClose_ = function() {
- if (isPopupClosed_()) {
- popupWindow_ = null;
- var darkCover = window.document.getElementById(window.popupManager.constants['darkCover']);
- if (darkCover) {
- darkCover.style.visibility = 'hidden';
- }
- if (onCloseHandler_ !== null) {
- onCloseHandler_();
- }
- if ((null !== interval_)) {
- window.clearInterval(interval_);
- interval_ = null;
- }
- }
- };
-
- return {
- // Function that opens the window.
- popup: function(width, height) {
- var urlToOpen = buildUrlToOpen_();
- if (onOpenHandler_ !== null) {
- onOpenHandler_();
- }
- var coordinates = that.getCenteredCoords(width, height);
- popupWindow_ = window.open(urlToOpen, "",
- "width=" + width + ",height=" + height +
- ",status=1,location=1,resizable=yes" +
- ",left=" + coordinates[0] +",top=" + coordinates[1]);
- interval_ = window.setInterval(waitForPopupClose_, 80);
- return true;
- }
- };
-});
diff --git a/chrome/common/extensions/docs/examples/apps/hello-python/NOTICE b/chrome/common/extensions/docs/examples/apps/hello-python/NOTICE
deleted file mode 100644
index 2e0d217..0000000
--- a/chrome/common/extensions/docs/examples/apps/hello-python/NOTICE
+++ /dev/null
@@ -1,53 +0,0 @@
-This sample application includes two Python libraries:
-
-
-Name: python-oauth2
-URL: http://github.com/simplegeo/python-oauth2/
-================================================================================
-The MIT License
-
-Copyright (c) 2007 Leah Culver
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-
-
-Name: httplib2
-URL: http://code.google.com/p/httplib2/
-================================================================================
-The MIT License
-
-Copyright (c) <year> <copyright holders>
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
diff --git a/chrome/common/extensions/docs/examples/apps/hello-python/README b/chrome/common/extensions/docs/examples/apps/hello-python/README
deleted file mode 100644
index 53ff640..0000000
--- a/chrome/common/extensions/docs/examples/apps/hello-python/README
+++ /dev/null
@@ -1,30 +0,0 @@
-Hello License Python
-====================
-
-Overview
---------
-This application implements a sample client for the Chrome Web Store Licensing
-API on Google's Python App Engine service.
-
-For information about this API, please see:
-http://code.google.com/chrome/webstore/
-
-Usage
------
-First, register an App Engine app at www.appspot.com. Make sure you select
-Federated Login as the login provider for the app.
-
-You'll need to configure this sample before it will be functional. Edit
-app.yaml and replace the text INSERT APPLICATION NAME HERE with the application
-identifier you registered.
-
-Second, obtain a token for the Chrome Web Store license server. Check the
-license server documentation for instructions on how to do this. Edit main.py
-and replace the following three configuration lines with your own information:
-
- 'oauth_token': 'INSERT OAUTH TOKEN HERE',
- 'oauth_token_secret': 'INSERT OAUTH TOKEN SECRET HERE',
- 'app_id': 'INSERT APPLICATION ID HERE',
-
-Then deploy your application to App Engine, and you will be able to log in
-with OpenID and check the license status of your account.
\ No newline at end of file
diff --git a/chrome/common/extensions/docs/examples/apps/hello-python/app.yaml b/chrome/common/extensions/docs/examples/apps/hello-python/app.yaml
deleted file mode 100644
index 14eca124..0000000
--- a/chrome/common/extensions/docs/examples/apps/hello-python/app.yaml
+++ /dev/null
@@ -1,16 +0,0 @@
-# Copyright (c) 2012 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.
-
-application: INSERT APPLICATION NAME HERE
-version: 1
-runtime: python
-api_version: 1
-
-handlers:
-- url: /favicon.ico
- static_files: favicon.ico
- upload: favicon.ico
-
-- url: .*
- script: main.py
diff --git a/chrome/common/extensions/docs/examples/apps/hello-python/favicon.ico b/chrome/common/extensions/docs/examples/apps/hello-python/favicon.ico
deleted file mode 100644
index 8e5f1b5..0000000
--- a/chrome/common/extensions/docs/examples/apps/hello-python/favicon.ico
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/apps/hello-python/httplib2/__init__.py b/chrome/common/extensions/docs/examples/apps/hello-python/httplib2/__init__.py
deleted file mode 100644
index 3cebcb3..0000000
--- a/chrome/common/extensions/docs/examples/apps/hello-python/httplib2/__init__.py
+++ /dev/null
@@ -1,1202 +0,0 @@
-from __future__ import generators
-"""
-httplib2
-
-A caching http interface that supports ETags and gzip
-to conserve bandwidth.
-
-Requires Python 2.3 or later
-
-Changelog:
-2007-08-18, Rick: Modified so it's able to use a socks proxy if needed.
-
-"""
-
-__author__ = "Joe Gregorio (joe@bitworking.org)"
-__copyright__ = "Copyright 2006, Joe Gregorio"
-__contributors__ = ["Thomas Broyer (t.broyer@ltgt.net)",
- "James Antill",
- "Xavier Verges Farrero",
- "Jonathan Feinberg",
- "Blair Zajac",
- "Sam Ruby",
- "Louis Nyffenegger"]
-__license__ = "MIT"
-__version__ = "$Rev$"
-
-import re
-import sys
-import email
-import email.Utils
-import email.Message
-import email.FeedParser
-import StringIO
-import gzip
-import zlib
-import httplib
-import urlparse
-import base64
-import os
-import copy
-import calendar
-import time
-import random
-# remove depracated warning in python2.6
-try:
- from hashlib import sha1 as _sha, md5 as _md5
-except ImportError:
- import sha
- import md5
- _sha = sha.new
- _md5 = md5.new
-import hmac
-from gettext import gettext as _
-import socket
-
-try:
- import socks
-except ImportError:
- socks = None
-
-# Build the appropriate socket wrapper for ssl
-try:
- import ssl # python 2.6
- _ssl_wrap_socket = ssl.wrap_socket
-except ImportError:
- def _ssl_wrap_socket(sock, key_file, cert_file):
- ssl_sock = socket.ssl(sock, key_file, cert_file)
- return httplib.FakeSocket(sock, ssl_sock)
-
-
-if sys.version_info >= (2,3):
- from iri2uri import iri2uri
-else:
- def iri2uri(uri):
- return uri
-
-def has_timeout(timeout): # python 2.6
- if hasattr(socket, '_GLOBAL_DEFAULT_TIMEOUT'):
- return (timeout is not None and timeout is not socket._GLOBAL_DEFAULT_TIMEOUT)
- return (timeout is not None)
-
-__all__ = ['Http', 'Response', 'ProxyInfo', 'HttpLib2Error',
- 'RedirectMissingLocation', 'RedirectLimit', 'FailedToDecompressContent',
- 'UnimplementedDigestAuthOptionError', 'UnimplementedHmacDigestAuthOptionError',
- 'debuglevel']
-
-
-# The httplib debug level, set to a non-zero value to get debug output
-debuglevel = 0
-
-
-# Python 2.3 support
-if sys.version_info < (2,4):
- def sorted(seq):
- seq.sort()
- return seq
-
-# Python 2.3 support
-def HTTPResponse__getheaders(self):
- """Return list of (header, value) tuples."""
- if self.msg is None:
- raise httplib.ResponseNotReady()
- return self.msg.items()
-
-if not hasattr(httplib.HTTPResponse, 'getheaders'):
- httplib.HTTPResponse.getheaders = HTTPResponse__getheaders
-
-# All exceptions raised here derive from HttpLib2Error
-class HttpLib2Error(Exception): pass
-
-# Some exceptions can be caught and optionally
-# be turned back into responses.
-class HttpLib2ErrorWithResponse(HttpLib2Error):
- def __init__(self, desc, response, content):
- self.response = response
- self.content = content
- HttpLib2Error.__init__(self, desc)
-
-class RedirectMissingLocation(HttpLib2ErrorWithResponse): pass
-class RedirectLimit(HttpLib2ErrorWithResponse): pass
-class FailedToDecompressContent(HttpLib2ErrorWithResponse): pass
-class UnimplementedDigestAuthOptionError(HttpLib2ErrorWithResponse): pass
-class UnimplementedHmacDigestAuthOptionError(HttpLib2ErrorWithResponse): pass
-
-class RelativeURIError(HttpLib2Error): pass
-class ServerNotFoundError(HttpLib2Error): pass
-
-# Open Items:
-# -----------
-# Proxy support
-
-# Are we removing the cached content too soon on PUT (only delete on 200 Maybe?)
-
-# Pluggable cache storage (supports storing the cache in
-# flat files by default. We need a plug-in architecture
-# that can support Berkeley DB and Squid)
-
-# == Known Issues ==
-# Does not handle a resource that uses conneg and Last-Modified but no ETag as a cache validator.
-# Does not handle Cache-Control: max-stale
-# Does not use Age: headers when calculating cache freshness.
-
-
-# The number of redirections to follow before giving up.
-# Note that only GET redirects are automatically followed.
-# Will also honor 301 requests by saving that info and never
-# requesting that URI again.
-DEFAULT_MAX_REDIRECTS = 5
-
-# Which headers are hop-by-hop headers by default
-HOP_BY_HOP = ['connection', 'keep-alive', 'proxy-authenticate', 'proxy-authorization', 'te', 'trailers', 'transfer-encoding', 'upgrade']
-
-def _get_end2end_headers(response):
- hopbyhop = list(HOP_BY_HOP)
- hopbyhop.extend([x.strip() for x in response.get('connection', '').split(',')])
- return [header for header in response.keys() if header not in hopbyhop]
-
-URI = re.compile(r"^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?")
-
-def parse_uri(uri):
- """Parses a URI using the regex given in Appendix B of RFC 3986.
-
- (scheme, authority, path, query, fragment) = parse_uri(uri)
- """
- groups = URI.match(uri).groups()
- return (groups[1], groups[3], groups[4], groups[6], groups[8])
-
-def urlnorm(uri):
- (scheme, authority, path, query, fragment) = parse_uri(uri)
- if not scheme or not authority:
- raise RelativeURIError("Only absolute URIs are allowed. uri = %s" % uri)
- authority = authority.lower()
- scheme = scheme.lower()
- if not path:
- path = "/"
- # Could do syntax based normalization of the URI before
- # computing the digest. See Section 6.2.2 of Std 66.
- request_uri = query and "?".join([path, query]) or path
- scheme = scheme.lower()
- defrag_uri = scheme + "://" + authority + request_uri
- return scheme, authority, request_uri, defrag_uri
-
-
-# Cache filename construction (original borrowed from Venus http://intertwingly.net/code/venus/)
-re_url_scheme = re.compile(r'^\w+://')
-re_slash = re.compile(r'[?/:|]+')
-
-def safename(filename):
- """Return a filename suitable for the cache.
-
- Strips dangerous and common characters to create a filename we
- can use to store the cache in.
- """
-
- try:
- if re_url_scheme.match(filename):
- if isinstance(filename,str):
- filename = filename.decode('utf-8')
- filename = filename.encode('idna')
- else:
- filename = filename.encode('idna')
- except UnicodeError:
- pass
- if isinstance(filename,unicode):
- filename=filename.encode('utf-8')
- filemd5 = _md5(filename).hexdigest()
- filename = re_url_scheme.sub("", filename)
- filename = re_slash.sub(",", filename)
-
- # limit length of filename
- if len(filename)>200:
- filename=filename[:200]
- return ",".join((filename, filemd5))
-
-NORMALIZE_SPACE = re.compile(r'(?:\r\n)?[ \t]+')
-def _normalize_headers(headers):
- return dict([ (key.lower(), NORMALIZE_SPACE.sub(value, ' ').strip()) for (key, value) in headers.iteritems()])
-
-def _parse_cache_control(headers):
- retval = {}
- if headers.has_key('cache-control'):
- parts = headers['cache-control'].split(',')
- parts_with_args = [tuple([x.strip().lower() for x in part.split("=", 1)]) for part in parts if -1 != part.find("=")]
- parts_wo_args = [(name.strip().lower(), 1) for name in parts if -1 == name.find("=")]
- retval = dict(parts_with_args + parts_wo_args)
- return retval
-
-# Whether to use a strict mode to parse WWW-Authenticate headers
-# Might lead to bad results in case of ill-formed header value,
-# so disabled by default, falling back to relaxed parsing.
-# Set to true to turn on, usefull for testing servers.
-USE_WWW_AUTH_STRICT_PARSING = 0
-
-# In regex below:
-# [^\0-\x1f\x7f-\xff()<>@,;:\\\"/[\]?={} \t]+ matches a "token" as defined by HTTP
-# "(?:[^\0-\x08\x0A-\x1f\x7f-\xff\\\"]|\\[\0-\x7f])*?" matches a "quoted-string" as defined by HTTP, when LWS have already been replaced by a single space
-# Actually, as an auth-param value can be either a token or a quoted-string, they are combined in a single pattern which matches both:
-# \"?((?<=\")(?:[^\0-\x1f\x7f-\xff\\\"]|\\[\0-\x7f])*?(?=\")|(?<!\")[^\0-\x08\x0A-\x1f\x7f-\xff()<>@,;:\\\"/[\]?={} \t]+(?!\"))\"?
-WWW_AUTH_STRICT = re.compile(r"^(?:\s*(?:,\s*)?([^\0-\x1f\x7f-\xff()<>@,;:\\\"/[\]?={} \t]+)\s*=\s*\"?((?<=\")(?:[^\0-\x08\x0A-\x1f\x7f-\xff\\\"]|\\[\0-\x7f])*?(?=\")|(?<!\")[^\0-\x1f\x7f-\xff()<>@,;:\\\"/[\]?={} \t]+(?!\"))\"?)(.*)$")
-WWW_AUTH_RELAXED = re.compile(r"^(?:\s*(?:,\s*)?([^ \t\r\n=]+)\s*=\s*\"?((?<=\")(?:[^\\\"]|\\.)*?(?=\")|(?<!\")[^ \t\r\n,]+(?!\"))\"?)(.*)$")
-UNQUOTE_PAIRS = re.compile(r'\\(.)')
-def _parse_www_authenticate(headers, headername='www-authenticate'):
- """Returns a dictionary of dictionaries, one dict
- per auth_scheme."""
- retval = {}
- if headers.has_key(headername):
- authenticate = headers[headername].strip()
- www_auth = USE_WWW_AUTH_STRICT_PARSING and WWW_AUTH_STRICT or WWW_AUTH_RELAXED
- while authenticate:
- # Break off the scheme at the beginning of the line
- if headername == 'authentication-info':
- (auth_scheme, the_rest) = ('digest', authenticate)
- else:
- (auth_scheme, the_rest) = authenticate.split(" ", 1)
- # Now loop over all the key value pairs that come after the scheme,
- # being careful not to roll into the next scheme
- match = www_auth.search(the_rest)
- auth_params = {}
- while match:
- if match and len(match.groups()) == 3:
- (key, value, the_rest) = match.groups()
- auth_params[key.lower()] = UNQUOTE_PAIRS.sub(r'\1', value) # '\\'.join([x.replace('\\', '') for x in value.split('\\\\')])
- match = www_auth.search(the_rest)
- retval[auth_scheme.lower()] = auth_params
- authenticate = the_rest.strip()
- return retval
-
-
-def _entry_disposition(response_headers, request_headers):
- """Determine freshness from the Date, Expires and Cache-Control headers.
-
- We don't handle the following:
-
- 1. Cache-Control: max-stale
- 2. Age: headers are not used in the calculations.
-
- Not that this algorithm is simpler than you might think
- because we are operating as a private (non-shared) cache.
- This lets us ignore 's-maxage'. We can also ignore
- 'proxy-invalidate' since we aren't a proxy.
- We will never return a stale document as
- fresh as a design decision, and thus the non-implementation
- of 'max-stale'. This also lets us safely ignore 'must-revalidate'
- since we operate as if every server has sent 'must-revalidate'.
- Since we are private we get to ignore both 'public' and
- 'private' parameters. We also ignore 'no-transform' since
- we don't do any transformations.
- The 'no-store' parameter is handled at a higher level.
- So the only Cache-Control parameters we look at are:
-
- no-cache
- only-if-cached
- max-age
- min-fresh
- """
-
- retval = "STALE"
- cc = _parse_cache_control(request_headers)
- cc_response = _parse_cache_control(response_headers)
-
- if request_headers.has_key('pragma') and request_headers['pragma'].lower().find('no-cache') != -1:
- retval = "TRANSPARENT"
- if 'cache-control' not in request_headers:
- request_headers['cache-control'] = 'no-cache'
- elif cc.has_key('no-cache'):
- retval = "TRANSPARENT"
- elif cc_response.has_key('no-cache'):
- retval = "STALE"
- elif cc.has_key('only-if-cached'):
- retval = "FRESH"
- elif response_headers.has_key('date'):
- date = calendar.timegm(email.Utils.parsedate_tz(response_headers['date']))
- now = time.time()
- current_age = max(0, now - date)
- if cc_response.has_key('max-age'):
- try:
- freshness_lifetime = int(cc_response['max-age'])
- except ValueError:
- freshness_lifetime = 0
- elif response_headers.has_key('expires'):
- expires = email.Utils.parsedate_tz(response_headers['expires'])
- if None == expires:
- freshness_lifetime = 0
- else:
- freshness_lifetime = max(0, calendar.timegm(expires) - date)
- else:
- freshness_lifetime = 0
- if cc.has_key('max-age'):
- try:
- freshness_lifetime = int(cc['max-age'])
- except ValueError:
- freshness_lifetime = 0
- if cc.has_key('min-fresh'):
- try:
- min_fresh = int(cc['min-fresh'])
- except ValueError:
- min_fresh = 0
- current_age += min_fresh
- if freshness_lifetime > current_age:
- retval = "FRESH"
- return retval
-
-def _decompressContent(response, new_content):
- content = new_content
- try:
- encoding = response.get('content-encoding', None)
- if encoding in ['gzip', 'deflate']:
- if encoding == 'gzip':
- content = gzip.GzipFile(fileobj=StringIO.StringIO(new_content)).read()
- if encoding == 'deflate':
- content = zlib.decompress(content)
- response['content-length'] = str(len(content))
- # Record the historical presence of the encoding in a way the won't interfere.
- response['-content-encoding'] = response['content-encoding']
- del response['content-encoding']
- except IOError:
- content = ""
- raise FailedToDecompressContent(_("Content purported to be compressed with %s but failed to decompress.") % response.get('content-encoding'), response, content)
- return content
-
-def _updateCache(request_headers, response_headers, content, cache, cachekey):
- if cachekey:
- cc = _parse_cache_control(request_headers)
- cc_response = _parse_cache_control(response_headers)
- if cc.has_key('no-store') or cc_response.has_key('no-store'):
- cache.delete(cachekey)
- else:
- info = email.Message.Message()
- for key, value in response_headers.iteritems():
- if key not in ['status','content-encoding','transfer-encoding']:
- info[key] = value
-
- # Add annotations to the cache to indicate what headers
- # are variant for this request.
- vary = response_headers.get('vary', None)
- if vary:
- vary_headers = vary.lower().replace(' ', '').split(',')
- for header in vary_headers:
- key = '-varied-%s' % header
- try:
- info[key] = request_headers[header]
- except KeyError:
- pass
-
- status = response_headers.status
- if status == 304:
- status = 200
-
- status_header = 'status: %d\r\n' % response_headers.status
-
- header_str = info.as_string()
-
- header_str = re.sub("\r(?!\n)|(?<!\r)\n", "\r\n", header_str)
- text = "".join([status_header, header_str, content])
-
- cache.set(cachekey, text)
-
-def _cnonce():
- dig = _md5("%s:%s" % (time.ctime(), ["0123456789"[random.randrange(0, 9)] for i in range(20)])).hexdigest()
- return dig[:16]
-
-def _wsse_username_token(cnonce, iso_now, password):
- return base64.b64encode(_sha("%s%s%s" % (cnonce, iso_now, password)).digest()).strip()
-
-
-# For credentials we need two things, first
-# a pool of credential to try (not necesarily tied to BAsic, Digest, etc.)
-# Then we also need a list of URIs that have already demanded authentication
-# That list is tricky since sub-URIs can take the same auth, or the
-# auth scheme may change as you descend the tree.
-# So we also need each Auth instance to be able to tell us
-# how close to the 'top' it is.
-
-class Authentication(object):
- def __init__(self, credentials, host, request_uri, headers, response, content, http):
- (scheme, authority, path, query, fragment) = parse_uri(request_uri)
- self.path = path
- self.host = host
- self.credentials = credentials
- self.http = http
-
- def depth(self, request_uri):
- (scheme, authority, path, query, fragment) = parse_uri(request_uri)
- return request_uri[len(self.path):].count("/")
-
- def inscope(self, host, request_uri):
- # XXX Should we normalize the request_uri?
- (scheme, authority, path, query, fragment) = parse_uri(request_uri)
- return (host == self.host) and path.startswith(self.path)
-
- def request(self, method, request_uri, headers, content):
- """Modify the request headers to add the appropriate
- Authorization header. Over-rise this in sub-classes."""
- pass
-
- def response(self, response, content):
- """Gives us a chance to update with new nonces
- or such returned from the last authorized response.
- Over-rise this in sub-classes if necessary.
-
- Return TRUE is the request is to be retried, for
- example Digest may return stale=true.
- """
- return False
-
-
-
-class BasicAuthentication(Authentication):
- def __init__(self, credentials, host, request_uri, headers, response, content, http):
- Authentication.__init__(self, credentials, host, request_uri, headers, response, content, http)
-
- def request(self, method, request_uri, headers, content):
- """Modify the request headers to add the appropriate
- Authorization header."""
- headers['authorization'] = 'Basic ' + base64.b64encode("%s:%s" % self.credentials).strip()
-
-
-class DigestAuthentication(Authentication):
- """Only do qop='auth' and MD5, since that
- is all Apache currently implements"""
- def __init__(self, credentials, host, request_uri, headers, response, content, http):
- Authentication.__init__(self, credentials, host, request_uri, headers, response, content, http)
- challenge = _parse_www_authenticate(response, 'www-authenticate')
- self.challenge = challenge['digest']
- qop = self.challenge.get('qop', 'auth')
- self.challenge['qop'] = ('auth' in [x.strip() for x in qop.split()]) and 'auth' or None
- if self.challenge['qop'] is None:
- raise UnimplementedDigestAuthOptionError( _("Unsupported value for qop: %s." % qop))
- self.challenge['algorithm'] = self.challenge.get('algorithm', 'MD5').upper()
- if self.challenge['algorithm'] != 'MD5':
- raise UnimplementedDigestAuthOptionError( _("Unsupported value for algorithm: %s." % self.challenge['algorithm']))
- self.A1 = "".join([self.credentials[0], ":", self.challenge['realm'], ":", self.credentials[1]])
- self.challenge['nc'] = 1
-
- def request(self, method, request_uri, headers, content, cnonce = None):
- """Modify the request headers"""
- H = lambda x: _md5(x).hexdigest()
- KD = lambda s, d: H("%s:%s" % (s, d))
- A2 = "".join([method, ":", request_uri])
- self.challenge['cnonce'] = cnonce or _cnonce()
- request_digest = '"%s"' % KD(H(self.A1), "%s:%s:%s:%s:%s" % (self.challenge['nonce'],
- '%08x' % self.challenge['nc'],
- self.challenge['cnonce'],
- self.challenge['qop'], H(A2)
- ))
- headers['Authorization'] = 'Digest username="%s", realm="%s", nonce="%s", uri="%s", algorithm=%s, response=%s, qop=%s, nc=%08x, cnonce="%s"' % (
- self.credentials[0],
- self.challenge['realm'],
- self.challenge['nonce'],
- request_uri,
- self.challenge['algorithm'],
- request_digest,
- self.challenge['qop'],
- self.challenge['nc'],
- self.challenge['cnonce'],
- )
- self.challenge['nc'] += 1
-
- def response(self, response, content):
- if not response.has_key('authentication-info'):
- challenge = _parse_www_authenticate(response, 'www-authenticate').get('digest', {})
- if 'true' == challenge.get('stale'):
- self.challenge['nonce'] = challenge['nonce']
- self.challenge['nc'] = 1
- return True
- else:
- updated_challenge = _parse_www_authenticate(response, 'authentication-info').get('digest', {})
-
- if updated_challenge.has_key('nextnonce'):
- self.challenge['nonce'] = updated_challenge['nextnonce']
- self.challenge['nc'] = 1
- return False
-
-
-class HmacDigestAuthentication(Authentication):
- """Adapted from Robert Sayre's code and DigestAuthentication above."""
- __author__ = "Thomas Broyer (t.broyer@ltgt.net)"
-
- def __init__(self, credentials, host, request_uri, headers, response, content, http):
- Authentication.__init__(self, credentials, host, request_uri, headers, response, content, http)
- challenge = _parse_www_authenticate(response, 'www-authenticate')
- self.challenge = challenge['hmacdigest']
- # TODO: self.challenge['domain']
- self.challenge['reason'] = self.challenge.get('reason', 'unauthorized')
- if self.challenge['reason'] not in ['unauthorized', 'integrity']:
- self.challenge['reason'] = 'unauthorized'
- self.challenge['salt'] = self.challenge.get('salt', '')
- if not self.challenge.get('snonce'):
- raise UnimplementedHmacDigestAuthOptionError( _("The challenge doesn't contain a server nonce, or this one is empty."))
- self.challenge['algorithm'] = self.challenge.get('algorithm', 'HMAC-SHA-1')
- if self.challenge['algorithm'] not in ['HMAC-SHA-1', 'HMAC-MD5']:
- raise UnimplementedHmacDigestAuthOptionError( _("Unsupported value for algorithm: %s." % self.challenge['algorithm']))
- self.challenge['pw-algorithm'] = self.challenge.get('pw-algorithm', 'SHA-1')
- if self.challenge['pw-algorithm'] not in ['SHA-1', 'MD5']:
- raise UnimplementedHmacDigestAuthOptionError( _("Unsupported value for pw-algorithm: %s." % self.challenge['pw-algorithm']))
- if self.challenge['algorithm'] == 'HMAC-MD5':
- self.hashmod = _md5
- else:
- self.hashmod = _sha
- if self.challenge['pw-algorithm'] == 'MD5':
- self.pwhashmod = _md5
- else:
- self.pwhashmod = _sha
- self.key = "".join([self.credentials[0], ":",
- self.pwhashmod.new("".join([self.credentials[1], self.challenge['salt']])).hexdigest().lower(),
- ":", self.challenge['realm']
- ])
- self.key = self.pwhashmod.new(self.key).hexdigest().lower()
-
- def request(self, method, request_uri, headers, content):
- """Modify the request headers"""
- keys = _get_end2end_headers(headers)
- keylist = "".join(["%s " % k for k in keys])
- headers_val = "".join([headers[k] for k in keys])
- created = time.strftime('%Y-%m-%dT%H:%M:%SZ',time.gmtime())
- cnonce = _cnonce()
- request_digest = "%s:%s:%s:%s:%s" % (method, request_uri, cnonce, self.challenge['snonce'], headers_val)
- request_digest = hmac.new(self.key, request_digest, self.hashmod).hexdigest().lower()
- headers['Authorization'] = 'HMACDigest username="%s", realm="%s", snonce="%s", cnonce="%s", uri="%s", created="%s", response="%s", headers="%s"' % (
- self.credentials[0],
- self.challenge['realm'],
- self.challenge['snonce'],
- cnonce,
- request_uri,
- created,
- request_digest,
- keylist,
- )
-
- def response(self, response, content):
- challenge = _parse_www_authenticate(response, 'www-authenticate').get('hmacdigest', {})
- if challenge.get('reason') in ['integrity', 'stale']:
- return True
- return False
-
-
-class WsseAuthentication(Authentication):
- """This is thinly tested and should not be relied upon.
- At this time there isn't any third party server to test against.
- Blogger and TypePad implemented this algorithm at one point
- but Blogger has since switched to Basic over HTTPS and
- TypePad has implemented it wrong, by never issuing a 401
- challenge but instead requiring your client to telepathically know that
- their endpoint is expecting WSSE profile="UsernameToken"."""
- def __init__(self, credentials, host, request_uri, headers, response, content, http):
- Authentication.__init__(self, credentials, host, request_uri, headers, response, content, http)
-
- def request(self, method, request_uri, headers, content):
- """Modify the request headers to add the appropriate
- Authorization header."""
- headers['Authorization'] = 'WSSE profile="UsernameToken"'
- iso_now = time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime())
- cnonce = _cnonce()
- password_digest = _wsse_username_token(cnonce, iso_now, self.credentials[1])
- headers['X-WSSE'] = 'UsernameToken Username="%s", PasswordDigest="%s", Nonce="%s", Created="%s"' % (
- self.credentials[0],
- password_digest,
- cnonce,
- iso_now)
-
-class GoogleLoginAuthentication(Authentication):
- def __init__(self, credentials, host, request_uri, headers, response, content, http):
- from urllib import urlencode
- Authentication.__init__(self, credentials, host, request_uri, headers, response, content, http)
- challenge = _parse_www_authenticate(response, 'www-authenticate')
- service = challenge['googlelogin'].get('service', 'xapi')
- # Bloggger actually returns the service in the challenge
- # For the rest we guess based on the URI
- if service == 'xapi' and request_uri.find("calendar") > 0:
- service = "cl"
- # No point in guessing Base or Spreadsheet
- #elif request_uri.find("spreadsheets") > 0:
- # service = "wise"
-
- auth = dict(Email=credentials[0], Passwd=credentials[1], service=service, source=headers['user-agent'])
- resp, content = self.http.request("https://www.google.com/accounts/ClientLogin", method="POST", body=urlencode(auth), headers={'Content-Type': 'application/x-www-form-urlencoded'})
- lines = content.split('\n')
- d = dict([tuple(line.split("=", 1)) for line in lines if line])
- if resp.status == 403:
- self.Auth = ""
- else:
- self.Auth = d['Auth']
-
- def request(self, method, request_uri, headers, content):
- """Modify the request headers to add the appropriate
- Authorization header."""
- headers['authorization'] = 'GoogleLogin Auth=' + self.Auth
-
-
-AUTH_SCHEME_CLASSES = {
- "basic": BasicAuthentication,
- "wsse": WsseAuthentication,
- "digest": DigestAuthentication,
- "hmacdigest": HmacDigestAuthentication,
- "googlelogin": GoogleLoginAuthentication
-}
-
-AUTH_SCHEME_ORDER = ["hmacdigest", "googlelogin", "digest", "wsse", "basic"]
-
-class FileCache(object):
- """Uses a local directory as a store for cached files.
- Not really safe to use if multiple threads or processes are going to
- be running on the same cache.
- """
- def __init__(self, cache, safe=safename): # use safe=lambda x: md5.new(x).hexdigest() for the old behavior
- self.cache = cache
- self.safe = safe
- if not os.path.exists(cache):
- os.makedirs(self.cache)
-
- def get(self, key):
- retval = None
- cacheFullPath = os.path.join(self.cache, self.safe(key))
- try:
- f = file(cacheFullPath, "rb")
- retval = f.read()
- f.close()
- except IOError:
- pass
- return retval
-
- def set(self, key, value):
- cacheFullPath = os.path.join(self.cache, self.safe(key))
- f = file(cacheFullPath, "wb")
- f.write(value)
- f.close()
-
- def delete(self, key):
- cacheFullPath = os.path.join(self.cache, self.safe(key))
- if os.path.exists(cacheFullPath):
- os.remove(cacheFullPath)
-
-class Credentials(object):
- def __init__(self):
- self.credentials = []
-
- def add(self, name, password, domain=""):
- self.credentials.append((domain.lower(), name, password))
-
- def clear(self):
- self.credentials = []
-
- def iter(self, domain):
- for (cdomain, name, password) in self.credentials:
- if cdomain == "" or domain == cdomain:
- yield (name, password)
-
-class KeyCerts(Credentials):
- """Identical to Credentials except that
- name/password are mapped to key/cert."""
- pass
-
-
-class ProxyInfo(object):
- """Collect information required to use a proxy."""
- def __init__(self, proxy_type, proxy_host, proxy_port, proxy_rdns=None, proxy_user=None, proxy_pass=None):
- """The parameter proxy_type must be set to one of socks.PROXY_TYPE_XXX
- constants. For example:
-
-p = ProxyInfo(proxy_type=socks.PROXY_TYPE_HTTP, proxy_host='localhost', proxy_port=8000)
- """
- self.proxy_type, self.proxy_host, self.proxy_port, self.proxy_rdns, self.proxy_user, self.proxy_pass = proxy_type, proxy_host, proxy_port, proxy_rdns, proxy_user, proxy_pass
-
- def astuple(self):
- return (self.proxy_type, self.proxy_host, self.proxy_port, self.proxy_rdns,
- self.proxy_user, self.proxy_pass)
-
- def isgood(self):
- return socks and (self.proxy_host != None) and (self.proxy_port != None)
-
-
-class HTTPConnectionWithTimeout(httplib.HTTPConnection):
- """HTTPConnection subclass that supports timeouts"""
-
- def __init__(self, host, port=None, strict=None, timeout=None, proxy_info=None):
- httplib.HTTPConnection.__init__(self, host, port, strict)
- self.timeout = timeout
- self.proxy_info = proxy_info
-
- def connect(self):
- """Connect to the host and port specified in __init__."""
- # Mostly verbatim from httplib.py.
- msg = "getaddrinfo returns an empty list"
- for res in socket.getaddrinfo(self.host, self.port, 0,
- socket.SOCK_STREAM):
- af, socktype, proto, canonname, sa = res
- try:
- if self.proxy_info and self.proxy_info.isgood():
- self.sock = socks.socksocket(af, socktype, proto)
- self.sock.setproxy(*self.proxy_info.astuple())
- else:
- self.sock = socket.socket(af, socktype, proto)
- # Different from httplib: support timeouts.
- if has_timeout(self.timeout):
- self.sock.settimeout(self.timeout)
- # End of difference from httplib.
- if self.debuglevel > 0:
- print "connect: (%s, %s)" % (self.host, self.port)
-
- self.sock.connect(sa)
- except socket.error, msg:
- if self.debuglevel > 0:
- print 'connect fail:', (self.host, self.port)
- if self.sock:
- self.sock.close()
- self.sock = None
- continue
- break
- if not self.sock:
- raise socket.error, msg
-
-class HTTPSConnectionWithTimeout(httplib.HTTPSConnection):
- "This class allows communication via SSL."
-
- def __init__(self, host, port=None, key_file=None, cert_file=None,
- strict=None, timeout=None, proxy_info=None):
- httplib.HTTPSConnection.__init__(self, host, port=port, key_file=key_file,
- cert_file=cert_file, strict=strict)
- self.timeout = timeout
- self.proxy_info = proxy_info
-
- def connect(self):
- "Connect to a host on a given (SSL) port."
-
- if self.proxy_info and self.proxy_info.isgood():
- sock = socks.socksocket(socket.AF_INET, socket.SOCK_STREAM)
- sock.setproxy(*self.proxy_info.astuple())
- else:
- sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-
- if has_timeout(self.timeout):
- sock.settimeout(self.timeout)
- sock.connect((self.host, self.port))
- self.sock =_ssl_wrap_socket(sock, self.key_file, self.cert_file)
-
-
-
-class Http(object):
- """An HTTP client that handles:
-- all methods
-- caching
-- ETags
-- compression,
-- HTTPS
-- Basic
-- Digest
-- WSSE
-
-and more.
- """
- def __init__(self, cache=None, timeout=None, proxy_info=None):
- """The value of proxy_info is a ProxyInfo instance.
-
-If 'cache' is a string then it is used as a directory name
-for a disk cache. Otherwise it must be an object that supports
-the same interface as FileCache."""
- self.proxy_info = proxy_info
- # Map domain name to an httplib connection
- self.connections = {}
- # The location of the cache, for now a directory
- # where cached responses are held.
- if cache and isinstance(cache, str):
- self.cache = FileCache(cache)
- else:
- self.cache = cache
-
- # Name/password
- self.credentials = Credentials()
-
- # Key/cert
- self.certificates = KeyCerts()
-
- # authorization objects
- self.authorizations = []
-
- # If set to False then no redirects are followed, even safe ones.
- self.follow_redirects = True
-
- # Which HTTP methods do we apply optimistic concurrency to, i.e.
- # which methods get an "if-match:" etag header added to them.
- self.optimistic_concurrency_methods = ["PUT"]
-
- # If 'follow_redirects' is True, and this is set to True then
- # all redirecs are followed, including unsafe ones.
- self.follow_all_redirects = False
-
- self.ignore_etag = False
-
- self.force_exception_to_status_code = False
-
- self.timeout = timeout
-
- def _auth_from_challenge(self, host, request_uri, headers, response, content):
- """A generator that creates Authorization objects
- that can be applied to requests.
- """
- challenges = _parse_www_authenticate(response, 'www-authenticate')
- for cred in self.credentials.iter(host):
- for scheme in AUTH_SCHEME_ORDER:
- if challenges.has_key(scheme):
- yield AUTH_SCHEME_CLASSES[scheme](cred, host, request_uri, headers, response, content, self)
-
- def add_credentials(self, name, password, domain=""):
- """Add a name and password that will be used
- any time a request requires authentication."""
- self.credentials.add(name, password, domain)
-
- def add_certificate(self, key, cert, domain):
- """Add a key and cert that will be used
- any time a request requires authentication."""
- self.certificates.add(key, cert, domain)
-
- def clear_credentials(self):
- """Remove all the names and passwords
- that are used for authentication"""
- self.credentials.clear()
- self.authorizations = []
-
- def _conn_request(self, conn, request_uri, method, body, headers):
- for i in range(2):
- try:
- conn.request(method, request_uri, body, headers)
- except socket.gaierror:
- conn.close()
- raise ServerNotFoundError("Unable to find the server at %s" % conn.host)
- except (socket.error, httplib.HTTPException):
- # Just because the server closed the connection doesn't apparently mean
- # that the server didn't send a response.
- pass
- try:
- response = conn.getresponse()
- except (socket.error, httplib.HTTPException):
- if i == 0:
- conn.close()
- conn.connect()
- continue
- else:
- raise
- else:
- content = ""
- if method == "HEAD":
- response.close()
- else:
- content = response.read()
- response = Response(response)
- if method != "HEAD":
- content = _decompressContent(response, content)
- break
- return (response, content)
-
-
- def _request(self, conn, host, absolute_uri, request_uri, method, body, headers, redirections, cachekey):
- """Do the actual request using the connection object
- and also follow one level of redirects if necessary"""
-
- auths = [(auth.depth(request_uri), auth) for auth in self.authorizations if auth.inscope(host, request_uri)]
- auth = auths and sorted(auths)[0][1] or None
- if auth:
- auth.request(method, request_uri, headers, body)
-
- (response, content) = self._conn_request(conn, request_uri, method, body, headers)
-
- if auth:
- if auth.response(response, body):
- auth.request(method, request_uri, headers, body)
- (response, content) = self._conn_request(conn, request_uri, method, body, headers )
- response._stale_digest = 1
-
- if response.status == 401:
- for authorization in self._auth_from_challenge(host, request_uri, headers, response, content):
- authorization.request(method, request_uri, headers, body)
- (response, content) = self._conn_request(conn, request_uri, method, body, headers, )
- if response.status != 401:
- self.authorizations.append(authorization)
- authorization.response(response, body)
- break
-
- if (self.follow_all_redirects or (method in ["GET", "HEAD"]) or response.status == 303):
- if self.follow_redirects and response.status in [300, 301, 302, 303, 307]:
- # Pick out the location header and basically start from the beginning
- # remembering first to strip the ETag header and decrement our 'depth'
- if redirections:
- if not response.has_key('location') and response.status != 300:
- raise RedirectMissingLocation( _("Redirected but the response is missing a Location: header."), response, content)
- # Fix-up relative redirects (which violate an RFC 2616 MUST)
- if response.has_key('location'):
- location = response['location']
- (scheme, authority, path, query, fragment) = parse_uri(location)
- if authority == None:
- response['location'] = urlparse.urljoin(absolute_uri, location)
- if response.status == 301 and method in ["GET", "HEAD"]:
- response['-x-permanent-redirect-url'] = response['location']
- if not response.has_key('content-location'):
- response['content-location'] = absolute_uri
- _updateCache(headers, response, content, self.cache, cachekey)
- if headers.has_key('if-none-match'):
- del headers['if-none-match']
- if headers.has_key('if-modified-since'):
- del headers['if-modified-since']
- if response.has_key('location'):
- location = response['location']
- old_response = copy.deepcopy(response)
- if not old_response.has_key('content-location'):
- old_response['content-location'] = absolute_uri
- redirect_method = ((response.status == 303) and (method not in ["GET", "HEAD"])) and "GET" or method
- (response, content) = self.request(location, redirect_method, body=body, headers = headers, redirections = redirections - 1)
- response.previous = old_response
- else:
- raise RedirectLimit( _("Redirected more times than rediection_limit allows."), response, content)
- elif response.status in [200, 203] and method == "GET":
- # Don't cache 206's since we aren't going to handle byte range requests
- if not response.has_key('content-location'):
- response['content-location'] = absolute_uri
- _updateCache(headers, response, content, self.cache, cachekey)
-
- return (response, content)
-
- def _normalize_headers(self, headers):
- return _normalize_headers(headers)
-
-# Need to catch and rebrand some exceptions
-# Then need to optionally turn all exceptions into status codes
-# including all socket.* and httplib.* exceptions.
-
-
- def request(self, uri, method="GET", body=None, headers=None, redirections=DEFAULT_MAX_REDIRECTS, connection_type=None):
- """ Performs a single HTTP request.
-The 'uri' is the URI of the HTTP resource and can begin
-with either 'http' or 'https'. The value of 'uri' must be an absolute URI.
-
-The 'method' is the HTTP method to perform, such as GET, POST, DELETE, etc.
-There is no restriction on the methods allowed.
-
-The 'body' is the entity body to be sent with the request. It is a string
-object.
-
-Any extra headers that are to be sent with the request should be provided in the
-'headers' dictionary.
-
-The maximum number of redirect to follow before raising an
-exception is 'redirections. The default is 5.
-
-The return value is a tuple of (response, content), the first
-being and instance of the 'Response' class, the second being
-a string that contains the response entity body.
- """
- try:
- if headers is None:
- headers = {}
- else:
- headers = self._normalize_headers(headers)
-
- if not headers.has_key('user-agent'):
- headers['user-agent'] = "Python-httplib2/%s" % __version__
-
- uri = iri2uri(uri)
-
- (scheme, authority, request_uri, defrag_uri) = urlnorm(uri)
- domain_port = authority.split(":")[0:2]
- if len(domain_port) == 2 and domain_port[1] == '443' and scheme == 'http':
- scheme = 'https'
- authority = domain_port[0]
-
- conn_key = scheme+":"+authority
- if conn_key in self.connections:
- conn = self.connections[conn_key]
- else:
- if not connection_type:
- connection_type = (scheme == 'https') and HTTPSConnectionWithTimeout or HTTPConnectionWithTimeout
- certs = list(self.certificates.iter(authority))
- if scheme == 'https' and certs:
- conn = self.connections[conn_key] = connection_type(authority, key_file=certs[0][0],
- cert_file=certs[0][1], timeout=self.timeout, proxy_info=self.proxy_info)
- else:
- conn = self.connections[conn_key] = connection_type(authority, timeout=self.timeout, proxy_info=self.proxy_info)
- conn.set_debuglevel(debuglevel)
-
- if method in ["GET", "HEAD"] and 'range' not in headers and 'accept-encoding' not in headers:
- headers['accept-encoding'] = 'gzip, deflate'
-
- info = email.Message.Message()
- cached_value = None
- if self.cache:
- cachekey = defrag_uri
- cached_value = self.cache.get(cachekey)
- if cached_value:
- # info = email.message_from_string(cached_value)
- #
- # Need to replace the line above with the kludge below
- # to fix the non-existent bug not fixed in this
- # bug report: http://mail.python.org/pipermail/python-bugs-list/2005-September/030289.html
- try:
- info, content = cached_value.split('\r\n\r\n', 1)
- feedparser = email.FeedParser.FeedParser()
- feedparser.feed(info)
- info = feedparser.close()
- feedparser._parse = None
- except IndexError:
- self.cache.delete(cachekey)
- cachekey = None
- cached_value = None
- else:
- cachekey = None
-
- if method in self.optimistic_concurrency_methods and self.cache and info.has_key('etag') and not self.ignore_etag and 'if-match' not in headers:
- # http://www.w3.org/1999/04/Editing/
- headers['if-match'] = info['etag']
-
- if method not in ["GET", "HEAD"] and self.cache and cachekey:
- # RFC 2616 Section 13.10
- self.cache.delete(cachekey)
-
- # Check the vary header in the cache to see if this request
- # matches what varies in the cache.
- if method in ['GET', 'HEAD'] and 'vary' in info:
- vary = info['vary']
- vary_headers = vary.lower().replace(' ', '').split(',')
- for header in vary_headers:
- key = '-varied-%s' % header
- value = info[key]
- if headers.get(header, '') != value:
- cached_value = None
- break
-
- if cached_value and method in ["GET", "HEAD"] and self.cache and 'range' not in headers:
- if info.has_key('-x-permanent-redirect-url'):
- # Should cached permanent redirects be counted in our redirection count? For now, yes.
- (response, new_content) = self.request(info['-x-permanent-redirect-url'], "GET", headers = headers, redirections = redirections - 1)
- response.previous = Response(info)
- response.previous.fromcache = True
- else:
- # Determine our course of action:
- # Is the cached entry fresh or stale?
- # Has the client requested a non-cached response?
- #
- # There seems to be three possible answers:
- # 1. [FRESH] Return the cache entry w/o doing a GET
- # 2. [STALE] Do the GET (but add in cache validators if available)
- # 3. [TRANSPARENT] Do a GET w/o any cache validators (Cache-Control: no-cache) on the request
- entry_disposition = _entry_disposition(info, headers)
-
- if entry_disposition == "FRESH":
- if not cached_value:
- info['status'] = '504'
- content = ""
- response = Response(info)
- if cached_value:
- response.fromcache = True
- return (response, content)
-
- if entry_disposition == "STALE":
- if info.has_key('etag') and not self.ignore_etag and not 'if-none-match' in headers:
- headers['if-none-match'] = info['etag']
- if info.has_key('last-modified') and not 'last-modified' in headers:
- headers['if-modified-since'] = info['last-modified']
- elif entry_disposition == "TRANSPARENT":
- pass
-
- (response, new_content) = self._request(conn, authority, uri, request_uri, method, body, headers, redirections, cachekey)
-
- if response.status == 304 and method == "GET":
- # Rewrite the cache entry with the new end-to-end headers
- # Take all headers that are in response
- # and overwrite their values in info.
- # unless they are hop-by-hop, or are listed in the connection header.
-
- for key in _get_end2end_headers(response):
- info[key] = response[key]
- merged_response = Response(info)
- if hasattr(response, "_stale_digest"):
- merged_response._stale_digest = response._stale_digest
- _updateCache(headers, merged_response, content, self.cache, cachekey)
- response = merged_response
- response.status = 200
- response.fromcache = True
-
- elif response.status == 200:
- content = new_content
- else:
- self.cache.delete(cachekey)
- content = new_content
- else:
- cc = _parse_cache_control(headers)
- if cc.has_key('only-if-cached'):
- info['status'] = '504'
- response = Response(info)
- content = ""
- else:
- (response, content) = self._request(conn, authority, uri, request_uri, method, body, headers, redirections, cachekey)
- except Exception, e:
- if self.force_exception_to_status_code:
- if isinstance(e, HttpLib2ErrorWithResponse):
- response = e.response
- content = e.content
- response.status = 500
- response.reason = str(e)
- elif isinstance(e, socket.timeout):
- content = "Request Timeout"
- response = Response( {
- "content-type": "text/plain",
- "status": "408",
- "content-length": len(content)
- })
- response.reason = "Request Timeout"
- else:
- content = str(e)
- response = Response( {
- "content-type": "text/plain",
- "status": "400",
- "content-length": len(content)
- })
- response.reason = "Bad Request"
- else:
- raise
-
-
- return (response, content)
-
-
-
-class Response(dict):
- """An object more like email.Message than httplib.HTTPResponse."""
-
- """Is this response from our local cache"""
- fromcache = False
-
- """HTTP protocol version used by server. 10 for HTTP/1.0, 11 for HTTP/1.1. """
- version = 11
-
- "Status code returned by server. "
- status = 200
-
- """Reason phrase returned by server."""
- reason = "Ok"
-
- previous = None
-
- def __init__(self, info):
- # info is either an email.Message or
- # an httplib.HTTPResponse object.
- if isinstance(info, httplib.HTTPResponse):
- for key, value in info.getheaders():
- self[key.lower()] = value
- self.status = info.status
- self['status'] = str(self.status)
- self.reason = info.reason
- self.version = info.version
- elif isinstance(info, email.Message.Message):
- for key, value in info.items():
- self[key] = value
- self.status = int(self['status'])
- else:
- for key, value in info.iteritems():
- self[key] = value
- self.status = int(self.get('status', self.status))
-
-
- def __getattr__(self, name):
- if name == 'dict':
- return self
- else:
- raise AttributeError, name
diff --git a/chrome/common/extensions/docs/examples/apps/hello-python/httplib2/iri2uri.py b/chrome/common/extensions/docs/examples/apps/hello-python/httplib2/iri2uri.py
deleted file mode 100644
index 70667ed..0000000
--- a/chrome/common/extensions/docs/examples/apps/hello-python/httplib2/iri2uri.py
+++ /dev/null
@@ -1,110 +0,0 @@
-"""
-iri2uri
-
-Converts an IRI to a URI.
-
-"""
-__author__ = "Joe Gregorio (joe@bitworking.org)"
-__copyright__ = "Copyright 2006, Joe Gregorio"
-__contributors__ = []
-__version__ = "1.0.0"
-__license__ = "MIT"
-__history__ = """
-"""
-
-import urlparse
-
-
-# Convert an IRI to a URI following the rules in RFC 3987
-#
-# The characters we need to enocde and escape are defined in the spec:
-#
-# iprivate = %xE000-F8FF / %xF0000-FFFFD / %x100000-10FFFD
-# ucschar = %xA0-D7FF / %xF900-FDCF / %xFDF0-FFEF
-# / %x10000-1FFFD / %x20000-2FFFD / %x30000-3FFFD
-# / %x40000-4FFFD / %x50000-5FFFD / %x60000-6FFFD
-# / %x70000-7FFFD / %x80000-8FFFD / %x90000-9FFFD
-# / %xA0000-AFFFD / %xB0000-BFFFD / %xC0000-CFFFD
-# / %xD0000-DFFFD / %xE1000-EFFFD
-
-escape_range = [
- (0xA0, 0xD7FF ),
- (0xE000, 0xF8FF ),
- (0xF900, 0xFDCF ),
- (0xFDF0, 0xFFEF),
- (0x10000, 0x1FFFD ),
- (0x20000, 0x2FFFD ),
- (0x30000, 0x3FFFD),
- (0x40000, 0x4FFFD ),
- (0x50000, 0x5FFFD ),
- (0x60000, 0x6FFFD),
- (0x70000, 0x7FFFD ),
- (0x80000, 0x8FFFD ),
- (0x90000, 0x9FFFD),
- (0xA0000, 0xAFFFD ),
- (0xB0000, 0xBFFFD ),
- (0xC0000, 0xCFFFD),
- (0xD0000, 0xDFFFD ),
- (0xE1000, 0xEFFFD),
- (0xF0000, 0xFFFFD ),
- (0x100000, 0x10FFFD)
-]
-
-def encode(c):
- retval = c
- i = ord(c)
- for low, high in escape_range:
- if i < low:
- break
- if i >= low and i <= high:
- retval = "".join(["%%%2X" % ord(o) for o in c.encode('utf-8')])
- break
- return retval
-
-
-def iri2uri(uri):
- """Convert an IRI to a URI. Note that IRIs must be
- passed in a unicode strings. That is, do not utf-8 encode
- the IRI before passing it into the function."""
- if isinstance(uri ,unicode):
- (scheme, authority, path, query, fragment) = urlparse.urlsplit(uri)
- authority = authority.encode('idna')
- # For each character in 'ucschar' or 'iprivate'
- # 1. encode as utf-8
- # 2. then %-encode each octet of that utf-8
- uri = urlparse.urlunsplit((scheme, authority, path, query, fragment))
- uri = "".join([encode(c) for c in uri])
- return uri
-
-if __name__ == "__main__":
- import unittest
-
- class Test(unittest.TestCase):
-
- def test_uris(self):
- """Test that URIs are invariant under the transformation."""
- invariant = [
- u"ftp://ftp.is.co.za/rfc/rfc1808.txt",
- u"http://www.ietf.org/rfc/rfc2396.txt",
- u"ldap://[2001:db8::7]/c=GB?objectClass?one",
- u"mailto:John.Doe@example.com",
- u"news:comp.infosystems.www.servers.unix",
- u"tel:+1-816-555-1212",
- u"telnet://192.0.2.16:80/",
- u"urn:oasis:names:specification:docbook:dtd:xml:4.1.2" ]
- for uri in invariant:
- self.assertEqual(uri, iri2uri(uri))
-
- def test_iri(self):
- """ Test that the right type of escaping is done for each part of the URI."""
- self.assertEqual("http://xn--o3h.com/%E2%98%84", iri2uri(u"http://\N{COMET}.com/\N{COMET}"))
- self.assertEqual("http://bitworking.org/?fred=%E2%98%84", iri2uri(u"http://bitworking.org/?fred=\N{COMET}"))
- self.assertEqual("http://bitworking.org/#%E2%98%84", iri2uri(u"http://bitworking.org/#\N{COMET}"))
- self.assertEqual("#%E2%98%84", iri2uri(u"#\N{COMET}"))
- self.assertEqual("/fred?bar=%E2%98%9A#%E2%98%84", iri2uri(u"/fred?bar=\N{BLACK LEFT POINTING INDEX}#\N{COMET}"))
- self.assertEqual("/fred?bar=%E2%98%9A#%E2%98%84", iri2uri(iri2uri(u"/fred?bar=\N{BLACK LEFT POINTING INDEX}#\N{COMET}")))
- self.assertNotEqual("/fred?bar=%E2%98%9A#%E2%98%84", iri2uri(u"/fred?bar=\N{BLACK LEFT POINTING INDEX}#\N{COMET}".encode('utf-8')))
-
- unittest.main()
-
-
diff --git a/chrome/common/extensions/docs/examples/apps/hello-python/index.yaml b/chrome/common/extensions/docs/examples/apps/hello-python/index.yaml
deleted file mode 100644
index da8f7f3..0000000
--- a/chrome/common/extensions/docs/examples/apps/hello-python/index.yaml
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright (c) 2012 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.
-
-indexes:
-
-# AUTOGENERATED
-
-# This index.yaml is automatically updated whenever the dev_appserver
-# detects that a new type of query is run. If you want to manage the
-# index.yaml file manually, remove the above marker line (the line
-# saying "# AUTOGENERATED"). If you want to manage some indexes
-# manually, move them above the marker line. The index.yaml file is
-# automatically uploaded to the admin console when you next deploy
-# your application using appcfg.py.
diff --git a/chrome/common/extensions/docs/examples/apps/hello-python/main.py b/chrome/common/extensions/docs/examples/apps/hello-python/main.py
deleted file mode 100755
index 48a8d90..0000000
--- a/chrome/common/extensions/docs/examples/apps/hello-python/main.py
+++ /dev/null
@@ -1,154 +0,0 @@
-#!/usr/bin/env python
-# Copyright (c) 2012 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.
-
-from google.appengine.ext import webapp
-from google.appengine.ext.webapp import util
-from google.appengine.api import users
-from google.appengine.api import urlfetch
-from google.appengine.ext.webapp import template
-from google.appengine.api.urlfetch import DownloadError
-import oauth2
-import urllib
-import logging
-import os
-import time
-import json
-
-# Configuration
-
-CONFIG = {
- 'oauth_consumer_key': 'anonymous',
- 'oauth_consumer_secret': 'anonymous',
- 'license_server': 'https://www.googleapis.com',
- 'license_path': '%(server)s/chromewebstore/v1/licenses/%(appid)s/%(userid)s',
- 'oauth_token': 'INSERT OAUTH TOKEN HERE',
- 'oauth_token_secret': 'INSERT OAUTH TOKEN SECRET HERE',
- 'app_id': 'INSERT APPLICATION ID HERE',
-}
-
-# Check to see if the server has been deployed. In the dev server, this
-# env variable will start with 'Development', in production, it will start with
-# 'Google App Engine'
-IS_PRODUCTION = os.environ['SERVER_SOFTWARE'].startswith('Google App Engine')
-
-# Valid access levels that may be returned by the license server.
-VALID_ACCESS_LEVELS = ['FREE_TRIAL', 'FULL']
-
-
-def fetch_license_data(userid):
- """Fetches the license for a given user by making an OAuth signed request
- to the license server.
-
- Args:
- userid OpenID of the user you are checking access for.
-
- Returns:
- The server's response as text.
- """
- url = CONFIG['license_path'] % {
- 'server': CONFIG['license_server'],
- 'appid': CONFIG['app_id'],
- 'userid': urllib.quote_plus(userid),
- }
-
- oauth_token = oauth2.Token(**{
- 'key': CONFIG['oauth_token'],
- 'secret': CONFIG['oauth_token_secret']
- })
-
- oauth_consumer = oauth2.Consumer(**{
- 'key': CONFIG['oauth_consumer_key'],
- 'secret': CONFIG['oauth_consumer_secret']
- })
-
- logging.debug('Requesting %s' % url)
- client = oauth2.Client(oauth_consumer, oauth_token)
- resp, content = client.request(url, 'GET')
- logging.debug('Got response code %s, content %s' % (resp, content))
- return content
-
-
-def parse_license_data(userid):
- """Returns the license for a given user as a structured object.
-
- Args:
- userid: The OpenID of the user to check.
-
- Returns:
- An object with the following parameters:
- error: True if something went wrong, False otherwise.
- message: A descriptive message if error is True.
- access: One of 'NO', 'FREE_TRIAL', or 'FULL' depending on the access.
- """
- license = {'error': False, 'message': '', 'access': 'NO'}
- try:
- response_text = fetch_license_data(userid)
- try:
- logging.debug('Attempting to JSON parse: %s' % response_text)
- response = json.loads(response_text)
- logging.debug('Got license server response: %s' % response)
- except ValueError:
- logging.exception('Could not parse response as JSON: %s' % response_text)
- license['error'] = True
- license['message'] = 'Could not parse the license server response'
- except DownloadError:
- logging.exception('Could not fetch license data')
- license['error'] = True
- license['message'] = 'Could not fetch license data'
-
- if 'error' in response:
- license['error'] = True
- license['message'] = response['error']['message']
- elif (response['result'] == 'YES'
- and response['accessLevel'] in VALID_ACCESS_LEVELS):
- license['access'] = response['accessLevel']
-
- return license
-
-
-class MainHandler(webapp.RequestHandler):
- """Request handler class."""
- def get(self):
- """Handler for GET requests."""
- user = users.get_current_user()
- if user:
- if IS_PRODUCTION:
- # We should use federated_identity in production, since the license
- # server requires an OpenID
- userid = user.federated_identity()
- else:
- # On the dev server, we won't have access to federated_identity, so
- # just use a default OpenID which will never return YES.
- # If you want to test different response values on the development
- # server, just change this default value (e.g. append '-yes' or
- # '-trial').
- userid = ('https://www.google.com/accounts/o8/id?'
- 'id=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx')
- license_data = parse_license_data(userid)
- template_data = {
- 'license': license_data,
- 'user_name': user.nickname(),
- 'user_id': userid,
- 'user_logout': users.create_logout_url(self.request.uri),
- }
- else:
- # Force the OpenID login endpoint to be for Google accounts only, since
- # the license server doesn't support any other type of OpenID provider.
- login_url = users.create_login_url(dest_url='/',
- federated_identity='google.com/accounts/o8/id')
- template_data = {
- 'user_login': login_url,
- }
-
- # Render a simple template
- path = os.path.join(os.path.dirname(__file__), 'templates', 'index.html')
- self.response.out.write(template.render(path, template_data))
-
-
-if __name__ == '__main__':
- application = webapp.WSGIApplication([
- ('/', MainHandler),
- ], debug=False)
- util.run_wsgi_app(application)
diff --git a/chrome/common/extensions/docs/examples/apps/hello-python/oauth2/__init__.py b/chrome/common/extensions/docs/examples/apps/hello-python/oauth2/__init__.py
deleted file mode 100644
index 65c3f07..0000000
--- a/chrome/common/extensions/docs/examples/apps/hello-python/oauth2/__init__.py
+++ /dev/null
@@ -1,758 +0,0 @@
-"""
-The MIT License
-
-Copyright (c) 2007-2010 Leah Culver, Joe Stump, Mark Paschal, Vic Fryzel
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-"""
-
-import urllib
-import time
-import random
-import urlparse
-import hmac
-import binascii
-import httplib2
-
-try:
- from urlparse import parse_qs, parse_qsl
-except ImportError:
- from cgi import parse_qs, parse_qsl
-
-
-VERSION = '1.0' # Hi Blaine!
-HTTP_METHOD = 'GET'
-SIGNATURE_METHOD = 'PLAINTEXT'
-
-
-class Error(RuntimeError):
- """Generic exception class."""
-
- def __init__(self, message='OAuth error occurred.'):
- self._message = message
-
- @property
- def message(self):
- """A hack to get around the deprecation errors in 2.6."""
- return self._message
-
- def __str__(self):
- return self._message
-
-
-class MissingSignature(Error):
- pass
-
-
-def build_authenticate_header(realm=''):
- """Optional WWW-Authenticate header (401 error)"""
- return {'WWW-Authenticate': 'OAuth realm="%s"' % realm}
-
-
-def build_xoauth_string(url, consumer, token=None):
- """Build an XOAUTH string for use in SMTP/IMPA authentication."""
- request = Request.from_consumer_and_token(consumer, token,
- "GET", url)
-
- signing_method = SignatureMethod_HMAC_SHA1()
- request.sign_request(signing_method, consumer, token)
-
- params = []
- for k, v in sorted(request.iteritems()):
- if v is not None:
- params.append('%s="%s"' % (k, escape(v)))
-
- return "%s %s %s" % ("GET", url, ','.join(params))
-
-
-def escape(s):
- """Escape a URL including any /."""
- return urllib.quote(s, safe='~')
-
-
-def generate_timestamp():
- """Get seconds since epoch (UTC)."""
- return int(time.time())
-
-
-def generate_nonce(length=8):
- """Generate pseudorandom number."""
- return ''.join([str(random.randint(0, 9)) for i in range(length)])
-
-
-def generate_verifier(length=8):
- """Generate pseudorandom number."""
- return ''.join([str(random.randint(0, 9)) for i in range(length)])
-
-
-class Consumer(object):
- """A consumer of OAuth-protected services.
-
- The OAuth consumer is a "third-party" service that wants to access
- protected resources from an OAuth service provider on behalf of an end
- user. It's kind of the OAuth client.
-
- Usually a consumer must be registered with the service provider by the
- developer of the consumer software. As part of that process, the service
- provider gives the consumer a *key* and a *secret* with which the consumer
- software can identify itself to the service. The consumer will include its
- key in each request to identify itself, but will use its secret only when
- signing requests, to prove that the request is from that particular
- registered consumer.
-
- Once registered, the consumer can then use its consumer credentials to ask
- the service provider for a request token, kicking off the OAuth
- authorization process.
- """
-
- key = None
- secret = None
-
- def __init__(self, key, secret):
- self.key = key
- self.secret = secret
-
- if self.key is None or self.secret is None:
- raise ValueError("Key and secret must be set.")
-
- def __str__(self):
- data = {'oauth_consumer_key': self.key,
- 'oauth_consumer_secret': self.secret}
-
- return urllib.urlencode(data)
-
-
-class Token(object):
- """An OAuth credential used to request authorization or a protected
- resource.
-
- Tokens in OAuth comprise a *key* and a *secret*. The key is included in
- requests to identify the token being used, but the secret is used only in
- the signature, to prove that the requester is who the server gave the
- token to.
-
- When first negotiating the authorization, the consumer asks for a *request
- token* that the live user authorizes with the service provider. The
- consumer then exchanges the request token for an *access token* that can
- be used to access protected resources.
- """
-
- key = None
- secret = None
- callback = None
- callback_confirmed = None
- verifier = None
-
- def __init__(self, key, secret):
- self.key = key
- self.secret = secret
-
- if self.key is None or self.secret is None:
- raise ValueError("Key and secret must be set.")
-
- def set_callback(self, callback):
- self.callback = callback
- self.callback_confirmed = 'true'
-
- def set_verifier(self, verifier=None):
- if verifier is not None:
- self.verifier = verifier
- else:
- self.verifier = generate_verifier()
-
- def get_callback_url(self):
- if self.callback and self.verifier:
- # Append the oauth_verifier.
- parts = urlparse.urlparse(self.callback)
- scheme, netloc, path, params, query, fragment = parts[:6]
- if query:
- query = '%s&oauth_verifier=%s' % (query, self.verifier)
- else:
- query = 'oauth_verifier=%s' % self.verifier
- return urlparse.urlunparse((scheme, netloc, path, params,
- query, fragment))
- return self.callback
-
- def to_string(self):
- """Returns this token as a plain string, suitable for storage.
-
- The resulting string includes the token's secret, so you should never
- send or store this string where a third party can read it.
- """
-
- data = {
- 'oauth_token': self.key,
- 'oauth_token_secret': self.secret,
- }
-
- if self.callback_confirmed is not None:
- data['oauth_callback_confirmed'] = self.callback_confirmed
- return urllib.urlencode(data)
-
- @staticmethod
- def from_string(s):
- """Deserializes a token from a string like one returned by
- `to_string()`."""
-
- if not len(s):
- raise ValueError("Invalid parameter string.")
-
- params = parse_qs(s, keep_blank_values=False)
- if not len(params):
- raise ValueError("Invalid parameter string.")
-
- try:
- key = params['oauth_token'][0]
- except Exception:
- raise ValueError("'oauth_token' not found in OAuth request.")
-
- try:
- secret = params['oauth_token_secret'][0]
- except Exception:
- raise ValueError("'oauth_token_secret' not found in "
- "OAuth request.")
-
- token = Token(key, secret)
- try:
- token.callback_confirmed = params['oauth_callback_confirmed'][0]
- except KeyError:
- pass # 1.0, no callback confirmed.
- return token
-
- def __str__(self):
- return self.to_string()
-
-
-def setter(attr):
- name = attr.__name__
-
- def getter(self):
- try:
- return self.__dict__[name]
- except KeyError:
- raise AttributeError(name)
-
- def deleter(self):
- del self.__dict__[name]
-
- return property(getter, attr, deleter)
-
-
-class Request(dict):
-
- """The parameters and information for an HTTP request, suitable for
- authorizing with OAuth credentials.
-
- When a consumer wants to access a service's protected resources, it does
- so using a signed HTTP request identifying itself (the consumer) with its
- key, and providing an access token authorized by the end user to access
- those resources.
-
- """
-
- version = VERSION
-
- def __init__(self, method=HTTP_METHOD, url=None, parameters=None):
- self.method = method
- self.url = url
- if parameters is not None:
- self.update(parameters)
-
- @setter
- def url(self, value):
- self.__dict__['url'] = value
- if value is not None:
- scheme, netloc, path, params, query, fragment = urlparse.urlparse(value)
-
- # Exclude default port numbers.
- if scheme == 'http' and netloc[-3:] == ':80':
- netloc = netloc[:-3]
- elif scheme == 'https' and netloc[-4:] == ':443':
- netloc = netloc[:-4]
- if scheme not in ('http', 'https'):
- raise ValueError("Unsupported URL %s (%s)." % (value, scheme))
-
- # Normalized URL excludes params, query, and fragment.
- self.normalized_url = urlparse.urlunparse((scheme, netloc, path, None, None, None))
- else:
- self.normalized_url = None
- self.__dict__['url'] = None
-
- @setter
- def method(self, value):
- self.__dict__['method'] = value.upper()
-
- def _get_timestamp_nonce(self):
- return self['oauth_timestamp'], self['oauth_nonce']
-
- def get_nonoauth_parameters(self):
- """Get any non-OAuth parameters."""
- return dict([(k, v) for k, v in self.iteritems()
- if not k.startswith('oauth_')])
-
- def to_header(self, realm=''):
- """Serialize as a header for an HTTPAuth request."""
- oauth_params = ((k, v) for k, v in self.items()
- if k.startswith('oauth_'))
- stringy_params = ((k, escape(str(v))) for k, v in oauth_params)
- header_params = ('%s="%s"' % (k, v) for k, v in stringy_params)
- params_header = ', '.join(header_params)
-
- auth_header = 'OAuth realm="%s"' % realm
- if params_header:
- auth_header = "%s, %s" % (auth_header, params_header)
-
- return {'Authorization': auth_header}
-
- def to_postdata(self):
- """Serialize as post data for a POST request."""
- # tell urlencode to deal with sequence values and map them correctly
- # to resulting querystring. for example self["k"] = ["v1", "v2"] will
- # result in 'k=v1&k=v2' and not k=%5B%27v1%27%2C+%27v2%27%5D
- return urllib.urlencode(self, True).replace('+', '%20')
-
- def to_url(self):
- """Serialize as a URL for a GET request."""
- base_url = urlparse.urlparse(self.url)
- try:
- query = base_url.query
- except AttributeError:
- # must be python <2.5
- query = base_url[4]
- query = parse_qs(query)
- for k, v in self.items():
- query.setdefault(k, []).append(v)
-
- try:
- scheme = base_url.scheme
- netloc = base_url.netloc
- path = base_url.path
- params = base_url.params
- fragment = base_url.fragment
- except AttributeError:
- # must be python <2.5
- scheme = base_url[0]
- netloc = base_url[1]
- path = base_url[2]
- params = base_url[3]
- fragment = base_url[5]
-
- url = (scheme, netloc, path, params,
- urllib.urlencode(query, True), fragment)
- return urlparse.urlunparse(url)
-
- def get_parameter(self, parameter):
- ret = self.get(parameter)
- if ret is None:
- raise Error('Parameter not found: %s' % parameter)
-
- return ret
-
- def get_normalized_parameters(self):
- """Return a string that contains the parameters that must be signed."""
- items = []
- for key, value in self.iteritems():
- if key == 'oauth_signature':
- continue
- # 1.0a/9.1.1 states that kvp must be sorted by key, then by value,
- # so we unpack sequence values into multiple items for sorting.
- if hasattr(value, '__iter__'):
- items.extend((key, item) for item in value)
- else:
- items.append((key, value))
-
- # Include any query string parameters from the provided URL
- query = urlparse.urlparse(self.url)[4]
-
- url_items = self._split_url_string(query).items()
- non_oauth_url_items = list([(k, v) for k, v in url_items if not k.startswith('oauth_')])
- items.extend(non_oauth_url_items)
-
- encoded_str = urllib.urlencode(sorted(items))
- # Encode signature parameters per Oauth Core 1.0 protocol
- # spec draft 7, section 3.6
- # (http://tools.ietf.org/html/draft-hammer-oauth-07#section-3.6)
- # Spaces must be encoded with "%20" instead of "+"
- return encoded_str.replace('+', '%20').replace('%7E', '~')
-
- def sign_request(self, signature_method, consumer, token):
- """Set the signature parameter to the result of sign."""
-
- if 'oauth_consumer_key' not in self:
- self['oauth_consumer_key'] = consumer.key
-
- if token and 'oauth_token' not in self:
- self['oauth_token'] = token.key
-
- self['oauth_signature_method'] = signature_method.name
- self['oauth_signature'] = signature_method.sign(self, consumer, token)
-
- @classmethod
- def make_timestamp(cls):
- """Get seconds since epoch (UTC)."""
- return str(int(time.time()))
-
- @classmethod
- def make_nonce(cls):
- """Generate pseudorandom number."""
- return str(random.randint(0, 100000000))
-
- @classmethod
- def from_request(cls, http_method, http_url, headers=None, parameters=None,
- query_string=None):
- """Combines multiple parameter sources."""
- if parameters is None:
- parameters = {}
-
- # Headers
- if headers and 'Authorization' in headers:
- auth_header = headers['Authorization']
- # Check that the authorization header is OAuth.
- if auth_header[:6] == 'OAuth ':
- auth_header = auth_header[6:]
- try:
- # Get the parameters from the header.
- header_params = cls._split_header(auth_header)
- parameters.update(header_params)
- except:
- raise Error('Unable to parse OAuth parameters from '
- 'Authorization header.')
-
- # GET or POST query string.
- if query_string:
- query_params = cls._split_url_string(query_string)
- parameters.update(query_params)
-
- # URL parameters.
- param_str = urlparse.urlparse(http_url)[4] # query
- url_params = cls._split_url_string(param_str)
- parameters.update(url_params)
-
- if parameters:
- return cls(http_method, http_url, parameters)
-
- return None
-
- @classmethod
- def from_consumer_and_token(cls, consumer, token=None,
- http_method=HTTP_METHOD, http_url=None, parameters=None):
- if not parameters:
- parameters = {}
-
- defaults = {
- 'oauth_consumer_key': consumer.key,
- 'oauth_timestamp': cls.make_timestamp(),
- 'oauth_nonce': cls.make_nonce(),
- 'oauth_version': cls.version,
- }
-
- defaults.update(parameters)
- parameters = defaults
-
- if token:
- parameters['oauth_token'] = token.key
- if token.verifier:
- parameters['oauth_verifier'] = token.verifier
-
- return Request(http_method, http_url, parameters)
-
- @classmethod
- def from_token_and_callback(cls, token, callback=None,
- http_method=HTTP_METHOD, http_url=None, parameters=None):
-
- if not parameters:
- parameters = {}
-
- parameters['oauth_token'] = token.key
-
- if callback:
- parameters['oauth_callback'] = callback
-
- return cls(http_method, http_url, parameters)
-
- @staticmethod
- def _split_header(header):
- """Turn Authorization: header into parameters."""
- params = {}
- parts = header.split(',')
- for param in parts:
- # Ignore realm parameter.
- if param.find('realm') > -1:
- continue
- # Remove whitespace.
- param = param.strip()
- # Split key-value.
- param_parts = param.split('=', 1)
- # Remove quotes and unescape the value.
- params[param_parts[0]] = urllib.unquote(param_parts[1].strip('\"'))
- return params
-
- @staticmethod
- def _split_url_string(param_str):
- """Turn URL string into parameters."""
- parameters = parse_qs(param_str, keep_blank_values=False)
- for k, v in parameters.iteritems():
- parameters[k] = urllib.unquote(v[0])
- return parameters
-
-
-class Client(httplib2.Http):
- """OAuthClient is a worker to attempt to execute a request."""
-
- def __init__(self, consumer, token=None, cache=None, timeout=None,
- proxy_info=None):
-
- if consumer is not None and not isinstance(consumer, Consumer):
- raise ValueError("Invalid consumer.")
-
- if token is not None and not isinstance(token, Token):
- raise ValueError("Invalid token.")
-
- self.consumer = consumer
- self.token = token
- self.method = SignatureMethod_HMAC_SHA1()
-
- httplib2.Http.__init__(self, cache=cache, timeout=timeout,
- proxy_info=proxy_info)
-
- def set_signature_method(self, method):
- if not isinstance(method, SignatureMethod):
- raise ValueError("Invalid signature method.")
-
- self.method = method
-
- def request(self, uri, method="GET", body=None, headers=None,
- redirections=httplib2.DEFAULT_MAX_REDIRECTS, connection_type=None):
- DEFAULT_CONTENT_TYPE = 'application/x-www-form-urlencoded'
-
- if not isinstance(headers, dict):
- headers = {}
-
- is_multipart = method == 'POST' and headers.get('Content-Type',
- DEFAULT_CONTENT_TYPE) != DEFAULT_CONTENT_TYPE
-
- if body and method == "POST" and not is_multipart:
- parameters = dict(parse_qsl(body))
- else:
- parameters = None
-
- req = Request.from_consumer_and_token(self.consumer,
- token=self.token, http_method=method, http_url=uri,
- parameters=parameters)
-
- req.sign_request(self.method, self.consumer, self.token)
-
- if method == "POST":
- headers['Content-Type'] = headers.get('Content-Type',
- DEFAULT_CONTENT_TYPE)
- if is_multipart:
- headers.update(req.to_header())
- else:
- body = req.to_postdata()
- elif method == "GET":
- uri = req.to_url()
- else:
- headers.update(req.to_header())
-
- return httplib2.Http.request(self, uri, method=method, body=body,
- headers=headers, redirections=redirections,
- connection_type=connection_type)
-
-
-class Server(object):
- """A skeletal implementation of a service provider, providing protected
- resources to requests from authorized consumers.
-
- This class implements the logic to check requests for authorization. You
- can use it with your web server or web framework to protect certain
- resources with OAuth.
- """
-
- timestamp_threshold = 300 # In seconds, five minutes.
- version = VERSION
- signature_methods = None
-
- def __init__(self, signature_methods=None):
- self.signature_methods = signature_methods or {}
-
- def add_signature_method(self, signature_method):
- self.signature_methods[signature_method.name] = signature_method
- return self.signature_methods
-
- def verify_request(self, request, consumer, token):
- """Verifies an api call and checks all the parameters."""
-
- version = self._get_version(request)
- self._check_signature(request, consumer, token)
- parameters = request.get_nonoauth_parameters()
- return parameters
-
- def build_authenticate_header(self, realm=''):
- """Optional support for the authenticate header."""
- return {'WWW-Authenticate': 'OAuth realm="%s"' % realm}
-
- def _get_version(self, request):
- """Verify the correct version request for this server."""
- try:
- version = request.get_parameter('oauth_version')
- except:
- version = VERSION
-
- if version and version != self.version:
- raise Error('OAuth version %s not supported.' % str(version))
-
- return version
-
- def _get_signature_method(self, request):
- """Figure out the signature with some defaults."""
- try:
- signature_method = request.get_parameter('oauth_signature_method')
- except:
- signature_method = SIGNATURE_METHOD
-
- try:
- # Get the signature method object.
- signature_method = self.signature_methods[signature_method]
- except:
- signature_method_names = ', '.join(self.signature_methods.keys())
- raise Error('Signature method %s not supported try one of the following: %s' % (signature_method, signature_method_names))
-
- return signature_method
-
- def _get_verifier(self, request):
- return request.get_parameter('oauth_verifier')
-
- def _check_signature(self, request, consumer, token):
- timestamp, nonce = request._get_timestamp_nonce()
- self._check_timestamp(timestamp)
- signature_method = self._get_signature_method(request)
-
- try:
- signature = request.get_parameter('oauth_signature')
- except:
- raise MissingSignature('Missing oauth_signature.')
-
- # Validate the signature.
- valid = signature_method.check(request, consumer, token, signature)
-
- if not valid:
- key, base = signature_method.signing_base(request, consumer, token)
-
- raise Error('Invalid signature. Expected signature base '
- 'string: %s' % base)
-
- built = signature_method.sign(request, consumer, token)
-
- def _check_timestamp(self, timestamp):
- """Verify that timestamp is recentish."""
- timestamp = int(timestamp)
- now = int(time.time())
- lapsed = now - timestamp
- if lapsed > self.timestamp_threshold:
- raise Error('Expired timestamp: given %d and now %s has a '
- 'greater difference than threshold %d' % (timestamp, now,
- self.timestamp_threshold))
-
-
-class SignatureMethod(object):
- """A way of signing requests.
-
- The OAuth protocol lets consumers and service providers pick a way to sign
- requests. This interface shows the methods expected by the other `oauth`
- modules for signing requests. Subclass it and implement its methods to
- provide a new way to sign requests.
- """
-
- def signing_base(self, request, consumer, token):
- """Calculates the string that needs to be signed.
-
- This method returns a 2-tuple containing the starting key for the
- signing and the message to be signed. The latter may be used in error
- messages to help clients debug their software.
-
- """
- raise NotImplementedError
-
- def sign(self, request, consumer, token):
- """Returns the signature for the given request, based on the consumer
- and token also provided.
-
- You should use your implementation of `signing_base()` to build the
- message to sign. Otherwise it may be less useful for debugging.
-
- """
- raise NotImplementedError
-
- def check(self, request, consumer, token, signature):
- """Returns whether the given signature is the correct signature for
- the given consumer and token signing the given request."""
- built = self.sign(request, consumer, token)
- return built == signature
-
-
-class SignatureMethod_HMAC_SHA1(SignatureMethod):
- name = 'HMAC-SHA1'
-
- def signing_base(self, request, consumer, token):
- if request.normalized_url is None:
- raise ValueError("Base URL for request is not set.")
-
- sig = (
- escape(request.method),
- escape(request.normalized_url),
- escape(request.get_normalized_parameters()),
- )
-
- key = '%s&' % escape(consumer.secret)
- if token:
- key += escape(token.secret)
- raw = '&'.join(sig)
- return key, raw
-
- def sign(self, request, consumer, token):
- """Builds the base signature string."""
- key, raw = self.signing_base(request, consumer, token)
-
- # HMAC object.
- try:
- from hashlib import sha1 as sha
- except ImportError:
- import sha # Deprecated
-
- hashed = hmac.new(key, raw, sha)
-
- # Calculate the digest base 64.
- return binascii.b2a_base64(hashed.digest())[:-1]
-
-
-class SignatureMethod_PLAINTEXT(SignatureMethod):
-
- name = 'PLAINTEXT'
-
- def signing_base(self, request, consumer, token):
- """Concatenates the consumer key and secret with the token's
- secret."""
- sig = '%s&' % escape(consumer.secret)
- if token:
- sig = sig + escape(token.secret)
- return sig, sig
-
- def sign(self, request, consumer, token):
- key, raw = self.signing_base(request, consumer, token)
- return raw
diff --git a/chrome/common/extensions/docs/examples/apps/hello-python/oauth2/clients/__init__.py b/chrome/common/extensions/docs/examples/apps/hello-python/oauth2/clients/__init__.py
deleted file mode 100644
index 2ae2839..0000000
--- a/chrome/common/extensions/docs/examples/apps/hello-python/oauth2/clients/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-pass
diff --git a/chrome/common/extensions/docs/examples/apps/hello-python/oauth2/clients/imap.py b/chrome/common/extensions/docs/examples/apps/hello-python/oauth2/clients/imap.py
deleted file mode 100644
index 68b7cd8..0000000
--- a/chrome/common/extensions/docs/examples/apps/hello-python/oauth2/clients/imap.py
+++ /dev/null
@@ -1,40 +0,0 @@
-"""
-The MIT License
-
-Copyright (c) 2007-2010 Leah Culver, Joe Stump, Mark Paschal, Vic Fryzel
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-"""
-
-import oauth2
-import imaplib
-
-
-class IMAP4_SSL(imaplib.IMAP4_SSL):
- """IMAP wrapper for imaplib.IMAP4_SSL that implements XOAUTH."""
-
- def authenticate(self, url, consumer, token):
- if consumer is not None and not isinstance(consumer, oauth2.Consumer):
- raise ValueError("Invalid consumer.")
-
- if token is not None and not isinstance(token, oauth2.Token):
- raise ValueError("Invalid token.")
-
- imaplib.IMAP4_SSL.authenticate(self, 'XOAUTH',
- lambda x: oauth2.build_xoauth_string(url, consumer, token))
diff --git a/chrome/common/extensions/docs/examples/apps/hello-python/oauth2/clients/smtp.py b/chrome/common/extensions/docs/examples/apps/hello-python/oauth2/clients/smtp.py
deleted file mode 100644
index 3e7bf0b0..0000000
--- a/chrome/common/extensions/docs/examples/apps/hello-python/oauth2/clients/smtp.py
+++ /dev/null
@@ -1,41 +0,0 @@
-"""
-The MIT License
-
-Copyright (c) 2007-2010 Leah Culver, Joe Stump, Mark Paschal, Vic Fryzel
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-"""
-
-import oauth2
-import smtplib
-import base64
-
-
-class SMTP(smtplib.SMTP):
- """SMTP wrapper for smtplib.SMTP that implements XOAUTH."""
-
- def authenticate(self, url, consumer, token):
- if consumer is not None and not isinstance(consumer, oauth2.Consumer):
- raise ValueError("Invalid consumer.")
-
- if token is not None and not isinstance(token, oauth2.Token):
- raise ValueError("Invalid token.")
-
- self.docmd('AUTH', 'XOAUTH %s' % \
- base64.b64encode(oauth2.build_xoauth_string(url, consumer, token)))
diff --git a/chrome/common/extensions/docs/examples/apps/hello-python/templates/index.html b/chrome/common/extensions/docs/examples/apps/hello-python/templates/index.html
deleted file mode 100644
index 0602513..0000000
--- a/chrome/common/extensions/docs/examples/apps/hello-python/templates/index.html
+++ /dev/null
@@ -1,57 +0,0 @@
-<!DOCTYPE html>
-<!--
- * 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>
- <style>
- body { font: 14px Arial; }
- .credentials { text-align: right; }
- p { padding: 100px 0; text-align: center; font-size: 24px; }
- p strong {
- display: inline-block; padding: 4px; border: 2px dotted #999;
- border-radius: 10px; margin: 0 5px;
- }
- .noaccess strong { color: #900; border-color: #900; }
- .fullaccess strong { color: #090; border-color: #090; }
- .trialaccess strong { color: #009; border-color: #009; }
- </style>
- </head>
- <body>
- <div class="credentials">
- {% if user_login %}
- <a href="{{user_login}}">Sign in</a>
- {% else %}
- <strong>{{user_id}}</strong> | <a href="{{user_logout}}">Sign out</a>
- {% endif %}
- </div>
- {% if not license %}
- <p class="notsignedin">
- You are <strong>not signed in</strong> to this app.
- </p>
- {% else %}
- {% if license.error %}
- <p><strong>There was an error loading the response:</strong>{{license.message}}</p>
- {% else %}
- {% ifequal license.access "NO" %}
- <p class="noaccess">
- You have <strong>no access</strong> to extra features in this app.
- </p>
- {% endifequal %}
- {% ifequal license.access "FREE_TRIAL" %}
- <p class="trialaccess">
- You are currently enrolled in a <strong>free trial</strong> of this app.
- </p>
- {% endifequal %}
- {% ifequal license.access "FULL" %}
- <p class="fullaccess">
- You have <strong>full access</strong> to the features of this app.
- </p>
- {% endifequal %}
- {% endif %}
- {% endif %}
-
- </body>
-</html>
\ No newline at end of file
diff --git a/chrome/common/extensions/docs/examples/extensions/app_launcher/browser_action_icon.png b/chrome/common/extensions/docs/examples/extensions/app_launcher/browser_action_icon.png
deleted file mode 100644
index e4b0f389..0000000
--- a/chrome/common/extensions/docs/examples/extensions/app_launcher/browser_action_icon.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/app_launcher/icon.png b/chrome/common/extensions/docs/examples/extensions/app_launcher/icon.png
deleted file mode 100644
index a7e8b2b..0000000
--- a/chrome/common/extensions/docs/examples/extensions/app_launcher/icon.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/app_launcher/manifest.json b/chrome/common/extensions/docs/examples/extensions/app_launcher/manifest.json
deleted file mode 100644
index 78e0c924..0000000
--- a/chrome/common/extensions/docs/examples/extensions/app_launcher/manifest.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "name": "App Launcher",
- "description": "Get access to your apps in a browser action",
- "version": "0.7.3",
- "permissions": ["management"],
- "browser_action": {
- "default_icon": "browser_action_icon.png",
- "default_title": "App Launcher",
- "default_popup": "popup.html"
- },
- "icons": {
- "48": "icon.png"
- },
- "manifest_version": 2
-}
diff --git a/chrome/common/extensions/docs/examples/extensions/app_launcher/popup.css b/chrome/common/extensions/docs/examples/extensions/app_launcher/popup.css
deleted file mode 100644
index c42fc36..0000000
--- a/chrome/common/extensions/docs/examples/extensions/app_launcher/popup.css
+++ /dev/null
@@ -1,53 +0,0 @@
-/* Copyright (c) 2010 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 {
- overflow-x: hidden;
-}
-
-body {
- font-family: Helvetica, Arial, sans-serif;
-}
-
-#search_container {
- text-align: center;
-}
-
-#search {
- width: 85%;
-}
-
-.app {
- width: 100%;
- margin-top: 7px;
- margin-bottom: 7px;
- margin-left: 2px;
- margin-right: 20px;
- white-space: nowrap;
-}
-
-.app img {
- vertical-align: middle;
- height: 38px;
- width: 38px;
-}
-
-.app_title {
- vertical-align: middle;
- margin-left: 5px;
-}
-
-.app:hover {
- background-color: rgb(250,250,250);
- cursor:pointer;
- outline: 1px dotted rgb(100,100,200);
-}
-
-.app_selected,.app_selected:hover {
- background-color: rgb(230,230,230);
-}
-
-#appstore_link {
- display: none;
-}
diff --git a/chrome/common/extensions/docs/examples/extensions/app_launcher/popup.html b/chrome/common/extensions/docs/examples/extensions/app_launcher/popup.html
deleted file mode 100644
index 77a9fb6..0000000
--- a/chrome/common/extensions/docs/examples/extensions/app_launcher/popup.html
+++ /dev/null
@@ -1,31 +0,0 @@
-<!doctype html>
-<!--
- * Copyright (c) 2010 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>
-<link rel="stylesheet" type="text/css" href="popup.css">
-<script src="popup.js"></script>
-</head>
-<body>
-
-<div id="spacer_dummy"></div>
-<div id="outer">
-
-<div id="appstore_link">
- <p>No apps installed.</p><p>
- <button>Go get some</button></p>
-</div>
-
-<div id="search_container">
- <input id="search" type="text" placeholder="type to search" spellcheck="false">
-</div>
-
-<div id="apps"></div>
-
-</div>
-
-</body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/extensions/app_launcher/popup.js b/chrome/common/extensions/docs/examples/extensions/app_launcher/popup.js
deleted file mode 100644
index 788228c..0000000
--- a/chrome/common/extensions/docs/examples/extensions/app_launcher/popup.js
+++ /dev/null
@@ -1,213 +0,0 @@
-// Copyright (c) 2011 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.
-
-function $(id) {
- return document.getElementById(id);
-}
-
-// Returns the largest size icon, or a default icon, for the given |app|.
-function getIconURL(app) {
- if (!app.icons || app.icons.length == 0) {
- return chrome.extension.getURL('icon.png');
- }
- var largest = {size:0};
- for (var i = 0; i < app.icons.length; i++) {
- var icon = app.icons[i];
- if (icon.size > largest.size) {
- largest = icon;
- }
- }
- return largest.url;
-}
-
-function launchApp(id) {
- chrome.management.launchApp(id);
- window.close(); // Only needed on OSX because of crbug.com/63594
-}
-
-// Adds DOM nodes for |app| into |appsDiv|.
-function addApp(appsDiv, app, selected) {
- var div = document.createElement('div');
- div.className = 'app' + (selected ? ' app_selected' : '');
-
- div.onclick = function() {
- launchApp(app.id);
- };
-
- var img = document.createElement('img');
- img.src = getIconURL(app);
- div.appendChild(img);
-
- var title = document.createElement('span');
- title.className = 'app_title';
- title.innerText = app.name;
- div.appendChild(title);
-
- appsDiv.appendChild(div);
-}
-
-// The list of all apps & extensions.
-var completeList = [];
-
-// A filtered list of apps we actually want to show.
-var appList = [];
-
-// The index of an app in |appList| that should be highlighted.
-var selectedIndex = 0;
-
-function reloadAppDisplay() {
- var appsDiv = $('apps');
-
- // Empty the current content.
- appsDiv.innerHTML = '';
-
- for (var i = 0; i < appList.length; i++) {
- var item = appList[i];
- addApp(appsDiv, item, i == selectedIndex);
- }
-}
-
-// Puts only enabled apps from completeList into appList.
-function rebuildAppList(filter) {
- selectedIndex = 0;
- appList = [];
- for (var i = 0; i < completeList.length; i++){
- var item = completeList[i];
- // Skip extensions and disabled apps.
- if (!item.isApp || !item.enabled) {
- continue;
- }
- if (filter && item.name.toLowerCase().search(filter) < 0) {
- continue;
- }
- appList.push(item);
- }
-}
-
-// In order to keep the popup bubble from shrinking as your search narrows the
-// list of apps shown, we set an explicit width on the outermost div.
-var didSetExplicitWidth = false;
-
-function adjustWidthIfNeeded(filter) {
- if (filter.length > 0 && !didSetExplicitWidth) {
- // Set an explicit width, correcting for any scroll bar present.
- var outer = $('outer');
- var correction = window.innerWidth - document.documentElement.clientWidth;
- var width = outer.offsetWidth;
- $('spacer_dummy').style.width = width + correction + 'px';
- didSetExplicitWidth = true;
- }
-}
-
-// Shows the list of apps based on the search box contents.
-function onSearchInput() {
- var filter = $('search').value;
- adjustWidthIfNeeded(filter);
- rebuildAppList(filter);
- reloadAppDisplay();
-}
-
-function compare(a, b) {
- return (a > b) ? 1 : (a == b ? 0 : -1);
-}
-
-function compareByName(app1, app2) {
- return compare(app1.name.toLowerCase(), app2.name.toLowerCase());
-}
-
-// Changes the selected app in the list.
-function changeSelection(newIndex) {
- if (newIndex >= 0 && newIndex <= appList.length - 1) {
- selectedIndex = newIndex;
- reloadAppDisplay();
-
- var selected = document.getElementsByClassName('app_selected')[0];
- var rect = selected.getBoundingClientRect();
- if (newIndex == 0) {
- window.scrollTo(0, 0);
- } else if (newIndex == appList.length - 1) {
- window.scrollTo(0, document.height);
- } else if (rect.top < 0) {
- window.scrollBy(0, rect.top);
- } else if (rect.bottom > innerHeight) {
- window.scrollBy(0, rect.bottom - innerHeight);
- }
- }
-}
-
-var keys = {
- ENTER : 13,
- ESCAPE : 27,
- END : 35,
- HOME : 36,
- LEFT : 37,
- UP : 38,
- RIGHT : 39,
- DOWN : 40
-};
-
-// Set up a key event handler that handles moving the selected app up/down,
-// hitting enter to launch the selected app, as well as auto-focusing the
-// search box as soon as you start typing.
-window.onkeydown = function(event) {
- switch (event.keyCode) {
- case keys.DOWN:
- changeSelection(selectedIndex + 1);
- break;
- case keys.UP:
- changeSelection(selectedIndex - 1);
- break;
- case keys.HOME:
- changeSelection(0);
- break;
- case keys.END:
- changeSelection(appList.length - 1);
- break;
- case keys.ENTER:
- var app = appList[selectedIndex];
- if (app) {
- launchApp(app.id);
- }
- break;
- default:
- // Focus the search box and return true so you can just start typing even
- // when the search box isn't focused.
- $('search').focus();
- return true;
- }
- return false;
-};
-
-
-// Initalize the popup window.
-document.addEventListener('DOMContentLoaded', function () {
- chrome.management.getAll(function(info) {
- var appCount = 0;
- for (var i = 0; i < info.length; i++) {
- if (info[i].isApp) {
- appCount++;
- }
- }
- if (appCount == 0) {
- $('search').style.display = 'none';
- $('appstore_link').style.display = '';
- return;
- }
- completeList = info.sort(compareByName);
- onSearchInput();
- });
-
- $('search').addEventListener('input', onSearchInput);
-
- // Opens the webstore in a new tab.
- document.querySelector('#appstore_link button').addEventListener('click',
- function () {
- chrome.tabs.create({
- 'url':'https://chrome.google.com/webstore',
- 'selected':true
- });
- window.close();
- });
-});
-
diff --git a/chrome/common/extensions/docs/examples/extensions/buildbot/active_issues.js b/chrome/common/extensions/docs/examples/extensions/buildbot/active_issues.js
deleted file mode 100644
index f85f32f..0000000
--- a/chrome/common/extensions/docs/examples/extensions/buildbot/active_issues.js
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2013 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.
-
-(function(){
-
-window.buildbot = window.buildbot || {};
-
-buildbot.ActiveIssues = function() {
- this.issues_ = {};
- this.eventCallback_ = null;
-};
-
-buildbot.ActiveIssues.prototype = {
- forEach: function(callback) {
- for (var key in this.issues_)
- callback(this.issues_[key]);
- },
-
- getIssue: function(number) {
- return this.issues_[number];
- },
-
- updateIssue: function(issue) {
- var eventType = this.issues_.hasOwnProperty(issue.issue) ?
- "issueUpdated" : "issueAdded";
- this.issues_[issue.issue] = issue;
- this.postEvent_({event: eventType, issue: issue.issue});
- },
-
- removeIssue: function(issue) {
- delete this.issues_[issue.issue];
- this.postEvent_({event: "issueRemoved", issue: issue.issue});
- },
-
- setEventCallback: function(callback) {
- this.eventCallback_ = callback;
- },
-
- postEvent_: function(obj) {
- if (this.eventCallback_)
- this.eventCallback_(obj);
- }
-};
-
-buildbot.getActiveIssues = function() {
- var background = chrome.extension.getBackgroundPage();
- if (!background.buildbot.hasOwnProperty("activeIssues"))
- background.buildbot.activeIssues = new buildbot.ActiveIssues;
-
- return background.buildbot.activeIssues;
-};
-
-})();
diff --git a/chrome/common/extensions/docs/examples/extensions/buildbot/bg.js b/chrome/common/extensions/docs/examples/extensions/buildbot/bg.js
deleted file mode 100644
index 8324e03a..0000000
--- a/chrome/common/extensions/docs/examples/extensions/buildbot/bg.js
+++ /dev/null
@@ -1,274 +0,0 @@
-// Copyright (c) 2012 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.
-
-// TODO(wittman): Convert this extension to event pages once they work with
-// the notifications API. Currently it's not possible to restore the
-// Notification object when event pages get reloaded. See
-// http://crbug.com/165276.
-
-(function() {
-
-var statusURL = "http://chromium-status.appspot.com/current?format=raw";
-var statusHistoryURL =
- "http://chromium-status.appspot.com/allstatus?limit=20&format=json";
-var pollFrequencyInMs = 30000;
-var tryPollFrequencyInMs = 30000;
-
-var prefs = new buildbot.PrefStore;
-
-function updateBadgeOnErrorStatus() {
- chrome.browserAction.setBadgeText({text:"?"});
- chrome.browserAction.setBadgeBackgroundColor({color:[0,0,255,255]});
-}
-
-var lastNotification = null;
-function notifyStatusChange(treeState, status) {
- if (lastNotification)
- lastNotification.close();
-
- lastNotification = new Notification("Tree is " + treeState, {
- icon: chrome.extension.getURL("icon.png"),
- body: status
- });
-}
-
-// The type parameter should be "open", "closed", or "throttled".
-function getLastStatusTime(callback, type) {
- buildbot.requestURL(statusHistoryURL, "text", function(text) {
- var entries = JSON.parse(text);
-
- for (var i = 0; i < entries.length; i++) {
- if (entries[i].general_state == type) {
- callback(new Date(entries[i].date + " UTC"));
- return;
- }
- }
- }, updateBadgeOnErrorStatus);
-}
-
-function updateTimeBadge(timeDeltaInMs) {
- var secondsSinceChangeEvent = Math.round(timeDeltaInMs / 1000);
- var minutesSinceChangeEvent = Math.round(secondsSinceChangeEvent / 60);
- var hoursSinceChangeEvent = Math.round(minutesSinceChangeEvent / 60);
- var daysSinceChangeEvent = Math.round(hoursSinceChangeEvent / 24);
-
- var text;
- if (secondsSinceChangeEvent < 60) {
- text = "<1m";
- } else if (minutesSinceChangeEvent < 57.5) {
- if (minutesSinceChangeEvent < 30) {
- text = minutesSinceChangeEvent + "m";
- } else {
- text = Math.round(minutesSinceChangeEvent / 5) * 5 + "m";
- }
- } else if (minutesSinceChangeEvent < 5 * 60) {
- var halfHours = Math.round(minutesSinceChangeEvent / 30);
- text = Math.floor(halfHours / 2) + (halfHours % 2 ? ".5" : "") + "h";
- } else if (hoursSinceChangeEvent < 23.5) {
- text = hoursSinceChangeEvent + "h";
- } else {
- text = daysSinceChangeEvent + "d";
- }
-
- chrome.browserAction.setBadgeText({text: text});
-}
-
-var lastState;
-var lastChangeTime;
-function updateStatus(status) {
- var badgeState = {
- open: {color: [0,255,0,255], defaultText: "\u2022"},
- closed: {color: [255,0,0,255], defaultText: "\u00D7"},
- throttled: {color: [255,255,0,255], defaultText: "!"}
- };
-
- chrome.browserAction.setTitle({title:status});
- var treeState = (/open/i).exec(status) ? "open" :
- (/throttled/i).exec(status) ? "throttled" : "closed";
-
- if (lastState && lastState != treeState) {
- prefs.getUseNotifications(function(useNotifications) {
- if (useNotifications)
- notifyStatusChange(treeState, status);
- });
- }
-
- chrome.browserAction.setBadgeBackgroundColor(
- {color: badgeState[treeState].color});
-
- if (lastChangeTime === undefined) {
- chrome.browserAction.setBadgeText(
- {text: badgeState[treeState].defaultText});
- lastState = treeState;
- getLastStatusTime(function(time) {
- lastChangeTime = time;
- updateTimeBadge(Date.now() - lastChangeTime);
- }, treeState);
- } else {
- if (treeState != lastState) {
- lastState = treeState;
- // The change event will occur 1/2 the polling frequency before we
- // are aware of it, on average.
- lastChangeTime = Date.now() - pollFrequencyInMs / 2;
- }
- updateTimeBadge(Date.now() - lastChangeTime);
- }
-}
-
-function requestStatus() {
- buildbot.requestURL(statusURL,
- "text",
- updateStatus,
- updateBadgeOnErrorStatus);
- setTimeout(requestStatus, pollFrequencyInMs);
-}
-
-// Record of the last defunct build number we're aware of on each builder. If
-// the build number is less than or equal to this number, the buildbot
-// information is not available and a request will return a 404.
-var lastDefunctTryJob = {};
-
-function fetchTryJobResults(fullPatchset, builder, buildnumber, completed) {
- var tryJobURL =
- "http://build.chromium.org/p/tryserver.chromium/json/builders/" +
- builder + "/builds/" + buildnumber;
-
- if (lastDefunctTryJob.hasOwnProperty(builder) &&
- buildnumber <= lastDefunctTryJob[builder]) {
- completed();
- return;
- }
-
- buildbot.requestURL(tryJobURL, "json", function(tryJobResult) {
- if (!fullPatchset.full_try_job_results)
- fullPatchset.full_try_job_results = {};
-
- var key = builder + "-" + buildnumber;
- fullPatchset.full_try_job_results[key] = tryJobResult;
-
- completed();
- }, function(errorStatus) {
- if (errorStatus == 404) {
- lastDefunctTryJob[builder] =
- Math.max(lastDefunctTryJob[builder] || 0, buildnumber);
- }
- completed();
- });
-}
-
-// Enums corresponding to how much state has been loaded for an issue.
-var PATCHES_COMPLETE = 0;
-var TRY_JOBS_COMPLETE = 1;
-
-function fetchPatches(issue, updatedCallback) {
- // Notify updated once after receiving all patchsets, and a second time after
- // receiving all try job results.
- var patchsetsRetrieved = 0;
- var tryJobResultsOutstanding = 0;
- issue.patchsets.forEach(function(patchset) {
- var patchURL = "https://codereview.chromium.org/api/" + issue.issue +
- "/" + patchset;
-
- buildbot.requestURL(patchURL, "json", function(patch) {
- if (!issue.full_patchsets)
- issue.full_patchsets = {};
-
- issue.full_patchsets[patch.patchset] = patch;
-
- // TODO(wittman): Revise to reduce load on the try servers. Repeatedly
- // loading old try results increases the size of the working set of try
- // jobs on the try servers, causing them to become disk-bound.
- // patch.try_job_results.forEach(function(results) {
- // if (results.buildnumber) {
- // tryJobResultsOutstanding++;
-
- // fetchTryJobResults(patch, results.builder, results.buildnumber,
- // function() {
- // if (--tryJobResultsOutstanding == 0)
- // updatedCallback(TRY_JOBS_COMPLETE);
- // });
- // }
- // });
-
- if (++patchsetsRetrieved == issue.patchsets.length) {
- updatedCallback(PATCHES_COMPLETE);
- // TODO(wittman): Remove once we revise the try job fetching code.
- updatedCallback(TRY_JOBS_COMPLETE);
- }
- });
- });
-}
-
-function updateTryStatus(status) {
- var seen = {};
- var activeIssues = buildbot.getActiveIssues();
- status.results.forEach(function(result) {
- var issueURL = "https://codereview.chromium.org/api/" + result.issue;
-
- buildbot.requestURL(issueURL, "json", function(issue) {
- fetchPatches(issue, function(state) {
- // If the issue already exists, wait until all the issue state has
- // loaded before updating the issue so we don't lose try job information
- // from the display.
- if (activeIssues.getIssue(issue.issue)) {
- if (state == TRY_JOBS_COMPLETE)
- activeIssues.updateIssue(issue);
- } else {
- activeIssues.updateIssue(issue);
- }
- });
- });
-
- seen[result.issue] = true;
- });
-
- activeIssues.forEach(function(issue) {
- if (!seen[issue.issue])
- activeIssues.removeIssue(issue);
- });
-}
-
-function fetchTryStatus(username) {
- if (!username)
- return;
-
- var url = "https://codereview.chromium.org/search" +
- // commit=2 is CLs with commit bit set, commit=3 is CLs with commit
- // bit cleared, commit=1 is either.
- "?closed=3&commit=1&limit=100&order=-modified&format=json&owner=" +
- username.trim();
- buildbot.requestURL(url, "json", updateTryStatus);
-}
-
-function requestTryStatus() {
- var searchBaseURL = "https://codereview.chromium.org/search";
-
- prefs.getTryJobUsername(function(username) {
- if (username == null) {
- var usernameScrapingURL = "https://codereview.chromium.org/search";
- // Try scraping username from Rietveld if unset.
- buildbot.requestURL(usernameScrapingURL, "text", function(text) {
- var match = /([^<>\s]+@\S+)\s+\(.+\)/.exec(text);
- if (match) {
- username = match[1];
- prefs.setTryJobUsername(username);
- fetchTryStatus(username);
- }
- });
- } else {
- fetchTryStatus(username);
- }
-
- setTimeout(requestTryStatus, tryPollFrequencyInMs);
- });
-}
-
-function main() {
- requestStatus();
- requestTryStatus();
-}
-
-main();
-
-})();
diff --git a/chrome/common/extensions/docs/examples/extensions/buildbot/chromium.png b/chrome/common/extensions/docs/examples/extensions/buildbot/chromium.png
deleted file mode 100644
index 0847b263..0000000
--- a/chrome/common/extensions/docs/examples/extensions/buildbot/chromium.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/buildbot/icon.png b/chrome/common/extensions/docs/examples/extensions/buildbot/icon.png
deleted file mode 100644
index c644a85..0000000
--- a/chrome/common/extensions/docs/examples/extensions/buildbot/icon.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/buildbot/manifest.json b/chrome/common/extensions/docs/examples/extensions/buildbot/manifest.json
deleted file mode 100644
index 0d86bcb..0000000
--- a/chrome/common/extensions/docs/examples/extensions/buildbot/manifest.json
+++ /dev/null
@@ -1,31 +0,0 @@
-{
- "name": "Chromium Buildbot Monitor",
- "version": "0.9.0",
- "description": "Displays the status of the Chromium buildbot in the toolbar. Click to see more detailed status in a popup.",
- "icons": { "128": "icon.png" },
- "background": {
- "scripts": ["utils.js",
- "prefs.js",
- "try_status.js",
- "active_issues.js",
- "bg.js"]
- },
- "permissions": [
- "notifications",
- "storage",
- "http://build.chromium.org/",
- "http://chromium-status.appspot.com/",
- "https://codereview.chromium.org/"
- ],
- "browser_action": {
- "default_title": "",
- "default_icon": "chromium.png",
- "default_popup": "popup.html"
- },
- "options_page": "options.html",
- "options_ui": {
- "chrome_style": true,
- "page": "options.html"
- },
- "manifest_version": 2
-}
diff --git a/chrome/common/extensions/docs/examples/extensions/buildbot/options.html b/chrome/common/extensions/docs/examples/extensions/buildbot/options.html
deleted file mode 100644
index e045aa6..0000000
--- a/chrome/common/extensions/docs/examples/extensions/buildbot/options.html
+++ /dev/null
@@ -1,24 +0,0 @@
-<!doctype html>
-<html>
-<head>
- <title>Chromium Buildbot Monitor Options</title>
- <style>
- body {
- padding: 10px;
- }
- </style>
-</head>
-<body>
- <label>
- Use desktop notifications:
- <input id="notifications" type="checkbox">
- </label>
- <br>
- <label>
- Username for try job monitoring:
- <input id="try-job-username" type="text">
- </label>
- <script src='prefs.js'></script>
- <script src='options.js'></script>
-</body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/extensions/buildbot/options.js b/chrome/common/extensions/docs/examples/extensions/buildbot/options.js
deleted file mode 100644
index 78c2994..0000000
--- a/chrome/common/extensions/docs/examples/extensions/buildbot/options.js
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright (c) 2012 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.
-
-(function() {
-
-window.buildbot = window.buildbot || {};
-
-var prefs = new buildbot.PrefStore;
-
-// Initialize the checkbox checked state from the saved preference.
-function main() {
- var checkbox = document.getElementById('notifications');
- prefs.getUseNotifications(function(useNotifications) {
- checkbox.checked = useNotifications;
- checkbox.addEventListener(
- 'click',
- function() {prefs.setUseNotifications(checkbox.checked);});
- });
-
- var textbox = document.getElementById('try-job-username');
- prefs.getTryJobUsername(function(tryJobUsername) {
- textbox.value = tryJobUsername;
- textbox.addEventListener(
- 'change',
- function() {prefs.setTryJobUsername(textbox.value);});
- });
-}
-
-main();
-
-})();
diff --git a/chrome/common/extensions/docs/examples/extensions/buildbot/popup.css b/chrome/common/extensions/docs/examples/extensions/buildbot/popup.css
deleted file mode 100644
index a6f597e..0000000
--- a/chrome/common/extensions/docs/examples/extensions/buildbot/popup.css
+++ /dev/null
@@ -1,93 +0,0 @@
-/**
- * Copyright 2013 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.
- */
-
-body {
- font-family: sans-serif;
- font-size: 0.8em;
- overflow: hidden;
-}
-
-a {
- text-decoration: underline;
- color: #444;
-}
-
-a:hover {
- color: black;
- cursor: pointer;
-}
-
-.status-label {
- text-align: right;
- font-size: 12px;
- font-weight: bold;
- min-width: 85px;
- padding: 0px;
-}
-
-.trunk-status-cell {
- padding: 0px;
-}
-
-.trunk-status-cell > iframe {
- height: 10px;
- border: none;
-}
-
-[data-issue] + .trunk-status-row > td,
-.closer-status-row + .other-status-row > td {
- padding-top: 5px;
-}
-
-div.issue-status {
- display: table;
- border-spacing: 1px 1px;
- width: 284px;
- margin: 1px 0px 1px 9px;
-}
-
-.issue-status-build {
- display: table-cell;
- width: 1px;
- height: 10px;
-}
-
-/* build statuses */
-.success {
- color: #FFFFFF;
- background-color: #8fdf5f;
- border-color: #4F8530;
-}
-
-.failure {
- color: #FFFFFF;
- background-color: #e98080;
- border-color: #A77272;
-}
-
-.warnings {
- color: #FFFFFF;
- background-color: #ffc343;
- border-color: #C29D46;
-}
-
-.never {
- color: #FFFFFF;
- background-color: #f0f0e0;
- border-color: #A77272;
-}
-
-.exception, .retry {
- color: #FFFFFF;
- background-color: #e0b0ff;
- border-color: #ACA0B3;
-}
-
-.running {
- color: #666666;
- background-color: #fffc6c;
- border-color: #C5C56D;
-}
diff --git a/chrome/common/extensions/docs/examples/extensions/buildbot/popup.html b/chrome/common/extensions/docs/examples/extensions/buildbot/popup.html
deleted file mode 100644
index d9366f57..0000000
--- a/chrome/common/extensions/docs/examples/extensions/buildbot/popup.html
+++ /dev/null
@@ -1,14 +0,0 @@
-<!doctype html>
-<html>
- <head>
- <title>Chromium Buildbot Monitor Popup</title>
- <link href="popup.css" rel="stylesheet" type="text/css" />
- </head>
- <body>
- <table id="status-table"></table>
- <script src='utils.js'></script>
- <script src='try_status.js'></script>
- <script src='active_issues.js'></script>
- <script src='popup.js'></script>
- </body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/extensions/buildbot/popup.js b/chrome/common/extensions/docs/examples/extensions/buildbot/popup.js
deleted file mode 100644
index 1fb4b04..0000000
--- a/chrome/common/extensions/docs/examples/extensions/buildbot/popup.js
+++ /dev/null
@@ -1,301 +0,0 @@
-// Copyright (c) 2012 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.
-
-(function(){
-
-var lkgrURL = 'http://chromium-status.appspot.com/lkgr';
-
-// Interval at which to reload the non-CL bot status.
-var botStatusRefreshIntervalInMs = 60 * 1000;
-// Interval at which to check for LKGR updates.
-var lkgrRefreshIntervalInMs = 60 * 1000;
-
-function getClassForTryJobResult(result) {
- // Some win bots seem to report a null result while building.
- if (result === null)
- result = buildbot.RUNNING;
-
- switch (parseInt(result)) {
- case buildbot.RUNNING:
- return "running";
-
- case buildbot.SUCCESS:
- return "success";
-
- case buildbot.WARNINGS:
- return "warnings";
-
- case buildbot.FAILURE:
- return "failure";
-
- case buildbot.SKIPPED:
- return "skipped";
-
- case buildbot.EXCEPTION:
- return "exception";
-
- case buildbot.RETRY:
- return "retry";
-
- case buildbot.NOT_STARTED:
- default:
- return "never";
- }
-}
-
-// Remove try jobs that have been supplanted by newer runs.
-function filterOldTryJobs(tryJobs) {
- var latest = {};
- tryJobs.forEach(function(tryJob) {
- if (!latest[tryJob.builder] ||
- latest[tryJob.builder].buildnumber < tryJob.buildnumber)
- latest[tryJob.builder] = tryJob;
- });
-
- var result = [];
- tryJobs.forEach(function(tryJob) {
- if (tryJob.buildnumber == latest[tryJob.builder].buildnumber)
- result.push(tryJob);
- });
-
- return result;
-}
-
-function createTryJobAnchorTitle(tryJob, fullTryJob) {
- var title = tryJob.builder;
-
- if (!fullTryJob)
- return title;
-
- var stepText = [];
- if (fullTryJob.currentStep)
- stepText.push("running " + fullTryJob.currentStep.name);
-
- if (fullTryJob.results == buildbot.FAILURE && fullTryJob.text) {
- stepText.push(fullTryJob.text.join(" "));
- } else {
- // Sometimes a step can fail without setting the try job text. Look
- // through all the steps to identify if this is the case.
- var text = [];
- fullTryJob.steps.forEach(function(step) {
- if (step.results[0] == buildbot.FAILURE)
- text.push(step.results[1][0]);
- });
-
- if (text.length > 0) {
- text.unshift("failure");
- stepText.push(text.join(" "));
- }
- }
-
- if (stepText.length > 0)
- title += ": " + stepText.join("; ");
-
- return title;
-}
-
-function createPatchsetStatusElement(patchset) {
- var table = document.createElement("div");
- table.className = "issue-status";
-
- var tryJobs = filterOldTryJobs(patchset.try_job_results);
- tryJobs.forEach(function(tryJob) {
- var key = tryJob.builder + "-" + tryJob.buildnumber;
- var fullTryJob = patchset.full_try_job_results &&
- patchset.full_try_job_results[key];
-
- var tryJobAnchor = document.createElement("a");
- tryJobAnchor.textContent = " ";
- tryJobAnchor.title = createTryJobAnchorTitle(tryJob, fullTryJob);
- tryJobAnchor.className = "issue-status-build " +
- getClassForTryJobResult(tryJob.result);
- tryJobAnchor.target = "_blank";
- tryJobAnchor.href = tryJob.url;
- table.appendChild(tryJobAnchor);
- });
-
- return table;
-}
-
-function getLastFullPatchsetWithTryJobs(issue) {
- var index = issue.patchsets.length - 1;
- var fullPatchsets = issue.full_patchsets;
- while (index >= 0 &&
- (!fullPatchsets ||
- !fullPatchsets[issue.patchsets[index]] ||
- !fullPatchsets[issue.patchsets[index]].try_job_results ||
- fullPatchsets[issue.patchsets[index]].try_job_results.length == 0)) {
- index--;
- }
-
- return index >= 0 ? fullPatchsets[issue.patchsets[index]] : null;
-}
-
-function createTryStatusRow(issue) {
- var table = document.getElementById("status-table");
-
- // Order by decreasing issue number.
- var position =
- document.getElementsByClassName("trunk-status-row")[0].rowIndex;
- while (position > 0 &&
- parseInt(issue.issue) >
- parseInt(table.rows[position - 1].getAttribute("data-issue"))) {
- position--;
- }
-
- var row = table.insertRow(position);
- row.setAttribute("data-issue", issue.issue);
-
- return row;
-}
-
-function updateIssueDisplay(issue) {
- var codereviewBaseURL = "https://codereview.chromium.org";
-
- var lastFullPatchset = getLastFullPatchsetWithTryJobs(issue);
-
- var row = document.querySelector("*[data-issue='" + issue.issue + "']");
- if (!lastFullPatchset) {
- if (row)
- row.parentNode.removeChild(row);
- return;
- }
-
- if (!row)
- row = createTryStatusRow(issue);
-
- var label = row.childNodes[0] || row.insertCell(-1);
- var status = row.childNodes[1] || row.insertCell(-1);
-
- label.className = "status-label";
- var clAnchor = label.childNodes[0] ||
- label.appendChild(document.createElement("a"));
- clAnchor.textContent = "CL " + issue.issue;
- clAnchor.href = codereviewBaseURL + "/" + issue.issue;
- clAnchor.title = issue.subject;
- if (lastFullPatchset && lastFullPatchset.message)
- clAnchor.title += " | " + lastFullPatchset.message;
- clAnchor.target = "_blank";
-
- var statusElement = createPatchsetStatusElement(lastFullPatchset);
- if (status.childElementCount < 1)
- status.appendChild(statusElement);
- else
- status.replaceChild(statusElement, status.firstChild);
-}
-
-function removeIssueDisplay(issueNumber) {
- var row = document.querySelector("*[data-issue='" + issueNumber + "']");
- row.parentNode.removeChild(row);
-}
-
-function addTryStatusRows() {
- buildbot.getActiveIssues().forEach(updateIssueDisplay);
-}
-
-function updateLKGR(lkgr) {
- var link = document.getElementById('link_lkgr');
- link.textContent = 'LKGR (' + lkgr + ')';
-}
-
-function addBotStatusRow(bot, className) {
- var table = document.getElementById("status-table");
-
- var baseURL = "http://build.chromium.org/p/chromium" +
- (bot.id != "" ? "." + bot.id : "");
- var consoleURL = baseURL + "/console";
- var statusURL = baseURL + "/horizontal_one_box_per_builder";
-
- var row = table.insertRow(-1);
- row.className = "trunk-status-row " + className;
- var label = row.insertCell(-1);
- label.className = "status-label";
- var labelAnchor = document.createElement("a");
- labelAnchor.href = consoleURL;
- labelAnchor.target = "_blank";
- labelAnchor.id = "link_" + bot.id;
- labelAnchor.textContent = bot.label;
- label.appendChild(labelAnchor);
-
- var status = row.insertCell(-1);
- status.className = "trunk-status-cell";
- var statusIframe = document.createElement("iframe");
- statusIframe.scrolling = "no";
- statusIframe.src = statusURL;
- status.appendChild(statusIframe);
-}
-
-function addBotStatusRows() {
- var closerBots = [
- {id: "", label: "Chromium"},
- {id: "win", label: "Win"},
- {id: "mac", label: "Mac"},
- {id: "linux", label: "Linux"},
- {id: "chromiumos", label: "ChromiumOS"},
- {id: "chrome", label: "Official"},
- {id: "memory", label: "Memory"}
- ];
-
- var otherBots = [
- {id: "lkgr", label: "LKGR"},
- {id: "perf", label: "Perf"},
- {id: "memory.fyi", label: "Memory FYI"},
- {id: "gpu", label: "GPU"},
- {id: "gpu.fyi", label: "GPU FYI"}
- ];
-
- closerBots.forEach(function(bot) {
- addBotStatusRow(bot, "closer-status-row");
- });
-
- otherBots.forEach(function(bot) {
- addBotStatusRow(bot, "other-status-row");
- });
-}
-
-function fillStatusTable() {
- addBotStatusRows();
- addTryStatusRows();
-}
-
-function main() {
- buildbot.requestURL(lkgrURL, "text", updateLKGR);
- fillStatusTable();
-
- buildbot.getActiveIssues().setEventCallback(function(request) {
- // NOTE(wittman): It doesn't appear that we can reliably detect closing of
- // the popup and remove the event callback, so ensure the popup window is
- // displayed before processing the event.
- if (!chrome.extension.getViews({type: "popup"}))
- return;
-
- switch (request.event) {
- case "issueUpdated":
- case "issueAdded":
- updateIssueDisplay(buildbot.getActiveIssues().getIssue(request.issue));
- break;
-
- case "issueRemoved":
- removeIssueDisplay(request.issue);
- break;
- }
- });
-
- setInterval(function() {
- buildbot.requestURL(lkgrURL, "text", updateLKGR);
- }, lkgrRefreshIntervalInMs);
-
- setInterval(function() {
- var botStatusElements =
- document.getElementsByClassName("trunk-status-iframe");
- for (var i = 0; i < botStatusElements.length; i++)
- // Force a reload of the iframe in a way that doesn't cause cross-domain
- // policy violations.
- botStatusElements.item(i).src = botStatusElements.item(i).src;
- }, botStatusRefreshIntervalInMs);
-}
-
-main();
-
-})();
diff --git a/chrome/common/extensions/docs/examples/extensions/buildbot/prefs.js b/chrome/common/extensions/docs/examples/extensions/buildbot/prefs.js
deleted file mode 100644
index 3071be3..0000000
--- a/chrome/common/extensions/docs/examples/extensions/buildbot/prefs.js
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright (c) 2013 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.
-
-(function() {
-
-window.buildbot = window.buildbot || {};
-
-buildbot.PrefStore = function() {
- this.defaults_ = {prefs: {use_notifications: false,
- try_job_username: null}};
-};
-
-buildbot.PrefStore.prototype = {
- get_: function(key, callback) {
- chrome.storage.sync.get(this.defaults_,
- function (storage) {
- callback(storage.prefs[key]);
- });
- },
-
- set_: function(key, value) {
- chrome.storage.sync.get(this.defaults_,
- function (storage) {
- storage.prefs[key] = value;
- chrome.storage.sync.set(storage);
- });
- },
-
- getUseNotifications: function(callback) {
- this.get_("use_notifications", callback);
- },
-
- setUseNotifications: function(use_notifications) {
- this.set_("use_notifications", use_notifications);
- },
-
- getTryJobUsername: function(callback) {
- this.get_("try_job_username", callback);
- },
-
- setTryJobUsername: function(try_job_username) {
- this.set_("try_job_username", try_job_username);
- }
-};
-
-})();
diff --git a/chrome/common/extensions/docs/examples/extensions/buildbot/try_status.js b/chrome/common/extensions/docs/examples/extensions/buildbot/try_status.js
deleted file mode 100644
index 1641580..0000000
--- a/chrome/common/extensions/docs/examples/extensions/buildbot/try_status.js
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright (c) 2013 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.
-
-(function() {
-
-window.buildbot = window.buildbot || {};
-
-buildbot.RUNNING = -1;
-buildbot.SUCCESS = 0;
-buildbot.WARNINGS = 1;
-buildbot.FAILURE = 2;
-buildbot.SKIPPED = 3;
-buildbot.EXCEPTION = 4;
-buildbot.RETRY = 5;
-buildbot.NOT_STARTED = 6;
-
-})();
diff --git a/chrome/common/extensions/docs/examples/extensions/buildbot/utils.js b/chrome/common/extensions/docs/examples/extensions/buildbot/utils.js
deleted file mode 100644
index ace9ed594..0000000
--- a/chrome/common/extensions/docs/examples/extensions/buildbot/utils.js
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright (c) 2013 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.
-
-(function() {
-
-window.buildbot = window.buildbot || {};
-
-buildbot.requestURL =
- function(url, responseType, callback, opt_errorStatusCallback) {
- var xhr = new XMLHttpRequest();
- if (responseType == "json")
- // WebKit doesn't handle xhr.responseType = "json" as of Chrome 25.
- xhr.responseType = "text";
- else
- xhr.responseType = responseType;
-
- xhr.onreadystatechange = function(state) {
- if (xhr.readyState == 4) {
- if (xhr.status == 200) {
- var response =
- responseType == "json" ? JSON.parse(xhr.response) : xhr.response;
- callback(response);
- } else {
- if (opt_errorStatusCallback)
- opt_errorStatusCallback(xhr.status);
- }
- }
- };
-
- xhr.onerror = function(error) {
- console.log("xhr error:", error);
- };
-
- xhr.open("GET", url, true);
- xhr.send();
-};
-
-})();
diff --git a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/ar/messages.json b/chrome/common/extensions/docs/examples/extensions/calendar/_locales/ar/messages.json
deleted file mode 100644
index 3fd46a01..0000000
--- a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/ar/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"name":{"message":"Google Calendar Checker (\u062a\u062f\u0639\u0645\u0647\u0627 Google)"},"title":{"message":"Google Calendar Checker"},"description":{"message":"\u064a\u0645\u0643\u0646\u0643 \u0628\u0633\u0631\u0639\u0629 \u0627\u0644\u062a\u0639\u0631\u0641 \u0639\u0644\u0649 \u0627\u0644\u0648\u0642\u062a \u0627\u0644\u0645\u062a\u0628\u0642\u064a \u0644\u0643 \u0625\u0644\u0649 \u0623\u0646 \u064a\u062d\u064a\u0646 \u0645\u0648\u0639\u062f \u0627\u062c\u062a\u0645\u0627\u0639\u0643 \u0627\u0644\u062a\u0627\u0644\u064a \u0645\u0646 \u0623\u064a \u062a\u0642\u0648\u064a\u0645 \u0645\u0646 \u062a\u0642\u0627\u0648\u064a\u0645\u0643. \u0627\u0646\u0642\u0631 \u0639\u0644\u0649 \u0627\u0644\u0632\u0631 \u0644\u064a\u062a\u0645 \u0646\u0642\u0644\u0643 \u0625\u0644\u0649 \u0627\u0644\u062a\u0642\u0648\u064a\u0645."},"direction":{"message":"rtl"},"notitle":{"message":"(\u0644\u064a\u0633 \u0647\u0646\u0627\u0643 \u0623\u064a \u0639\u0646\u0648\u0627\u0646)"},"optionstitle":{"message":"Google Calendar Checker"},"minutes":{"message":"$1 \u062f\u0642\u064a\u0642\u0629","placeholders":{"1":{"content":"$1"}}},"hours":{"message":"$1 \u0633\u0627\u0639\u0629","placeholders":{"1":{"content":"$1"}}},"days":{"message":"$1 \u064a\u0648\u0645","placeholders":{"1":{"content":"$1"}}},"multicalendartext":{"message":"\u062f\u0639\u0645 \u0645\u062a\u0639\u062f\u062f \u0644\u0644\u062a\u0642\u0648\u064a\u0645"},"extensionname":{"message":"Google Calendar Checker"},"status_saved":{"message":"\u062a\u0645 \u062d\u0641\u0638 \u0627\u0644\u0625\u0639\u062f\u0627\u062f\u0627\u062a."},"status_saving":{"message":"\u062c\u0627\u0631\u0650 \u0627\u0644\u062d\u0641\u0638..."},"multicalendartooltip":{"message":"\u0627\u0644\u0631\u062c\u0627\u0621 \u062a\u062d\u062f\u064a\u062f \u0627\u0644\u0645\u0631\u0628\u0639 \u0644\u062a\u0645\u0643\u064a\u0646 \u0627\u0644\u062f\u0639\u0645 \u0627\u0644\u0645\u062a\u0639\u062f\u062f \u0644\u0644\u062a\u0642\u0648\u064a\u0645."},"imagetooltip":{"message":"\u062a\u0642\u0648\u064a\u0645 Google"}}
diff --git a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/bg/messages.json b/chrome/common/extensions/docs/examples/extensions/calendar/_locales/bg/messages.json
deleted file mode 100644
index e7dc1a6..0000000
--- a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/bg/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"name":{"message":"Google Calendar Checker (by Google)"},"title":{"message":"Google Calendar Checker"},"description":{"message":"\u0412\u0438\u0436\u0442\u0435 \u0431\u044a\u0440\u0437\u043e \u043a\u043e\u043b\u043a\u043e \u0432\u0440\u0435\u043c\u0435 \u0432\u0438 \u043e\u0441\u0442\u0430\u0432\u0430 \u0434\u043e \u0441\u043b\u0435\u0434\u0432\u0430\u0449\u0430\u0442\u0430 \u0432\u0438 \u0441\u0440\u0435\u0449\u0430 \u043e\u0442 \u0432\u0441\u0435\u043a\u0438 \u0441\u0432\u043e\u0439 \u043a\u0430\u043b\u0435\u043d\u0434\u0430\u0440. \u041a\u043b\u0438\u043a\u043d\u0435\u0442\u0435 \u0432\u044a\u0440\u0445\u0443 \u0431\u0443\u0442\u043e\u043d\u0430, \u0437\u0430 \u0434\u0430 \u0433\u043e \u043e\u0442\u0432\u043e\u0440\u0438\u0442\u0435."},"direction":{"message":"ltr"},"notitle":{"message":"(\u0411\u0435\u0437 \u0437\u0430\u0433\u043b\u0430\u0432\u0438\u0435)"},"optionstitle":{"message":"Google Calendar Checker"},"minutes":{"message":"$1 \u043c","placeholders":{"1":{"content":"$1"}}},"hours":{"message":"$1 \u0447","placeholders":{"1":{"content":"$1"}}},"days":{"message":"$1 \u0434","placeholders":{"1":{"content":"$1"}}},"multicalendartext":{"message":"\u041f\u043e\u0434\u0434\u0440\u044a\u0436\u043a\u0430 \u043d\u0430 \u043d\u044f\u043a\u043e\u043b\u043a\u043e \u043a\u0430\u043b\u0435\u043d\u0434\u0430\u0440\u0430"},"extensionname":{"message":"Google Calendar Checker"},"status_saved":{"message":"\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438\u0442\u0435 \u0441\u0430 \u0437\u0430\u043f\u0430\u0437\u0435\u043d\u0438."},"status_saving":{"message":"\u0417\u0430\u043f\u0430\u0437\u0432\u0430 \u0441\u0435...."},"multicalendartooltip":{"message":"\u041c\u043e\u043b\u044f, \u043f\u043e\u0441\u0442\u0430\u0432\u0435\u0442\u0435 \u043e\u0442\u043c\u0435\u0442\u043a\u0430 \u0432 \u043a\u0432\u0430\u0434\u0440\u0430\u0442\u0447\u0435\u0442\u043e, \u0437\u0430 \u0434\u0430 \u0430\u043a\u0442\u0438\u0432\u0438\u0440\u0430\u0442\u0435 \u043f\u043e\u0434\u0434\u0440\u044a\u0436\u043a\u0430\u0442\u0430 \u043d\u0430 \u043d\u044f\u043a\u043e\u043b\u043a\u043e \u043a\u0430\u043b\u0435\u043d\u0434\u0430\u0440\u0430"},"imagetooltip":{"message":"Google \u041a\u0430\u043b\u0435\u043d\u0434\u0430\u0440"}}
diff --git a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/ca/messages.json b/chrome/common/extensions/docs/examples/extensions/calendar/_locales/ca/messages.json
deleted file mode 100644
index b0ab0c6..0000000
--- a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/ca/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"name":{"message":"Google Calendar Checker (de Google)"},"title":{"message":"Google Calendar Checker"},"description":{"message":"Comproveu r\u00e0pidament el temps que falta per a la propera reuni\u00f3 a qualsevol dels vostres calendaris. Feu clic al bot\u00f3 per anar-hi."},"direction":{"message":"ltr"},"notitle":{"message":"(Sense t\u00edtol)"},"optionstitle":{"message":"Google Calendar Checker"},"minutes":{"message":"$1 min","placeholders":{"1":{"content":"$1"}}},"hours":{"message":"$1 h","placeholders":{"1":{"content":"$1"}}},"days":{"message":"$1 dies","placeholders":{"1":{"content":"$1"}}},"multicalendartext":{"message":"Compatibilitat amb m\u00faltiples calendaris"},"extensionname":{"message":"Google Calendar Checker"},"status_saved":{"message":"S'ha desat la configuraci\u00f3."},"status_saving":{"message":"S'est\u00e0 desant..."},"multicalendartooltip":{"message":"Activeu la casella per activar la compatibilitat amb m\u00faltiples calendaris"},"imagetooltip":{"message":"Google Calendar"}}
diff --git a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/cs/messages.json b/chrome/common/extensions/docs/examples/extensions/calendar/_locales/cs/messages.json
deleted file mode 100644
index 6e31a42..0000000
--- a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/cs/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"name":{"message":"Kontrola Kalend\u00e1\u0159e Google (od spole\u010dnosti Google)"},"title":{"message":"Kontrola Kalend\u00e1\u0159e Google"},"description":{"message":"Umo\u017e\u0148uje rychle zobrazit \u010das, kter\u00fd zb\u00fdv\u00e1 do dal\u0161\u00ed sch\u016fzky napl\u00e1novan\u00e9 v kter\u00e9mkoli z va\u0161ich kalend\u00e1\u0159\u016f. Kliknut\u00edm na tla\u010d\u00edtko p\u0159ejdete do kalend\u00e1\u0159e."},"direction":{"message":"ltr"},"notitle":{"message":"(Bez n\u00e1zvu)"},"optionstitle":{"message":"Kontrola Kalend\u00e1\u0159e Google"},"minutes":{"message":"$1 min","placeholders":{"1":{"content":"$1"}}},"hours":{"message":"$1 h","placeholders":{"1":{"content":"$1"}}},"days":{"message":"$1 d","placeholders":{"1":{"content":"$1"}}},"multicalendartext":{"message":"Podpora n\u011bkolika kalend\u00e1\u0159\u016f"},"extensionname":{"message":"Kontrola Kalend\u00e1\u0159e Google"},"status_saved":{"message":"Nastaven\u00ed byla ulo\u017eena."},"status_saving":{"message":"Ukl\u00e1d\u00e1n\u00ed...."},"multicalendartooltip":{"message":"Za\u0161krtnut\u00edm pol\u00ed\u010dka pros\u00edm povolte podporu v\u00edce kalend\u00e1\u0159\u016f"},"imagetooltip":{"message":"Kalend\u00e1\u0159 Google"}}
diff --git a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/da/messages.json b/chrome/common/extensions/docs/examples/extensions/calendar/_locales/da/messages.json
deleted file mode 100644
index 209b6d9..0000000
--- a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/da/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"name":{"message":"Google Calendar Checker (fra Google)"},"title":{"message":"Google Calendar Checker"},"description":{"message":"Tjek hurtigt hvor lang tid der er til n\u00e6ste m\u00f8de i en af dine kalendre. Klik p\u00e5 knappen for at \u00e5bne din kalender."},"direction":{"message":"ltr"},"notitle":{"message":"(Ingen titel)"},"optionstitle":{"message":"Google Calendar Checker"},"minutes":{"message":"$1 m","placeholders":{"1":{"content":"$1"}}},"hours":{"message":"$1 t","placeholders":{"1":{"content":"$1"}}},"days":{"message":"$1 d","placeholders":{"1":{"content":"$1"}}},"multicalendartext":{"message":"Support til flere kalendere"},"extensionname":{"message":"Google Calendar Checker"},"status_saved":{"message":"Indstillingerne er gemt."},"status_saving":{"message":"Gemmer..."},"multicalendartooltip":{"message":"S\u00e6t kryds i feltet for at aktivere support til flere kalendere"},"imagetooltip":{"message":"Google Kalender"}}
diff --git a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/de/messages.json b/chrome/common/extensions/docs/examples/extensions/calendar/_locales/de/messages.json
deleted file mode 100644
index 3892f39..0000000
--- a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/de/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"name":{"message":"Google Calendar Checker"},"title":{"message":"Google Calendar Checker"},"description":{"message":"Werfen Sie schnell einen Blick auf die verbleibende Zeit bis zum n\u00e4chsten Termin in einem Ihrer Kalender. Klicken Sie zum \u00d6ffnen Ihres Kalenders auf die Schaltfl\u00e4che."},"direction":{"message":"ltr"},"notitle":{"message":"(Kein Titel)"},"optionstitle":{"message":"Google Calendar Checker"},"minutes":{"message":"$1 Min.","placeholders":{"1":{"content":"$1"}}},"hours":{"message":"$1 Std.","placeholders":{"1":{"content":"$1"}}},"days":{"message":"$1 Tage","placeholders":{"1":{"content":"$1"}}},"multicalendartext":{"message":"Unterst\u00fctzung mehrerer Kalender"},"extensionname":{"message":"Google Calendar Checker"},"status_saved":{"message":"Einstellungen gespeichert"},"status_saving":{"message":"Speichern...."},"multicalendartooltip":{"message":"Aktivieren Sie das Kontrollk\u00e4stchen, um die Unterst\u00fctzung mehrerer Kalender einzuschalten."},"imagetooltip":{"message":"Google Kalender"}}
diff --git a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/el/messages.json b/chrome/common/extensions/docs/examples/extensions/calendar/_locales/el/messages.json
deleted file mode 100644
index 9cd461d..0000000
--- a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/el/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"name":{"message":"Google Calendar Checker (\u03b1\u03c0\u03cc \u03c4\u03b7\u03bd Google)"},"title":{"message":"Google Calendar Checker"},"description":{"message":"\u0394\u03b5\u03af\u03c4\u03b5 \u03b3\u03c1\u03ae\u03b3\u03bf\u03c1\u03b1 \u03c0\u03cc\u03c4\u03b5 \u03b5\u03af\u03bd\u03b1\u03b9 \u03b7 \u03b5\u03c0\u03cc\u03bc\u03b5\u03bd\u03b7 \u03c3\u03c5\u03bd\u03ac\u03bd\u03c4\u03b7\u03c3\u03ae \u03c3\u03b1\u03c2 \u03b1\u03c0\u03cc \u03bf\u03c0\u03bf\u03b9\u03bf\u03b4\u03ae\u03c0\u03bf\u03c4\u03b5 \u03b1\u03c0\u03cc \u03c4\u03b1 \u03b7\u03bc\u03b5\u03c1\u03bf\u03bb\u03cc\u03b3\u03b9\u03ac \u03c3\u03b1\u03c2. \u039a\u03ac\u03bd\u03c4\u03b5 \u03ba\u03bb\u03b9\u03ba \u03c3\u03c4\u03bf \u03ba\u03bf\u03c5\u03bc\u03c0\u03af \u03b3\u03b9\u03b1 \u03bd\u03b1 \u03bc\u03b5\u03c4\u03b1\u03c6\u03b5\u03c1\u03b8\u03b5\u03af\u03c4\u03b5 \u03c3\u03c4\u03bf \u03b7\u03bc\u03b5\u03c1\u03bf\u03bb\u03cc\u03b3\u03b9\u03cc \u03c3\u03b1\u03c2."},"direction":{"message":"ltr"},"notitle":{"message":"(\u03a7\u03c9\u03c1\u03af\u03c2 \u03c4\u03af\u03c4\u03bb\u03bf)"},"optionstitle":{"message":"Google Calendar Checker"},"minutes":{"message":"$1\u03bb","placeholders":{"1":{"content":"$1"}}},"hours":{"message":"$1\u03c9","placeholders":{"1":{"content":"$1"}}},"days":{"message":"$1\u03b7","placeholders":{"1":{"content":"$1"}}},"multicalendartext":{"message":"\u03a5\u03c0\u03bf\u03c3\u03c4\u03ae\u03c1\u03b9\u03be\u03b7 \u03c0\u03bf\u03bb\u03bb\u03ce\u03bd \u03b7\u03bc\u03b5\u03c1\u03bf\u03bb\u03bf\u03b3\u03af\u03c9\u03bd"},"extensionname":{"message":"Google Calendar Checker"},"status_saved":{"message":"\u039f\u03b9 \u03c1\u03c5\u03b8\u03bc\u03af\u03c3\u03b5\u03b9\u03c2 \u03b1\u03c0\u03bf\u03b8\u03b7\u03ba\u03b5\u03cd\u03c4\u03b7\u03ba\u03b1\u03bd."},"status_saving":{"message":"\u0391\u03c0\u03bf\u03b8\u03ae\u03ba\u03b5\u03c5\u03c3\u03b7...."},"multicalendartooltip":{"message":"\u0395\u03c0\u03b9\u03bb\u03ad\u03be\u03c4\u03b5 \u03c4\u03bf \u03c0\u03bb\u03b1\u03af\u03c3\u03b9\u03bf \u03b3\u03b9\u03b1 \u03bd\u03b1 \u03b5\u03bd\u03b5\u03c1\u03b3\u03bf\u03c0\u03bf\u03b9\u03ae\u03c3\u03b5\u03c4\u03b5 \u03c4\u03b7\u03bd \u03c5\u03c0\u03bf\u03c3\u03c4\u03ae\u03c1\u03b9\u03be\u03b7 \u03c0\u03bf\u03bb\u03bb\u03ce\u03bd \u03b7\u03bc\u03b5\u03c1\u03bf\u03bb\u03bf\u03b3\u03af\u03c9\u03bd"},"imagetooltip":{"message":"\u0397\u03bc\u03b5\u03c1\u03bf\u03bb\u03cc\u03b3\u03b9\u03bf Google"}}
diff --git a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/en/messages.json b/chrome/common/extensions/docs/examples/extensions/calendar/_locales/en/messages.json
deleted file mode 100644
index 2b19e00..0000000
--- a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/en/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"name":{"message":"Google Calendar Checker (by Google)"},"title":{"message":"Google Calendar Checker"},"description":{"message":"Quickly see the time until your next meeting from any of your calendars. Click on the button to be taken to your calendar."},"direction":{"message":"ltr"},"notitle":{"message":"(No Title)"},"optionstitle":{"message":"Google Calendar Checker"},"minutes":{"message":"$1m","placeholders":{"1":{"content":"$1"}}},"hours":{"message":"$1h","placeholders":{"1":{"content":"$1"}}},"days":{"message":"$1d","placeholders":{"1":{"content":"$1"}}},"multicalendartext":{"message":"Multi Calendar Support"},"extensionname":{"message":"Google Calendar Checker"},"status_saved":{"message":"Settings Saved."},"status_saving":{"message":"Saving...."},"multicalendartooltip":{"message":"Please check the box to enable multiple calendar support"},"imagetooltip":{"message":"Google Calendar"}}
diff --git a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/en_GB/messages.json b/chrome/common/extensions/docs/examples/extensions/calendar/_locales/en_GB/messages.json
deleted file mode 100644
index 87ef60e9..0000000
--- a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/en_GB/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"name":{"message":"Google Calendar Checker (by Google)"},"title":{"message":"Google Calendar Checker"},"description":{"message":"Quickly see the time until your next meeting from any of your calendars. Click the button to be taken to your calendar."},"direction":{"message":"ltr"},"notitle":{"message":"(No Title)"},"optionstitle":{"message":"Google Calendar Checker"},"minutes":{"message":"$1m","placeholders":{"1":{"content":"$1"}}},"hours":{"message":"$1h","placeholders":{"1":{"content":"$1"}}},"days":{"message":"$1d","placeholders":{"1":{"content":"$1"}}},"multicalendartext":{"message":"Multi-Calendar Support"},"extensionname":{"message":"Google Calendar Checker"},"status_saved":{"message":"Settings Saved."},"status_saving":{"message":"Saving...."},"multicalendartooltip":{"message":"Please tick the box to enable multiple calendar support"},"imagetooltip":{"message":"Google Calendar"}}
diff --git a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/es/messages.json b/chrome/common/extensions/docs/examples/extensions/calendar/_locales/es/messages.json
deleted file mode 100644
index 03d60100..0000000
--- a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/es/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"name":{"message":"Google Calendar Checker (de Google)"},"title":{"message":"Google Calendar Checker"},"description":{"message":"Consulta r\u00e1pidamente cu\u00e1nto tiempo falta para tu pr\u00f3xima reuni\u00f3n en cualquiera de tus calendarios. Haz clic en el bot\u00f3n para acceder al calendario."},"direction":{"message":"ltr"},"notitle":{"message":"(Sin t\u00edtulo)"},"optionstitle":{"message":"Google Calendar Checker"},"minutes":{"message":"$1min","placeholders":{"1":{"content":"$1"}}},"hours":{"message":"$1h","placeholders":{"1":{"content":"$1"}}},"days":{"message":"$1d","placeholders":{"1":{"content":"$1"}}},"multicalendartext":{"message":"Compatibilidad con varios calendarios"},"extensionname":{"message":"Google Calendar Checker"},"status_saved":{"message":"Se ha guardado la configuraci\u00f3n."},"status_saving":{"message":"Guardando...."},"multicalendartooltip":{"message":"Selecciona la casilla para habilitar la compatibilidad con varios calendarios"},"imagetooltip":{"message":"Google Calendar"}}
diff --git a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/es_419/messages.json b/chrome/common/extensions/docs/examples/extensions/calendar/_locales/es_419/messages.json
deleted file mode 100644
index e7b2536a..0000000
--- a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/es_419/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"name":{"message":"Google Calendar Checker (de Google)"},"title":{"message":"Google Calendar Checker"},"description":{"message":"F\u00edjate r\u00e1pidamente cu\u00e1nto tiempo falta para tu pr\u00f3xima reuni\u00f3n en alguno de tus calendarios. Haz clic en el bot\u00f3n para que te lleve hasta tu calendario."},"direction":{"message":"ltr"},"notitle":{"message":"(Sin t\u00edtulo)"},"optionstitle":{"message":"Google Calendar Checker"},"minutes":{"message":"$1\u00a0m","placeholders":{"1":{"content":"$1"}}},"hours":{"message":"$1\u00a0h","placeholders":{"1":{"content":"$1"}}},"days":{"message":"$1d","placeholders":{"1":{"content":"$1"}}},"multicalendartext":{"message":"Ayuda de Multi Calendar"},"extensionname":{"message":"Google Calendar Checker"},"status_saved":{"message":"Configuraciones guardadas"},"status_saving":{"message":"Guardando...."},"multicalendartooltip":{"message":"Marca el casillero para habilitar la ayuda del calendario m\u00faltiple."},"imagetooltip":{"message":"Google Calendar"}}
diff --git a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/et/messages.json b/chrome/common/extensions/docs/examples/extensions/calendar/_locales/et/messages.json
deleted file mode 100644
index 5828ccd..0000000
--- a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/et/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"name":{"message":"Google Calendar Checker (Google)"},"title":{"message":"Google Calendar Checker"},"description":{"message":"Vaadake kiiresti oma j\u00e4rgmise koosolekuni j\u00e4\u00e4nud aega \u00fcksk\u00f5ik millisest oma kalendrist. Kalendrisse minekuks kl\u00f5psake nupul."},"direction":{"message":"ltr"},"notitle":{"message":"(Pealkiri puudub)"},"optionstitle":{"message":"Google Calendar Checker"},"minutes":{"message":"$1 min","placeholders":{"1":{"content":"$1"}}},"hours":{"message":"$1 h","placeholders":{"1":{"content":"$1"}}},"days":{"message":"$1 p\u00e4ev(a)","placeholders":{"1":{"content":"$1"}}},"multicalendartext":{"message":"Multi-Calendari tugi"},"extensionname":{"message":"Google Calendar Checker"},"status_saved":{"message":"Seaded salvestatud."},"status_saving":{"message":"Salvestamine ..."},"multicalendartooltip":{"message":"Mitme kalendri toe lubamiseks m\u00e4rkige ruut"},"imagetooltip":{"message":"Google'i kalender"}}
diff --git a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/fi/messages.json b/chrome/common/extensions/docs/examples/extensions/calendar/_locales/fi/messages.json
deleted file mode 100644
index ddc2088..0000000
--- a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/fi/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"name":{"message":"Google Calendar Checker (Googlen tekem\u00e4)"},"title":{"message":"Google Calendar Checker"},"description":{"message":"N\u00e4et nopeasti ajan seuraavaan tapaamiseesi mist\u00e4 tahansa kalenteristasi. Siirryt kalenteriin napsauttamalla painiketta."},"direction":{"message":"ltr"},"notitle":{"message":"(Ei nime\u00e4)"},"optionstitle":{"message":"Google Calendar Checker"},"minutes":{"message":"$1 min","placeholders":{"1":{"content":"$1"}}},"hours":{"message":"$1 t","placeholders":{"1":{"content":"$1"}}},"days":{"message":"$1 pv","placeholders":{"1":{"content":"$1"}}},"multicalendartext":{"message":"Useiden kalentereiden tuki"},"extensionname":{"message":"Google Calendar Checker"},"status_saved":{"message":"Asetukset tallennettu."},"status_saving":{"message":"Tallennetaan..."},"multicalendartooltip":{"message":"Ota useiden kalentereiden tuki k\u00e4ytt\u00f6\u00f6n valitsemalla valintaruutu"},"imagetooltip":{"message":"Google-kalenteri"}}
diff --git a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/fil/messages.json b/chrome/common/extensions/docs/examples/extensions/calendar/_locales/fil/messages.json
deleted file mode 100644
index 16cdeba..0000000
--- a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/fil/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"name":{"message":"Google Calendar Checker (mula sa Google)"},"title":{"message":"Google Calendar Checker"},"description":{"message":"Mabilisang tingnan ang oras hanggang sa iyong susunod na pagpupulong mula sa alinman sa iyong mga kalendaryo. Mag-click sa pindutan upang mapunta sa iyong kalendaryo."},"direction":{"message":"ltr"},"notitle":{"message":"(Walang Pamagat)"},"optionstitle":{"message":"Google Calendar Checker"},"minutes":{"message":"$1m","placeholders":{"1":{"content":"$1"}}},"hours":{"message":"$1o","placeholders":{"1":{"content":"$1"}}},"days":{"message":"$1a","placeholders":{"1":{"content":"$1"}}},"multicalendartext":{"message":"Suporta sa Maramihang Kalendaryo"},"extensionname":{"message":"Google Calendar Checker"},"status_saved":{"message":"Na-save ang Mga Setting."},"status_saving":{"message":"Sine-save...."},"multicalendartooltip":{"message":"Pakilagyan ng check ang kahon upang paganahin ang suporta sa maramihang kalendaryo"},"imagetooltip":{"message":"Google Calendar"}}
diff --git a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/fr/messages.json b/chrome/common/extensions/docs/examples/extensions/calendar/_locales/fr/messages.json
deleted file mode 100644
index f8e413af..0000000
--- a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/fr/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"name":{"message":"Google\u00a0Calendar Checker (par Google)"},"title":{"message":"Google\u00a0Calendar Checker"},"description":{"message":"V\u00e9rifiez rapidement dans vos agendas le temps qu'il vous reste avant votre prochaine r\u00e9union. Cliquez sur le bouton pour ouvrir l'agenda correspondant."},"direction":{"message":"ltr"},"notitle":{"message":"(Sans titre)"},"optionstitle":{"message":"Google\u00a0Calendar Checker"},"minutes":{"message":"$1\u00a0mn","placeholders":{"1":{"content":"$1"}}},"hours":{"message":"$1\u00a0h","placeholders":{"1":{"content":"$1"}}},"days":{"message":"$1\u00a0j","placeholders":{"1":{"content":"$1"}}},"multicalendartext":{"message":"Prise en charge multi-agendas"},"extensionname":{"message":"Google\u00a0Calendar Checker"},"status_saved":{"message":"Param\u00e8tres enregistr\u00e9s"},"status_saving":{"message":"Enregistrement...."},"multicalendartooltip":{"message":"Cocher la case pour activer la prise en charge multi-agendas"},"imagetooltip":{"message":"Google\u00a0Agenda"}}
diff --git a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/he/messages.json b/chrome/common/extensions/docs/examples/extensions/calendar/_locales/he/messages.json
deleted file mode 100644
index 09f1654..0000000
--- a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/he/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"name":{"message":"Google Calendar Checker (\u05de\u05d0\u05ea Google)"},"title":{"message":"Google Calendar Checker"},"description":{"message":"\u05e8\u05d0\u05d4 \u05d1\u05de\u05d4\u05d9\u05e8\u05d5\u05ea \u05db\u05de\u05d4 \u05d6\u05de\u05df \u05d9\u05e9 \u05dc\u05da \u05e2\u05d3 \u05d4\u05e4\u05d2\u05d9\u05e9\u05d4 \u05d4\u05d1\u05d0\u05d4 \u05e9\u05dc\u05da \u05de\u05db\u05dc \u05dc\u05d5\u05d7 \u05e9\u05e0\u05d4 \u05e9\u05dc\u05da. \u05dc\u05d7\u05e5 \u05e2\u05dc \u05d4\u05dc\u05d7\u05e6\u05df \u05db\u05d3\u05d9 \u05dc\u05e2\u05d1\u05d5\u05e8 \u05dc\u05dc\u05d5\u05d7 \u05d4\u05e9\u05e0\u05d4 \u05e9\u05dc\u05da."},"direction":{"message":"rtl"},"notitle":{"message":"(\u05dc\u05dc\u05d0 \u05db\u05d5\u05ea\u05e8\u05ea)"},"optionstitle":{"message":"Google Calendar Checker"},"minutes":{"message":"$1\u05d3'","placeholders":{"1":{"content":"$1"}}},"hours":{"message":"$1\u05e9'","placeholders":{"1":{"content":"$1"}}},"days":{"message":"$1\u05d9'","placeholders":{"1":{"content":"$1"}}},"multicalendartext":{"message":"\u05ea\u05de\u05d9\u05db\u05d4 \u05d1\u05d9\u05d5\u05de\u05e0\u05d9\u05dd \u05de\u05e8\u05d5\u05d1\u05d9\u05dd"},"extensionname":{"message":"Google Calendar Checker"},"status_saved":{"message":"\u05d4\u05d4\u05d2\u05d3\u05e8\u05d5\u05ea \u05e0\u05e9\u05de\u05e8\u05d5."},"status_saving":{"message":"\u05e9\u05d5\u05de\u05e8...."},"multicalendartooltip":{"message":"\u05e1\u05de\u05df \u05d0\u05ea \u05d4\u05ea\u05d9\u05d1\u05d4 \u05db\u05d3\u05d9 \u05dc\u05d4\u05e4\u05d5\u05da \u05d0\u05ea \u05d4\u05ea\u05de\u05d9\u05db\u05d4 \u05d1\u05d9\u05d5\u05de\u05e0\u05d9\u05dd \u05de\u05e8\u05d5\u05d1\u05d9\u05dd \u05dc\u05e4\u05e2\u05d9\u05dc\u05d4"},"imagetooltip":{"message":"\u05d9\u05d5\u05de\u05df Google"}}
diff --git a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/hi/messages.json b/chrome/common/extensions/docs/examples/extensions/calendar/_locales/hi/messages.json
deleted file mode 100644
index 2b19e00..0000000
--- a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/hi/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"name":{"message":"Google Calendar Checker (by Google)"},"title":{"message":"Google Calendar Checker"},"description":{"message":"Quickly see the time until your next meeting from any of your calendars. Click on the button to be taken to your calendar."},"direction":{"message":"ltr"},"notitle":{"message":"(No Title)"},"optionstitle":{"message":"Google Calendar Checker"},"minutes":{"message":"$1m","placeholders":{"1":{"content":"$1"}}},"hours":{"message":"$1h","placeholders":{"1":{"content":"$1"}}},"days":{"message":"$1d","placeholders":{"1":{"content":"$1"}}},"multicalendartext":{"message":"Multi Calendar Support"},"extensionname":{"message":"Google Calendar Checker"},"status_saved":{"message":"Settings Saved."},"status_saving":{"message":"Saving...."},"multicalendartooltip":{"message":"Please check the box to enable multiple calendar support"},"imagetooltip":{"message":"Google Calendar"}}
diff --git a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/hr/messages.json b/chrome/common/extensions/docs/examples/extensions/calendar/_locales/hr/messages.json
deleted file mode 100644
index f2ab5e5..0000000
--- a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/hr/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"name":{"message":"Google Calendar Checker (od Googlea)"},"title":{"message":"Google Calendar Checker"},"description":{"message":"Brzo pogledajte koliko imate vremena do idu\u0107eg sastanka iz svih svojih kalendara. Kliknite gumb koji \u0107e vas odvesti u va\u0161 kalendar."},"direction":{"message":"ltr"},"notitle":{"message":"(Nema naslova)"},"optionstitle":{"message":"Google Calendar Checker"},"minutes":{"message":"$1 m","placeholders":{"1":{"content":"$1"}}},"hours":{"message":"$1 h","placeholders":{"1":{"content":"$1"}}},"days":{"message":"$1 d","placeholders":{"1":{"content":"$1"}}},"multicalendartext":{"message":"Podr\u0161ka za vi\u0161e kalendara"},"extensionname":{"message":"Google Calendar Checker"},"status_saved":{"message":"Postavke su spremljene."},"status_saving":{"message":"Spremanje...."},"multicalendartooltip":{"message":"Uklju\u010dite potvrdni okvir za omogu\u0107avanje podr\u0161ke za vi\u0161e kalendara"},"imagetooltip":{"message":"Google Kalendar"}}
diff --git a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/hu/messages.json b/chrome/common/extensions/docs/examples/extensions/calendar/_locales/hu/messages.json
deleted file mode 100644
index 6be01dc..0000000
--- a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/hu/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"name":{"message":"Google Calendar Checker (a Google-t\u00f3l)"},"title":{"message":"Google Calendar Checker"},"description":{"message":"Gyorsan megn\u00e9zheti b\u00e1rmelyik napt\u00e1r\u00e1ban, hogy mennyi ideje van m\u00e9g a k\u00f6vetkez\u0151 tal\u00e1lkoz\u00f3ig. Kattintson a gombra a napt\u00e1r megtekint\u00e9s\u00e9hez."},"direction":{"message":"ltr"},"notitle":{"message":"(Nincs c\u00edm)"},"optionstitle":{"message":"Google Calendar Checker"},"minutes":{"message":"$1p","placeholders":{"1":{"content":"$1"}}},"hours":{"message":"$1\u00f3","placeholders":{"1":{"content":"$1"}}},"days":{"message":"$1nap","placeholders":{"1":{"content":"$1"}}},"multicalendartext":{"message":"T\u00f6bb napt\u00e1r t\u00e1mogat\u00e1sa"},"extensionname":{"message":"Google Calendar Checker"},"status_saved":{"message":"Be\u00e1ll\u00edt\u00e1sok elmentve."},"status_saving":{"message":"Ment\u00e9s..."},"multicalendartooltip":{"message":"K\u00e9rj\u00fck, jel\u00f6lje be a jel\u00f6l\u0151n\u00e9gyzetet t\u00f6bb napt\u00e1r t\u00e1mogat\u00e1s\u00e1nak enged\u00e9lyez\u00e9s\u00e9hez"},"imagetooltip":{"message":"Google Napt\u00e1r"}}
diff --git a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/id/messages.json b/chrome/common/extensions/docs/examples/extensions/calendar/_locales/id/messages.json
deleted file mode 100644
index 37056ba..0000000
--- a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/id/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"name":{"message":"Pemeriksa Google Kalender (oleh Google)"},"title":{"message":"Pemeriksa Google Kalender"},"description":{"message":"Lihat waktu dengan cepat sampai pertemuan berikutnya dari kalender apa pun. Klik tombol untuk diarahkan ke kalender Anda."},"direction":{"message":"ltr"},"notitle":{"message":"(Tanpa Judul)"},"optionstitle":{"message":"Pemeriksa Google Kalender"},"minutes":{"message":"$1m","placeholders":{"1":{"content":"$1"}}},"hours":{"message":"$1j","placeholders":{"1":{"content":"$1"}}},"days":{"message":"$1h","placeholders":{"1":{"content":"$1"}}},"multicalendartext":{"message":"Dukungan Multi-Kalender"},"extensionname":{"message":"Pemeriksa Google Kalender"},"status_saved":{"message":"Setelan Disimpan."},"status_saving":{"message":"Menyimpan..."},"multicalendartooltip":{"message":"Harap periksa kotak untuk mengaktifkan dukungan multi-kalender"},"imagetooltip":{"message":"Google Kalender"}}
diff --git a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/it/messages.json b/chrome/common/extensions/docs/examples/extensions/calendar/_locales/it/messages.json
deleted file mode 100644
index 90e8daf..0000000
--- a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/it/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"name":{"message":"Google Calendar Checker (di Google)"},"title":{"message":"Google Calendar Checker"},"description":{"message":"Usa uno dei tuoi calendari per controllare rapidamente quanto manca alla prossima riunione. Fai clic sul pulsante per accedere al calendario."},"direction":{"message":"ltr"},"notitle":{"message":"(Nessun titolo)"},"optionstitle":{"message":"Google Calendar Checker"},"minutes":{"message":"$1 m","placeholders":{"1":{"content":"$1"}}},"hours":{"message":"$1 h","placeholders":{"1":{"content":"$1"}}},"days":{"message":"$1 g","placeholders":{"1":{"content":"$1"}}},"multicalendartext":{"message":"Supporto di pi\u00f9 calendari"},"extensionname":{"message":"Google Calendar Checker"},"status_saved":{"message":"Impostazioni salvate."},"status_saving":{"message":"Salvataggio in corso..."},"multicalendartooltip":{"message":"Seleziona la casella per attivare il supporto di pi\u00f9 calendari"},"imagetooltip":{"message":"Google Calendar"}}
diff --git a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/ja/messages.json b/chrome/common/extensions/docs/examples/extensions/calendar/_locales/ja/messages.json
deleted file mode 100644
index 30cdf0bbb..0000000
--- a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/ja/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"name":{"message":"Google Calendar Checker\uff08by Google\uff09"},"title":{"message":"Google Calendar Checker"},"description":{"message":"\u3069\u306e\u30ab\u30ec\u30f3\u30c0\u30fc\u304b\u3089\u3067\u3082\u6b21\u306e\u4f1a\u8b70\u307e\u3067\u306e\u6642\u9593\u3092\u3059\u3070\u3084\u304f\u30c1\u30a7\u30c3\u30af\u3002\u30dc\u30bf\u30f3\u3092\u30af\u30ea\u30c3\u30af\u3059\u308b\u3068\u30ab\u30ec\u30f3\u30c0\u30fc\u306b\u30a2\u30af\u30bb\u30b9\u3067\u304d\u307e\u3059\u3002"},"direction":{"message":"ltr"},"notitle":{"message":"\uff08\u30bf\u30a4\u30c8\u30eb\u306a\u3057\uff09"},"optionstitle":{"message":"Google Calendar Checker"},"minutes":{"message":"$1m","placeholders":{"1":{"content":"$1"}}},"hours":{"message":"$1h","placeholders":{"1":{"content":"$1"}}},"days":{"message":"$1d","placeholders":{"1":{"content":"$1"}}},"multicalendartext":{"message":"\u8907\u6570\u306e\u30ab\u30ec\u30f3\u30c0\u30fc\u306b\u5bfe\u5fdc"},"extensionname":{"message":"Google Calendar Checker"},"status_saved":{"message":"\u8a2d\u5b9a\u304c\u4fdd\u5b58\u3055\u308c\u307e\u3057\u305f\u3002"},"status_saving":{"message":"\u4fdd\u5b58\u3057\u3066\u3044\u307e\u3059..."},"multicalendartooltip":{"message":"\u8907\u6570\u306e\u30ab\u30ec\u30f3\u30c0\u30fc\u3092\u4f7f\u7528\u3067\u304d\u308b\u3088\u3046\u306b\u3059\u308b\u306b\u306f\u30c1\u30a7\u30c3\u30af\u30dc\u30c3\u30af\u30b9\u3092\u30aa\u30f3\u306b\u3057\u3066\u304f\u3060\u3055\u3044"},"imagetooltip":{"message":"Google \u30ab\u30ec\u30f3\u30c0\u30fc"}}
diff --git a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/ko/messages.json b/chrome/common/extensions/docs/examples/extensions/calendar/_locales/ko/messages.json
deleted file mode 100644
index 4e381a8..0000000
--- a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/ko/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"name":{"message":"Google \uce98\ub9b0\ub354 \uccb4\ud06c \ub3c4\uc6b0\ubbf8(Google \uc81c\uacf5)"},"title":{"message":"Google \uce98\ub9b0\ub354 \uccb4\ud06c \ub3c4\uc6b0\ubbf8"},"description":{"message":"\uce98\ub9b0\ub354 \uc5b4\ub514\uc5d0\uc11c\ub098 \ub2e4\uc74c \ubaa8\uc784\uae4c\uc9c0 \ub0a8\uc740 \uc2dc\uac04\uc744 \uc2e0\uc18d\ud558\uac8c \uc0b4\ud3b4\ubcfc \uc218 \uc788\uc2b5\ub2c8\ub2e4. \uce98\ub9b0\ub354\ub85c \uc774\ub3d9\ud558\ub824\uba74 \ubc84\ud2bc\uc744 \ud074\ub9ad\ud558\uc138\uc694."},"direction":{"message":"ltr"},"notitle":{"message":"(\uc81c\ubaa9 \uc5c6\uc74c)"},"optionstitle":{"message":"Google \uce98\ub9b0\ub354 \uccb4\ud06c \ub3c4\uc6b0\ubbf8"},"minutes":{"message":"$1m","placeholders":{"1":{"content":"$1"}}},"hours":{"message":"$1h","placeholders":{"1":{"content":"$1"}}},"days":{"message":"$1d","placeholders":{"1":{"content":"$1"}}},"multicalendartext":{"message":"\uc5ec\ub7ec \uce98\ub9b0\ub354 \uc9c0\uc6d0"},"extensionname":{"message":"Google \uce98\ub9b0\ub354 \uccb4\ud06c \ub3c4\uc6b0\ubbf8"},"status_saved":{"message":"\uc124\uc815\uc744 \uc800\uc7a5\ud588\uc2b5\ub2c8\ub2e4."},"status_saving":{"message":"\uc800\uc7a5 \uc911..."},"multicalendartooltip":{"message":"\uc5ec\ub7ec \uce98\ub9b0\ub354 \uc9c0\uc6d0\uc744 \uc0ac\uc6a9\ud558\ub3c4\ub85d \uc124\uc815\ud558\ub824\uba74 \ud655\uc778\ub780\uc744 \uc120\ud0dd\ud558\uc138\uc694."},"imagetooltip":{"message":"Google \uce98\ub9b0\ub354"}}
diff --git a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/lt/messages.json b/chrome/common/extensions/docs/examples/extensions/calendar/_locales/lt/messages.json
deleted file mode 100644
index aac503f..0000000
--- a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/lt/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"name":{"message":"Google Calendar Checker (Google)"},"title":{"message":"Google Calendar Checker"},"description":{"message":"Bet kuriame i\u0161 savo kalendori\u0173 greitai \u017ei\u016br\u0117kite, kiek laiko liko iki kito susitikimo. Jei norite patekti \u012f kalendori\u0173, spustel\u0117kite mygtuk\u0105."},"direction":{"message":"ltr"},"notitle":{"message":"(N\u0117ra pavadinimo)"},"optionstitle":{"message":"Google Calendar Checker"},"minutes":{"message":"$1 min.","placeholders":{"1":{"content":"$1"}}},"hours":{"message":"$1 val.","placeholders":{"1":{"content":"$1"}}},"days":{"message":"$1 d.","placeholders":{"1":{"content":"$1"}}},"multicalendartext":{"message":"Keli\u0173 kalendori\u0173 palaikymas"},"extensionname":{"message":"Google Calendar Checker"},"status_saved":{"message":"Nustatymai i\u0161saugoti."},"status_saving":{"message":"I\u0161saugoma..."},"multicalendartooltip":{"message":"Kad \u012fgalintum\u0117te keli\u0173 kalendori\u0173 palaikym\u0105, pa\u017eym\u0117kite laukel\u012f"},"imagetooltip":{"message":"\u201eGoogle\u201c kalendorius"}}
diff --git a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/lv/messages.json b/chrome/common/extensions/docs/examples/extensions/calendar/_locales/lv/messages.json
deleted file mode 100644
index be33183..0000000
--- a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/lv/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"name":{"message":"Google Calendar Checker (nodro\u0161ina Google)"},"title":{"message":"Google Calendar Checker"},"description":{"message":"Varat \u0101tri skat\u012bt, cik daudz laika atlicis l\u012bdz n\u0101kamajai sapulcei, izmantojot jebkuru no saviem kalend\u0101riem. Lai atv\u0113rtu kalend\u0101ru, nospiediet pogu."},"direction":{"message":"ltr"},"notitle":{"message":"(Bez nosaukuma)"},"optionstitle":{"message":"Google Calendar Checker"},"minutes":{"message":"$1\u00a0min","placeholders":{"1":{"content":"$1"}}},"hours":{"message":"$1\u00a0h","placeholders":{"1":{"content":"$1"}}},"days":{"message":"$1\u00a0d","placeholders":{"1":{"content":"$1"}}},"multicalendartext":{"message":"Vair\u0101ku kalend\u0101ru atbalsts"},"extensionname":{"message":"Google Calendar Checker"},"status_saved":{"message":"Iestat\u012bjumi ir saglab\u0101ti."},"status_saving":{"message":"Notiek saglab\u0101\u0161ana..."},"multicalendartooltip":{"message":"L\u016bdzu, atz\u012bm\u0113jiet lodzi\u0146u, lai iesp\u0113jotu vair\u0101ku kalend\u0101ru atbalstu."},"imagetooltip":{"message":"Google kalend\u0101rs"}}
diff --git a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/nb/messages.json b/chrome/common/extensions/docs/examples/extensions/calendar/_locales/nb/messages.json
deleted file mode 100644
index 666df6e5..0000000
--- a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/nb/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"name":{"message":"Google Calendar Checker (laget av Google)"},"title":{"message":"Google Calendar Checker"},"description":{"message":"Finn ut raskt hvor lenge det er til neste m\u00f8te fra alle kalendrene dine. Klikk p\u00e5 knappen for \u00e5 g\u00e5 videre til kalenderen."},"direction":{"message":"ltr"},"notitle":{"message":"(Ingen tittel)"},"optionstitle":{"message":"Google Calendar Checker"},"minutes":{"message":"$1 min","placeholders":{"1":{"content":"$1"}}},"hours":{"message":"$1 t","placeholders":{"1":{"content":"$1"}}},"days":{"message":"$1 d","placeholders":{"1":{"content":"$1"}}},"multicalendartext":{"message":"St\u00f8tte for flere kalendere"},"extensionname":{"message":"Google Calendar Checker"},"status_saved":{"message":"Innstillinger lagret."},"status_saving":{"message":"Lagrer \u2026"},"multicalendartooltip":{"message":"Merk av i ruten for \u00e5 aktivere st\u00f8tte for flere kalendere"},"imagetooltip":{"message":"Google Kalender"}}
diff --git a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/nl/messages.json b/chrome/common/extensions/docs/examples/extensions/calendar/_locales/nl/messages.json
deleted file mode 100644
index 9ffa222..0000000
--- a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/nl/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"name":{"message":"Google Calendar Checker (van Google)"},"title":{"message":"Google Calendar Checker"},"description":{"message":"Snel in al uw agenda's bekijken hoe lang het nog duurt voordat uw volgende vergadering begint. Klik op de knop om naar uw agenda te gaan."},"direction":{"message":"ltr"},"notitle":{"message":"(Naamloos)"},"optionstitle":{"message":"Google Calendar Checker"},"minutes":{"message":"$1 m","placeholders":{"1":{"content":"$1"}}},"hours":{"message":"$1 u","placeholders":{"1":{"content":"$1"}}},"days":{"message":"$1 d","placeholders":{"1":{"content":"$1"}}},"multicalendartext":{"message":"Ondersteuning voor meerdere agenda's"},"extensionname":{"message":"Google Calendar Checker"},"status_saved":{"message":"Instellingen zijn opgeslagen."},"status_saving":{"message":"Opslaan..."},"multicalendartooltip":{"message":"Vink het selectievakje aan om de ondersteuning voor meerdere agenda's in te schakelen"},"imagetooltip":{"message":"Google Agenda"}}
diff --git a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/pl/messages.json b/chrome/common/extensions/docs/examples/extensions/calendar/_locales/pl/messages.json
deleted file mode 100644
index 2a3d471..0000000
--- a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/pl/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"name":{"message":"Google Calendar Checker (by Google)"},"title":{"message":"Google Calendar Checker"},"description":{"message":"Szybko sprawd\u017a w dowolnym kalendarzu, ile masz czasu do nast\u0119pnego zebrania. Kliknij przycisk, aby przej\u015b\u0107 do kalendarza."},"direction":{"message":"ltr"},"notitle":{"message":"(Bez tytu\u0142u)"},"optionstitle":{"message":"Google Calendar Checker"},"minutes":{"message":"$1m","placeholders":{"1":{"content":"$1"}}},"hours":{"message":"$1g","placeholders":{"1":{"content":"$1"}}},"days":{"message":"$1d","placeholders":{"1":{"content":"$1"}}},"multicalendartext":{"message":"Obs\u0142uga wielu kalendarzy"},"extensionname":{"message":"Google Calendar Checker"},"status_saved":{"message":"Zapisano ustawienia."},"status_saving":{"message":"Zapisywanie..."},"multicalendartooltip":{"message":"Zaznacz pole, aby w\u0142\u0105czy\u0107 obs\u0142ug\u0119 wielu kalendarzy"},"imagetooltip":{"message":"Kalendarz Google"}}
diff --git a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/pt_BR/messages.json b/chrome/common/extensions/docs/examples/extensions/calendar/_locales/pt_BR/messages.json
deleted file mode 100644
index 3a79f1dd..0000000
--- a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/pt_BR/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"name":{"message":"Google Calendar Checker (do Google)"},"title":{"message":"Google Calendar Checker"},"description":{"message":"Veja rapidamente quanto tempo voc\u00ea tem at\u00e9 seu pr\u00f3ximo compromisso. Clique no bot\u00e3o para abrir sua agenda."},"direction":{"message":"ltr"},"notitle":{"message":"(Sem t\u00edtulo)"},"optionstitle":{"message":"Google Calendar Checker"},"minutes":{"message":"$1m","placeholders":{"1":{"content":"$1"}}},"hours":{"message":"$1h","placeholders":{"1":{"content":"$1"}}},"days":{"message":"$1d","placeholders":{"1":{"content":"$1"}}},"multicalendartext":{"message":"Suporte para v\u00e1rias agendas"},"extensionname":{"message":"Google Calendar Checker"},"status_saved":{"message":"Configura\u00e7\u00f5es salvas."},"status_saving":{"message":"Salvando..."},"multicalendartooltip":{"message":"Marque a caixa para ativar o suporte para v\u00e1rias agendas"},"imagetooltip":{"message":"Google Agenda"}}
diff --git a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/pt_PT/messages.json b/chrome/common/extensions/docs/examples/extensions/calendar/_locales/pt_PT/messages.json
deleted file mode 100644
index 53f249fa..0000000
--- a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/pt_PT/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"name":{"message":"Google Calendar Checker (do Google)"},"title":{"message":"Google Calendar Checker"},"description":{"message":"Veja rapidamente quanto tempo falta para a sua pr\u00f3xima reuni\u00e3o a partir de qualquer um dos seus calend\u00e1rios. Clique no bot\u00e3o para aceder ao calend\u00e1rio."},"direction":{"message":"ltr"},"notitle":{"message":"(Sem t\u00edtulo)"},"optionstitle":{"message":"Google Calendar Checker"},"minutes":{"message":"$1m","placeholders":{"1":{"content":"$1"}}},"hours":{"message":"$1h","placeholders":{"1":{"content":"$1"}}},"days":{"message":"$1d","placeholders":{"1":{"content":"$1"}}},"multicalendartext":{"message":"Suporte para v\u00e1rios calend\u00e1rios"},"extensionname":{"message":"Google Calendar Checker"},"status_saved":{"message":"Defini\u00e7\u00f5es guardadas."},"status_saving":{"message":"A guardar..."},"multicalendartooltip":{"message":"Marque a caixa para permitir o suporte de v\u00e1rios calend\u00e1rios."},"imagetooltip":{"message":"Calend\u00e1rio Google"}}
diff --git a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/ro/messages.json b/chrome/common/extensions/docs/examples/extensions/calendar/_locales/ro/messages.json
deleted file mode 100644
index 3540609..0000000
--- a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/ro/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"name":{"message":"Google Calendar Checker (de la Google)"},"title":{"message":"Google Calendar Checker"},"description":{"message":"Vede\u0163i rapid timpul p\u00e2n\u0103 la urm\u0103toarea \u00eent\u00e2lnire, din oricare dintre calendarele dvs. Face\u0163i clic pe buton pentru a accesa calendarul."},"direction":{"message":"ltr"},"notitle":{"message":"(F\u0103r\u0103 titlu)"},"optionstitle":{"message":"Google Calendar Checker"},"minutes":{"message":"$1 m","placeholders":{"1":{"content":"$1"}}},"hours":{"message":"$1 h","placeholders":{"1":{"content":"$1"}}},"days":{"message":"$1 z","placeholders":{"1":{"content":"$1"}}},"multicalendartext":{"message":"Asisten\u0163\u0103 pentru mai multe calendare"},"extensionname":{"message":"Google Calendar Checker"},"status_saved":{"message":"Set\u0103rile au fost salvate."},"status_saving":{"message":"Se salveaz\u0103..."},"multicalendartooltip":{"message":"Bifa\u0163i caseta pentru a activa asisten\u0163a pentru mai multe calendare"},"imagetooltip":{"message":"Google Calendar"}}
diff --git a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/ru/messages.json b/chrome/common/extensions/docs/examples/extensions/calendar/_locales/ru/messages.json
deleted file mode 100644
index 34363260..0000000
--- a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/ru/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"name":{"message":"Google Calendar Checker (\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043e \u0432 Google)"},"title":{"message":"Google Calendar Checker"},"description":{"message":"\u041e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0439\u0442\u0435 \u0432\u0440\u0435\u043c\u044f \u0434\u043e \u0431\u043b\u0438\u0436\u0430\u0439\u0448\u0435\u0433\u043e \u043c\u0435\u0440\u043e\u043f\u0440\u0438\u044f\u0442\u0438\u044f. \u041f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043a\u0430\u043b\u0435\u043d\u0434\u0430\u0440\u0435\u0439. \u041d\u0430\u0436\u043c\u0438\u0442\u0435 \u043a\u043d\u043e\u043f\u043a\u0443, \u0447\u0442\u043e\u0431\u044b \u043e\u0442\u043a\u0440\u044b\u0442\u044c \u043d\u0443\u0436\u043d\u044b\u0439 \u043a\u0430\u043b\u0435\u043d\u0434\u0430\u0440\u044c."},"direction":{"message":"ltr"},"notitle":{"message":"(\u0417\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442)"},"optionstitle":{"message":"Google Calendar Checker"},"minutes":{"message":"$1\u043c.","placeholders":{"1":{"content":"$1"}}},"hours":{"message":"$1\u0447.","placeholders":{"1":{"content":"$1"}}},"days":{"message":"$1\u0434.","placeholders":{"1":{"content":"$1"}}},"multicalendartext":{"message":"\u041f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u041a\u0430\u043b\u0435\u043d\u0434\u0430\u0440\u0435\u0439"},"extensionname":{"message":"Google Calendar Checker"},"status_saved":{"message":"\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u044b."},"status_saving":{"message":"\u0421\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435...."},"multicalendartooltip":{"message":"\u041d\u0435 \u0437\u0430\u0431\u0443\u0434\u044c\u0442\u0435 \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0444\u043b\u0430\u0436\u043e\u043a, \u0447\u0442\u043e\u0431\u044b \u0430\u043a\u0442\u0438\u0432\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u041a\u0430\u043b\u0435\u043d\u0434\u0430\u0440\u0435\u0439"},"imagetooltip":{"message":"\u041a\u0430\u043b\u0435\u043d\u0434\u0430\u0440\u044c Google"}}
diff --git a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/sk/messages.json b/chrome/common/extensions/docs/examples/extensions/calendar/_locales/sk/messages.json
deleted file mode 100644
index 65257bf..0000000
--- a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/sk/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"name":{"message":"Kontrola Kalend\u00e1ra Google (od spolo\u010dnosti Google)"},"title":{"message":"Kontrola Kalend\u00e1ra Google"},"description":{"message":"V \u013eubovo\u013enom z va\u0161ich kalend\u00e1rov si v r\u00fdchlosti si zobrazte, ko\u013eko \u010dasu m\u00e1te do \u010fal\u0161ej sch\u00f4dzky. Kliknut\u00edm na tla\u010didlo prejdete do svojho kalend\u00e1ra."},"direction":{"message":"ltr"},"notitle":{"message":"(Bez n\u00e1zvu)"},"optionstitle":{"message":"Kontrola Kalend\u00e1ra Google"},"minutes":{"message":"$1 min","placeholders":{"1":{"content":"$1"}}},"hours":{"message":"$1 h","placeholders":{"1":{"content":"$1"}}},"days":{"message":"$1 d","placeholders":{"1":{"content":"$1"}}},"multicalendartext":{"message":"Podpora viacer\u00fdch Kalend\u00e1rov"},"extensionname":{"message":"Kontrola Kalend\u00e1ra Google"},"status_saved":{"message":"Nastavenia boli ulo\u017een\u00e9."},"status_saving":{"message":"Prebieha ukladanie...."},"multicalendartooltip":{"message":"Ak chcete povoli\u0165 podporu viacer\u00fdch kalend\u00e1rov, za\u010diarknite toto pol\u00ed\u010dko"},"imagetooltip":{"message":"Kalend\u00e1r Google"}}
diff --git a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/sl/messages.json b/chrome/common/extensions/docs/examples/extensions/calendar/_locales/sl/messages.json
deleted file mode 100644
index 09a2113..0000000
--- a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/sl/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"name":{"message":"Google Calendar Checker"},"title":{"message":"Google Calendar Checker"},"description":{"message":"Hitro preverite, koliko je \u0161e do naslednjega sestanka v katerem koli od va\u0161ih koledarjev. Kliknite gumb, da odprete koledar."},"direction":{"message":"ltr"},"notitle":{"message":"(Brez naslova)"},"optionstitle":{"message":"Google Calendar Checker"},"minutes":{"message":"$1 min","placeholders":{"1":{"content":"$1"}}},"hours":{"message":"$1 h","placeholders":{"1":{"content":"$1"}}},"days":{"message":"$1 d","placeholders":{"1":{"content":"$1"}}},"multicalendartext":{"message":"Podpora za ve\u010d koledarjev"},"extensionname":{"message":"Google Calendar Checker"},"status_saved":{"message":"Nastavitve shranjene."},"status_saving":{"message":"Shranjevanje ..."},"multicalendartooltip":{"message":"Potrdite polje, da omogo\u010dite podporo za ve\u010d koledarjev."},"imagetooltip":{"message":"Google Koledar"}}
diff --git a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/sr/messages.json b/chrome/common/extensions/docs/examples/extensions/calendar/_locales/sr/messages.json
deleted file mode 100644
index d55c41b..0000000
--- a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/sr/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"name":{"message":"Google Calendar Checker (\u043e\u0434 Google-\u0430)"},"title":{"message":"Google Calendar Checker"},"description":{"message":"\u0411\u0440\u0437\u043e \u043f\u043e\u0433\u043b\u0435\u0434\u0430\u0458\u0442\u0435 \u043a\u043e\u043b\u0438\u043a\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0430 \u0438\u043c\u0430\u0442\u0435 \u0434\u043e \u0441\u043b\u0435\u0434\u0435\u045b\u0435\u0433 \u0441\u0430\u0441\u0442\u0430\u043d\u043a\u0430 \u0443 \u0431\u0438\u043b\u043e \u043a\u043e\u043c \u043a\u0430\u043b\u0435\u043d\u0434\u0430\u0440\u0443. \u041a\u043b\u0438\u043a\u043d\u0438\u0442\u0435 \u043d\u0430 \u0434\u0443\u0433\u043c\u0435 \u0434\u0430 \u0431\u0438\u0441\u0442\u0435 \u043e\u0442\u0432\u043e\u0440\u0438\u043b\u0438 \u043a\u0430\u043b\u0435\u043d\u0434\u0430\u0440."},"direction":{"message":"ltr"},"notitle":{"message":"(\u0411\u0435\u0437 \u043d\u0430\u0441\u043b\u043e\u0432\u0430)"},"optionstitle":{"message":"Google Calendar Checker"},"minutes":{"message":"$1 \u043c\u0438\u043d","placeholders":{"1":{"content":"$1"}}},"hours":{"message":"$1 \u0441","placeholders":{"1":{"content":"$1"}}},"days":{"message":"$1 \u0434","placeholders":{"1":{"content":"$1"}}},"multicalendartext":{"message":"\u041f\u043e\u0434\u0440\u0448\u043a\u0430 \u0437\u0430 \u0432\u0438\u0448\u0435 \u043a\u0430\u043b\u0435\u043d\u0434\u0430\u0440\u0430"},"extensionname":{"message":"Google Calendar Checker"},"status_saved":{"message":"\u041f\u043e\u0434\u0435\u0448\u0430\u0432\u0430\u045a\u0430 \u0441\u0443 \u0441\u0430\u0447\u0443\u0432\u0430\u043d\u0430."},"status_saving":{"message":"\u0427\u0443\u0432\u0430\u045a\u0435...."},"multicalendartooltip":{"message":"\u041f\u043e\u0442\u0432\u0440\u0434\u0438\u0442\u0435 \u0438\u0437\u0431\u043e\u0440 \u0443 \u043f\u043e\u0459\u0443 \u0437\u0430 \u043f\u043e\u0442\u0432\u0440\u0434\u0443 \u0434\u0430 \u0431\u0438\u0441\u0442\u0435 \u043e\u043c\u043e\u0433\u0443\u045b\u0438\u043b\u0438 \u043f\u043e\u0434\u0440\u0448\u043a\u0443 \u0437\u0430 \u0432\u0438\u0448\u0435 \u043a\u0430\u043b\u0435\u043d\u0434\u0430\u0440\u0430"},"imagetooltip":{"message":"Google \u043a\u0430\u043b\u0435\u043d\u0434\u0430\u0440"}}
diff --git a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/sv/messages.json b/chrome/common/extensions/docs/examples/extensions/calendar/_locales/sv/messages.json
deleted file mode 100644
index edb0193..0000000
--- a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/sv/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"name":{"message":"Google Calendar Checker (fr\u00e5n Google)"},"title":{"message":"Google Calendar Checker"},"description":{"message":"Se snabbt i dina kalendrar hur l\u00e4nge det \u00e4r till n\u00e4sta m\u00f6te. Klicka p\u00e5 knappen s\u00e5 kommer du till kalendern."},"direction":{"message":"ltr"},"notitle":{"message":"(Namnl\u00f6s)"},"optionstitle":{"message":"Google Calendar Checker"},"minutes":{"message":"$1min","placeholders":{"1":{"content":"$1"}}},"hours":{"message":"$1tim","placeholders":{"1":{"content":"$1"}}},"days":{"message":"$1d","placeholders":{"1":{"content":"$1"}}},"multicalendartext":{"message":"Support f\u00f6r flera kalendrar"},"extensionname":{"message":"Google Calendar Checker"},"status_saved":{"message":"Inst\u00e4llningarna har sparats."},"status_saving":{"message":"Sparar..."},"multicalendartooltip":{"message":"Aktivera support f\u00f6r flera kalendrar genom att markera rutan"},"imagetooltip":{"message":"Google Kalender"}}
diff --git a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/th/messages.json b/chrome/common/extensions/docs/examples/extensions/calendar/_locales/th/messages.json
deleted file mode 100644
index c9680f1c..0000000
--- a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/th/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"name":{"message":"Google Calendar Checker (\u0e42\u0e14\u0e22 Google)"},"title":{"message":"Google Calendar Checker"},"description":{"message":"\u0e14\u0e39\u0e40\u0e27\u0e25\u0e32\u0e17\u0e35\u0e48\u0e04\u0e38\u0e13\u0e21\u0e35\u0e01\u0e48\u0e2d\u0e19\u0e16\u0e36\u0e07\u0e01\u0e32\u0e23\u0e1b\u0e23\u0e30\u0e0a\u0e38\u0e21\u0e04\u0e23\u0e31\u0e49\u0e07\u0e15\u0e48\u0e2d\u0e44\u0e1b\u0e44\u0e14\u0e49\u0e08\u0e32\u0e01\u0e1b\u0e0f\u0e34\u0e17\u0e34\u0e19\u0e43\u0e14\u0e46 \u0e01\u0e47\u0e44\u0e14\u0e49\u0e02\u0e2d\u0e07\u0e04\u0e38\u0e13 \u0e43\u0e2b\u0e49\u0e04\u0e25\u0e34\u0e01\u0e17\u0e35\u0e48\u0e1b\u0e38\u0e48\u0e21\u0e40\u0e1e\u0e37\u0e48\u0e2d\u0e44\u0e1b\u0e17\u0e35\u0e48\u0e1b\u0e0f\u0e34\u0e17\u0e34\u0e19\u0e02\u0e2d\u0e07\u0e04\u0e38\u0e13"},"direction":{"message":"ltr"},"notitle":{"message":"(\u0e44\u0e21\u0e48\u0e21\u0e35\u0e0a\u0e37\u0e48\u0e2d)"},"optionstitle":{"message":"Google Calendar Checker"},"minutes":{"message":"$1m","placeholders":{"1":{"content":"$1"}}},"hours":{"message":"$1h","placeholders":{"1":{"content":"$1"}}},"days":{"message":"$1d","placeholders":{"1":{"content":"$1"}}},"multicalendartext":{"message":"\u0e01\u0e32\u0e23\u0e2a\u0e19\u0e31\u0e1a\u0e2a\u0e19\u0e38\u0e19\u0e1b\u0e0f\u0e34\u0e17\u0e34\u0e19\u0e2b\u0e25\u0e32\u0e22\u0e23\u0e30\u0e1a\u0e1a"},"extensionname":{"message":"Google Calendar Checker"},"status_saved":{"message":"\u0e1a\u0e31\u0e19\u0e17\u0e36\u0e01\u0e01\u0e32\u0e23\u0e15\u0e31\u0e49\u0e07\u0e04\u0e48\u0e32\u0e41\u0e25\u0e49\u0e27"},"status_saving":{"message":"\u0e01\u0e33\u0e25\u0e31\u0e07\u0e1a\u0e31\u0e19\u0e17\u0e36\u0e01...."},"multicalendartooltip":{"message":"\u0e42\u0e1b\u0e23\u0e14\u0e40\u0e25\u0e37\u0e2d\u0e01\u0e0a\u0e48\u0e2d\u0e07\u0e17\u0e33\u0e40\u0e04\u0e23\u0e37\u0e48\u0e2d\u0e07\u0e2b\u0e21\u0e32\u0e22 \u0e40\u0e1e\u0e37\u0e48\u0e2d\u0e40\u0e1b\u0e34\u0e14\u0e43\u0e0a\u0e49\u0e07\u0e32\u0e19\u0e01\u0e32\u0e23\u0e2a\u0e19\u0e31\u0e1a\u0e2a\u0e19\u0e38\u0e19\u0e1b\u0e0f\u0e34\u0e17\u0e34\u0e19\u0e2b\u0e25\u0e32\u0e22\u0e23\u0e30\u0e1a\u0e1a"},"imagetooltip":{"message":"Google \u0e1b\u0e0f\u0e34\u0e17\u0e34\u0e19"}}
diff --git a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/tr/messages.json b/chrome/common/extensions/docs/examples/extensions/calendar/_locales/tr/messages.json
deleted file mode 100644
index a54371e..0000000
--- a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/tr/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"name":{"message":"Google Calendar Checker (Google'dan)"},"title":{"message":"Google Calendar Checker"},"description":{"message":"Takvimlerinizden herhangi birine bakarak bir sonraki toplant\u0131n\u0131za ne kadar zaman kald\u0131\u011f\u0131n\u0131 hemen g\u00f6r\u00fcn. Takviminizi a\u00e7mak i\u00e7in d\u00fc\u011fmeyi t\u0131klay\u0131n."},"direction":{"message":"ltr"},"notitle":{"message":"(Ba\u015fl\u0131ks\u0131z)"},"optionstitle":{"message":"Google Calendar Checker"},"minutes":{"message":"$1d","placeholders":{"1":{"content":"$1"}}},"hours":{"message":"$1s","placeholders":{"1":{"content":"$1"}}},"days":{"message":"$1g","placeholders":{"1":{"content":"$1"}}},"multicalendartext":{"message":"Birden Fazla Takvim Deste\u011fi"},"extensionname":{"message":"Google Calendar Checker"},"status_saved":{"message":"Ayarlar Kaydedildi."},"status_saving":{"message":"Kaydediliyor..."},"multicalendartooltip":{"message":"Birden fazla takvim deste\u011fini etkinle\u015ftirmek i\u00e7in l\u00fctfen kutuyu i\u015faretleyin"},"imagetooltip":{"message":"Google Takvim"}}
diff --git a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/uk/messages.json b/chrome/common/extensions/docs/examples/extensions/calendar/_locales/uk/messages.json
deleted file mode 100644
index 21c7514..0000000
--- a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/uk/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"name":{"message":"Google Calendar Checker (\u0432\u0456\u0434 Google)"},"title":{"message":"Google Calendar Checker"},"description":{"message":"\u0428\u0432\u0438\u0434\u043a\u043e \u043f\u0435\u0440\u0435\u0433\u043b\u044f\u0434\u0430\u0439\u0442\u0435 \u0441\u0432\u043e\u0457 \u043a\u0430\u043b\u0435\u043d\u0434\u0430\u0440\u0456, \u0449\u043e\u0431 \u0434\u0456\u0437\u043d\u0430\u0442\u0438\u0441\u044f, \u0441\u043a\u0456\u043b\u044c\u043a\u0438 \u0447\u0430\u0441\u0443 \u0437\u0430\u043b\u0438\u0448\u0438\u043b\u043e\u0441\u044f \u0434\u043e \u043d\u0430\u0441\u0442\u0443\u043f\u043d\u043e\u0457 \u0437\u0443\u0441\u0442\u0440\u0456\u0447\u0456. \u041d\u0430\u0442\u0438\u0441\u043d\u0456\u0442\u044c \u0446\u044e \u043a\u043d\u043e\u043f\u043a\u0443, \u0449\u043e\u0431 \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u0434\u043e \u043a\u0430\u043b\u0435\u043d\u0434\u0430\u0440\u044f."},"direction":{"message":"ltr"},"notitle":{"message":"(\u0411\u0435\u0437 \u043d\u0430\u0437\u0432\u0438)"},"optionstitle":{"message":"Google Calendar Checker"},"minutes":{"message":"$1 \u0445\u0432.","placeholders":{"1":{"content":"$1"}}},"hours":{"message":"$1 \u0433\u043e\u0434.","placeholders":{"1":{"content":"$1"}}},"days":{"message":"$1 \u0434\u043d.","placeholders":{"1":{"content":"$1"}}},"multicalendartext":{"message":"\u041f\u0456\u0434\u0442\u0440\u0438\u043c\u043a\u0430 \u0434\u0435\u043a\u0456\u043b\u044c\u043a\u043e\u0445 \u043a\u0430\u043b\u0435\u043d\u0434\u0430\u0440\u0456\u0432"},"extensionname":{"message":"Google Calendar Checker"},"status_saved":{"message":"\u041d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f \u0437\u0431\u0435\u0440\u0435\u0436\u0435\u043d\u043e."},"status_saving":{"message":"\u0417\u0431\u0435\u0440\u0456\u0433\u0430\u043d\u043d\u044f...."},"multicalendartooltip":{"message":"\u041f\u043e\u0441\u0442\u0430\u0432\u0442\u0435 \u043f\u0440\u0430\u043f\u043e\u0440\u0435\u0446\u044c, \u0449\u043e\u0431 \u0443\u0432\u0456\u043c\u043a\u043d\u0443\u0442\u0438 \u043f\u0456\u0434\u0442\u0440\u0438\u043c\u043a\u0443 \u0434\u0435\u043a\u0456\u043b\u044c\u043a\u043e\u0445 \u043a\u0430\u043b\u0435\u043d\u0434\u0430\u0440\u0456\u0432"},"imagetooltip":{"message":"\u041a\u0430\u043b\u0435\u043d\u0434\u0430\u0440 Google"}}
diff --git a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/vi/messages.json b/chrome/common/extensions/docs/examples/extensions/calendar/_locales/vi/messages.json
deleted file mode 100644
index a54d48b..0000000
--- a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/vi/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"name":{"message":"Google Calendar Checker (c\u1ee7a Google)"},"title":{"message":"Google Calendar Checker"},"description":{"message":"Xem nhanh th\u1eddi gian tr\u01b0\u1edbc khi \u0111\u1ebfn cu\u1ed9c h\u1ecdp ti\u1ebfp theo t\u1eeb b\u1ea5t k\u1ef3 l\u1ecbch n\u00e0o c\u1ee7a b\u1ea1n. H\u00e3y nh\u1ea5p v\u00e0o n\u00fat \u0111\u1ec3 \u0111\u01b0\u1ee3c \u0111\u01b0a \u0111\u1ebfn l\u1ecbch c\u1ee7a b\u1ea1n."},"direction":{"message":"ltr"},"notitle":{"message":"(Kh\u00f4ng c\u00f3 ti\u00eau \u0111\u1ec1)"},"optionstitle":{"message":"Google Calendar Checker"},"minutes":{"message":"$1m","placeholders":{"1":{"content":"$1"}}},"hours":{"message":"$1h","placeholders":{"1":{"content":"$1"}}},"days":{"message":"$1d","placeholders":{"1":{"content":"$1"}}},"multicalendartext":{"message":"H\u1ed7 tr\u1ee3 nhi\u1ec1u l\u1ecbch"},"extensionname":{"message":"Google Calendar Checker"},"status_saved":{"message":"\u0110\u00e3 l\u01b0u c\u00e0i \u0111\u1eb7t."},"status_saving":{"message":"\u0110ang l\u01b0u...."},"multicalendartooltip":{"message":"Vui l\u00f2ng ch\u1ecdn h\u1ed9p n\u00e0y \u0111\u1ec3 b\u1eadt t\u00ednh n\u0103ng h\u1ed7 tr\u1ee3 nhi\u1ec1u l\u1ecbch"},"imagetooltip":{"message":"L\u1ecbch Google"}}
diff --git a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/zh_CN/messages.json b/chrome/common/extensions/docs/examples/extensions/calendar/_locales/zh_CN/messages.json
deleted file mode 100644
index 7c2ecea..0000000
--- a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/zh_CN/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"name":{"message":"Google Calendar Checker\uff08\u7531 Google \u63d0\u4f9b\uff09"},"title":{"message":"Google Calendar Checker"},"description":{"message":"\u5feb\u901f\u67e5\u770b\u79bb\u60a8\u7684\u4efb\u610f\u65e5\u5386\u4e2d\u4e0b\u4e00\u6b21\u4f1a\u8bae\u8fd8\u6709\u591a\u957f\u65f6\u95f4\u3002\u60a8\u53ea\u9700\u70b9\u51fb\u8be5\u6309\u94ae\u5373\u53ef\u8fdb\u5165\u81ea\u5df1\u7684\u65e5\u5386\u3002"},"direction":{"message":"ltr"},"notitle":{"message":"\uff08\u65e0\u6807\u9898\uff09"},"optionstitle":{"message":"Google Calendar Checker"},"minutes":{"message":"$1m","placeholders":{"1":{"content":"$1"}}},"hours":{"message":"$1h","placeholders":{"1":{"content":"$1"}}},"days":{"message":"$1d","placeholders":{"1":{"content":"$1"}}},"multicalendartext":{"message":"\u591a\u65e5\u5386\u652f\u6301"},"extensionname":{"message":"Google Calendar Checker"},"status_saved":{"message":"\u8bbe\u7f6e\u5df2\u4fdd\u5b58\u3002"},"status_saving":{"message":"\u6b63\u5728\u4fdd\u5b58..."},"multicalendartooltip":{"message":"\u8bf7\u9009\u4e2d\u6b64\u6846\u4ee5\u542f\u7528\u591a\u65e5\u5386\u652f\u6301"},"imagetooltip":{"message":"Google \u65e5\u5386"}}
diff --git a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/zh_TW/messages.json b/chrome/common/extensions/docs/examples/extensions/calendar/_locales/zh_TW/messages.json
deleted file mode 100644
index 5c99aba..0000000
--- a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/zh_TW/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"name":{"message":"Google Calendar Checker (\u7531 Google \u63d0\u4f9b)"},"title":{"message":"Google Calendar Checker"},"description":{"message":"\u5f9e\u4efb\u4f55\u65e5\u66c6\u7686\u53ef\u8fc5\u901f\u67e5\u770b\u8ddd\u96e2\u4e0b\u6b21\u6703\u8b70\u9084\u5269\u4e0b\u591a\u5c11\u6642\u9593\u3002\u6309\u4e00\u4e0b\u6309\u9215\u5373\u53ef\u524d\u5f80\u60a8\u7684\u65e5\u66c6\u3002"},"direction":{"message":"ltr"},"notitle":{"message":"(\u7121\u6a19\u984c)"},"optionstitle":{"message":"Google Calendar Checker"},"minutes":{"message":"$1m","placeholders":{"1":{"content":"$1"}}},"hours":{"message":"$1h","placeholders":{"1":{"content":"$1"}}},"days":{"message":"$1d","placeholders":{"1":{"content":"$1"}}},"multicalendartext":{"message":"\u591a\u91cd\u65e5\u66c6\u652f\u63f4"},"extensionname":{"message":"Google Calendar Checker"},"status_saved":{"message":"\u8a2d\u5b9a\u5df2\u5132\u5b58\u3002"},"status_saving":{"message":"\u5132\u5b58\u4e2d...."},"multicalendartooltip":{"message":"\u8acb\u52fe\u9078\u6b64\u65b9\u584a\uff0c\u4ee5\u555f\u7528\u591a\u91cd\u65e5\u66c6\u652f\u63f4\u529f\u80fd"},"imagetooltip":{"message":"Google \u65e5\u66c6"}}
diff --git a/chrome/common/extensions/docs/examples/extensions/calendar/images/icon-128.png b/chrome/common/extensions/docs/examples/extensions/calendar/images/icon-128.png
deleted file mode 100644
index 78cbdcde..0000000
--- a/chrome/common/extensions/docs/examples/extensions/calendar/images/icon-128.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/calendar/images/icon-16.png b/chrome/common/extensions/docs/examples/extensions/calendar/images/icon-16.png
deleted file mode 100644
index 922ae44d..0000000
--- a/chrome/common/extensions/docs/examples/extensions/calendar/images/icon-16.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/calendar/images/icon-19.png b/chrome/common/extensions/docs/examples/extensions/calendar/images/icon-19.png
deleted file mode 100644
index 0100daf..0000000
--- a/chrome/common/extensions/docs/examples/extensions/calendar/images/icon-19.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/calendar/images/icon-38.png b/chrome/common/extensions/docs/examples/extensions/calendar/images/icon-38.png
deleted file mode 100644
index 5f6e785..0000000
--- a/chrome/common/extensions/docs/examples/extensions/calendar/images/icon-38.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/calendar/images/icon-48.png b/chrome/common/extensions/docs/examples/extensions/calendar/images/icon-48.png
deleted file mode 100644
index 636ba83..0000000
--- a/chrome/common/extensions/docs/examples/extensions/calendar/images/icon-48.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/calendar/javascript/background.js b/chrome/common/extensions/docs/examples/extensions/calendar/javascript/background.js
deleted file mode 100644
index fe466a4..0000000
--- a/chrome/common/extensions/docs/examples/extensions/calendar/javascript/background.js
+++ /dev/null
@@ -1,41 +0,0 @@
-/**
- * Copyright (c) 2013 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.
- */
-
-var warningId = 'notification.warning';
-
-function hideWarning(done) {
- chrome.notifications.clear(warningId, function() {
- if (done) done();
- });
-}
-
-function showWarning() {
- hideWarning(function() {
- chrome.notifications.create(warningId, {
- iconUrl: chrome.runtime.getURL('images/icon-48.png'),
- title: 'Removal required',
- type: 'basic',
- message: chrome.i18n.getMessage('name') + ' is obsolete ' +
- 'and must be removed. A replacement Extension ' +
- 'is available.',
- buttons: [{ title: 'Learn More' }],
- priority: 2,
- }, function() {});
- });
-}
-
-function openWarningPage() {
- chrome.tabs.create({
- url: 'chrome://extensions?options=' + chrome.runtime.id
- });
-}
-
-chrome.browserAction.setBadgeBackgroundColor({ color: '#FF0000' });
-chrome.browserAction.setBadgeText({ text: '!' });
-chrome.browserAction.onClicked.addListener(openWarningPage);
-chrome.notifications.onClicked.addListener(openWarningPage);
-chrome.notifications.onButtonClicked.addListener(openWarningPage);
-chrome.runtime.onInstalled.addListener(showWarning);
diff --git a/chrome/common/extensions/docs/examples/extensions/calendar/javascript/options.js b/chrome/common/extensions/docs/examples/extensions/calendar/javascript/options.js
deleted file mode 100644
index a524b89..0000000
--- a/chrome/common/extensions/docs/examples/extensions/calendar/javascript/options.js
+++ /dev/null
@@ -1,17 +0,0 @@
-/**
- * Copyright (c) 2013 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.
- */
-
-var $ = document.getElementById.bind(document);
-
-var url = 'https://chrome.google.com/webstore/detail/' +
- 'google-calendar-by-google/gmbgaklkmjakoegficnlkhebmhkjfich';
-
-$('name').textContent = chrome.i18n.getMessage('name');
-$('link').href = url;
-$('remove').onclick = function() {
- chrome.management.uninstallSelf({showConfirmDialog: true});
- window.close();
-};
diff --git a/chrome/common/extensions/docs/examples/extensions/calendar/manifest.json b/chrome/common/extensions/docs/examples/extensions/calendar/manifest.json
deleted file mode 100644
index 51ee744..0000000
--- a/chrome/common/extensions/docs/examples/extensions/calendar/manifest.json
+++ /dev/null
@@ -1,31 +0,0 @@
-{
- "name": "__MSG_name__",
- "description": "__MSG_description__",
- "manifest_version": 2,
- "default_locale":"en",
- "options_page": "views/options.html",
- "options_ui": {
- "page": "views/options.html",
- "chrome_style": true
- },
- "version": "2.0.0",
- "background": {
- "scripts": ["javascript/background.js"],
- "persistent": false
- },
- "permissions": [
- "notifications"
- ],
- "browser_action": {
- "default_icon": {
- "19": "images/icon-19.png",
- "38": "images/icon-38.png"
- },
- "default_title": "__MSG_title__"
- },
- "icons": {
- "128": "images/icon-128.png",
- "48": "images/icon-48.png",
- "16":"images/icon-16.png"
- }
-}
diff --git a/chrome/common/extensions/docs/examples/extensions/calendar/views/options.html b/chrome/common/extensions/docs/examples/extensions/calendar/views/options.html
deleted file mode 100644
index 92c8d52..0000000
--- a/chrome/common/extensions/docs/examples/extensions/calendar/views/options.html
+++ /dev/null
@@ -1,27 +0,0 @@
-<!DOCTYPE html>
-<!--
- * Copyright (c) 2012 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>
-<body>
-
-<p>
-<strong><span id="name"></span> is now obsolete and must be removed, as it
-relies on an API which will be turned off imminently</strong>.
-<a href="https://developers.google.com/google-apps/calendar/v2/developers_guide_protocol">Learn more</a>.
-</p>
-
-<p>
-Instead, we recommend the more powerful <a id="link">Google Calendar (by
-Google)</a> Extension.
-</p>
-
-<p>
-<button id="remove">Remove from Chrome...</button>
-</p>
-
-<script src="../javascript/options.js"></script>
-</body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/extensions/catblock/background.js b/chrome/common/extensions/docs/examples/extensions/catblock/background.js
deleted file mode 100644
index 7fdb601..0000000
--- a/chrome/common/extensions/docs/examples/extensions/catblock/background.js
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright (c) 2012 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.
-
-// Simple extension to replace lolcat images from
-// http://icanhascheezburger.com/ with loldog images instead.
-
-chrome.webRequest.onBeforeRequest.addListener(
- function(info) {
- console.log("Cat intercepted: " + info.url);
- // Redirect the lolcal request to a random loldog URL.
- var i = Math.round(Math.random() * loldogs.length);
- return {redirectUrl: loldogs[i]};
- },
- // filters
- {
- urls: [
- "https://i.chzbgr.com/*"
- ],
- types: ["image"]
- },
- // extraInfoSpec
- ["blocking"]);
diff --git a/chrome/common/extensions/docs/examples/extensions/catblock/loldogs.js b/chrome/common/extensions/docs/examples/extensions/catblock/loldogs.js
deleted file mode 100644
index a8013b1..0000000
--- a/chrome/common/extensions/docs/examples/extensions/catblock/loldogs.js
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright (c) 2012 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.
-
-var loldogs = [
-"http://ihasahotdog.files.wordpress.com/2011/08/funny-dog-pictures-yoo-bin-warndid.jpg",
-"http://ihasahotdog.files.wordpress.com/2011/08/funny-dog-pictures-it-juzz-liek-ezploded-or-sumfin.jpg",
-"http://ihasahotdog.files.wordpress.com/2011/08/funny-dog-pictures-cool-story-bro-got-anymore-bacon.jpg",
-"http://ihasahotdog.files.wordpress.com/2011/08/funny-dog-pictures-ohaii-iz-n-ur-livin-room-defyin-ur-gravaties.jpg",
-"http://ihasahotdog.files.wordpress.com/2011/08/cue-puppy-pictures-spike-is-not-sleeping-on-duty-hes-lulling-you-into-a-false-sense-of-security.jpg",
-"http://ihasahotdog.files.wordpress.com/2011/08/funny-dog-pictures-pens-too-mainstream.jpg",
-"http://ihasahotdog.files.wordpress.com/2011/08/funny-dog-pictures-tyrannodoggus-rex.jpg",
-"http://ihasahotdog.files.wordpress.com/2011/08/funny-dog-pictures-sniper-dog-in-position.jpg",
-"http://ihasahotdog.files.wordpress.com/2011/07/funny-dog-pictures-i-see-wat-yur-doin-must-put-it-on-internet.jpg",
-"http://ihasahotdog.files.wordpress.com/2011/07/cute-puppy-pictures-fresh-squeed.jpg",
-"http://ihasahotdog.files.wordpress.com/2011/07/funny-dog-pictures-that-sir-is-not-my-issue.jpg",
-"http://ihasahotdog.files.wordpress.com/2011/07/funny-dog-pictures-trippin.jpg",
-"http://ihasahotdog.files.wordpress.com/2011/07/funny-dog-pictures-oh-gurl-diz-iz-my-jam.jpg",
-"http://ihasahotdog.files.wordpress.com/2011/07/funny-dog-pictures-get-off-teh-lawn-we-haz-no-komment-on-teh-allejed-mailman-insident.jpg",
-"http://ihasahotdog.files.wordpress.com/2011/07/funny-dog-pictures-sowwy-i-kin-still-feel-da-pea.jpg",
-"http://ihasahotdog.files.wordpress.com/2011/07/funny-dog-pictures-hang-upz-ai-haz-dem.jpg",
-"http://ihasahotdog.files.wordpress.com/2011/07/funny-dog-pictures-i-haz-a-happy-cuz-im-going-to-mai-fer-ebber-home.jpg",
-"http://ihasahotdog.files.wordpress.com/2011/07/funny-dog-pictures-the-guitar-its-a-les-paw.jpg",
-"http://ihasahotdog.files.wordpress.com/2011/07/funny-dog-pictures-if-you-need-me-ill-just-be-watching-the-game.jpg",
-"http://ihasahotdog.files.wordpress.com/2011/07/funny-dog-pictures-camouflage-complete.jpg",
-"http://ihasahotdog.files.wordpress.com/2011/07/cute-puppy-pictures-its-okay-i-tuck-myself-in.jpg",
-"http://ihasahotdog.files.wordpress.com/2011/07/funny-dog-pictures-transformers-more-than-meets-the-eye.jpg",
-"http://ihasahotdog.files.wordpress.com/2011/07/cute-puppy-pictures-a-long-night-of-pwnage.jpg",
-"http://ihasahotdog.files.wordpress.com/2011/07/raised-in-the-woods-sos-he-knew-every-tree-killed-him-a-bear-when-he-was-only-three.jpg",
-"http://ihasahotdog.files.wordpress.com/2011/07/this-be-ten-times-betteh-den-laska.jpg",
-"http://ihasahotdog.files.wordpress.com/2011/07/funny-dog-pictures-wut-did-u-say-mai-heering-iz-spotty.jpg",
-"http://ihasahotdog.files.wordpress.com/2011/07/funny-dog-pictures-albark-einstein-discusses-relativity.jpg",
-"http://ihasahotdog.files.wordpress.com/2011/06/funny-dog-pictures-goggie-ob-teh-week-i-love-you.jpg",
-"http://ihasahotdog.files.wordpress.com/2011/06/funny-dog-pictures-oh-lord-take-me-now-i-broke-my-chew-toy.jpg",
-"http://ihasahotdog.files.wordpress.com/2011/06/funny-dog-pictures-i-has-a-safe.jpg",
-"http://ihasahotdog.files.wordpress.com/2011/06/funny-dog-pictures-corgi-choir.jpg",
-"http://ihasahotdog.files.wordpress.com/2011/06/funny-dog-pictures-goggie-ob-teh-week-snaaaaacks-i-love-snaaaaacks.jpg",
-"http://ihasahotdog.files.wordpress.com/2011/06/funny-dog-pictures-porky-pug-bath-club-est.jpg",
-"http://ihasahotdog.files.wordpress.com/2011/06/funny-dog-pictures-so-wuts-so-tuff-abowt.jpg",
-"http://ihasahotdog.files.wordpress.com/2011/06/funny-dog-pictures-taek-teh-pitcher-awreddy.jpg",
-"http://ihasahotdog.files.wordpress.com/2011/06/funny-dog-pictures-hip-um-pot-o-mush-impresshun-iz-good.jpg",
-"http://ihasahotdog.files.wordpress.com/2011/06/funny-dog-pictures-if-it-touchez-floor-itz-mine-no-secund-rule.jpg",
-"http://ihasahotdog.files.wordpress.com/2011/06/funny-dog-pictures-pug-life.jpg",
-"http://ihasahotdog.files.wordpress.com/2011/06/funny-dog-pictures-readz-us-a-storee.jpg",
-"http://ihasahotdog.files.wordpress.com/2011/06/funny-dog-pictures-green-light-red-light-green-light.jpg",
-"http://ihasahotdog.files.wordpress.com/2011/06/648800e7-f305-43e8-83ed-06a5325923c8.jpg",
-"http://ihasahotdog.files.wordpress.com/2011/06/cute-puppy-pictures-why-ai-always-gets-picked-last.jpg",
-"http://ihasahotdog.files.wordpress.com/2011/06/cute-puppy-pictures-corgagram.jpg",
-"http://ihasahotdog.files.wordpress.com/2011/06/cute-puppy-pictures-shes-got-a-chicken-to-ride-and-she-dont-care.jpg",
-"http://ihasahotdog.files.wordpress.com/2011/06/funny-dog-pictures-caring-is-for-the-birds.jpg",
-"http://ihasahotdog.files.wordpress.com/2011/06/funny-dog-pictures-goggie-ob-teh-week-pudge-is-teh-boss.jpg",
-];
diff --git a/chrome/common/extensions/docs/examples/extensions/catblock/manifest.json b/chrome/common/extensions/docs/examples/extensions/catblock/manifest.json
deleted file mode 100644
index e775432..0000000
--- a/chrome/common/extensions/docs/examples/extensions/catblock/manifest.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- "name": "CatBlock",
- "version": "1.0",
- "description": "I can't has cheezburger!",
- "permissions": ["webRequest", "webRequestBlocking",
- "https://i.chzbgr.com/*"],
- "background": {
- "scripts": ["loldogs.js", "background.js"]
- },
-
- "manifest_version": 2
-}
diff --git a/chrome/common/extensions/docs/examples/extensions/catifier/event_page.js b/chrome/common/extensions/docs/examples/extensions/catifier/event_page.js
deleted file mode 100644
index 2618fdc..0000000
--- a/chrome/common/extensions/docs/examples/extensions/catifier/event_page.js
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright (c) 2012 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.
-
-// Sample extension to replace all JPEG images (but no PNG/GIF/... images) with
-// lolcat images from http://icanhascheezburger.com/ - except for images on
-// Google.
-
-var RequestMatcher = chrome.declarativeWebRequest.RequestMatcher;
-var IgnoreRules = chrome.declarativeWebRequest.IgnoreRules;
-var RedirectRequest = chrome.declarativeWebRequest.RedirectRequest;
-
-var catImageUrl =
- 'https://i.chzbgr.com/completestore/12/8/23/S__rxG9hIUK4sNuMdTIY9w2.jpg';
-
-// Registers redirect rules assuming that currently no rules are registered by
-// this extension, yet.
-function registerRules() {
- var redirectRule = {
- priority: 100,
- conditions: [
- // If any of these conditions is fulfilled, the actions are executed.
- new RequestMatcher({
- // Both, the url and the resourceType must match.
- url: {pathSuffix: '.jpg'},
- resourceType: ['image']
- }),
- new RequestMatcher({
- url: {pathSuffix: '.jpeg'},
- resourceType: ['image']
- }),
- ],
- actions: [
- new RedirectRequest({redirectUrl: catImageUrl})
- ]
- };
-
- var exceptionRule = {
- priority: 1000,
- conditions: [
- // We use hostContains to compensate for various top-level domains.
- new RequestMatcher({url: {hostContains: '.google.'}})
- ],
- actions: [
- new IgnoreRules({lowerPriorityThan: 1000})
- ]
- };
-
- var callback = function() {
- if (chrome.runtime.lastError) {
- console.error('Error adding rules: ' + chrome.runtime.lastError);
- } else {
- console.info('Rules successfully installed');
- chrome.declarativeWebRequest.onRequest.getRules(null,
- function(rules) {
- console.info('Now the following rules are registered: ' +
- JSON.stringify(rules, null, 2));
- });
- }
- };
-
- chrome.declarativeWebRequest.onRequest.addRules(
- [redirectRule, exceptionRule], callback);
-}
-
-function setup() {
- // This function is also called when the extension has been updated. Because
- // registered rules are persisted beyond browser restarts, we remove
- // previously registered rules before registering new ones.
- chrome.declarativeWebRequest.onRequest.removeRules(
- null,
- function() {
- if (chrome.runtime.lastError) {
- console.error('Error clearing rules: ' + chrome.runtime.lastError);
- } else {
- registerRules();
- }
- });
-}
-
-// This is triggered when the extension is installed or updated.
-chrome.runtime.onInstalled.addListener(setup);
diff --git a/chrome/common/extensions/docs/examples/extensions/catifier/manifest.json b/chrome/common/extensions/docs/examples/extensions/catifier/manifest.json
deleted file mode 100644
index ba37252..0000000
--- a/chrome/common/extensions/docs/examples/extensions/catifier/manifest.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- "name": "Catifier",
- "version": "1.0",
- "description": "Moar cats!",
- "permissions": ["declarativeWebRequest", "<all_urls>"],
- "background": {
- "scripts": ["event_page.js"],
- "persistent": false
- },
-
- "manifest_version": 2
-}
diff --git a/chrome/common/extensions/docs/examples/extensions/chrome_search/background.js b/chrome/common/extensions/docs/examples/extensions/chrome_search/background.js
deleted file mode 100644
index 1dda1e5..0000000
--- a/chrome/common/extensions/docs/examples/extensions/chrome_search/background.js
+++ /dev/null
@@ -1,171 +0,0 @@
-// Copyright (c) 2012 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.
-
-var currentRequest = null;
-
-chrome.omnibox.onInputChanged.addListener(
- function(text, suggest) {
- if (currentRequest != null) {
- currentRequest.onreadystatechange = null;
- currentRequest.abort();
- currentRequest = null;
- }
-
- updateDefaultSuggestion(text);
- if (text == '' || text == 'halp')
- return;
-
- currentRequest = search(text, function(xml) {
- var results = [];
- var entries = xml.getElementsByTagName("entry");
-
- for (var i = 0, entry; i < 5 && (entry = entries[i]); i++) {
- var path = entry.getElementsByTagName("file")[0].getAttribute("name");
- var line =
- entry.getElementsByTagName("match")[0].getAttribute("lineNumber");
- var file = path.split("/").pop();
-
- var description = '<url>' + file + '</url>';
- if (/^file:/.test(text)) {
- description += ' <dim>' + path + '</dim>';
- } else {
- var content = entry.getElementsByTagName("content")[0].textContent;
-
- // There can be multiple lines. Kill all the ones except the one that
- // contains the first match. We can ocassionally fail to find a single
- // line that matches, so we still handle multiple lines below.
- var matches = content.split(/\n/);
- for (var j = 0, match; match = matches[j]; j++) {
- if (match.indexOf('<b>') > -1) {
- content = match;
- break;
- }
- }
-
- // Replace any extraneous whitespace to make it look nicer.
- content = content.replace(/[\n\t]/g, ' ');
- content = content.replace(/ {2,}/g, ' ');
-
- // Codesearch wraps the result in <pre> tags. Remove those if they're
- // still there.
- content = content.replace(/<\/?pre>/g, '');
-
- // Codesearch highlights the matches with 'b' tags. Replaces those
- // with 'match'.
- content = content.replace(/<(\/)?b>/g, '<$1match>');
-
- description += ' ' + content;
- }
-
- results.push({
- content: path + '@' + line,
- description: description
- });
- }
-
- suggest(results);
- });
- }
-);
-
-function resetDefaultSuggestion() {
- chrome.omnibox.setDefaultSuggestion({
- description: '<url><match>src:</match></url> Search Chromium source'
- });
-}
-
-resetDefaultSuggestion();
-
-function updateDefaultSuggestion(text) {
- var isRegex = /^re:/.test(text);
- var isFile = /^file:/.test(text);
- var isHalp = (text == 'halp');
- var isPlaintext = text.length && !isRegex && !isFile && !isHalp;
-
- var description = '<match><url>src</url></match><dim> [</dim>';
- description +=
- isPlaintext ? ('<match>' + text + '</match>') : 'plaintext-search';
- description += '<dim> | </dim>';
- description += isRegex ? ('<match>' + text + '</match>') : 're:regex-search';
- description += '<dim> | </dim>';
- description += isFile ? ('<match>' + text + '</match>') : 'file:filename';
- description += '<dim> | </dim>';
- description += isHalp ? '<match>halp</match>' : 'halp';
- description += '<dim> ]</dim>';
-
- chrome.omnibox.setDefaultSuggestion({
- description: description
- });
-}
-
-chrome.omnibox.onInputStarted.addListener(function() {
- updateDefaultSuggestion('');
-});
-
-chrome.omnibox.onInputCancelled.addListener(function() {
- resetDefaultSuggestion();
-});
-
-function search(query, callback) {
- if (query == 'halp')
- return;
-
- if (/^re:/.test(query))
- query = query.substring('re:'.length);
- else if (/^file:/.test(query))
- query = 'file:"' + query.substring('file:'.length) + '"';
- else
- query = '"' + query + '"';
-
- var url = "https://code.google.com/p/chromium/codesearch#search/&type=cs&q=" + query +
- "&exact_package=chromium&type=cs";
- var req = new XMLHttpRequest();
- req.open("GET", url, true);
- req.setRequestHeader("GData-Version", "2");
- req.onreadystatechange = function() {
- if (req.readyState == 4) {
- callback(req.responseXML);
- }
- }
- req.send(null);
- return req;
-}
-
-function getUrl(path, line) {
- var url = "https://code.google.com/p/chromium/codesearch#" + path
- "&sq=package:chromium";
- if (line)
- url += "&l=" + line;
- return url;
-}
-
-function getEntryUrl(entry) {
- return getUrl(
- entry.getElementsByTagName("file")[0].getAttribute("name"),
- entry.getElementsByTagName("match")[0].getAttribute("lineNumber"));
- return url;
-}
-
-function navigate(url) {
- chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
- chrome.tabs.update(tabs[0].id, {url: url});
- });
-}
-
-chrome.omnibox.onInputEntered.addListener(function(text) {
- // TODO(aa): We need a way to pass arbitrary data through. Maybe that is just
- // URL?
- if (/@\d+\b/.test(text)) {
- var chunks = text.split('@');
- var path = chunks[0];
- var line = chunks[1];
- navigate(getUrl(path, line));
- } else if (text == 'halp') {
- // TODO(aa)
- } else {
- navigate("https://code.google.com/p/chromium/codesearch#search/&type=cs" +
- "&q=" + text +
- "&exact_package=chromium&type=cs");
- }
-});
diff --git a/chrome/common/extensions/docs/examples/extensions/chrome_search/manifest.json b/chrome/common/extensions/docs/examples/extensions/chrome_search/manifest.json
deleted file mode 100644
index 771783b..0000000
--- a/chrome/common/extensions/docs/examples/extensions/chrome_search/manifest.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "background": {
- "scripts": ["background.js"]
- },
- "description": "Add support to the omnibox to search the Chromium source code.",
- "name": "Chromium Search",
- "omnibox": { "keyword" : "src" },
- "permissions": [ "http://www.google.com/" ],
- "version": "6.1",
- "minimum_chrome_version": "9",
-
- "manifest_version": 2
-}
diff --git a/chrome/common/extensions/docs/examples/extensions/constant_context/background.js b/chrome/common/extensions/docs/examples/extensions/constant_context/background.js
deleted file mode 100644
index 6a5460d9..0000000
--- a/chrome/common/extensions/docs/examples/extensions/constant_context/background.js
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2017 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.
-
-// Create a rule that will show the page action when the conditions are met.
-const kMatchRule = {
- // Declare the rule conditions.
- conditions: [new chrome.declarativeContent.PageStateMatcher({
- pageUrl: {hostEquals: 'developer.chrome.com'},
- })],
- // Shows the page action when the condition is met.
- actions: [new chrome.declarativeContent.ShowPageAction()]
-}
-
-// Register the runtime.onInstalled event listener.
-chrome.runtime.onInstalled.addListener(function() {
- // Overrride the rules to replace them with kMatchRule.
- chrome.declarativeContent.onPageChanged.removeRules(undefined, function() {
- chrome.declarativeContent.onPageChanged.addRules([kMatchRule]);
- });
-});
diff --git a/chrome/common/extensions/docs/examples/extensions/constant_context/content_script.js b/chrome/common/extensions/docs/examples/extensions/constant_context/content_script.js
deleted file mode 100644
index 91cc428..0000000
--- a/chrome/common/extensions/docs/examples/extensions/constant_context/content_script.js
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2017 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.
-
-chrome.storage.local.get(['words'], function(object) {
- let regExp = new RegExp('\\b(' + object.words.join('|') + ')\\b');
- const kSets = [
- {selectors: 'p, span', color: '#f7d68f'},
- {selectors: 'li, td', color: '#89b1ed'},
- {selectors: 'h1, h2, h3, th', color: '#8ae2a0'}
- ];
- for (let set of kSets) {
- let elements = Array.from(document.querySelectorAll(set.selectors));
- for (let element of elements) {
- if (regExp.test(element.innerText))
- element.style.backgroundColor = set.color;
- }
- }
-});
diff --git a/chrome/common/extensions/docs/examples/extensions/constant_context/images/cc128.png b/chrome/common/extensions/docs/examples/extensions/constant_context/images/cc128.png
deleted file mode 100644
index e135104..0000000
--- a/chrome/common/extensions/docs/examples/extensions/constant_context/images/cc128.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/constant_context/images/cc16.png b/chrome/common/extensions/docs/examples/extensions/constant_context/images/cc16.png
deleted file mode 100644
index 4fb1eb35..0000000
--- a/chrome/common/extensions/docs/examples/extensions/constant_context/images/cc16.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/constant_context/images/cc32.png b/chrome/common/extensions/docs/examples/extensions/constant_context/images/cc32.png
deleted file mode 100644
index 340103ee..0000000
--- a/chrome/common/extensions/docs/examples/extensions/constant_context/images/cc32.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/constant_context/images/cc48.png b/chrome/common/extensions/docs/examples/extensions/constant_context/images/cc48.png
deleted file mode 100644
index 5d06080e..0000000
--- a/chrome/common/extensions/docs/examples/extensions/constant_context/images/cc48.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/constant_context/manifest.json b/chrome/common/extensions/docs/examples/extensions/constant_context/manifest.json
deleted file mode 100644
index ebccaa5..0000000
--- a/chrome/common/extensions/docs/examples/extensions/constant_context/manifest.json
+++ /dev/null
@@ -1,37 +0,0 @@
-{
- "name": "Constant Context",
- "description" : "Highlights elements with keywords on developer.chrome",
- "version": "1.0",
- "page_action": {
- "default_icon": {
- "16": "images/cc16.png",
- "32": "images/cc32.png"
- },
- "default_popup": "popup.html"
- },
- "icons": {
- "16": "images/cc16.png",
- "48": "images/cc48.png",
- "32": "images/cc32.png",
- "128": "images/cc128.png"
- },
- "permissions": [
- "https://developer.chrome.com/*",
- "storage",
- "declarativeContent"
- ],
- "manifest_version": 2,
- "background": {
- "scripts": ["background.js"],
- "persistent": false
- },
- "web_accessible_resources": ["style.css"],
- "content_scripts": [
- {
- "all_frames": true,
- "js": ["content_script.js"],
- "matches": ["https://developer.chrome.com/*"],
- "run_at": "document_idle"
- }
- ]
-}
diff --git a/chrome/common/extensions/docs/examples/extensions/constant_context/popup.html b/chrome/common/extensions/docs/examples/extensions/constant_context/popup.html
deleted file mode 100644
index 9481b48..0000000
--- a/chrome/common/extensions/docs/examples/extensions/constant_context/popup.html
+++ /dev/null
@@ -1,29 +0,0 @@
-<!DOCTYPE html>
-<html>
- <head>
- <title>Constant Context</title>
- <style>
- body {
- min-width: 300px;
- font-size: 15px;
- }
- input {
- margin: 5px;
- outline: none;
- }
- </style>
- </head>
-
- <body>
- <h2>Constant Context</h2>
- <p>Highlights context around words.</p>
- <ul id="displayWords"></ul>
- <form id="form">
- <input type="text" name="word" id="userWords">
- <br>
- <input type='submit' value='Submit' id='wordSubmit'>
- <button id="clearList">Clear</button>
- </form>
- </body>
- <script src="popup.js"></script>
-</html>
diff --git a/chrome/common/extensions/docs/examples/extensions/constant_context/popup.js b/chrome/common/extensions/docs/examples/extensions/constant_context/popup.js
deleted file mode 100644
index ba4881c..0000000
--- a/chrome/common/extensions/docs/examples/extensions/constant_context/popup.js
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2017 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.
-
-function displayWords() {
- chrome.storage.local.get(['words'], function(object) {
- let pageList = document.getElementById('displayWords');
- if (object.words) {
- searchWords = object.words
- for (var i = 0; i < searchWords.length; i++){
- let listItem = document.createElement('li');
- listItem.innerText = searchWords[i]
- pageList.appendChild(listItem);
- }
- }
- });
-}
-
-displayWords();
-
-document.getElementById('wordSubmit').onclick = function() {
- let userWords = document.getElementById('userWords').value.trim();
- chrome.storage.local.get(['words'], function(object) {
- let newWords = object.words || [];
- newWords.push(userWords);
- chrome.storage.local.set({words: newWords});
- })
- chrome.tabs.executeScript(null, {
- file: 'content_script.js'
- });
-}
-
-document.getElementById('clearList').onclick = function() {
- chrome.storage.local.clear();
-}
diff --git a/chrome/common/extensions/docs/examples/extensions/download_images/background.js b/chrome/common/extensions/docs/examples/extensions/download_images/background.js
deleted file mode 100644
index 5d660788..0000000
--- a/chrome/common/extensions/docs/examples/extensions/download_images/background.js
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2018 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.
-
-'use strict';
-
-// Declare extension default properties
-let downloadsArray = [];
-let initialState = {
- 'savedImages': downloadsArray,
- 'thumbnails': false,
- 'saveImages': true
-};
-
-// Set extension setting on installation
-chrome.runtime.onInstalled.addListener(function() {
- chrome.declarativeContent.onPageChanged.removeRules(undefined, function() {
- chrome.declarativeContent.onPageChanged.addRules([{
- conditions: [
- new chrome.declarativeContent.PageStateMatcher({
- pageUrl: { hostEquals: 'developer.chrome.com', schemes: ['https'] },
- css: ['img']
- })
- ],
- actions: [ new chrome.declarativeContent.ShowPageAction() ]
- }]);
- });
- chrome.storage.local.set(initialState);
-});
diff --git a/chrome/common/extensions/docs/examples/extensions/download_images/images/download_image128.png b/chrome/common/extensions/docs/examples/extensions/download_images/images/download_image128.png
deleted file mode 100644
index 77e5f82..0000000
--- a/chrome/common/extensions/docs/examples/extensions/download_images/images/download_image128.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/download_images/images/download_image16.png b/chrome/common/extensions/docs/examples/extensions/download_images/images/download_image16.png
deleted file mode 100644
index 6df385d..0000000
--- a/chrome/common/extensions/docs/examples/extensions/download_images/images/download_image16.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/download_images/images/download_image32.png b/chrome/common/extensions/docs/examples/extensions/download_images/images/download_image32.png
deleted file mode 100644
index d6a9bf3..0000000
--- a/chrome/common/extensions/docs/examples/extensions/download_images/images/download_image32.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/download_images/images/download_image48.png b/chrome/common/extensions/docs/examples/extensions/download_images/images/download_image48.png
deleted file mode 100644
index c4bcded3..0000000
--- a/chrome/common/extensions/docs/examples/extensions/download_images/images/download_image48.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/download_images/manifest.json b/chrome/common/extensions/docs/examples/extensions/download_images/manifest.json
deleted file mode 100644
index 58fd910b1..0000000
--- a/chrome/common/extensions/docs/examples/extensions/download_images/manifest.json
+++ /dev/null
@@ -1,32 +0,0 @@
-{
- "name": "Download Images",
- "description" : "Displays all webpage images and allows user to download",
- "version": "1.0",
- "manifest_version": 2,
- "page_action": {
- "default_popup": "popup.html",
- "default_icon": {
- "16": "/images/download_image16.png",
- "32": "/images/download_image32.png",
- "48": "/images/download_image48.png",
- "128": "/images/download_image128.png"
- }
- },
- "icons": {
- "16": "/images/download_image16.png",
- "32": "/images/download_image32.png",
- "48": "/images/download_image48.png",
- "128": "/images/download_image128.png"
- },
- "permissions": [
- "downloads",
- "storage",
- "activeTab",
- "declarativeContent"
- ],
- "background": {
- "scripts": ["background.js"],
- "persistent": false
- },
- "options_page": "options.html"
-}
diff --git a/chrome/common/extensions/docs/examples/extensions/download_images/options.html b/chrome/common/extensions/docs/examples/extensions/download_images/options.html
deleted file mode 100644
index 40b9474..0000000
--- a/chrome/common/extensions/docs/examples/extensions/download_images/options.html
+++ /dev/null
@@ -1,40 +0,0 @@
-<!DOCTYPE html>
-<html>
- <head>
- <title>Options: Download Images</title>
- <style>
- #options_div {
- margin: 30px;
- }
- #saved_images {
- display: flex;
- align-items: center;
- justify-content: center;
- }
-
- img {
- max-width: 100%;
- max-height: 100%;
- }
-
- .square {
- height: 175px;
- width: 175px;
- margin: 10px;
- }
- </style>
- </head>
- <body>
- <div id="options_div">
- <input type="checkbox" id="thumbnails"> Display Images as Thumbnails
- <br />
- <br />
- <input type="checkbox" id="save_images"> Save Downloaded Images
- <br />
- <br />
- <button id="delete_button">Delete Saved Images</button>
- </div>
- <div id="savedImages"></div>
- <script src="options.js"></script>
- </body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/extensions/download_images/options.js b/chrome/common/extensions/docs/examples/extensions/download_images/options.js
deleted file mode 100644
index c35e9b9..0000000
--- a/chrome/common/extensions/docs/examples/extensions/download_images/options.js
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2018 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.
-
-'use strict'
-
-// Selects saveImagesOption checkbox element
-let saveImagesOption = document.getElementById('save_images');
-// Selects thumbnailOption checkbox element
-let thumbnailOption = document.getElementById('thumbnails');
-
-function setCheckbox(data, checkbox) {
- checkbox.checked = data;
-};
-
-// Gets thumbnails and saveImages value from storage
-chrome.storage.local.get(['saveImages', 'thumbnails'], function(data) {
- setCheckbox(data.saveImages, saveImagesOption);
- saveImagesOption.checked = data.saveImages === true;
- setCheckbox(data.thumbnails, thumbnailOption);
-});
-
-// Saves users prefrences
-function storeOption(optionName, optionValue) {
- let data = {};
- data[optionName] = optionValue;
- chrome.storage.local.set(data);
-};
-
-saveImagesOption.onchange = function() {
- storeOption('saveImages', saveImagesOption.checked);
-};
-
-thumbnailOption.onchange = function() {
- storeOption('thumbnails', thumbnailOption.checked);
-};
-
-let savedImages = document.getElementById('savedImages');
-
-let deleteButton = document.getElementById('delete_button');
-
-deleteButton.onclick = function() {
- let blankArray = [];
- chrome.storage.local.set({'savedImages': blankArray});
- location.reload();
-};
-// Gets saved downloaded images from storage
-chrome.storage.local.get('savedImages', function(element) {
- let pageImages = element.savedImages;
- pageImages.forEach(function(image) {
- // Create div element and give it class of square
- let newDiv = document.createElement('div');
- newDiv.className = 'square';
- // Create image element
- let newImage = document.createElement('img');
- // let lineBreak = document.createElement('br');
- // Image source is equal to saved download image
- newImage.src = image;
- newImage.addEventListener('click', function() {
- chrome.downloads.download({url: newImage.src});
- });
- // Append all elements to options page
- newDiv.appendChild(newImage);
- savedImages.appendChild(newDiv);
- });
-});
diff --git a/chrome/common/extensions/docs/examples/extensions/download_images/popup.html b/chrome/common/extensions/docs/examples/extensions/download_images/popup.html
deleted file mode 100644
index dd10122..0000000
--- a/chrome/common/extensions/docs/examples/extensions/download_images/popup.html
+++ /dev/null
@@ -1,32 +0,0 @@
-<!DOCTYPE html>
-<html>
- <head>
- <title>Download Images</title>
- <style>
- body {
- min-width: 300px;
- font-size: 15px;
- }
- input {
- margin: 5px;
- outline: none;
- }
- img {
- max-width: 100%;
- max-height: 100%;
- }
- .square {
- height: 175px;
- width: 175px;
- margin: 10px;
- }
- </style>
- </head>
- <body>
- <h1>Click image to download.</h1>
- <button id="options_button">Options</button>
- <br>
- <div id="image_div"></div>
- <script src="popup.js"></script>
- </body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/extensions/download_images/popup.js b/chrome/common/extensions/docs/examples/extensions/download_images/popup.js
deleted file mode 100644
index 81cc647..0000000
--- a/chrome/common/extensions/docs/examples/extensions/download_images/popup.js
+++ /dev/null
@@ -1,85 +0,0 @@
-// Copyright 2018 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.
-
-'use strict'
-
-// Script code to inject on page
-// Selects images then returns array of their currentSrc
-const scriptCode =
- `(function() {
- let images = document.querySelectorAll('img');
- let srcArray =
- Array.from(images).map(function(image) {
- return image.currentSrc;
- });
- return srcArray
- })();`;
-
-
-// Declare add image function to save downloaded images
-function addImage(url) {
- chrome.storage.local.get('savedImages', function(result) {
- // Check if storage has exsisting arrays
- // If array found, blank array is replaced with found array
- // If no array, we add to created blank array
- let downloadsArray = result.savedImages || [];
- // Images are added
- downloadsArray.push(url);
- // Chrome stores the new array with the new image
- chrome.storage.local.set({'savedImages': downloadsArray}, function() {
- if (chrome.runtime.lastError) {
- console.log(chrome.runtime.lastError);
- } else {
- console.log('Image saved successfully');
- };
- });
- });
-};
-
-// Grabs the imageDiv from the popup
-let imageDiv = document.getElementById('image_div');
-function setUp(array) {
- chrome.storage.local.get(
- ['saveImages', 'thumbnails'], function(config) {
- for (let src of array) {
- let newImage = document.createElement('img');
- let lineBreak = document.createElement('br');
- newImage.src = src;
- console.log(newImage)
- // Add an onclick event listener
- newImage.addEventListener('click', function() {
- // Downloads and image when it is clicked on
- chrome.downloads.download({url: newImage.src});
- // Checks if extension is set to store images
- if (config.saveImages === true) {
- // If true, call addImage function
- addImage(newImage.src);
- };
- });
- // Checks extension thumbnail settings
- if (config.thumbnails === true) {
- // If on, popup displays images as thumnails
- let newDiv = document.createElement('div');
- newDiv.className = 'square';
- newDiv.appendChild(newImage);
- imageDiv.appendChild(newDiv);
- } else {
- // If off, images are displayed at full size
- imageDiv.appendChild(newImage);
- };
- imageDiv.appendChild(lineBreak);
- };
- });
-};
-
-// Runs script when popup is opened
-chrome.tabs.executeScript({code: scriptCode}, function(result) {
- setUp(result[0]);
-});
-
-let optionsButton = document.getElementById('options_button');
-
-optionsButton.onclick = function() {
- chrome.tabs.create({ url: "options.html" });
-}
diff --git a/chrome/common/extensions/docs/examples/extensions/email_this_page/background.js b/chrome/common/extensions/docs/examples/extensions/email_this_page/background.js
deleted file mode 100644
index a16ef80..0000000
--- a/chrome/common/extensions/docs/examples/extensions/email_this_page/background.js
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright (c) 2012 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.
-
-function customMailtoUrl() {
- if (window.localStorage == null)
- return "";
- if (window.localStorage.customMailtoUrl == null)
- return "";
- return window.localStorage.customMailtoUrl;
-}
-
-function executeMailto(tab_id, subject, body, selection) {
- var default_handler = customMailtoUrl().length == 0;
-
- var action_url = "mailto:?"
- if (subject.length > 0)
- action_url += "subject=" + encodeURIComponent(subject) + "&";
-
- if (body.length > 0) {
- action_url += "body=" + encodeURIComponent(body);
-
- // Append the current selection to the end of the text message.
- if (selection.length > 0) {
- action_url += encodeURIComponent("\n\n") +
- encodeURIComponent(selection);
- }
- }
-
- if (!default_handler) {
- // Custom URL's (such as opening mailto in Gmail tab) should have a
- // separate tab to avoid clobbering the page you are on.
- var custom_url = customMailtoUrl();
- action_url = custom_url.replace("%s", encodeURIComponent(action_url));
- console.log('Custom url: ' + action_url);
- chrome.tabs.create({ url: action_url });
- } else {
- // Plain vanilla mailto links open up in the same tab to prevent
- // blank tabs being left behind.
- console.log('Action url: ' + action_url);
- chrome.tabs.update(tab_id, { url: action_url });
- }
-}
-
-chrome.runtime.onConnect.addListener(function(port) {
- var tab = port.sender.tab;
-
- // This will get called by the content script we execute in
- // the tab as a result of the user pressing the browser action.
- port.onMessage.addListener(function(info) {
- var max_length = 1024;
- if (info.selection.length > max_length)
- info.selection = info.selection.substring(0, max_length);
- executeMailto(tab.id, info.title, tab.url, info.selection);
- });
-});
-
-// Called when the user clicks on the browser action icon.
-chrome.browserAction.onClicked.addListener(function(tab) {
- // We can only inject scripts to find the title on pages loaded with http
- // and https so for all other pages, we don't ask for the title.
- if (tab.url.indexOf("http:") != 0 &&
- tab.url.indexOf("https:") != 0) {
- executeMailto(tab.id, "", tab.url, "");
- } else {
- chrome.tabs.executeScript(null, {file: "content_script.js"});
- }
-});
diff --git a/chrome/common/extensions/docs/examples/extensions/email_this_page/content_script.js b/chrome/common/extensions/docs/examples/extensions/email_this_page/content_script.js
deleted file mode 100644
index 08744ef..0000000
--- a/chrome/common/extensions/docs/examples/extensions/email_this_page/content_script.js
+++ /dev/null
@@ -1,10 +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.
-
-var additionalInfo = {
- "title": document.title,
- "selection": window.getSelection().toString()
-};
-
-chrome.runtime.connect().postMessage(additionalInfo);
diff --git a/chrome/common/extensions/docs/examples/extensions/email_this_page/email_16x16.png b/chrome/common/extensions/docs/examples/extensions/email_this_page/email_16x16.png
deleted file mode 100644
index 5ab1a150..0000000
--- a/chrome/common/extensions/docs/examples/extensions/email_this_page/email_16x16.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/email_this_page/mail_128x128.png b/chrome/common/extensions/docs/examples/extensions/email_this_page/mail_128x128.png
deleted file mode 100644
index 835df38..0000000
--- a/chrome/common/extensions/docs/examples/extensions/email_this_page/mail_128x128.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/email_this_page/manifest.json b/chrome/common/extensions/docs/examples/extensions/email_this_page/manifest.json
deleted file mode 100644
index 3801b87..0000000
--- a/chrome/common/extensions/docs/examples/extensions/email_this_page/manifest.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
- "name": "Email this page (by Google)",
- "description": "This extension adds an email button to the toolbar which allows you to email the page link using your default mail client or Gmail.",
- "version": "1.2.6",
- "background": {
- "scripts": ["background.js"],
- "persistent": false
- },
- "icons": { "128": "mail_128x128.png" },
- "options_page": "options.html",
- "permissions": [
- "tabs", "http://*/*", "https://*/*"
- ],
- "browser_action": {
- "default_title": "Email this page",
- "default_icon": "email_16x16.png"
- },
-
- "manifest_version": 2
-}
diff --git a/chrome/common/extensions/docs/examples/extensions/email_this_page/options.html b/chrome/common/extensions/docs/examples/extensions/email_this_page/options.html
deleted file mode 100644
index a27f7ebc..0000000
--- a/chrome/common/extensions/docs/examples/extensions/email_this_page/options.html
+++ /dev/null
@@ -1,44 +0,0 @@
-<!DOCTYPE>
-<!--
- * Copyright (c) 2012 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>
- <title>Options for the Send as Email extension</title>
-<style>
-#providerSelection {
- font-family: Helvetica, Arial, sans-serif;
- font-size: 10pt;
-}
-</style>
-<script src="options.js"></script>
-</head>
-<body>
-<table class="simple">
-<tr>
- <td rowspan="2" valign="top" align="center" width="80">
- <img src="mail_128x128.png" width="64" height="64" />
- </td>
- <td height="22"></td>
-</tr>
-<tr>
- <td valign="center">
- <div id="providerSelection">
- <strong>Select provider to use when emailing a web page address:</strong>
- <br /><br />
- <label>
- <input id="default" type="radio" name="mailto" value="mailto" checked>
- Your default mail handler<br>
- </label>
-
- <label>
- <input id="gmail" type="radio" name="mailto" value="gmail">Gmail<br>
- </label>
- </div>
- </td>
-</tr>
-</table>
-</body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/extensions/email_this_page/options.js b/chrome/common/extensions/docs/examples/extensions/email_this_page/options.js
deleted file mode 100644
index 2c682a4..0000000
--- a/chrome/common/extensions/docs/examples/extensions/email_this_page/options.js
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (c) 2012 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.
-
-var gmail = "https://mail.google.com/mail/?extsrc=mailto&url=%s";
-
-function toggle(radioButton) {
- if (window.localStorage == null) {
- alert('Local storage is required for changing providers');
- return;
- }
- if (document.getElementById('gmail').checked) {
- window.localStorage.customMailtoUrl = gmail;
- } else {
- window.localStorage.customMailtoUrl = "";
- }
-}
-
-function main() {
- if (window.localStorage == null) {
- alert("LocalStorage must be enabled for changing options.");
- document.getElementById('default').disabled = true;
- document.getElementById('gmail').disabled = true;
- return;
- }
-
- // Default handler is checked. If we've chosen another provider, we must
- // change the checkmark.
- if (window.localStorage.customMailtoUrl == gmail)
- document.getElementById('gmail').checked = true;
-}
-
-document.addEventListener('DOMContentLoaded', function () {
- main();
- document.querySelector('#default').addEventListener('click', toggle);
- document.querySelector('#gmail').addEventListener('click', toggle);
-});
diff --git a/chrome/common/extensions/docs/examples/extensions/fx/bg.js b/chrome/common/extensions/docs/examples/extensions/fx/bg.js
deleted file mode 100644
index 3f3814ba..0000000
--- a/chrome/common/extensions/docs/examples/extensions/fx/bg.js
+++ /dev/null
@@ -1,431 +0,0 @@
-// Copyright (c) 2012 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.
-
-/*
- * Background page for Chrome Sounds extension.
- * This tracks various events from Chrome and plays sounds.
- */
-
-// Map of hostname suffixes or URLs without query params to sounds.
-// Yeah OK, some of these are a little cliche...
-var urlSounds = {
- "http://www.google.ca/": "canadian-hello.mp3",
- "chrome://histograms/": "time-passing.mp3",
- "chrome://memory/": "transform!.mp3",
- "chrome://crash/": "sadtrombone.mp3",
- "chrome://extensions/": "beepboop.mp3",
- "http://www.google.com.au/": "didgeridoo.mp3",
- "http://www.google.com.my/": "my_subway.mp3",
- "http://www.google.com/appserve/fiberrfi/": "dialup.mp3",
- "lively.com": "cricket.mp3",
- "http://www.google.co.uk/": "mind_the_gap.mp3",
- "http://news.google.com/": "news.mp3",
- "http://www.bing.com/": "sonar.mp3",
-};
-
-// Map of query parameter words to sounds.
-// More easy cliches...
-var searchSounds = {
- "scotland": "bagpipe.mp3",
- "seattle": "rain.mp3",
-};
-
-// Map of tab numbers to notes on a scale.
-var tabNoteSounds = {
- "tab0": "mando-1.mp3",
- "tab1": "mando-2.mp3",
- "tab2": "mando-3.mp3",
- "tab3": "mando-4.mp3",
- "tab4": "mando-5.mp3",
- "tab5": "mando-6.mp3",
- "tab6": "mando-7.mp3",
-};
-
-// Map of sounds that play in a continuous loop while an event is happening
-// in the content area (e.g. "keypress" while start and keep looping while
-// the user keeps typing).
-var contentSounds = {
- "keypress": "typewriter-1.mp3",
- "resize": "harp-transition-2.mp3",
- "scroll": "shepard.mp3"
-};
-
-// Map of events to their default sounds
-var eventSounds = {
- "tabCreated": "conga1.mp3",
- "tabMoved": "bell-transition.mp3",
- "tabRemoved": "smash-glass-1.mp3",
- "tabSelectionChanged": "click.mp3",
- "tabAttached": "whoosh-15.mp3",
- "tabDetached": "sword-shrill.mp3",
- "tabNavigated": "click.mp3",
- "windowCreated": "bell-small.mp3",
- "windowFocusChanged": "click.mp3",
- "bookmarkCreated": "bubble-drop.mp3",
- "bookmarkMoved": "thud.mp3",
- "bookmarkRemoved": "explosion-6.mp3",
- "windowCreatedIncognito": "weird-wind1.mp3",
- "startup": "whoosh-19.mp3"
-};
-
-var soundLists = [urlSounds, searchSounds, eventSounds, tabNoteSounds,
- contentSounds];
-
-var sounds = {};
-
-// Map of event names to extension events.
-// Events intentionally skipped:
-// chrome.windows.onRemoved - can't suppress the tab removed that comes first
-var events = {
- "tabCreated": chrome.tabs.onCreated,
- "tabMoved": chrome.tabs.onMoved,
- "tabRemoved": chrome.tabs.onRemoved,
- "tabSelectionChanged": chrome.tabs.onSelectionChanged,
- "tabAttached": chrome.tabs.onAttached,
- "tabDetached": chrome.tabs.onDetached,
- "tabNavigated": chrome.tabs.onUpdated,
- "windowCreated": chrome.windows.onCreated,
- "windowFocusChanged": chrome.windows.onFocusChanged,
- "bookmarkCreated": chrome.bookmarks.onCreated,
- "bookmarkMoved": chrome.bookmarks.onMoved,
- "bookmarkRemoved": chrome.bookmarks.onRemoved
-};
-
-// Map of event name to a validation function that is should return true if
-// the default sound should be played for this event.
-var eventValidator = {
- "tabCreated": tabCreated,
- "tabNavigated": tabNavigated,
- "tabRemoved": tabRemoved,
- "tabSelectionChanged": tabSelectionChanged,
- "windowCreated": windowCreated,
- "windowFocusChanged": windowFocusChanged,
-};
-
-var started = false;
-
-function shouldPlay(id) {
- // Ignore all events until the startup sound has finished.
- if (id != "startup" && !started)
- return false;
- var val = localStorage.getItem(id);
- if (val && val != "enabled") {
- console.log(id + " disabled");
- return false;
- }
- return true;
-}
-
-function didPlay(id) {
- if (!localStorage.getItem(id))
- localStorage.setItem(id, "enabled");
-}
-
-function playSound(id, loop) {
- if (!shouldPlay(id))
- return;
-
- var sound = sounds[id];
- console.log("playsound: " + id);
- if (sound && sound.src) {
- if (!sound.paused) {
- if (sound.currentTime < 0.2) {
- console.log("ignoring fast replay: " + id + "/" + sound.currentTime);
- return;
- }
- sound.pause();
- sound.currentTime = 0;
- }
- if (loop)
- sound.loop = loop;
-
- // Sometimes, when playing multiple times, readyState is HAVE_METADATA.
- if (sound.readyState == 0) { // HAVE_NOTHING
- console.log("bad ready state: " + sound.readyState);
- } else if (sound.error) {
- console.log("media error: " + sound.error);
- } else {
- didPlay(id);
- sound.play();
- }
- } else {
- console.log("bad playSound: " + id);
- }
-}
-
-function stopSound(id) {
- console.log("stopSound: " + id);
- var sound = sounds[id];
- if (sound && sound.src && !sound.paused) {
- sound.pause();
- sound.currentTime = 0;
- }
-}
-
-var base_url = "http://dl.google.com/dl/chrome/extensions/audio/";
-
-function soundLoadError(audio, id) {
- console.log("failed to load sound: " + id + "-" + audio.src);
- audio.src = "";
- if (id == "startup")
- started = true;
-}
-
-function soundLoaded(audio, id) {
- console.log("loaded sound: " + id);
- sounds[id] = audio;
- if (id == "startup")
- playSound(id);
-}
-
-// Hack to keep a reference to the objects while we're waiting for them to load.
-var notYetLoaded = {};
-
-function loadSound(file, id) {
- if (!file.length) {
- console.log("no sound for " + id);
- return;
- }
- var audio = new Audio();
- audio.id = id;
- audio.onerror = function() { soundLoadError(audio, id); };
- audio.addEventListener("canplaythrough",
- function() { soundLoaded(audio, id); }, false);
- if (id == "startup") {
- audio.addEventListener("ended", function() { started = true; });
- }
- audio.src = base_url + file;
- audio.load();
- notYetLoaded[id] = audio;
-}
-
-// Remember the last event so that we can avoid multiple events firing
-// unnecessarily (e.g. selection changed due to close).
-var eventsToEat = 0;
-
-function eatEvent(name) {
- if (eventsToEat > 0) {
- console.log("ate event: " + name);
- eventsToEat--;
- return true;
- }
- return false;
-}
-
-function soundEvent(event, name) {
- if (event) {
- var validator = eventValidator[name];
- if (validator) {
- event.addListener(function() {
- console.log("handling custom event: " + name);
-
- // Check this first since the validator may bump the count for future
- // events.
- var canPlay = (eventsToEat == 0);
- if (validator.apply(this, arguments)) {
- if (!canPlay) {
- console.log("ate event: " + name);
- eventsToEat--;
- return;
- }
- playSound(name);
- }
- });
- } else {
- event.addListener(function() {
- console.log("handling event: " + name);
- if (eatEvent(name)) {
- return;
- }
- playSound(name);
- });
- }
- } else {
- console.log("no event for " + name);
- }
-}
-
-var navSound;
-
-function stopNavSound() {
- if (navSound) {
- stopSound(navSound);
- navSound = null;
- }
-}
-
-function playNavSound(id) {
- stopNavSound();
- navSound = id;
- playSound(id);
-}
-
-function tabNavigated(tabId, changeInfo, tab) {
- // Quick fix to catch the case where the content script doesn't have a chance
- // to stop itself.
- stopSound("keypress");
-
- //console.log(JSON.stringify(changeInfo) + JSON.stringify(tab));
- if (changeInfo.status != "complete") {
- return false;
- }
- if (eatEvent("tabNavigated")) {
- return false;
- }
-
- console.log(JSON.stringify(tab));
-
- if (navSound)
- stopSound(navSound);
-
- var re = /https?:\/\/([^\/:]*)[^\?]*\??(.*)/i;
- match = re.exec(tab.url);
- if (match) {
- if (match.length == 3) {
- var query = match[2];
- var parts = query.split("&");
- for (var i in parts) {
- if (parts[i].indexOf("q=") == 0) {
- var q = decodeURIComponent(parts[i].substring(2));
- q = q.replace("+", " ");
- console.log("query == " + q);
- var words = q.split(" ");
- for (j in words) {
- if (searchSounds[words[j]]) {
- console.log("searchSound: " + words[j]);
- playNavSound(words[j]);
- return false;
- }
- }
- break;
- }
- }
- }
- if (match.length >= 2) {
- var hostname = match[1];
- if (hostname) {
- var parts = hostname.split(".");
- if (parts.length > 1) {
- var tld2 = parts.slice(-2).join(".");
- var tld3 = parts.slice(-3).join(".");
- var sound = urlSounds[tld2];
- if (sound) {
- playNavSound(tld2);
- return false;
- }
- sound = urlSounds[tld3];
- if (sound) {
- playNavSound(tld3);
- return false;
- }
- }
- }
- }
- }
-
- // Now try a direct URL match (without query string).
- var url = tab.url;
- var query = url.indexOf("?");
- if (query > 0) {
- url = tab.url.substring(0, query);
- }
- console.log(tab.url);
- var sound = urlSounds[url];
- if (sound) {
- playNavSound(url);
- return false;
- }
-
- return true;
-}
-
-var selectedTabId = -1;
-
-function tabSelectionChanged(tabId) {
- selectedTabId = tabId;
- if (eatEvent("tabSelectionChanged"))
- return false;
-
- var count = 7;
- chrome.tabs.get(tabId, function(tab) {
- var index = tab.index % count;
- playSound("tab" + index);
- });
- return false;
-}
-
-function tabCreated(tab) {
- if (eatEvent("tabCreated")) {
- return false;
- }
- eventsToEat++; // tabNavigated or tabSelectionChanged
- // TODO - unfortunately, we can't detect whether this tab will get focus, so
- // we can't decide whether or not to eat a second event.
- return true;
-}
-
-function tabRemoved(tabId) {
- if (eatEvent("tabRemoved")) {
- return false;
- }
- if (tabId == selectedTabId) {
- eventsToEat++; // tabSelectionChanged
- stopNavSound();
- }
- return true;
-}
-
-function windowCreated(window) {
- if (eatEvent("windowCreated")) {
- return false;
- }
- eventsToEat += 3; // tabNavigated, tabSelectionChanged, windowFocusChanged
- if (window.incognito) {
- playSound("windowCreatedIncognito");
- return false;
- }
- return true;
-}
-
-var selectedWindowId = -1;
-
-function windowFocusChanged(windowId) {
- if (windowId == selectedWindowId) {
- return false;
- }
- selectedWindowId = windowId;
- if (eatEvent("windowFocusChanged")) {
- return false;
- }
- return true;
-}
-
-function contentScriptHandler(request) {
- if (contentSounds[request.eventName]) {
- if (request.eventValue == "started") {
- playSound(request.eventName, true);
- } else if (request.eventValue == "stopped") {
- stopSound(request.eventName);
- } else {
- playSound(request.eventName);
- }
- }
- console.log("got message: " + JSON.stringify(request));
-}
-
-
-//////////////////////////////////////////////////////
-
-// Listen for messages from content scripts.
-chrome.extension.onRequest.addListener(contentScriptHandler);
-
-// Load the sounds and register event listeners.
-for (var list in soundLists) {
- for (var id in soundLists[list]) {
- loadSound(soundLists[list][id], id);
- }
-}
-for (var name in events) {
- soundEvent(events[name], name);
-}
diff --git a/chrome/common/extensions/docs/examples/extensions/fx/content.js b/chrome/common/extensions/docs/examples/extensions/fx/content.js
deleted file mode 100644
index b79095c..0000000
--- a/chrome/common/extensions/docs/examples/extensions/fx/content.js
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Content script for Chrome Sounds.
- * Tracks in-page events and notifies the background page.
- */
-
-function sendEvent(event, value) {
- console.log("sendEvent: " + event + "," + value);
- chrome.extension.sendRequest({eventName: event, eventValue: value});
-}
-
-// Timers to trigger "stopEvent" for coalescing events.
-var timers = {};
-
-function stopEvent(type) {
- timers[type] = 0;
- sendEvent(type, "stopped");
-}
-
-// Automatically coalesces repeating events into a start and a stop event.
-// |validator| is a function which should return true if the event is
-// considered to be a valid event of this type.
-function handleEvent(event, type, validator) {
- if (validator) {
- if (!validator(event)) {
- return;
- }
- }
- var timerId = timers[type];
- var eventInProgress = (timerId > 0);
- if (eventInProgress) {
- clearTimeout(timerId);
- timers[type] = 0;
- } else {
- sendEvent(type, "started");
- }
- timers[type] = setTimeout(stopEvent, 300, type);
-}
-
-function listenAndCoalesce(target, type, validator) {
- target.addEventListener(type, function(event) {
- handleEvent(event, type, validator);
- }, true);
-}
-
-listenAndCoalesce(document, "scroll");
-
-// For some reason, "resize" doesn't seem to work with addEventListener.
-if ((window == window.top) && document.body && !document.body.onresize) {
- document.body.onresize = function(event) {
- sendEvent("resize", "");
- };
-}
-
-listenAndCoalesce(document, "keypress", function(event) {
- if (event.charCode == 13)
- return false;
-
- // TODO(erikkay) This doesn't work in gmail's rich text compose window.
- return event.target.tagName == "TEXTAREA" ||
- event.target.tagName == "INPUT" ||
- event.target.isContentEditable;
-});
diff --git a/chrome/common/extensions/docs/examples/extensions/fx/icon.png b/chrome/common/extensions/docs/examples/extensions/fx/icon.png
deleted file mode 100644
index dd6b4a7..0000000
--- a/chrome/common/extensions/docs/examples/extensions/fx/icon.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/fx/manifest.json b/chrome/common/extensions/docs/examples/extensions/fx/manifest.json
deleted file mode 100644
index 962c5eec..0000000
--- a/chrome/common/extensions/docs/examples/extensions/fx/manifest.json
+++ /dev/null
@@ -1,22 +0,0 @@
-{
- "name": "Chrome Sounds",
- "version": "1.2",
- "description": "Enjoy a more magical and immersive experience when browsing the web using the power of sound.",
- "background": {
- "scripts": ["bg.js"]
- },
- "options_page": "options.html",
- "icons": { "128": "icon.png" },
- "permissions": [
- "tabs",
- "bookmarks",
- "http://*/*",
- "https://*/*"
- ],
- "content_scripts": [ {
- "matches": ["http://*/*", "https://*/*"],
- "js": ["content.js"],
- "all_frames": true
- }],
- "manifest_version": 2
-}
diff --git a/chrome/common/extensions/docs/examples/extensions/fx/options.html b/chrome/common/extensions/docs/examples/extensions/fx/options.html
deleted file mode 100644
index 12d86c3..0000000
--- a/chrome/common/extensions/docs/examples/extensions/fx/options.html
+++ /dev/null
@@ -1,31 +0,0 @@
-<!doctype html>
-<html>
-<head>
-<style>
-body {
- font-family: sans-serif;
-}
-#attributions {
- margin-top: 20px;
- color: #666666;
- Xfont-size: 10px;
-}
-.sound {
- cursor: pointer;
-}
-</style>
-<script src="options.js"></script>
-</head>
-<body>
-<div id="sounds"></div>
-<div id="attributions">
-Sounds from:
-<ul>
-<li><a href="http://www.freesound.org">www.freesound.org</a></li>
-<li><a href="http://www.free-samples-n-loops.com/loops.html">www.free-samples-n-loops.com/loops.html</a></li>
-<li>Googlers with microphones.*</li>
-</ul>
-<span style="font-size:10px">* Canadian sound made by actual Canadian.</span>
-</div>
-</body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/extensions/fx/options.js b/chrome/common/extensions/docs/examples/extensions/fx/options.js
deleted file mode 100644
index 21d0afaa..0000000
--- a/chrome/common/extensions/docs/examples/extensions/fx/options.js
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright (c) 2012 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.
-
-function playSound(id) {
- console.log(id);
- chrome.extension.getBackgroundPage().playSound(id, false);
-}
-
-function stopSound(id) {
- chrome.extension.getBackgroundPage().stopSound(id);
-}
-
-function soundChanged(event) {
- var key = event.target.name;
- var checked = event.target.checked;
- if (checked) {
- localStorage.setItem(key, "enabled");
- playSound(event.target.name);
- } else {
- localStorage.setItem(key, "disabled");
- stopSound(event.target.name);
- }
-}
-
-function showSounds() {
- var sounds = document.getElementById("sounds");
- if (!localStorage.length) {
- sounds.innerText = "";
- return;
- }
- sounds.innerText = "Discovered sounds: (uncheck to disable)";
- var keys = new Array();
- for (var key in localStorage) {
- keys.push(key);
- console.log(key);
- }
- keys.sort();
- for (var index in keys) {
- var key = keys[index];
- var div = document.createElement("div");
- var check = document.createElement("input");
- check.type = "checkbox"
- check.name = key;
- check.checked = localStorage[key] == "enabled";
- check.onchange = soundChanged;
- div.appendChild(check);
- var text = document.createElement("span");
- text.id = key;
- text.innerText = key;
- text.className = "sound";
- text.onclick = function(event) { playSound(event.target.id); };
- div.appendChild(text);
- sounds.appendChild(div);
- }
-}
-
-document.addEventListener('DOMContentLoaded', showSounds);
-document.addEventListener('focus', showSounds);
diff --git a/chrome/common/extensions/docs/examples/extensions/gdocs/README b/chrome/common/extensions/docs/examples/extensions/gdocs/README
deleted file mode 100644
index 9c0393b..0000000
--- a/chrome/common/extensions/docs/examples/extensions/gdocs/README
+++ /dev/null
@@ -1,69 +0,0 @@
-Sample extension to demonstrate integration with an OAuth service.
-
-Overview
---------
-This sample demonstrates the use of OAuth to authorize against
-Google's Contacts API inside of an extension. It implements a library which
-may be reused generically to authorize requests to any 3-legged OAuth API.
-
-Library
--------
-The library files are:
- * chrome_ex_oauth.html
- * chrome_ex_oauth.js
- * chrome_ex_oauthsimple.js
-
-To use these files, place them in the root of your extension and include both
-.js files in your background page in the following order:
-
- <script type="text/javascript" src="chrome_ex_oauthsimple.js"></script>
- <script type="text/javascript" src="chrome_ex_oauth.js"></script>
-
-To initialize the API, create a ChromeExOAuth object in the background page:
-
- var oauth = ChromeExOAuth.initBackgroundPage({
- 'request_url' : <OAuth request URL>,
- 'authorize_url' : <OAuth authorize URL>,
- 'access_url' : <OAuth access token URL>,
- 'consumer_key' : <OAuth consumer key>,
- 'consumer_secret' : <OAuth consumer secret>,
- 'scope' : <scope parameter for this auth>,
- 'app_name' : <application name, not used by all OAuth providers>
- });
-
-Call the authorize() function to redirect the user to the OAuth provider in
-order to obtain an access token. The client library abstracts most of this
-process, so all you need to do is pass a callback to the authorize() function
-and a new tab will open and redirect the user. If the library already has
-stored an access token for the current scope, then no tab will be opened. In
-either case, the callback will be called with the resulting token and secret.
-
- oauth.authorize(onAuthorized);
-
-There is no need to store the token and secret, as this library already stores
-these values in localStorage. Once the callback you specified is called, you
-can call the sendSignedRequest function to send OAuth-signed requests to the
-API. The sendSignedRequest call takes an url to fetch, a callback function,
-and an optional parameter object as its arguments. The callback is passed
-the response text as well as the XMLHttpRequest object which was used to
-make the request as its arguments.
-
- function callback(text, xhr) {
- //...
- };
-
- function onAuthorized() {
- var url = <API url inside of the requested scope>;
- var request = {
- 'method' : 'GET',
- 'parameters' : {
- <Any request parameters as key : value pairs>
- }
- }
- oauth.sendSignedRequest(url, callback, request);
- };
- oauth.authorize(onAuthorized);
-
-
-
-
diff --git a/chrome/common/extensions/docs/examples/extensions/gdocs/background.html b/chrome/common/extensions/docs/examples/extensions/gdocs/background.html
deleted file mode 100644
index 34478f5..0000000
--- a/chrome/common/extensions/docs/examples/extensions/gdocs/background.html
+++ /dev/null
@@ -1,61 +0,0 @@
-<!DOCTYPE html>
-<!--
- * Copyright (c) 2010 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.
- *
- * Author: Eric Bidelman <ericbidelman@chromium.org>
--->
-<html>
- <head>
- <script type="text/javascript" src="chrome_ex_oauthsimple.js"></script>
- <script type="text/javascript" src="chrome_ex_oauth.js"></script>
- <script type="text/javascript">
- var DOCLIST_SCOPE = 'https://docs.google.com/feeds';
- var DOCLIST_FEED = DOCLIST_SCOPE + '/default/private/full/';
- var docs = []; // In memory cache for the user's entire doclist.
- var refreshRate = localStorage.refreshRate || 300; // 5 min default.
- var pollIntervalMin = 1000 * refreshRate;
- var requests = [];
-
- var oauth = ChromeExOAuth.initBackgroundPage({
- 'request_url': 'https://www.google.com/accounts/OAuthGetRequestToken',
- 'authorize_url': 'https://www.google.com/accounts/OAuthAuthorizeToken',
- 'access_url': 'https://www.google.com/accounts/OAuthGetAccessToken',
- 'consumer_key': 'anonymous',
- 'consumer_secret': 'anonymous',
- 'scope': DOCLIST_SCOPE,
- 'app_name': 'Chrome Extension Sample - Accessing Google Docs with OAuth'
- });
-
- function setIcon(opt_badgeObj) {
- if (opt_badgeObj) {
- var badgeOpts = {};
- if (opt_badgeObj && opt_badgeObj.text != undefined) {
- badgeOpts['text'] = opt_badgeObj.text;
- }
- if (opt_badgeObj && opt_badgeObj.tabId) {
- badgeOpts['tabId'] = opt_badgeObj.tabId;
- }
- chrome.browserAction.setBadgeText(badgeOpts);
- }
- };
-
- function clearPendingRequests() {
- for (var i = 0, req; req = requests[i]; ++i) {
- window.clearTimeout(req);
- }
- requests = [];
- };
-
- function logout() {
- docs = [];
- setIcon({'text': ''});
- oauth.clearTokens();
- clearPendingRequests();
- };
- </script>
- </head>
- <body>
- </body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/extensions/gdocs/chrome_ex_oauth.html b/chrome/common/extensions/docs/examples/extensions/gdocs/chrome_ex_oauth.html
deleted file mode 100644
index 61d0ac2..0000000
--- a/chrome/common/extensions/docs/examples/extensions/gdocs/chrome_ex_oauth.html
+++ /dev/null
@@ -1,30 +0,0 @@
-<!DOCTYPE html>
-<!--
- * Copyright (c) 2010 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.
- *
- * Author: Eric Bidelman <ericbidelman@chromium.org>
--->
-<html>
- <head>
- <meta charset="UTF-8">
- <title>OAuth Redirect Page</title>
- <style type="text/css">
- body {
- font: 16px Arial;
- color: #333;
- }
- </style>
- <script type="text/javascript" src="chrome_ex_oauthsimple.js"></script>
- <script type="text/javascript" src="chrome_ex_oauth.js"></script>
- <script type="text/javascript">
- function onLoad() {
- ChromeExOAuth.initCallbackPage();
- };
- </script>
- </head>
- <body onload="onLoad();">
- Redirecting...
- </body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/extensions/gdocs/chrome_ex_oauth.js b/chrome/common/extensions/docs/examples/extensions/gdocs/chrome_ex_oauth.js
deleted file mode 100644
index e28a594..0000000
--- a/chrome/common/extensions/docs/examples/extensions/gdocs/chrome_ex_oauth.js
+++ /dev/null
@@ -1,592 +0,0 @@
-// Copyright (c) 2010 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.
-
-/**
- * Constructor - no need to invoke directly, call initBackgroundPage instead.
- * @constructor
- * @param {String} url_request_token The OAuth request token URL.
- * @param {String} url_auth_token The OAuth authorize token URL.
- * @param {String} url_access_token The OAuth access token URL.
- * @param {String} consumer_key The OAuth consumer key.
- * @param {String} consumer_secret The OAuth consumer secret.
- * @param {String} oauth_scope The OAuth scope parameter.
- * @param {Object} opt_args Optional arguments. Recognized parameters:
- * "app_name" {String} Name of the current application
- * "callback_page" {String} If you renamed chrome_ex_oauth.html, the name
- * this file was renamed to.
- */
-function ChromeExOAuth(url_request_token, url_auth_token, url_access_token,
- consumer_key, consumer_secret, oauth_scope, opt_args) {
- this.url_request_token = url_request_token;
- this.url_auth_token = url_auth_token;
- this.url_access_token = url_access_token;
- this.consumer_key = consumer_key;
- this.consumer_secret = consumer_secret;
- this.oauth_scope = oauth_scope;
- this.app_name = opt_args && opt_args['app_name'] ||
- "ChromeExOAuth Library";
- this.key_token = "oauth_token";
- this.key_token_secret = "oauth_token_secret";
- this.callback_page = opt_args && opt_args['callback_page'] ||
- "chrome_ex_oauth.html";
- this.auth_params = {};
- if (opt_args && opt_args['auth_params']) {
- for (key in opt_args['auth_params']) {
- if (opt_args['auth_params'].hasOwnProperty(key)) {
- this.auth_params[key] = opt_args['auth_params'][key];
- }
- }
- }
-};
-
-/*******************************************************************************
- * PUBLIC API METHODS
- * Call these from your background page.
- ******************************************************************************/
-
-/**
- * Initializes the OAuth helper from the background page. You must call this
- * before attempting to make any OAuth calls.
- * @param {Object} oauth_config Configuration parameters in a JavaScript object.
- * The following parameters are recognized:
- * "request_url" {String} OAuth request token URL.
- * "authorize_url" {String} OAuth authorize token URL.
- * "access_url" {String} OAuth access token URL.
- * "consumer_key" {String} OAuth consumer key.
- * "consumer_secret" {String} OAuth consumer secret.
- * "scope" {String} OAuth access scope.
- * "app_name" {String} Application name.
- * "auth_params" {Object} Additional parameters to pass to the
- * Authorization token URL. For an example, 'hd', 'hl', 'btmpl':
- * http://code.google.com/apis/accounts/docs/OAuth_ref.html#GetAuth
- * @return {ChromeExOAuth} An initialized ChromeExOAuth object.
- */
-ChromeExOAuth.initBackgroundPage = function(oauth_config) {
- window.chromeExOAuthConfig = oauth_config;
- window.chromeExOAuth = ChromeExOAuth.fromConfig(oauth_config);
- window.chromeExOAuthRedirectStarted = false;
- window.chromeExOAuthRequestingAccess = false;
-
- var url_match = chrome.extension.getURL(window.chromeExOAuth.callback_page);
- var tabs = {};
- chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
- if (changeInfo.url &&
- changeInfo.url.substr(0, url_match.length) === url_match &&
- changeInfo.url != tabs[tabId] &&
- window.chromeExOAuthRequestingAccess == false) {
- chrome.tabs.create({ 'url' : changeInfo.url }, function(tab) {
- tabs[tab.id] = tab.url;
- chrome.tabs.remove(tabId);
- });
- }
- });
-
- return window.chromeExOAuth;
-};
-
-/**
- * Authorizes the current user with the configued API. You must call this
- * before calling sendSignedRequest.
- * @param {Function} callback A function to call once an access token has
- * been obtained. This callback will be passed the following arguments:
- * token {String} The OAuth access token.
- * secret {String} The OAuth access token secret.
- */
-ChromeExOAuth.prototype.authorize = function(callback) {
- if (this.hasToken()) {
- callback(this.getToken(), this.getTokenSecret());
- } else {
- window.chromeExOAuthOnAuthorize = function(token, secret) {
- callback(token, secret);
- };
- chrome.tabs.create({ 'url' :chrome.extension.getURL(this.callback_page) });
- }
-};
-
-/**
- * Clears any OAuth tokens stored for this configuration. Effectively a
- * "logout" of the configured OAuth API.
- */
-ChromeExOAuth.prototype.clearTokens = function() {
- delete localStorage[this.key_token + encodeURI(this.oauth_scope)];
- delete localStorage[this.key_token_secret + encodeURI(this.oauth_scope)];
-};
-
-/**
- * Returns whether a token is currently stored for this configuration.
- * Effectively a check to see whether the current user is "logged in" to
- * the configured OAuth API.
- * @return {Boolean} True if an access token exists.
- */
-ChromeExOAuth.prototype.hasToken = function() {
- return !!this.getToken();
-};
-
-/**
- * Makes an OAuth-signed HTTP request with the currently authorized tokens.
- * @param {String} url The URL to send the request to. Querystring parameters
- * should be omitted.
- * @param {Function} callback A function to be called once the request is
- * completed. This callback will be passed the following arguments:
- * responseText {String} The text response.
- * xhr {XMLHttpRequest} The XMLHttpRequest object which was used to
- * send the request. Useful if you need to check response status
- * code, etc.
- * @param {Object} opt_params Additional parameters to configure the request.
- * The following parameters are accepted:
- * "method" {String} The HTTP method to use. Defaults to "GET".
- * "body" {String} A request body to send. Defaults to null.
- * "parameters" {Object} Query parameters to include in the request.
- * "headers" {Object} Additional headers to include in the request.
- */
-ChromeExOAuth.prototype.sendSignedRequest = function(url, callback,
- opt_params) {
- var method = opt_params && opt_params['method'] || 'GET';
- var body = opt_params && opt_params['body'] || null;
- var params = opt_params && opt_params['parameters'] || {};
- var headers = opt_params && opt_params['headers'] || {};
-
- var signedUrl = this.signURL(url, method, params);
-
- ChromeExOAuth.sendRequest(method, signedUrl, headers, body, function (xhr) {
- if (xhr.readyState == 4) {
- callback(xhr.responseText, xhr);
- }
- });
-};
-
-/**
- * Adds the required OAuth parameters to the given url and returns the
- * result. Useful if you need a signed url but don't want to make an XHR
- * request.
- * @param {String} method The http method to use.
- * @param {String} url The base url of the resource you are querying.
- * @param {Object} opt_params Query parameters to include in the request.
- * @return {String} The base url plus any query params plus any OAuth params.
- */
-ChromeExOAuth.prototype.signURL = function(url, method, opt_params) {
- var token = this.getToken();
- var secret = this.getTokenSecret();
- if (!token || !secret) {
- throw new Error("No oauth token or token secret");
- }
-
- var params = opt_params || {};
-
- var result = OAuthSimple().sign({
- action : method,
- path : url,
- parameters : params,
- signatures: {
- consumer_key : this.consumer_key,
- shared_secret : this.consumer_secret,
- oauth_secret : secret,
- oauth_token: token
- }
- });
-
- return result.signed_url;
-};
-
-/**
- * Generates the Authorization header based on the oauth parameters.
- * @param {String} url The base url of the resource you are querying.
- * @param {Object} opt_params Query parameters to include in the request.
- * @return {String} An Authorization header containing the oauth_* params.
- */
-ChromeExOAuth.prototype.getAuthorizationHeader = function(url, method,
- opt_params) {
- var token = this.getToken();
- var secret = this.getTokenSecret();
- if (!token || !secret) {
- throw new Error("No oauth token or token secret");
- }
-
- var params = opt_params || {};
-
- return OAuthSimple().getHeaderString({
- action: method,
- path : url,
- parameters : params,
- signatures: {
- consumer_key : this.consumer_key,
- shared_secret : this.consumer_secret,
- oauth_secret : secret,
- oauth_token: token
- }
- });
-};
-
-/*******************************************************************************
- * PRIVATE API METHODS
- * Used by the library. There should be no need to call these methods directly.
- ******************************************************************************/
-
-/**
- * Creates a new ChromeExOAuth object from the supplied configuration object.
- * @param {Object} oauth_config Configuration parameters in a JavaScript object.
- * The following parameters are recognized:
- * "request_url" {String} OAuth request token URL.
- * "authorize_url" {String} OAuth authorize token URL.
- * "access_url" {String} OAuth access token URL.
- * "consumer_key" {String} OAuth consumer key.
- * "consumer_secret" {String} OAuth consumer secret.
- * "scope" {String} OAuth access scope.
- * "app_name" {String} Application name.
- * "auth_params" {Object} Additional parameters to pass to the
- * Authorization token URL. For an example, 'hd', 'hl', 'btmpl':
- * http://code.google.com/apis/accounts/docs/OAuth_ref.html#GetAuth
- * @return {ChromeExOAuth} An initialized ChromeExOAuth object.
- */
-ChromeExOAuth.fromConfig = function(oauth_config) {
- return new ChromeExOAuth(
- oauth_config['request_url'],
- oauth_config['authorize_url'],
- oauth_config['access_url'],
- oauth_config['consumer_key'],
- oauth_config['consumer_secret'],
- oauth_config['scope'],
- {
- 'app_name' : oauth_config['app_name'],
- 'auth_params' : oauth_config['auth_params']
- }
- );
-};
-
-/**
- * Initializes chrome_ex_oauth.html and redirects the page if needed to start
- * the OAuth flow. Once an access token is obtained, this function closes
- * chrome_ex_oauth.html.
- */
-ChromeExOAuth.initCallbackPage = function() {
- var background_page = chrome.extension.getBackgroundPage();
- var oauth_config = background_page.chromeExOAuthConfig;
- var oauth = ChromeExOAuth.fromConfig(oauth_config);
- background_page.chromeExOAuthRedirectStarted = true;
- oauth.initOAuthFlow(function (token, secret) {
- background_page.chromeExOAuthOnAuthorize(token, secret);
- background_page.chromeExOAuthRedirectStarted = false;
- chrome.tabs.query({active: true, currentWindow: true}, function (tabs) {
- chrome.tabs.remove(tabs[0].id);
- });
- });
-};
-
-/**
- * Sends an HTTP request. Convenience wrapper for XMLHttpRequest calls.
- * @param {String} method The HTTP method to use.
- * @param {String} url The URL to send the request to.
- * @param {Object} headers Optional request headers in key/value format.
- * @param {String} body Optional body content.
- * @param {Function} callback Function to call when the XMLHttpRequest's
- * ready state changes. See documentation for XMLHttpRequest's
- * onreadystatechange handler for more information.
- */
-ChromeExOAuth.sendRequest = function(method, url, headers, body, callback) {
- var xhr = new XMLHttpRequest();
- xhr.onreadystatechange = function(data) {
- callback(xhr, data);
- }
- xhr.open(method, url, true);
- if (headers) {
- for (var header in headers) {
- if (headers.hasOwnProperty(header)) {
- xhr.setRequestHeader(header, headers[header]);
- }
- }
- }
- xhr.send(body);
-};
-
-/**
- * Decodes a URL-encoded string into key/value pairs.
- * @param {String} encoded An URL-encoded string.
- * @return {Object} An object representing the decoded key/value pairs found
- * in the encoded string.
- */
-ChromeExOAuth.formDecode = function(encoded) {
- var params = encoded.split("&");
- var decoded = {};
- for (var i = 0, param; param = params[i]; i++) {
- var keyval = param.split("=");
- if (keyval.length == 2) {
- var key = ChromeExOAuth.fromRfc3986(keyval[0]);
- var val = ChromeExOAuth.fromRfc3986(keyval[1]);
- decoded[key] = val;
- }
- }
- return decoded;
-};
-
-/**
- * Returns the current window's querystring decoded into key/value pairs.
- * @return {Object} A object representing any key/value pairs found in the
- * current window's querystring.
- */
-ChromeExOAuth.getQueryStringParams = function() {
- var urlparts = window.location.href.split("?");
- if (urlparts.length >= 2) {
- var querystring = urlparts.slice(1).join("?");
- return ChromeExOAuth.formDecode(querystring);
- }
- return {};
-};
-
-/**
- * Binds a function call to a specific object. This function will also take
- * a variable number of additional arguments which will be prepended to the
- * arguments passed to the bound function when it is called.
- * @param {Function} func The function to bind.
- * @param {Object} obj The object to bind to the function's "this".
- * @return {Function} A closure that will call the bound function.
- */
-ChromeExOAuth.bind = function(func, obj) {
- var newargs = Array.prototype.slice.call(arguments).slice(2);
- return function() {
- var combinedargs = newargs.concat(Array.prototype.slice.call(arguments));
- func.apply(obj, combinedargs);
- };
-};
-
-/**
- * Encodes a value according to the RFC3986 specification.
- * @param {String} val The string to encode.
- */
-ChromeExOAuth.toRfc3986 = function(val){
- return encodeURIComponent(val)
- .replace(/\!/g, "%21")
- .replace(/\*/g, "%2A")
- .replace(/'/g, "%27")
- .replace(/\(/g, "%28")
- .replace(/\)/g, "%29");
-};
-
-/**
- * Decodes a string that has been encoded according to RFC3986.
- * @param {String} val The string to decode.
- */
-ChromeExOAuth.fromRfc3986 = function(val){
- var tmp = val
- .replace(/%21/g, "!")
- .replace(/%2A/g, "*")
- .replace(/%27/g, "'")
- .replace(/%28/g, "(")
- .replace(/%29/g, ")");
- return decodeURIComponent(tmp);
-};
-
-/**
- * Adds a key/value parameter to the supplied URL.
- * @param {String} url An URL which may or may not contain querystring values.
- * @param {String} key A key
- * @param {String} value A value
- * @return {String} The URL with URL-encoded versions of the key and value
- * appended, prefixing them with "&" or "?" as needed.
- */
-ChromeExOAuth.addURLParam = function(url, key, value) {
- var sep = (url.indexOf('?') >= 0) ? "&" : "?";
- return url + sep +
- ChromeExOAuth.toRfc3986(key) + "=" + ChromeExOAuth.toRfc3986(value);
-};
-
-/**
- * Stores an OAuth token for the configured scope.
- * @param {String} token The token to store.
- */
-ChromeExOAuth.prototype.setToken = function(token) {
- localStorage[this.key_token + encodeURI(this.oauth_scope)] = token;
-};
-
-/**
- * Retrieves any stored token for the configured scope.
- * @return {String} The stored token.
- */
-ChromeExOAuth.prototype.getToken = function() {
- return localStorage[this.key_token + encodeURI(this.oauth_scope)];
-};
-
-/**
- * Stores an OAuth token secret for the configured scope.
- * @param {String} secret The secret to store.
- */
-ChromeExOAuth.prototype.setTokenSecret = function(secret) {
- localStorage[this.key_token_secret + encodeURI(this.oauth_scope)] = secret;
-};
-
-/**
- * Retrieves any stored secret for the configured scope.
- * @return {String} The stored secret.
- */
-ChromeExOAuth.prototype.getTokenSecret = function() {
- return localStorage[this.key_token_secret + encodeURI(this.oauth_scope)];
-};
-
-/**
- * Starts an OAuth authorization flow for the current page. If a token exists,
- * no redirect is needed and the supplied callback is called immediately.
- * If this method detects that a redirect has finished, it grabs the
- * appropriate OAuth parameters from the URL and attempts to retrieve an
- * access token. If no token exists and no redirect has happened, then
- * an access token is requested and the page is ultimately redirected.
- * @param {Function} callback The function to call once the flow has finished.
- * This callback will be passed the following arguments:
- * token {String} The OAuth access token.
- * secret {String} The OAuth access token secret.
- */
-ChromeExOAuth.prototype.initOAuthFlow = function(callback) {
- if (!this.hasToken()) {
- var params = ChromeExOAuth.getQueryStringParams();
- if (params['chromeexoauthcallback'] == 'true') {
- var oauth_token = params['oauth_token'];
- var oauth_verifier = params['oauth_verifier']
- this.getAccessToken(oauth_token, oauth_verifier, callback);
- } else {
- var request_params = {
- 'url_callback_param' : 'chromeexoauthcallback'
- }
- this.getRequestToken(function(url) {
- window.location.href = url;
- }, request_params);
- }
- } else {
- callback(this.getToken(), this.getTokenSecret());
- }
-};
-
-/**
- * Requests an OAuth request token.
- * @param {Function} callback Function to call once the authorize URL is
- * calculated. This callback will be passed the following arguments:
- * url {String} The URL the user must be redirected to in order to
- * approve the token.
- * @param {Object} opt_args Optional arguments. The following parameters
- * are accepted:
- * "url_callback" {String} The URL the OAuth provider will redirect to.
- * "url_callback_param" {String} A parameter to include in the callback
- * URL in order to indicate to this library that a redirect has
- * taken place.
- */
-ChromeExOAuth.prototype.getRequestToken = function(callback, opt_args) {
- if (typeof callback !== "function") {
- throw new Error("Specified callback must be a function.");
- }
- var url = opt_args && opt_args['url_callback'] ||
- window && window.top && window.top.location &&
- window.top.location.href;
-
- var url_param = opt_args && opt_args['url_callback_param'] ||
- "chromeexoauthcallback";
- var url_callback = ChromeExOAuth.addURLParam(url, url_param, "true");
-
- var result = OAuthSimple().sign({
- path : this.url_request_token,
- parameters: {
- "xoauth_displayname" : this.app_name,
- "scope" : this.oauth_scope,
- "oauth_callback" : url_callback
- },
- signatures: {
- consumer_key : this.consumer_key,
- shared_secret : this.consumer_secret
- }
- });
- var onToken = ChromeExOAuth.bind(this.onRequestToken, this, callback);
- ChromeExOAuth.sendRequest("GET", result.signed_url, null, null, onToken);
-};
-
-/**
- * Called when a request token has been returned. Stores the request token
- * secret for later use and sends the authorization url to the supplied
- * callback (for redirecting the user).
- * @param {Function} callback Function to call once the authorize URL is
- * calculated. This callback will be passed the following arguments:
- * url {String} The URL the user must be redirected to in order to
- * approve the token.
- * @param {XMLHttpRequest} xhr The XMLHttpRequest object used to fetch the
- * request token.
- */
-ChromeExOAuth.prototype.onRequestToken = function(callback, xhr) {
- if (xhr.readyState == 4) {
- if (xhr.status == 200) {
- var params = ChromeExOAuth.formDecode(xhr.responseText);
- var token = params['oauth_token'];
- this.setTokenSecret(params['oauth_token_secret']);
- var url = ChromeExOAuth.addURLParam(this.url_auth_token,
- "oauth_token", token);
- for (var key in this.auth_params) {
- if (this.auth_params.hasOwnProperty(key)) {
- url = ChromeExOAuth.addURLParam(url, key, this.auth_params[key]);
- }
- }
- callback(url);
- } else {
- throw new Error("Fetching request token failed. Status " + xhr.status);
- }
- }
-};
-
-/**
- * Requests an OAuth access token.
- * @param {String} oauth_token The OAuth request token.
- * @param {String} oauth_verifier The OAuth token verifier.
- * @param {Function} callback The function to call once the token is obtained.
- * This callback will be passed the following arguments:
- * token {String} The OAuth access token.
- * secret {String} The OAuth access token secret.
- */
-ChromeExOAuth.prototype.getAccessToken = function(oauth_token, oauth_verifier,
- callback) {
- if (typeof callback !== "function") {
- throw new Error("Specified callback must be a function.");
- }
- var bg = chrome.extension.getBackgroundPage();
- if (bg.chromeExOAuthRequestingAccess == false) {
- bg.chromeExOAuthRequestingAccess = true;
-
- var result = OAuthSimple().sign({
- path : this.url_access_token,
- parameters: {
- "oauth_token" : oauth_token,
- "oauth_verifier" : oauth_verifier
- },
- signatures: {
- consumer_key : this.consumer_key,
- shared_secret : this.consumer_secret,
- oauth_secret : this.getTokenSecret(this.oauth_scope)
- }
- });
-
- var onToken = ChromeExOAuth.bind(this.onAccessToken, this, callback);
- ChromeExOAuth.sendRequest("GET", result.signed_url, null, null, onToken);
- }
-};
-
-/**
- * Called when an access token has been returned. Stores the access token and
- * access token secret for later use and sends them to the supplied callback.
- * @param {Function} callback The function to call once the token is obtained.
- * This callback will be passed the following arguments:
- * token {String} The OAuth access token.
- * secret {String} The OAuth access token secret.
- * @param {XMLHttpRequest} xhr The XMLHttpRequest object used to fetch the
- * access token.
- */
-ChromeExOAuth.prototype.onAccessToken = function(callback, xhr) {
- if (xhr.readyState == 4) {
- var bg = chrome.extension.getBackgroundPage();
- if (xhr.status == 200) {
- var params = ChromeExOAuth.formDecode(xhr.responseText);
- var token = params["oauth_token"];
- var secret = params["oauth_token_secret"];
- this.setToken(token);
- this.setTokenSecret(secret);
- bg.chromeExOAuthRequestingAccess = false;
- callback(token, secret);
- } else {
- bg.chromeExOAuthRequestingAccess = false;
- throw new Error("Fetching access token failed with status " + xhr.status);
- }
- }
-};
-
diff --git a/chrome/common/extensions/docs/examples/extensions/gdocs/chrome_ex_oauthsimple.js b/chrome/common/extensions/docs/examples/extensions/gdocs/chrome_ex_oauthsimple.js
deleted file mode 100644
index af0fe8a..0000000
--- a/chrome/common/extensions/docs/examples/extensions/gdocs/chrome_ex_oauthsimple.js
+++ /dev/null
@@ -1,458 +0,0 @@
-/* OAuthSimple
- * A simpler version of OAuth
- *
- * author: jr conlin
- * mail: src@anticipatr.com
- * copyright: unitedHeroes.net
- * version: 1.0
- * url: http://unitedHeroes.net/OAuthSimple
- *
- * Copyright (c) 2009, unitedHeroes.net
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of the unitedHeroes.net nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY UNITEDHEROES.NET ''AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL UNITEDHEROES.NET BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-var OAuthSimple;
-
-if (OAuthSimple === undefined)
-{
- /* Simple OAuth
- *
- * This class only builds the OAuth elements, it does not do the actual
- * transmission or reception of the tokens. It does not validate elements
- * of the token. It is for client use only.
- *
- * api_key is the API key, also known as the OAuth consumer key
- * shared_secret is the shared secret (duh).
- *
- * Both the api_key and shared_secret are generally provided by the site
- * offering OAuth services. You need to specify them at object creation
- * because nobody <explative>ing uses OAuth without that minimal set of
- * signatures.
- *
- * If you want to use the higher order security that comes from the
- * OAuth token (sorry, I don't provide the functions to fetch that because
- * sites aren't horribly consistent about how they offer that), you need to
- * pass those in either with .setTokensAndSecrets() or as an argument to the
- * .sign() or .getHeaderString() functions.
- *
- * Example:
- <code>
- var oauthObject = OAuthSimple().sign({path:'http://example.com/rest/',
- parameters: 'foo=bar&gorp=banana',
- signatures:{
- api_key:'12345abcd',
- shared_secret:'xyz-5309'
- }});
- document.getElementById('someLink').href=oauthObject.signed_url;
- </code>
- *
- * that will sign as a "GET" using "SHA1-MAC" the url. If you need more than
- * that, read on, McDuff.
- */
-
- /** OAuthSimple creator
- *
- * Create an instance of OAuthSimple
- *
- * @param api_key {string} The API Key (sometimes referred to as the consumer key) This value is usually supplied by the site you wish to use.
- * @param shared_secret (string) The shared secret. This value is also usually provided by the site you wish to use.
- */
- OAuthSimple = function (consumer_key,shared_secret)
- {
-/* if (api_key == undefined)
- throw("Missing argument: api_key (oauth_consumer_key) for OAuthSimple. This is usually provided by the hosting site.");
- if (shared_secret == undefined)
- throw("Missing argument: shared_secret (shared secret) for OAuthSimple. This is usually provided by the hosting site.");
-*/ this._secrets={};
- this._parameters={};
-
- // General configuration options.
- if (consumer_key !== undefined) {
- this._secrets['consumer_key'] = consumer_key;
- }
- if (shared_secret !== undefined) {
- this._secrets['shared_secret'] = shared_secret;
- }
- this._default_signature_method= "HMAC-SHA1";
- this._action = "GET";
- this._nonce_chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
-
-
- this.reset = function() {
- this._parameters={};
- this._path=undefined;
- return this;
- };
-
- /** set the parameters either from a hash or a string
- *
- * @param {string,object} List of parameters for the call, this can either be a URI string (e.g. "foo=bar&gorp=banana" or an object/hash)
- */
- this.setParameters = function (parameters) {
- if (parameters === undefined) {
- parameters = {};
- }
- if (typeof(parameters) == 'string') {
- parameters=this._parseParameterString(parameters);
- }
- this._parameters = parameters;
- if (this._parameters['oauth_nonce'] === undefined) {
- this._getNonce();
- }
- if (this._parameters['oauth_timestamp'] === undefined) {
- this._getTimestamp();
- }
- if (this._parameters['oauth_method'] === undefined) {
- this.setSignatureMethod();
- }
- if (this._parameters['oauth_consumer_key'] === undefined) {
- this._getApiKey();
- }
- if(this._parameters['oauth_token'] === undefined) {
- this._getAccessToken();
- }
-
- return this;
- };
-
- /** convienence method for setParameters
- *
- * @param parameters {string,object} See .setParameters
- */
- this.setQueryString = function (parameters) {
- return this.setParameters(parameters);
- };
-
- /** Set the target URL (does not include the parameters)
- *
- * @param path {string} the fully qualified URI (excluding query arguments) (e.g "http://example.org/foo")
- */
- this.setURL = function (path) {
- if (path == '') {
- throw ('No path specified for OAuthSimple.setURL');
- }
- this._path = path;
- return this;
- };
-
- /** convienence method for setURL
- *
- * @param path {string} see .setURL
- */
- this.setPath = function(path){
- return this.setURL(path);
- };
-
- /** set the "action" for the url, (e.g. GET,POST, DELETE, etc.)
- *
- * @param action {string} HTTP Action word.
- */
- this.setAction = function(action) {
- if (action === undefined) {
- action="GET";
- }
- action = action.toUpperCase();
- if (action.match('[^A-Z]')) {
- throw ('Invalid action specified for OAuthSimple.setAction');
- }
- this._action = action;
- return this;
- };
-
- /** set the signatures (as well as validate the ones you have)
- *
- * @param signatures {object} object/hash of the token/signature pairs {api_key:, shared_secret:, oauth_token: oauth_secret:}
- */
- this.setTokensAndSecrets = function(signatures) {
- if (signatures)
- {
- for (var i in signatures) {
- this._secrets[i] = signatures[i];
- }
- }
- // Aliases
- if (this._secrets['api_key']) {
- this._secrets.consumer_key = this._secrets.api_key;
- }
- if (this._secrets['access_token']) {
- this._secrets.oauth_token = this._secrets.access_token;
- }
- if (this._secrets['access_secret']) {
- this._secrets.oauth_secret = this._secrets.access_secret;
- }
- // Gauntlet
- if (this._secrets.consumer_key === undefined) {
- throw('Missing required consumer_key in OAuthSimple.setTokensAndSecrets');
- }
- if (this._secrets.shared_secret === undefined) {
- throw('Missing required shared_secret in OAuthSimple.setTokensAndSecrets');
- }
- if ((this._secrets.oauth_token !== undefined) && (this._secrets.oauth_secret === undefined)) {
- throw('Missing oauth_secret for supplied oauth_token in OAuthSimple.setTokensAndSecrets');
- }
- return this;
- };
-
- /** set the signature method (currently only Plaintext or SHA-MAC1)
- *
- * @param method {string} Method of signing the transaction (only PLAINTEXT and SHA-MAC1 allowed for now)
- */
- this.setSignatureMethod = function(method) {
- if (method === undefined) {
- method = this._default_signature_method;
- }
- //TODO: accept things other than PlainText or SHA-MAC1
- if (method.toUpperCase().match(/(PLAINTEXT|HMAC-SHA1)/) === undefined) {
- throw ('Unknown signing method specified for OAuthSimple.setSignatureMethod');
- }
- this._parameters['oauth_signature_method']= method.toUpperCase();
- return this;
- };
-
- /** sign the request
- *
- * note: all arguments are optional, provided you've set them using the
- * other helper functions.
- *
- * @param args {object} hash of arguments for the call
- * {action:, path:, parameters:, method:, signatures:}
- * all arguments are optional.
- */
- this.sign = function (args) {
- if (args === undefined) {
- args = {};
- }
- // Set any given parameters
- if(args['action'] !== undefined) {
- this.setAction(args['action']);
- }
- if (args['path'] !== undefined) {
- this.setPath(args['path']);
- }
- if (args['method'] !== undefined) {
- this.setSignatureMethod(args['method']);
- }
- this.setTokensAndSecrets(args['signatures']);
- if (args['parameters'] !== undefined){
- this.setParameters(args['parameters']);
- }
- // check the parameters
- var normParams = this._normalizedParameters();
- this._parameters['oauth_signature']=this._generateSignature(normParams);
- return {
- parameters: this._parameters,
- signature: this._oauthEscape(this._parameters['oauth_signature']),
- signed_url: this._path + '?' + this._normalizedParameters(),
- header: this.getHeaderString()
- };
- };
-
- /** Return a formatted "header" string
- *
- * NOTE: This doesn't set the "Authorization: " prefix, which is required.
- * I don't set it because various set header functions prefer different
- * ways to do that.
- *
- * @param args {object} see .sign
- */
- this.getHeaderString = function(args) {
- if (this._parameters['oauth_signature'] === undefined) {
- this.sign(args);
- }
-
- var result = 'OAuth ';
- for (var pName in this._parameters)
- {
- if (!pName.match(/^oauth/)) {
- continue;
- }
- if ((this._parameters[pName]) instanceof Array)
- {
- var pLength = this._parameters[pName].length;
- for (var j=0;j<pLength;j++)
- {
- result += pName +'="'+this._oauthEscape(this._parameters[pName][j])+'" ';
- }
- }
- else
- {
- result += pName + '="'+this._oauthEscape(this._parameters[pName])+'" ';
- }
- }
- return result;
- };
-
- // Start Private Methods.
-
- /** convert the parameter string into a hash of objects.
- *
- */
- this._parseParameterString = function(paramString){
- var elements = paramString.split('&');
- var result={};
- for(var element=elements.shift();element;element=elements.shift())
- {
- var keyToken=element.split('=');
- var value='';
- if (keyToken[1]) {
- value=decodeURIComponent(keyToken[1]);
- }
- if(result[keyToken[0]]){
- if (!(result[keyToken[0]] instanceof Array))
- {
- result[keyToken[0]] = Array(result[keyToken[0]],value);
- }
- else
- {
- result[keyToken[0]].push(value);
- }
- }
- else
- {
- result[keyToken[0]]=value;
- }
- }
- return result;
- };
-
- this._oauthEscape = function(string) {
- if (string === undefined) {
- return "";
- }
- if (string instanceof Array)
- {
- throw('Array passed to _oauthEscape');
- }
- return encodeURIComponent(string).replace(/\!/g, "%21").
- replace(/\*/g, "%2A").
- replace(/'/g, "%27").
- replace(/\(/g, "%28").
- replace(/\)/g, "%29");
- };
-
- this._getNonce = function (length) {
- if (length === undefined) {
- length=5;
- }
- var result = "";
- var cLength = this._nonce_chars.length;
- for (var i = 0; i < length;i++) {
- var rnum = Math.floor(Math.random() *cLength);
- result += this._nonce_chars.substring(rnum,rnum+1);
- }
- this._parameters['oauth_nonce']=result;
- return result;
- };
-
- this._getApiKey = function() {
- if (this._secrets.consumer_key === undefined) {
- throw('No consumer_key set for OAuthSimple.');
- }
- this._parameters['oauth_consumer_key']=this._secrets.consumer_key;
- return this._parameters.oauth_consumer_key;
- };
-
- this._getAccessToken = function() {
- if (this._secrets['oauth_secret'] === undefined) {
- return '';
- }
- if (this._secrets['oauth_token'] === undefined) {
- throw('No oauth_token (access_token) set for OAuthSimple.');
- }
- this._parameters['oauth_token'] = this._secrets.oauth_token;
- return this._parameters.oauth_token;
- };
-
- this._getTimestamp = function() {
- var d = new Date();
- var ts = Math.floor(d.getTime()/1000);
- this._parameters['oauth_timestamp'] = ts;
- return ts;
- };
-
- this.b64_hmac_sha1 = function(k,d,_p,_z){
- // heavily optimized and compressed version of http://pajhome.org.uk/crypt/md5/sha1.js
- // _p = b64pad, _z = character size; not used here but I left them available just in case
- if(!_p){_p='=';}if(!_z){_z=8;}function _f(t,b,c,d){if(t<20){return(b&c)|((~b)&d);}if(t<40){return b^c^d;}if(t<60){return(b&c)|(b&d)|(c&d);}return b^c^d;}function _k(t){return(t<20)?1518500249:(t<40)?1859775393:(t<60)?-1894007588:-899497514;}function _s(x,y){var l=(x&0xFFFF)+(y&0xFFFF),m=(x>>16)+(y>>16)+(l>>16);return(m<<16)|(l&0xFFFF);}function _r(n,c){return(n<<c)|(n>>>(32-c));}function _c(x,l){x[l>>5]|=0x80<<(24-l%32);x[((l+64>>9)<<4)+15]=l;var w=[80],a=1732584193,b=-271733879,c=-1732584194,d=271733878,e=-1009589776;for(var i=0;i<x.length;i+=16){var o=a,p=b,q=c,r=d,s=e;for(var j=0;j<80;j++){if(j<16){w[j]=x[i+j];}else{w[j]=_r(w[j-3]^w[j-8]^w[j-14]^w[j-16],1);}var t=_s(_s(_r(a,5),_f(j,b,c,d)),_s(_s(e,w[j]),_k(j)));e=d;d=c;c=_r(b,30);b=a;a=t;}a=_s(a,o);b=_s(b,p);c=_s(c,q);d=_s(d,r);e=_s(e,s);}return[a,b,c,d,e];}function _b(s){var b=[],m=(1<<_z)-1;for(var i=0;i<s.length*_z;i+=_z){b[i>>5]|=(s.charCodeAt(i/8)&m)<<(32-_z-i%32);}return b;}function _h(k,d){var b=_b(k);if(b.length>16){b=_c(b,k.length*_z);}var p=[16],o=[16];for(var i=0;i<16;i++){p[i]=b[i]^0x36363636;o[i]=b[i]^0x5C5C5C5C;}var h=_c(p.concat(_b(d)),512+d.length*_z);return _c(o.concat(h),512+160);}function _n(b){var t="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",s='';for(var i=0;i<b.length*4;i+=3){var r=(((b[i>>2]>>8*(3-i%4))&0xFF)<<16)|(((b[i+1>>2]>>8*(3-(i+1)%4))&0xFF)<<8)|((b[i+2>>2]>>8*(3-(i+2)%4))&0xFF);for(var j=0;j<4;j++){if(i*8+j*6>b.length*32){s+=_p;}else{s+=t.charAt((r>>6*(3-j))&0x3F);}}}return s;}function _x(k,d){return _n(_h(k,d));}return _x(k,d);
- }
-
-
- this._normalizedParameters = function() {
- var elements = new Array();
- var paramNames = [];
- var ra =0;
- for (var paramName in this._parameters)
- {
- if (ra++ > 1000) {
- throw('runaway 1');
- }
- paramNames.unshift(paramName);
- }
- paramNames = paramNames.sort();
- pLen = paramNames.length;
- for (var i=0;i<pLen; i++)
- {
- paramName=paramNames[i];
- //skip secrets.
- if (paramName.match(/\w+_secret/)) {
- continue;
- }
- if (this._parameters[paramName] instanceof Array)
- {
- var sorted = this._parameters[paramName].sort();
- var spLen = sorted.length;
- for (var j = 0;j<spLen;j++){
- if (ra++ > 1000) {
- throw('runaway 1');
- }
- elements.push(this._oauthEscape(paramName) + '=' +
- this._oauthEscape(sorted[j]));
- }
- continue;
- }
- elements.push(this._oauthEscape(paramName) + '=' +
- this._oauthEscape(this._parameters[paramName]));
- }
- return elements.join('&');
- };
-
- this._generateSignature = function() {
-
- var secretKey = this._oauthEscape(this._secrets.shared_secret)+'&'+
- this._oauthEscape(this._secrets.oauth_secret);
- if (this._parameters['oauth_signature_method'] == 'PLAINTEXT')
- {
- return secretKey;
- }
- if (this._parameters['oauth_signature_method'] == 'HMAC-SHA1')
- {
- var sigString = this._oauthEscape(this._action)+'&'+this._oauthEscape(this._path)+'&'+this._oauthEscape(this._normalizedParameters());
- return this.b64_hmac_sha1(secretKey,sigString);
- }
- return null;
- };
-
- return this;
- };
-}
diff --git a/chrome/common/extensions/docs/examples/extensions/gdocs/img/docs_spreadsheets-128.gif b/chrome/common/extensions/docs/examples/extensions/gdocs/img/docs_spreadsheets-128.gif
deleted file mode 100644
index e85c4fd..0000000
--- a/chrome/common/extensions/docs/examples/extensions/gdocs/img/docs_spreadsheets-128.gif
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/gdocs/img/docs_spreadsheets-32.gif b/chrome/common/extensions/docs/examples/extensions/gdocs/img/docs_spreadsheets-32.gif
deleted file mode 100644
index da38b31..0000000
--- a/chrome/common/extensions/docs/examples/extensions/gdocs/img/docs_spreadsheets-32.gif
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/gdocs/img/docs_spreadsheets-48.gif b/chrome/common/extensions/docs/examples/extensions/gdocs/img/docs_spreadsheets-48.gif
deleted file mode 100644
index dd54d63..0000000
--- a/chrome/common/extensions/docs/examples/extensions/gdocs/img/docs_spreadsheets-48.gif
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/gdocs/img/icons/audio.gif b/chrome/common/extensions/docs/examples/extensions/gdocs/img/icons/audio.gif
deleted file mode 100644
index 997d82d..0000000
--- a/chrome/common/extensions/docs/examples/extensions/gdocs/img/icons/audio.gif
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/gdocs/img/icons/document.gif b/chrome/common/extensions/docs/examples/extensions/gdocs/img/icons/document.gif
deleted file mode 100644
index f202ab19..0000000
--- a/chrome/common/extensions/docs/examples/extensions/gdocs/img/icons/document.gif
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/gdocs/img/icons/file.gif b/chrome/common/extensions/docs/examples/extensions/gdocs/img/icons/file.gif
deleted file mode 100644
index 9374dd2..0000000
--- a/chrome/common/extensions/docs/examples/extensions/gdocs/img/icons/file.gif
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/gdocs/img/icons/folder.gif b/chrome/common/extensions/docs/examples/extensions/gdocs/img/icons/folder.gif
deleted file mode 100644
index f6bc4f1..0000000
--- a/chrome/common/extensions/docs/examples/extensions/gdocs/img/icons/folder.gif
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/gdocs/img/icons/form.gif b/chrome/common/extensions/docs/examples/extensions/gdocs/img/icons/form.gif
deleted file mode 100644
index e7b521d..0000000
--- a/chrome/common/extensions/docs/examples/extensions/gdocs/img/icons/form.gif
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/gdocs/img/icons/pdf.gif b/chrome/common/extensions/docs/examples/extensions/gdocs/img/icons/pdf.gif
deleted file mode 100644
index 136eb0b..0000000
--- a/chrome/common/extensions/docs/examples/extensions/gdocs/img/icons/pdf.gif
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/gdocs/img/icons/presentation.gif b/chrome/common/extensions/docs/examples/extensions/gdocs/img/icons/presentation.gif
deleted file mode 100644
index cede720..0000000
--- a/chrome/common/extensions/docs/examples/extensions/gdocs/img/icons/presentation.gif
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/gdocs/img/icons/spreadsheet.gif b/chrome/common/extensions/docs/examples/extensions/gdocs/img/icons/spreadsheet.gif
deleted file mode 100644
index ec3954f6..0000000
--- a/chrome/common/extensions/docs/examples/extensions/gdocs/img/icons/spreadsheet.gif
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/gdocs/js/jquery-1.4.1.min.js b/chrome/common/extensions/docs/examples/extensions/gdocs/js/jquery-1.4.1.min.js
deleted file mode 100644
index 0c7294c9..0000000
--- a/chrome/common/extensions/docs/examples/extensions/gdocs/js/jquery-1.4.1.min.js
+++ /dev/null
@@ -1,152 +0,0 @@
-/*!
- * jQuery JavaScript Library v1.4.1
- * http://jquery.com/
- *
- * Copyright 2010, John Resig
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * Includes Sizzle.js
- * http://sizzlejs.com/
- * Copyright 2010, The Dojo Foundation
- * Released under the MIT, BSD, and GPL Licenses.
- *
- * Date: Mon Jan 25 19:43:33 2010 -0500
- */
-(function(z,v){function la(){if(!c.isReady){try{r.documentElement.doScroll("left")}catch(a){setTimeout(la,1);return}c.ready()}}function Ma(a,b){b.src?c.ajax({url:b.src,async:false,dataType:"script"}):c.globalEval(b.text||b.textContent||b.innerHTML||"");b.parentNode&&b.parentNode.removeChild(b)}function X(a,b,d,f,e,i){var j=a.length;if(typeof b==="object"){for(var n in b)X(a,n,b[n],f,e,d);return a}if(d!==v){f=!i&&f&&c.isFunction(d);for(n=0;n<j;n++)e(a[n],b,f?d.call(a[n],n,e(a[n],b)):d,i);return a}return j?
-e(a[0],b):null}function J(){return(new Date).getTime()}function Y(){return false}function Z(){return true}function ma(a,b,d){d[0].type=a;return c.event.handle.apply(b,d)}function na(a){var b,d=[],f=[],e=arguments,i,j,n,o,m,s,x=c.extend({},c.data(this,"events").live);if(!(a.button&&a.type==="click")){for(o in x){j=x[o];if(j.live===a.type||j.altLive&&c.inArray(a.type,j.altLive)>-1){i=j.data;i.beforeFilter&&i.beforeFilter[a.type]&&!i.beforeFilter[a.type](a)||f.push(j.selector)}else delete x[o]}i=c(a.target).closest(f,
-a.currentTarget);m=0;for(s=i.length;m<s;m++)for(o in x){j=x[o];n=i[m].elem;f=null;if(i[m].selector===j.selector){if(j.live==="mouseenter"||j.live==="mouseleave")f=c(a.relatedTarget).closest(j.selector)[0];if(!f||f!==n)d.push({elem:n,fn:j})}}m=0;for(s=d.length;m<s;m++){i=d[m];a.currentTarget=i.elem;a.data=i.fn.data;if(i.fn.apply(i.elem,e)===false){b=false;break}}return b}}function oa(a,b){return"live."+(a?a+".":"")+b.replace(/\./g,"`").replace(/ /g,"&")}function pa(a){return!a||!a.parentNode||a.parentNode.nodeType===
-11}function qa(a,b){var d=0;b.each(function(){if(this.nodeName===(a[d]&&a[d].nodeName)){var f=c.data(a[d++]),e=c.data(this,f);if(f=f&&f.events){delete e.handle;e.events={};for(var i in f)for(var j in f[i])c.event.add(this,i,f[i][j],f[i][j].data)}}})}function ra(a,b,d){var f,e,i;if(a.length===1&&typeof a[0]==="string"&&a[0].length<512&&a[0].indexOf("<option")<0&&(c.support.checkClone||!sa.test(a[0]))){e=true;if(i=c.fragments[a[0]])if(i!==1)f=i}if(!f){b=b&&b[0]?b[0].ownerDocument||b[0]:r;f=b.createDocumentFragment();
-c.clean(a,b,f,d)}if(e)c.fragments[a[0]]=i?f:1;return{fragment:f,cacheable:e}}function K(a,b){var d={};c.each(ta.concat.apply([],ta.slice(0,b)),function(){d[this]=a});return d}function ua(a){return"scrollTo"in a&&a.document?a:a.nodeType===9?a.defaultView||a.parentWindow:false}var c=function(a,b){return new c.fn.init(a,b)},Na=z.jQuery,Oa=z.$,r=z.document,S,Pa=/^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/,Qa=/^.[^:#\[\.,]*$/,Ra=/\S/,Sa=/^(\s|\u00A0)+|(\s|\u00A0)+$/g,Ta=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,O=navigator.userAgent,
-va=false,P=[],L,$=Object.prototype.toString,aa=Object.prototype.hasOwnProperty,ba=Array.prototype.push,Q=Array.prototype.slice,wa=Array.prototype.indexOf;c.fn=c.prototype={init:function(a,b){var d,f;if(!a)return this;if(a.nodeType){this.context=this[0]=a;this.length=1;return this}if(typeof a==="string")if((d=Pa.exec(a))&&(d[1]||!b))if(d[1]){f=b?b.ownerDocument||b:r;if(a=Ta.exec(a))if(c.isPlainObject(b)){a=[r.createElement(a[1])];c.fn.attr.call(a,b,true)}else a=[f.createElement(a[1])];else{a=ra([d[1]],
-[f]);a=(a.cacheable?a.fragment.cloneNode(true):a.fragment).childNodes}}else{if(b=r.getElementById(d[2])){if(b.id!==d[2])return S.find(a);this.length=1;this[0]=b}this.context=r;this.selector=a;return this}else if(!b&&/^\w+$/.test(a)){this.selector=a;this.context=r;a=r.getElementsByTagName(a)}else return!b||b.jquery?(b||S).find(a):c(b).find(a);else if(c.isFunction(a))return S.ready(a);if(a.selector!==v){this.selector=a.selector;this.context=a.context}return c.isArray(a)?this.setArray(a):c.makeArray(a,
-this)},selector:"",jquery:"1.4.1",length:0,size:function(){return this.length},toArray:function(){return Q.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this.slice(a)[0]:this[a]},pushStack:function(a,b,d){a=c(a||null);a.prevObject=this;a.context=this.context;if(b==="find")a.selector=this.selector+(this.selector?" ":"")+d;else if(b)a.selector=this.selector+"."+b+"("+d+")";return a},setArray:function(a){this.length=0;ba.apply(this,a);return this},each:function(a,b){return c.each(this,
-a,b)},ready:function(a){c.bindReady();if(c.isReady)a.call(r,c);else P&&P.push(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(Q.apply(this,arguments),"slice",Q.call(arguments).join(","))},map:function(a){return this.pushStack(c.map(this,function(b,d){return a.call(b,d,b)}))},end:function(){return this.prevObject||c(null)},push:ba,sort:[].sort,splice:[].splice};
-c.fn.init.prototype=c.fn;c.extend=c.fn.extend=function(){var a=arguments[0]||{},b=1,d=arguments.length,f=false,e,i,j,n;if(typeof a==="boolean"){f=a;a=arguments[1]||{};b=2}if(typeof a!=="object"&&!c.isFunction(a))a={};if(d===b){a=this;--b}for(;b<d;b++)if((e=arguments[b])!=null)for(i in e){j=a[i];n=e[i];if(a!==n)if(f&&n&&(c.isPlainObject(n)||c.isArray(n))){j=j&&(c.isPlainObject(j)||c.isArray(j))?j:c.isArray(n)?[]:{};a[i]=c.extend(f,j,n)}else if(n!==v)a[i]=n}return a};c.extend({noConflict:function(a){z.$=
-Oa;if(a)z.jQuery=Na;return c},isReady:false,ready:function(){if(!c.isReady){if(!r.body)return setTimeout(c.ready,13);c.isReady=true;if(P){for(var a,b=0;a=P[b++];)a.call(r,c);P=null}c.fn.triggerHandler&&c(r).triggerHandler("ready")}},bindReady:function(){if(!va){va=true;if(r.readyState==="complete")return c.ready();if(r.addEventListener){r.addEventListener("DOMContentLoaded",L,false);z.addEventListener("load",c.ready,false)}else if(r.attachEvent){r.attachEvent("onreadystatechange",L);z.attachEvent("onload",
-c.ready);var a=false;try{a=z.frameElement==null}catch(b){}r.documentElement.doScroll&&a&&la()}}},isFunction:function(a){return $.call(a)==="[object Function]"},isArray:function(a){return $.call(a)==="[object Array]"},isPlainObject:function(a){if(!a||$.call(a)!=="[object Object]"||a.nodeType||a.setInterval)return false;if(a.constructor&&!aa.call(a,"constructor")&&!aa.call(a.constructor.prototype,"isPrototypeOf"))return false;var b;for(b in a);return b===v||aa.call(a,b)},isEmptyObject:function(a){for(var b in a)return false;
-return true},error:function(a){throw a;},parseJSON:function(a){if(typeof a!=="string"||!a)return null;if(/^[\],:{}\s]*$/.test(a.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,"")))return z.JSON&&z.JSON.parse?z.JSON.parse(a):(new Function("return "+a))();else c.error("Invalid JSON: "+a)},noop:function(){},globalEval:function(a){if(a&&Ra.test(a)){var b=r.getElementsByTagName("head")[0]||
-r.documentElement,d=r.createElement("script");d.type="text/javascript";if(c.support.scriptEval)d.appendChild(r.createTextNode(a));else d.text=a;b.insertBefore(d,b.firstChild);b.removeChild(d)}},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,b,d){var f,e=0,i=a.length,j=i===v||c.isFunction(a);if(d)if(j)for(f in a){if(b.apply(a[f],d)===false)break}else for(;e<i;){if(b.apply(a[e++],d)===false)break}else if(j)for(f in a){if(b.call(a[f],f,a[f])===false)break}else for(d=
-a[0];e<i&&b.call(d,e,d)!==false;d=a[++e]);return a},trim:function(a){return(a||"").replace(Sa,"")},makeArray:function(a,b){b=b||[];if(a!=null)a.length==null||typeof a==="string"||c.isFunction(a)||typeof a!=="function"&&a.setInterval?ba.call(b,a):c.merge(b,a);return b},inArray:function(a,b){if(b.indexOf)return b.indexOf(a);for(var d=0,f=b.length;d<f;d++)if(b[d]===a)return d;return-1},merge:function(a,b){var d=a.length,f=0;if(typeof b.length==="number")for(var e=b.length;f<e;f++)a[d++]=b[f];else for(;b[f]!==
-v;)a[d++]=b[f++];a.length=d;return a},grep:function(a,b,d){for(var f=[],e=0,i=a.length;e<i;e++)!d!==!b(a[e],e)&&f.push(a[e]);return f},map:function(a,b,d){for(var f=[],e,i=0,j=a.length;i<j;i++){e=b(a[i],i,d);if(e!=null)f[f.length]=e}return f.concat.apply([],f)},guid:1,proxy:function(a,b,d){if(arguments.length===2)if(typeof b==="string"){d=a;a=d[b];b=v}else if(b&&!c.isFunction(b)){d=b;b=v}if(!b&&a)b=function(){return a.apply(d||this,arguments)};if(a)b.guid=a.guid=a.guid||b.guid||c.guid++;return b},
-uaMatch:function(a){a=a.toLowerCase();a=/(webkit)[ \/]([\w.]+)/.exec(a)||/(opera)(?:.*version)?[ \/]([\w.]+)/.exec(a)||/(msie) ([\w.]+)/.exec(a)||!/compatible/.test(a)&&/(mozilla)(?:.*? rv:([\w.]+))?/.exec(a)||[];return{browser:a[1]||"",version:a[2]||"0"}},browser:{}});O=c.uaMatch(O);if(O.browser){c.browser[O.browser]=true;c.browser.version=O.version}if(c.browser.webkit)c.browser.safari=true;if(wa)c.inArray=function(a,b){return wa.call(b,a)};S=c(r);if(r.addEventListener)L=function(){r.removeEventListener("DOMContentLoaded",
-L,false);c.ready()};else if(r.attachEvent)L=function(){if(r.readyState==="complete"){r.detachEvent("onreadystatechange",L);c.ready()}};(function(){c.support={};var a=r.documentElement,b=r.createElement("script"),d=r.createElement("div"),f="script"+J();d.style.display="none";d.innerHTML=" <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";var e=d.getElementsByTagName("*"),i=d.getElementsByTagName("a")[0];if(!(!e||!e.length||!i)){c.support=
-{leadingWhitespace:d.firstChild.nodeType===3,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/red/.test(i.getAttribute("style")),hrefNormalized:i.getAttribute("href")==="/a",opacity:/^0.55$/.test(i.style.opacity),cssFloat:!!i.style.cssFloat,checkOn:d.getElementsByTagName("input")[0].value==="on",optSelected:r.createElement("select").appendChild(r.createElement("option")).selected,checkClone:false,scriptEval:false,noCloneEvent:true,boxModel:null};
-b.type="text/javascript";try{b.appendChild(r.createTextNode("window."+f+"=1;"))}catch(j){}a.insertBefore(b,a.firstChild);if(z[f]){c.support.scriptEval=true;delete z[f]}a.removeChild(b);if(d.attachEvent&&d.fireEvent){d.attachEvent("onclick",function n(){c.support.noCloneEvent=false;d.detachEvent("onclick",n)});d.cloneNode(true).fireEvent("onclick")}d=r.createElement("div");d.innerHTML="<input type='radio' name='radiotest' checked='checked'/>";a=r.createDocumentFragment();a.appendChild(d.firstChild);
-c.support.checkClone=a.cloneNode(true).cloneNode(true).lastChild.checked;c(function(){var n=r.createElement("div");n.style.width=n.style.paddingLeft="1px";r.body.appendChild(n);c.boxModel=c.support.boxModel=n.offsetWidth===2;r.body.removeChild(n).style.display="none"});a=function(n){var o=r.createElement("div");n="on"+n;var m=n in o;if(!m){o.setAttribute(n,"return;");m=typeof o[n]==="function"}return m};c.support.submitBubbles=a("submit");c.support.changeBubbles=a("change");a=b=d=e=i=null}})();c.props=
-{"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",frameborder:"frameBorder"};var G="jQuery"+J(),Ua=0,xa={},Va={};c.extend({cache:{},expando:G,noData:{embed:true,object:true,applet:true},data:function(a,b,d){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==z?xa:a;var f=a[G],e=c.cache;if(!b&&!f)return null;f||(f=++Ua);if(typeof b==="object"){a[G]=f;e=e[f]=c.extend(true,
-{},b)}else e=e[f]?e[f]:typeof d==="undefined"?Va:(e[f]={});if(d!==v){a[G]=f;e[b]=d}return typeof b==="string"?e[b]:e}},removeData:function(a,b){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==z?xa:a;var d=a[G],f=c.cache,e=f[d];if(b){if(e){delete e[b];c.isEmptyObject(e)&&c.removeData(a)}}else{try{delete a[G]}catch(i){a.removeAttribute&&a.removeAttribute(G)}delete f[d]}}}});c.fn.extend({data:function(a,b){if(typeof a==="undefined"&&this.length)return c.data(this[0]);else if(typeof a==="object")return this.each(function(){c.data(this,
-a)});var d=a.split(".");d[1]=d[1]?"."+d[1]:"";if(b===v){var f=this.triggerHandler("getData"+d[1]+"!",[d[0]]);if(f===v&&this.length)f=c.data(this[0],a);return f===v&&d[1]?this.data(d[0]):f}else return this.trigger("setData"+d[1]+"!",[d[0],b]).each(function(){c.data(this,a,b)})},removeData:function(a){return this.each(function(){c.removeData(this,a)})}});c.extend({queue:function(a,b,d){if(a){b=(b||"fx")+"queue";var f=c.data(a,b);if(!d)return f||[];if(!f||c.isArray(d))f=c.data(a,b,c.makeArray(d));else f.push(d);
-return f}},dequeue:function(a,b){b=b||"fx";var d=c.queue(a,b),f=d.shift();if(f==="inprogress")f=d.shift();if(f){b==="fx"&&d.unshift("inprogress");f.call(a,function(){c.dequeue(a,b)})}}});c.fn.extend({queue:function(a,b){if(typeof a!=="string"){b=a;a="fx"}if(b===v)return c.queue(this[0],a);return this.each(function(){var d=c.queue(this,a,b);a==="fx"&&d[0]!=="inprogress"&&c.dequeue(this,a)})},dequeue:function(a){return this.each(function(){c.dequeue(this,a)})},delay:function(a,b){a=c.fx?c.fx.speeds[a]||
-a:a;b=b||"fx";return this.queue(b,function(){var d=this;setTimeout(function(){c.dequeue(d,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])}});var ya=/[\n\t]/g,ca=/\s+/,Wa=/\r/g,Xa=/href|src|style/,Ya=/(button|input)/i,Za=/(button|input|object|select|textarea)/i,$a=/^(a|area)$/i,za=/radio|checkbox/;c.fn.extend({attr:function(a,b){return X(this,a,b,true,c.attr)},removeAttr:function(a){return this.each(function(){c.attr(this,a,"");this.nodeType===1&&this.removeAttribute(a)})},addClass:function(a){if(c.isFunction(a))return this.each(function(o){var m=
-c(this);m.addClass(a.call(this,o,m.attr("class")))});if(a&&typeof a==="string")for(var b=(a||"").split(ca),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1)if(e.className)for(var i=" "+e.className+" ",j=0,n=b.length;j<n;j++){if(i.indexOf(" "+b[j]+" ")<0)e.className+=" "+b[j]}else e.className=a}return this},removeClass:function(a){if(c.isFunction(a))return this.each(function(o){var m=c(this);m.removeClass(a.call(this,o,m.attr("class")))});if(a&&typeof a==="string"||a===v)for(var b=(a||"").split(ca),
-d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1&&e.className)if(a){for(var i=(" "+e.className+" ").replace(ya," "),j=0,n=b.length;j<n;j++)i=i.replace(" "+b[j]+" "," ");e.className=i.substring(1,i.length-1)}else e.className=""}return this},toggleClass:function(a,b){var d=typeof a,f=typeof b==="boolean";if(c.isFunction(a))return this.each(function(e){var i=c(this);i.toggleClass(a.call(this,e,i.attr("class"),b),b)});return this.each(function(){if(d==="string")for(var e,i=0,j=c(this),n=b,o=
-a.split(ca);e=o[i++];){n=f?n:!j.hasClass(e);j[n?"addClass":"removeClass"](e)}else if(d==="undefined"||d==="boolean"){this.className&&c.data(this,"__className__",this.className);this.className=this.className||a===false?"":c.data(this,"__className__")||""}})},hasClass:function(a){a=" "+a+" ";for(var b=0,d=this.length;b<d;b++)if((" "+this[b].className+" ").replace(ya," ").indexOf(a)>-1)return true;return false},val:function(a){if(a===v){var b=this[0];if(b){if(c.nodeName(b,"option"))return(b.attributes.value||
-{}).specified?b.value:b.text;if(c.nodeName(b,"select")){var d=b.selectedIndex,f=[],e=b.options;b=b.type==="select-one";if(d<0)return null;var i=b?d:0;for(d=b?d+1:e.length;i<d;i++){var j=e[i];if(j.selected){a=c(j).val();if(b)return a;f.push(a)}}return f}if(za.test(b.type)&&!c.support.checkOn)return b.getAttribute("value")===null?"on":b.value;return(b.value||"").replace(Wa,"")}return v}var n=c.isFunction(a);return this.each(function(o){var m=c(this),s=a;if(this.nodeType===1){if(n)s=a.call(this,o,m.val());
-if(typeof s==="number")s+="";if(c.isArray(s)&&za.test(this.type))this.checked=c.inArray(m.val(),s)>=0;else if(c.nodeName(this,"select")){var x=c.makeArray(s);c("option",this).each(function(){this.selected=c.inArray(c(this).val(),x)>=0});if(!x.length)this.selectedIndex=-1}else this.value=s}})}});c.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(a,b,d,f){if(!a||a.nodeType===3||a.nodeType===8)return v;if(f&&b in c.attrFn)return c(a)[b](d);
-f=a.nodeType!==1||!c.isXMLDoc(a);var e=d!==v;b=f&&c.props[b]||b;if(a.nodeType===1){var i=Xa.test(b);if(b in a&&f&&!i){if(e){b==="type"&&Ya.test(a.nodeName)&&a.parentNode&&c.error("type property can't be changed");a[b]=d}if(c.nodeName(a,"form")&&a.getAttributeNode(b))return a.getAttributeNode(b).nodeValue;if(b==="tabIndex")return(b=a.getAttributeNode("tabIndex"))&&b.specified?b.value:Za.test(a.nodeName)||$a.test(a.nodeName)&&a.href?0:v;return a[b]}if(!c.support.style&&f&&b==="style"){if(e)a.style.cssText=
-""+d;return a.style.cssText}e&&a.setAttribute(b,""+d);a=!c.support.hrefNormalized&&f&&i?a.getAttribute(b,2):a.getAttribute(b);return a===null?v:a}return c.style(a,b,d)}});var ab=function(a){return a.replace(/[^\w\s\.\|`]/g,function(b){return"\\"+b})};c.event={add:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){if(a.setInterval&&a!==z&&!a.frameElement)a=z;if(!d.guid)d.guid=c.guid++;if(f!==v){d=c.proxy(d);d.data=f}var e=c.data(a,"events")||c.data(a,"events",{}),i=c.data(a,"handle"),j;if(!i){j=
-function(){return typeof c!=="undefined"&&!c.event.triggered?c.event.handle.apply(j.elem,arguments):v};i=c.data(a,"handle",j)}if(i){i.elem=a;b=b.split(/\s+/);for(var n,o=0;n=b[o++];){var m=n.split(".");n=m.shift();if(o>1){d=c.proxy(d);if(f!==v)d.data=f}d.type=m.slice(0).sort().join(".");var s=e[n],x=this.special[n]||{};if(!s){s=e[n]={};if(!x.setup||x.setup.call(a,f,m,d)===false)if(a.addEventListener)a.addEventListener(n,i,false);else a.attachEvent&&a.attachEvent("on"+n,i)}if(x.add)if((m=x.add.call(a,
-d,f,m,s))&&c.isFunction(m)){m.guid=m.guid||d.guid;m.data=m.data||d.data;m.type=m.type||d.type;d=m}s[d.guid]=d;this.global[n]=true}a=null}}},global:{},remove:function(a,b,d){if(!(a.nodeType===3||a.nodeType===8)){var f=c.data(a,"events"),e,i,j;if(f){if(b===v||typeof b==="string"&&b.charAt(0)===".")for(i in f)this.remove(a,i+(b||""));else{if(b.type){d=b.handler;b=b.type}b=b.split(/\s+/);for(var n=0;i=b[n++];){var o=i.split(".");i=o.shift();var m=!o.length,s=c.map(o.slice(0).sort(),ab);s=new RegExp("(^|\\.)"+
-s.join("\\.(?:.*\\.)?")+"(\\.|$)");var x=this.special[i]||{};if(f[i]){if(d){j=f[i][d.guid];delete f[i][d.guid]}else for(var A in f[i])if(m||s.test(f[i][A].type))delete f[i][A];x.remove&&x.remove.call(a,o,j);for(e in f[i])break;if(!e){if(!x.teardown||x.teardown.call(a,o)===false)if(a.removeEventListener)a.removeEventListener(i,c.data(a,"handle"),false);else a.detachEvent&&a.detachEvent("on"+i,c.data(a,"handle"));e=null;delete f[i]}}}}for(e in f)break;if(!e){if(A=c.data(a,"handle"))A.elem=null;c.removeData(a,
-"events");c.removeData(a,"handle")}}}},trigger:function(a,b,d,f){var e=a.type||a;if(!f){a=typeof a==="object"?a[G]?a:c.extend(c.Event(e),a):c.Event(e);if(e.indexOf("!")>=0){a.type=e=e.slice(0,-1);a.exclusive=true}if(!d){a.stopPropagation();this.global[e]&&c.each(c.cache,function(){this.events&&this.events[e]&&c.event.trigger(a,b,this.handle.elem)})}if(!d||d.nodeType===3||d.nodeType===8)return v;a.result=v;a.target=d;b=c.makeArray(b);b.unshift(a)}a.currentTarget=d;(f=c.data(d,"handle"))&&f.apply(d,
-b);f=d.parentNode||d.ownerDocument;try{if(!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()]))if(d["on"+e]&&d["on"+e].apply(d,b)===false)a.result=false}catch(i){}if(!a.isPropagationStopped()&&f)c.event.trigger(a,b,f,true);else if(!a.isDefaultPrevented()){d=a.target;var j;if(!(c.nodeName(d,"a")&&e==="click")&&!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()])){try{if(d[e]){if(j=d["on"+e])d["on"+e]=null;this.triggered=true;d[e]()}}catch(n){}if(j)d["on"+e]=j;this.triggered=false}}},handle:function(a){var b,
-d;a=arguments[0]=c.event.fix(a||z.event);a.currentTarget=this;d=a.type.split(".");a.type=d.shift();b=!d.length&&!a.exclusive;var f=new RegExp("(^|\\.)"+d.slice(0).sort().join("\\.(?:.*\\.)?")+"(\\.|$)");d=(c.data(this,"events")||{})[a.type];for(var e in d){var i=d[e];if(b||f.test(i.type)){a.handler=i;a.data=i.data;i=i.apply(this,arguments);if(i!==v){a.result=i;if(i===false){a.preventDefault();a.stopPropagation()}}if(a.isImmediatePropagationStopped())break}}return a.result},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
-fix:function(a){if(a[G])return a;var b=a;a=c.Event(b);for(var d=this.props.length,f;d;){f=this.props[--d];a[f]=b[f]}if(!a.target)a.target=a.srcElement||r;if(a.target.nodeType===3)a.target=a.target.parentNode;if(!a.relatedTarget&&a.fromElement)a.relatedTarget=a.fromElement===a.target?a.toElement:a.fromElement;if(a.pageX==null&&a.clientX!=null){b=r.documentElement;d=r.body;a.pageX=a.clientX+(b&&b.scrollLeft||d&&d.scrollLeft||0)-(b&&b.clientLeft||d&&d.clientLeft||0);a.pageY=a.clientY+(b&&b.scrollTop||
-d&&d.scrollTop||0)-(b&&b.clientTop||d&&d.clientTop||0)}if(!a.which&&(a.charCode||a.charCode===0?a.charCode:a.keyCode))a.which=a.charCode||a.keyCode;if(!a.metaKey&&a.ctrlKey)a.metaKey=a.ctrlKey;if(!a.which&&a.button!==v)a.which=a.button&1?1:a.button&2?3:a.button&4?2:0;return a},guid:1E8,proxy:c.proxy,special:{ready:{setup:c.bindReady,teardown:c.noop},live:{add:function(a,b){c.extend(a,b||{});a.guid+=b.selector+b.live;b.liveProxy=a;c.event.add(this,b.live,na,b)},remove:function(a){if(a.length){var b=
-0,d=new RegExp("(^|\\.)"+a[0]+"(\\.|$)");c.each(c.data(this,"events").live||{},function(){d.test(this.type)&&b++});b<1&&c.event.remove(this,a[0],na)}},special:{}},beforeunload:{setup:function(a,b,d){if(this.setInterval)this.onbeforeunload=d;return false},teardown:function(a,b){if(this.onbeforeunload===b)this.onbeforeunload=null}}}};c.Event=function(a){if(!this.preventDefault)return new c.Event(a);if(a&&a.type){this.originalEvent=a;this.type=a.type}else this.type=a;this.timeStamp=J();this[G]=true};
-c.Event.prototype={preventDefault:function(){this.isDefaultPrevented=Z;var a=this.originalEvent;if(a){a.preventDefault&&a.preventDefault();a.returnValue=false}},stopPropagation:function(){this.isPropagationStopped=Z;var a=this.originalEvent;if(a){a.stopPropagation&&a.stopPropagation();a.cancelBubble=true}},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=Z;this.stopPropagation()},isDefaultPrevented:Y,isPropagationStopped:Y,isImmediatePropagationStopped:Y};var Aa=function(a){for(var b=
-a.relatedTarget;b&&b!==this;)try{b=b.parentNode}catch(d){break}if(b!==this){a.type=a.data;c.event.handle.apply(this,arguments)}},Ba=function(a){a.type=a.data;c.event.handle.apply(this,arguments)};c.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){c.event.special[a]={setup:function(d){c.event.add(this,b,d&&d.selector?Ba:Aa,a)},teardown:function(d){c.event.remove(this,b,d&&d.selector?Ba:Aa)}}});if(!c.support.submitBubbles)c.event.special.submit={setup:function(a,b,d){if(this.nodeName.toLowerCase()!==
-"form"){c.event.add(this,"click.specialSubmit."+d.guid,function(f){var e=f.target,i=e.type;if((i==="submit"||i==="image")&&c(e).closest("form").length)return ma("submit",this,arguments)});c.event.add(this,"keypress.specialSubmit."+d.guid,function(f){var e=f.target,i=e.type;if((i==="text"||i==="password")&&c(e).closest("form").length&&f.keyCode===13)return ma("submit",this,arguments)})}else return false},remove:function(a,b){c.event.remove(this,"click.specialSubmit"+(b?"."+b.guid:""));c.event.remove(this,
-"keypress.specialSubmit"+(b?"."+b.guid:""))}};if(!c.support.changeBubbles){var da=/textarea|input|select/i;function Ca(a){var b=a.type,d=a.value;if(b==="radio"||b==="checkbox")d=a.checked;else if(b==="select-multiple")d=a.selectedIndex>-1?c.map(a.options,function(f){return f.selected}).join("-"):"";else if(a.nodeName.toLowerCase()==="select")d=a.selectedIndex;return d}function ea(a,b){var d=a.target,f,e;if(!(!da.test(d.nodeName)||d.readOnly)){f=c.data(d,"_change_data");e=Ca(d);if(a.type!=="focusout"||
-d.type!=="radio")c.data(d,"_change_data",e);if(!(f===v||e===f))if(f!=null||e){a.type="change";return c.event.trigger(a,b,d)}}}c.event.special.change={filters:{focusout:ea,click:function(a){var b=a.target,d=b.type;if(d==="radio"||d==="checkbox"||b.nodeName.toLowerCase()==="select")return ea.call(this,a)},keydown:function(a){var b=a.target,d=b.type;if(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(d==="checkbox"||d==="radio")||d==="select-multiple")return ea.call(this,a)},beforeactivate:function(a){a=
-a.target;a.nodeName.toLowerCase()==="input"&&a.type==="radio"&&c.data(a,"_change_data",Ca(a))}},setup:function(a,b,d){for(var f in T)c.event.add(this,f+".specialChange."+d.guid,T[f]);return da.test(this.nodeName)},remove:function(a,b){for(var d in T)c.event.remove(this,d+".specialChange"+(b?"."+b.guid:""),T[d]);return da.test(this.nodeName)}};var T=c.event.special.change.filters}r.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(f){f=c.event.fix(f);f.type=b;return c.event.handle.call(this,
-f)}c.event.special[b]={setup:function(){this.addEventListener(a,d,true)},teardown:function(){this.removeEventListener(a,d,true)}}});c.each(["bind","one"],function(a,b){c.fn[b]=function(d,f,e){if(typeof d==="object"){for(var i in d)this[b](i,f,d[i],e);return this}if(c.isFunction(f)){e=f;f=v}var j=b==="one"?c.proxy(e,function(n){c(this).unbind(n,j);return e.apply(this,arguments)}):e;return d==="unload"&&b!=="one"?this.one(d,f,e):this.each(function(){c.event.add(this,d,j,f)})}});c.fn.extend({unbind:function(a,
-b){if(typeof a==="object"&&!a.preventDefault){for(var d in a)this.unbind(d,a[d]);return this}return this.each(function(){c.event.remove(this,a,b)})},trigger:function(a,b){return this.each(function(){c.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0]){a=c.Event(a);a.preventDefault();a.stopPropagation();c.event.trigger(a,b,this[0]);return a.result}},toggle:function(a){for(var b=arguments,d=1;d<b.length;)c.proxy(a,b[d++]);return this.click(c.proxy(a,function(f){var e=(c.data(this,"lastToggle"+
-a.guid)||0)%d;c.data(this,"lastToggle"+a.guid,e+1);f.preventDefault();return b[e].apply(this,arguments)||false}))},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}});c.each(["live","die"],function(a,b){c.fn[b]=function(d,f,e){var i,j=0;if(c.isFunction(f)){e=f;f=v}for(d=(d||"").split(/\s+/);(i=d[j++])!=null;){i=i==="focus"?"focusin":i==="blur"?"focusout":i==="hover"?d.push("mouseleave")&&"mouseenter":i;b==="live"?c(this.context).bind(oa(i,this.selector),{data:f,selector:this.selector,
-live:i},e):c(this.context).unbind(oa(i,this.selector),e?{guid:e.guid+this.selector+i}:null)}return this}});c.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error".split(" "),function(a,b){c.fn[b]=function(d){return d?this.bind(b,d):this.trigger(b)};if(c.attrFn)c.attrFn[b]=true});z.attachEvent&&!z.addEventListener&&z.attachEvent("onunload",function(){for(var a in c.cache)if(c.cache[a].handle)try{c.event.remove(c.cache[a].handle.elem)}catch(b){}});
-(function(){function a(g){for(var h="",k,l=0;g[l];l++){k=g[l];if(k.nodeType===3||k.nodeType===4)h+=k.nodeValue;else if(k.nodeType!==8)h+=a(k.childNodes)}return h}function b(g,h,k,l,q,p){q=0;for(var u=l.length;q<u;q++){var t=l[q];if(t){t=t[g];for(var y=false;t;){if(t.sizcache===k){y=l[t.sizset];break}if(t.nodeType===1&&!p){t.sizcache=k;t.sizset=q}if(t.nodeName.toLowerCase()===h){y=t;break}t=t[g]}l[q]=y}}}function d(g,h,k,l,q,p){q=0;for(var u=l.length;q<u;q++){var t=l[q];if(t){t=t[g];for(var y=false;t;){if(t.sizcache===
-k){y=l[t.sizset];break}if(t.nodeType===1){if(!p){t.sizcache=k;t.sizset=q}if(typeof h!=="string"){if(t===h){y=true;break}}else if(o.filter(h,[t]).length>0){y=t;break}}t=t[g]}l[q]=y}}}var f=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,e=0,i=Object.prototype.toString,j=false,n=true;[0,0].sort(function(){n=false;return 0});var o=function(g,h,k,l){k=k||[];var q=h=h||r;if(h.nodeType!==1&&h.nodeType!==9)return[];if(!g||
-typeof g!=="string")return k;for(var p=[],u,t,y,R,H=true,M=w(h),I=g;(f.exec(""),u=f.exec(I))!==null;){I=u[3];p.push(u[1]);if(u[2]){R=u[3];break}}if(p.length>1&&s.exec(g))if(p.length===2&&m.relative[p[0]])t=fa(p[0]+p[1],h);else for(t=m.relative[p[0]]?[h]:o(p.shift(),h);p.length;){g=p.shift();if(m.relative[g])g+=p.shift();t=fa(g,t)}else{if(!l&&p.length>1&&h.nodeType===9&&!M&&m.match.ID.test(p[0])&&!m.match.ID.test(p[p.length-1])){u=o.find(p.shift(),h,M);h=u.expr?o.filter(u.expr,u.set)[0]:u.set[0]}if(h){u=
-l?{expr:p.pop(),set:A(l)}:o.find(p.pop(),p.length===1&&(p[0]==="~"||p[0]==="+")&&h.parentNode?h.parentNode:h,M);t=u.expr?o.filter(u.expr,u.set):u.set;if(p.length>0)y=A(t);else H=false;for(;p.length;){var D=p.pop();u=D;if(m.relative[D])u=p.pop();else D="";if(u==null)u=h;m.relative[D](y,u,M)}}else y=[]}y||(y=t);y||o.error(D||g);if(i.call(y)==="[object Array]")if(H)if(h&&h.nodeType===1)for(g=0;y[g]!=null;g++){if(y[g]&&(y[g]===true||y[g].nodeType===1&&E(h,y[g])))k.push(t[g])}else for(g=0;y[g]!=null;g++)y[g]&&
-y[g].nodeType===1&&k.push(t[g]);else k.push.apply(k,y);else A(y,k);if(R){o(R,q,k,l);o.uniqueSort(k)}return k};o.uniqueSort=function(g){if(C){j=n;g.sort(C);if(j)for(var h=1;h<g.length;h++)g[h]===g[h-1]&&g.splice(h--,1)}return g};o.matches=function(g,h){return o(g,null,null,h)};o.find=function(g,h,k){var l,q;if(!g)return[];for(var p=0,u=m.order.length;p<u;p++){var t=m.order[p];if(q=m.leftMatch[t].exec(g)){var y=q[1];q.splice(1,1);if(y.substr(y.length-1)!=="\\"){q[1]=(q[1]||"").replace(/\\/g,"");l=m.find[t](q,
-h,k);if(l!=null){g=g.replace(m.match[t],"");break}}}}l||(l=h.getElementsByTagName("*"));return{set:l,expr:g}};o.filter=function(g,h,k,l){for(var q=g,p=[],u=h,t,y,R=h&&h[0]&&w(h[0]);g&&h.length;){for(var H in m.filter)if((t=m.leftMatch[H].exec(g))!=null&&t[2]){var M=m.filter[H],I,D;D=t[1];y=false;t.splice(1,1);if(D.substr(D.length-1)!=="\\"){if(u===p)p=[];if(m.preFilter[H])if(t=m.preFilter[H](t,u,k,p,l,R)){if(t===true)continue}else y=I=true;if(t)for(var U=0;(D=u[U])!=null;U++)if(D){I=M(D,t,U,u);var Da=
-l^!!I;if(k&&I!=null)if(Da)y=true;else u[U]=false;else if(Da){p.push(D);y=true}}if(I!==v){k||(u=p);g=g.replace(m.match[H],"");if(!y)return[];break}}}if(g===q)if(y==null)o.error(g);else break;q=g}return u};o.error=function(g){throw"Syntax error, unrecognized expression: "+g;};var m=o.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
-TAG:/^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(g){return g.getAttribute("href")}},relative:{"+":function(g,h){var k=typeof h==="string",l=k&&!/\W/.test(h);k=k&&!l;if(l)h=h.toLowerCase();l=0;for(var q=g.length,
-p;l<q;l++)if(p=g[l]){for(;(p=p.previousSibling)&&p.nodeType!==1;);g[l]=k||p&&p.nodeName.toLowerCase()===h?p||false:p===h}k&&o.filter(h,g,true)},">":function(g,h){var k=typeof h==="string";if(k&&!/\W/.test(h)){h=h.toLowerCase();for(var l=0,q=g.length;l<q;l++){var p=g[l];if(p){k=p.parentNode;g[l]=k.nodeName.toLowerCase()===h?k:false}}}else{l=0;for(q=g.length;l<q;l++)if(p=g[l])g[l]=k?p.parentNode:p.parentNode===h;k&&o.filter(h,g,true)}},"":function(g,h,k){var l=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=
-h=h.toLowerCase();q=b}q("parentNode",h,l,g,p,k)},"~":function(g,h,k){var l=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=h=h.toLowerCase();q=b}q("previousSibling",h,l,g,p,k)}},find:{ID:function(g,h,k){if(typeof h.getElementById!=="undefined"&&!k)return(g=h.getElementById(g[1]))?[g]:[]},NAME:function(g,h){if(typeof h.getElementsByName!=="undefined"){var k=[];h=h.getElementsByName(g[1]);for(var l=0,q=h.length;l<q;l++)h[l].getAttribute("name")===g[1]&&k.push(h[l]);return k.length===0?null:k}},
-TAG:function(g,h){return h.getElementsByTagName(g[1])}},preFilter:{CLASS:function(g,h,k,l,q,p){g=" "+g[1].replace(/\\/g,"")+" ";if(p)return g;p=0;for(var u;(u=h[p])!=null;p++)if(u)if(q^(u.className&&(" "+u.className+" ").replace(/[\t\n]/g," ").indexOf(g)>=0))k||l.push(u);else if(k)h[p]=false;return false},ID:function(g){return g[1].replace(/\\/g,"")},TAG:function(g){return g[1].toLowerCase()},CHILD:function(g){if(g[1]==="nth"){var h=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&&
-"2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=h[1]+(h[2]||1)-0;g[3]=h[3]-0}g[0]=e++;return g},ATTR:function(g,h,k,l,q,p){h=g[1].replace(/\\/g,"");if(!p&&m.attrMap[h])g[1]=m.attrMap[h];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,h,k,l,q){if(g[1]==="not")if((f.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=o(g[3],null,null,h);else{g=o.filter(g[3],h,k,true^q);k||l.push.apply(l,g);return false}else if(m.match.POS.test(g[0])||m.match.CHILD.test(g[0]))return true;return g},POS:function(g){g.unshift(true);
-return g}},filters:{enabled:function(g){return g.disabled===false&&g.type!=="hidden"},disabled:function(g){return g.disabled===true},checked:function(g){return g.checked===true},selected:function(g){return g.selected===true},parent:function(g){return!!g.firstChild},empty:function(g){return!g.firstChild},has:function(g,h,k){return!!o(k[3],g).length},header:function(g){return/h\d/i.test(g.nodeName)},text:function(g){return"text"===g.type},radio:function(g){return"radio"===g.type},checkbox:function(g){return"checkbox"===
-g.type},file:function(g){return"file"===g.type},password:function(g){return"password"===g.type},submit:function(g){return"submit"===g.type},image:function(g){return"image"===g.type},reset:function(g){return"reset"===g.type},button:function(g){return"button"===g.type||g.nodeName.toLowerCase()==="button"},input:function(g){return/input|select|textarea|button/i.test(g.nodeName)}},setFilters:{first:function(g,h){return h===0},last:function(g,h,k,l){return h===l.length-1},even:function(g,h){return h%2===
-0},odd:function(g,h){return h%2===1},lt:function(g,h,k){return h<k[3]-0},gt:function(g,h,k){return h>k[3]-0},nth:function(g,h,k){return k[3]-0===h},eq:function(g,h,k){return k[3]-0===h}},filter:{PSEUDO:function(g,h,k,l){var q=h[1],p=m.filters[q];if(p)return p(g,k,h,l);else if(q==="contains")return(g.textContent||g.innerText||a([g])||"").indexOf(h[3])>=0;else if(q==="not"){h=h[3];k=0;for(l=h.length;k<l;k++)if(h[k]===g)return false;return true}else o.error("Syntax error, unrecognized expression: "+
-q)},CHILD:function(g,h){var k=h[1],l=g;switch(k){case "only":case "first":for(;l=l.previousSibling;)if(l.nodeType===1)return false;if(k==="first")return true;l=g;case "last":for(;l=l.nextSibling;)if(l.nodeType===1)return false;return true;case "nth":k=h[2];var q=h[3];if(k===1&&q===0)return true;h=h[0];var p=g.parentNode;if(p&&(p.sizcache!==h||!g.nodeIndex)){var u=0;for(l=p.firstChild;l;l=l.nextSibling)if(l.nodeType===1)l.nodeIndex=++u;p.sizcache=h}g=g.nodeIndex-q;return k===0?g===0:g%k===0&&g/k>=
-0}},ID:function(g,h){return g.nodeType===1&&g.getAttribute("id")===h},TAG:function(g,h){return h==="*"&&g.nodeType===1||g.nodeName.toLowerCase()===h},CLASS:function(g,h){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(h)>-1},ATTR:function(g,h){var k=h[1];g=m.attrHandle[k]?m.attrHandle[k](g):g[k]!=null?g[k]:g.getAttribute(k);k=g+"";var l=h[2];h=h[4];return g==null?l==="!=":l==="="?k===h:l==="*="?k.indexOf(h)>=0:l==="~="?(" "+k+" ").indexOf(h)>=0:!h?k&&g!==false:l==="!="?k!==h:l==="^="?
-k.indexOf(h)===0:l==="$="?k.substr(k.length-h.length)===h:l==="|="?k===h||k.substr(0,h.length+1)===h+"-":false},POS:function(g,h,k,l){var q=m.setFilters[h[2]];if(q)return q(g,k,h,l)}}},s=m.match.POS;for(var x in m.match){m.match[x]=new RegExp(m.match[x].source+/(?![^\[]*\])(?![^\(]*\))/.source);m.leftMatch[x]=new RegExp(/(^(?:.|\r|\n)*?)/.source+m.match[x].source.replace(/\\(\d+)/g,function(g,h){return"\\"+(h-0+1)}))}var A=function(g,h){g=Array.prototype.slice.call(g,0);if(h){h.push.apply(h,g);return h}return g};
-try{Array.prototype.slice.call(r.documentElement.childNodes,0)}catch(B){A=function(g,h){h=h||[];if(i.call(g)==="[object Array]")Array.prototype.push.apply(h,g);else if(typeof g.length==="number")for(var k=0,l=g.length;k<l;k++)h.push(g[k]);else for(k=0;g[k];k++)h.push(g[k]);return h}}var C;if(r.documentElement.compareDocumentPosition)C=function(g,h){if(!g.compareDocumentPosition||!h.compareDocumentPosition){if(g==h)j=true;return g.compareDocumentPosition?-1:1}g=g.compareDocumentPosition(h)&4?-1:g===
-h?0:1;if(g===0)j=true;return g};else if("sourceIndex"in r.documentElement)C=function(g,h){if(!g.sourceIndex||!h.sourceIndex){if(g==h)j=true;return g.sourceIndex?-1:1}g=g.sourceIndex-h.sourceIndex;if(g===0)j=true;return g};else if(r.createRange)C=function(g,h){if(!g.ownerDocument||!h.ownerDocument){if(g==h)j=true;return g.ownerDocument?-1:1}var k=g.ownerDocument.createRange(),l=h.ownerDocument.createRange();k.setStart(g,0);k.setEnd(g,0);l.setStart(h,0);l.setEnd(h,0);g=k.compareBoundaryPoints(Range.START_TO_END,
-l);if(g===0)j=true;return g};(function(){var g=r.createElement("div"),h="script"+(new Date).getTime();g.innerHTML="<a name='"+h+"'/>";var k=r.documentElement;k.insertBefore(g,k.firstChild);if(r.getElementById(h)){m.find.ID=function(l,q,p){if(typeof q.getElementById!=="undefined"&&!p)return(q=q.getElementById(l[1]))?q.id===l[1]||typeof q.getAttributeNode!=="undefined"&&q.getAttributeNode("id").nodeValue===l[1]?[q]:v:[]};m.filter.ID=function(l,q){var p=typeof l.getAttributeNode!=="undefined"&&l.getAttributeNode("id");
-return l.nodeType===1&&p&&p.nodeValue===q}}k.removeChild(g);k=g=null})();(function(){var g=r.createElement("div");g.appendChild(r.createComment(""));if(g.getElementsByTagName("*").length>0)m.find.TAG=function(h,k){k=k.getElementsByTagName(h[1]);if(h[1]==="*"){h=[];for(var l=0;k[l];l++)k[l].nodeType===1&&h.push(k[l]);k=h}return k};g.innerHTML="<a href='#'></a>";if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")m.attrHandle.href=function(h){return h.getAttribute("href",
-2)};g=null})();r.querySelectorAll&&function(){var g=o,h=r.createElement("div");h.innerHTML="<p class='TEST'></p>";if(!(h.querySelectorAll&&h.querySelectorAll(".TEST").length===0)){o=function(l,q,p,u){q=q||r;if(!u&&q.nodeType===9&&!w(q))try{return A(q.querySelectorAll(l),p)}catch(t){}return g(l,q,p,u)};for(var k in g)o[k]=g[k];h=null}}();(function(){var g=r.createElement("div");g.innerHTML="<div class='test e'></div><div class='test'></div>";if(!(!g.getElementsByClassName||g.getElementsByClassName("e").length===
-0)){g.lastChild.className="e";if(g.getElementsByClassName("e").length!==1){m.order.splice(1,0,"CLASS");m.find.CLASS=function(h,k,l){if(typeof k.getElementsByClassName!=="undefined"&&!l)return k.getElementsByClassName(h[1])};g=null}}})();var E=r.compareDocumentPosition?function(g,h){return g.compareDocumentPosition(h)&16}:function(g,h){return g!==h&&(g.contains?g.contains(h):true)},w=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false},fa=function(g,h){var k=[],
-l="",q;for(h=h.nodeType?[h]:h;q=m.match.PSEUDO.exec(g);){l+=q[0];g=g.replace(m.match.PSEUDO,"")}g=m.relative[g]?g+"*":g;q=0;for(var p=h.length;q<p;q++)o(g,h[q],k);return o.filter(l,k)};c.find=o;c.expr=o.selectors;c.expr[":"]=c.expr.filters;c.unique=o.uniqueSort;c.getText=a;c.isXMLDoc=w;c.contains=E})();var bb=/Until$/,cb=/^(?:parents|prevUntil|prevAll)/,db=/,/;Q=Array.prototype.slice;var Ea=function(a,b,d){if(c.isFunction(b))return c.grep(a,function(e,i){return!!b.call(e,i,e)===d});else if(b.nodeType)return c.grep(a,
-function(e){return e===b===d});else if(typeof b==="string"){var f=c.grep(a,function(e){return e.nodeType===1});if(Qa.test(b))return c.filter(b,f,!d);else b=c.filter(b,f)}return c.grep(a,function(e){return c.inArray(e,b)>=0===d})};c.fn.extend({find:function(a){for(var b=this.pushStack("","find",a),d=0,f=0,e=this.length;f<e;f++){d=b.length;c.find(a,this[f],b);if(f>0)for(var i=d;i<b.length;i++)for(var j=0;j<d;j++)if(b[j]===b[i]){b.splice(i--,1);break}}return b},has:function(a){var b=c(a);return this.filter(function(){for(var d=
-0,f=b.length;d<f;d++)if(c.contains(this,b[d]))return true})},not:function(a){return this.pushStack(Ea(this,a,false),"not",a)},filter:function(a){return this.pushStack(Ea(this,a,true),"filter",a)},is:function(a){return!!a&&c.filter(a,this).length>0},closest:function(a,b){if(c.isArray(a)){var d=[],f=this[0],e,i={},j;if(f&&a.length){e=0;for(var n=a.length;e<n;e++){j=a[e];i[j]||(i[j]=c.expr.match.POS.test(j)?c(j,b||this.context):j)}for(;f&&f.ownerDocument&&f!==b;){for(j in i){e=i[j];if(e.jquery?e.index(f)>
--1:c(f).is(e)){d.push({selector:j,elem:f});delete i[j]}}f=f.parentNode}}return d}var o=c.expr.match.POS.test(a)?c(a,b||this.context):null;return this.map(function(m,s){for(;s&&s.ownerDocument&&s!==b;){if(o?o.index(s)>-1:c(s).is(a))return s;s=s.parentNode}return null})},index:function(a){if(!a||typeof a==="string")return c.inArray(this[0],a?c(a):this.parent().children());return c.inArray(a.jquery?a[0]:a,this)},add:function(a,b){a=typeof a==="string"?c(a,b||this.context):c.makeArray(a);b=c.merge(this.get(),
-a);return this.pushStack(pa(a[0])||pa(b[0])?b:c.unique(b))},andSelf:function(){return this.add(this.prevObject)}});c.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return c.dir(a,"parentNode")},parentsUntil:function(a,b,d){return c.dir(a,"parentNode",d)},next:function(a){return c.nth(a,2,"nextSibling")},prev:function(a){return c.nth(a,2,"previousSibling")},nextAll:function(a){return c.dir(a,"nextSibling")},prevAll:function(a){return c.dir(a,"previousSibling")},
-nextUntil:function(a,b,d){return c.dir(a,"nextSibling",d)},prevUntil:function(a,b,d){return c.dir(a,"previousSibling",d)},siblings:function(a){return c.sibling(a.parentNode.firstChild,a)},children:function(a){return c.sibling(a.firstChild)},contents:function(a){return c.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:c.makeArray(a.childNodes)}},function(a,b){c.fn[a]=function(d,f){var e=c.map(this,b,d);bb.test(a)||(f=d);if(f&&typeof f==="string")e=c.filter(f,e);e=this.length>1?c.unique(e):
-e;if((this.length>1||db.test(f))&&cb.test(a))e=e.reverse();return this.pushStack(e,a,Q.call(arguments).join(","))}});c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return c.find.matches(a,b)},dir:function(a,b,d){var f=[];for(a=a[b];a&&a.nodeType!==9&&(d===v||a.nodeType!==1||!c(a).is(d));){a.nodeType===1&&f.push(a);a=a[b]}return f},nth:function(a,b,d){b=b||1;for(var f=0;a;a=a[d])if(a.nodeType===1&&++f===b)break;return a},sibling:function(a,b){for(var d=[];a;a=a.nextSibling)a.nodeType===1&&a!==
-b&&d.push(a);return d}});var Fa=/ jQuery\d+="(?:\d+|null)"/g,V=/^\s+/,Ga=/(<([\w:]+)[^>]*?)\/>/g,eb=/^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,Ha=/<([\w:]+)/,fb=/<tbody/i,gb=/<|&\w+;/,sa=/checked\s*(?:[^=]|=\s*.checked.)/i,Ia=function(a,b,d){return eb.test(d)?a:b+"></"+d+">"},F={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],
-col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]};F.optgroup=F.option;F.tbody=F.tfoot=F.colgroup=F.caption=F.thead;F.th=F.td;if(!c.support.htmlSerialize)F._default=[1,"div<div>","</div>"];c.fn.extend({text:function(a){if(c.isFunction(a))return this.each(function(b){var d=c(this);d.text(a.call(this,b,d.text()))});if(typeof a!=="object"&&a!==v)return this.empty().append((this[0]&&this[0].ownerDocument||r).createTextNode(a));return c.getText(this)},
-wrapAll:function(a){if(c.isFunction(a))return this.each(function(d){c(this).wrapAll(a.call(this,d))});if(this[0]){var b=c(a,this[0].ownerDocument).eq(0).clone(true);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var d=this;d.firstChild&&d.firstChild.nodeType===1;)d=d.firstChild;return d}).append(this)}return this},wrapInner:function(a){if(c.isFunction(a))return this.each(function(b){c(this).wrapInner(a.call(this,b))});return this.each(function(){var b=c(this),d=b.contents();d.length?
-d.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){c(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){c.nodeName(this,"body")||c(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,
-false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a=c(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this.nextSibling)});else if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,c(arguments[0]).toArray());return a}},clone:function(a){var b=this.map(function(){if(!c.support.noCloneEvent&&
-!c.isXMLDoc(this)){var d=this.outerHTML,f=this.ownerDocument;if(!d){d=f.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(Fa,"").replace(V,"")],f)[0]}else return this.cloneNode(true)});if(a===true){qa(this,b);qa(this.find("*"),b.find("*"))}return b},html:function(a){if(a===v)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(Fa,""):null;else if(typeof a==="string"&&!/<script/i.test(a)&&(c.support.leadingWhitespace||!V.test(a))&&!F[(Ha.exec(a)||
-["",""])[1].toLowerCase()]){a=a.replace(Ga,Ia);try{for(var b=0,d=this.length;b<d;b++)if(this[b].nodeType===1){c.cleanData(this[b].getElementsByTagName("*"));this[b].innerHTML=a}}catch(f){this.empty().append(a)}}else c.isFunction(a)?this.each(function(e){var i=c(this),j=i.html();i.empty().append(function(){return a.call(this,e,j)})}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&this[0].parentNode){if(c.isFunction(a))return this.each(function(b){var d=c(this),f=d.html();d.replaceWith(a.call(this,
-b,f))});else a=c(a).detach();return this.each(function(){var b=this.nextSibling,d=this.parentNode;c(this).remove();b?c(b).before(a):c(d).append(a)})}else return this.pushStack(c(c.isFunction(a)?a():a),"replaceWith",a)},detach:function(a){return this.remove(a,true)},domManip:function(a,b,d){function f(s){return c.nodeName(s,"table")?s.getElementsByTagName("tbody")[0]||s.appendChild(s.ownerDocument.createElement("tbody")):s}var e,i,j=a[0],n=[];if(!c.support.checkClone&&arguments.length===3&&typeof j===
-"string"&&sa.test(j))return this.each(function(){c(this).domManip(a,b,d,true)});if(c.isFunction(j))return this.each(function(s){var x=c(this);a[0]=j.call(this,s,b?x.html():v);x.domManip(a,b,d)});if(this[0]){e=a[0]&&a[0].parentNode&&a[0].parentNode.nodeType===11?{fragment:a[0].parentNode}:ra(a,this,n);if(i=e.fragment.firstChild){b=b&&c.nodeName(i,"tr");for(var o=0,m=this.length;o<m;o++)d.call(b?f(this[o],i):this[o],e.cacheable||this.length>1||o>0?e.fragment.cloneNode(true):e.fragment)}n&&c.each(n,
-Ma)}return this}});c.fragments={};c.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){c.fn[a]=function(d){var f=[];d=c(d);for(var e=0,i=d.length;e<i;e++){var j=(e>0?this.clone(true):this).get();c.fn[b].apply(c(d[e]),j);f=f.concat(j)}return this.pushStack(f,a,d.selector)}});c.each({remove:function(a,b){if(!a||c.filter(a,[this]).length){if(!b&&this.nodeType===1){c.cleanData(this.getElementsByTagName("*"));c.cleanData([this])}this.parentNode&&
-this.parentNode.removeChild(this)}},empty:function(){for(this.nodeType===1&&c.cleanData(this.getElementsByTagName("*"));this.firstChild;)this.removeChild(this.firstChild)}},function(a,b){c.fn[a]=function(){return this.each(b,arguments)}});c.extend({clean:function(a,b,d,f){b=b||r;if(typeof b.createElement==="undefined")b=b.ownerDocument||b[0]&&b[0].ownerDocument||r;var e=[];c.each(a,function(i,j){if(typeof j==="number")j+="";if(j){if(typeof j==="string"&&!gb.test(j))j=b.createTextNode(j);else if(typeof j===
-"string"){j=j.replace(Ga,Ia);var n=(Ha.exec(j)||["",""])[1].toLowerCase(),o=F[n]||F._default,m=o[0];i=b.createElement("div");for(i.innerHTML=o[1]+j+o[2];m--;)i=i.lastChild;if(!c.support.tbody){m=fb.test(j);n=n==="table"&&!m?i.firstChild&&i.firstChild.childNodes:o[1]==="<table>"&&!m?i.childNodes:[];for(o=n.length-1;o>=0;--o)c.nodeName(n[o],"tbody")&&!n[o].childNodes.length&&n[o].parentNode.removeChild(n[o])}!c.support.leadingWhitespace&&V.test(j)&&i.insertBefore(b.createTextNode(V.exec(j)[0]),i.firstChild);
-j=c.makeArray(i.childNodes)}if(j.nodeType)e.push(j);else e=c.merge(e,j)}});if(d)for(a=0;e[a];a++)if(f&&c.nodeName(e[a],"script")&&(!e[a].type||e[a].type.toLowerCase()==="text/javascript"))f.push(e[a].parentNode?e[a].parentNode.removeChild(e[a]):e[a]);else{e[a].nodeType===1&&e.splice.apply(e,[a+1,0].concat(c.makeArray(e[a].getElementsByTagName("script"))));d.appendChild(e[a])}return e},cleanData:function(a){for(var b=0,d;(d=a[b])!=null;b++){c.event.remove(d);c.removeData(d)}}});var hb=/z-?index|font-?weight|opacity|zoom|line-?height/i,
-Ja=/alpha\([^)]*\)/,Ka=/opacity=([^)]*)/,ga=/float/i,ha=/-([a-z])/ig,ib=/([A-Z])/g,jb=/^-?\d+(?:px)?$/i,kb=/^-?\d/,lb={position:"absolute",visibility:"hidden",display:"block"},mb=["Left","Right"],nb=["Top","Bottom"],ob=r.defaultView&&r.defaultView.getComputedStyle,La=c.support.cssFloat?"cssFloat":"styleFloat",ia=function(a,b){return b.toUpperCase()};c.fn.css=function(a,b){return X(this,a,b,true,function(d,f,e){if(e===v)return c.curCSS(d,f);if(typeof e==="number"&&!hb.test(f))e+="px";c.style(d,f,e)})};
-c.extend({style:function(a,b,d){if(!a||a.nodeType===3||a.nodeType===8)return v;if((b==="width"||b==="height")&&parseFloat(d)<0)d=v;var f=a.style||a,e=d!==v;if(!c.support.opacity&&b==="opacity"){if(e){f.zoom=1;b=parseInt(d,10)+""==="NaN"?"":"alpha(opacity="+d*100+")";a=f.filter||c.curCSS(a,"filter")||"";f.filter=Ja.test(a)?a.replace(Ja,b):b}return f.filter&&f.filter.indexOf("opacity=")>=0?parseFloat(Ka.exec(f.filter)[1])/100+"":""}if(ga.test(b))b=La;b=b.replace(ha,ia);if(e)f[b]=d;return f[b]},css:function(a,
-b,d,f){if(b==="width"||b==="height"){var e,i=b==="width"?mb:nb;function j(){e=b==="width"?a.offsetWidth:a.offsetHeight;f!=="border"&&c.each(i,function(){f||(e-=parseFloat(c.curCSS(a,"padding"+this,true))||0);if(f==="margin")e+=parseFloat(c.curCSS(a,"margin"+this,true))||0;else e-=parseFloat(c.curCSS(a,"border"+this+"Width",true))||0})}a.offsetWidth!==0?j():c.swap(a,lb,j);return Math.max(0,Math.round(e))}return c.curCSS(a,b,d)},curCSS:function(a,b,d){var f,e=a.style;if(!c.support.opacity&&b==="opacity"&&
-a.currentStyle){f=Ka.test(a.currentStyle.filter||"")?parseFloat(RegExp.$1)/100+"":"";return f===""?"1":f}if(ga.test(b))b=La;if(!d&&e&&e[b])f=e[b];else if(ob){if(ga.test(b))b="float";b=b.replace(ib,"-$1").toLowerCase();e=a.ownerDocument.defaultView;if(!e)return null;if(a=e.getComputedStyle(a,null))f=a.getPropertyValue(b);if(b==="opacity"&&f==="")f="1"}else if(a.currentStyle){d=b.replace(ha,ia);f=a.currentStyle[b]||a.currentStyle[d];if(!jb.test(f)&&kb.test(f)){b=e.left;var i=a.runtimeStyle.left;a.runtimeStyle.left=
-a.currentStyle.left;e.left=d==="fontSize"?"1em":f||0;f=e.pixelLeft+"px";e.left=b;a.runtimeStyle.left=i}}return f},swap:function(a,b,d){var f={};for(var e in b){f[e]=a.style[e];a.style[e]=b[e]}d.call(a);for(e in b)a.style[e]=f[e]}});if(c.expr&&c.expr.filters){c.expr.filters.hidden=function(a){var b=a.offsetWidth,d=a.offsetHeight,f=a.nodeName.toLowerCase()==="tr";return b===0&&d===0&&!f?true:b>0&&d>0&&!f?false:c.curCSS(a,"display")==="none"};c.expr.filters.visible=function(a){return!c.expr.filters.hidden(a)}}var pb=
-J(),qb=/<script(.|\s)*?\/script>/gi,rb=/select|textarea/i,sb=/color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,N=/=\?(&|$)/,ja=/\?/,tb=/(\?|&)_=.*?(&|$)/,ub=/^(\w+:)?\/\/([^\/?#]+)/,vb=/%20/g;c.fn.extend({_load:c.fn.load,load:function(a,b,d){if(typeof a!=="string")return this._load(a);else if(!this.length)return this;var f=a.indexOf(" ");if(f>=0){var e=a.slice(f,a.length);a=a.slice(0,f)}f="GET";if(b)if(c.isFunction(b)){d=b;b=null}else if(typeof b==="object"){b=
-c.param(b,c.ajaxSettings.traditional);f="POST"}var i=this;c.ajax({url:a,type:f,dataType:"html",data:b,complete:function(j,n){if(n==="success"||n==="notmodified")i.html(e?c("<div />").append(j.responseText.replace(qb,"")).find(e):j.responseText);d&&i.each(d,[j.responseText,n,j])}});return this},serialize:function(){return c.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?c.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&
-(this.checked||rb.test(this.nodeName)||sb.test(this.type))}).map(function(a,b){a=c(this).val();return a==null?null:c.isArray(a)?c.map(a,function(d){return{name:b.name,value:d}}):{name:b.name,value:a}}).get()}});c.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){c.fn[b]=function(d){return this.bind(b,d)}});c.extend({get:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b=null}return c.ajax({type:"GET",url:a,data:b,success:d,dataType:f})},getScript:function(a,
-b){return c.get(a,null,b,"script")},getJSON:function(a,b,d){return c.get(a,b,d,"json")},post:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b={}}return c.ajax({type:"POST",url:a,data:b,success:d,dataType:f})},ajaxSetup:function(a){c.extend(c.ajaxSettings,a)},ajaxSettings:{url:location.href,global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:z.XMLHttpRequest&&(z.location.protocol!=="file:"||!z.ActiveXObject)?function(){return new z.XMLHttpRequest}:
-function(){try{return new z.ActiveXObject("Microsoft.XMLHTTP")}catch(a){}},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},etag:{},ajax:function(a){function b(){e.success&&e.success.call(o,n,j,w);e.global&&f("ajaxSuccess",[w,e])}function d(){e.complete&&e.complete.call(o,w,j);e.global&&f("ajaxComplete",[w,e]);e.global&&!--c.active&&c.event.trigger("ajaxStop")}
-function f(q,p){(e.context?c(e.context):c.event).trigger(q,p)}var e=c.extend(true,{},c.ajaxSettings,a),i,j,n,o=a&&a.context||e,m=e.type.toUpperCase();if(e.data&&e.processData&&typeof e.data!=="string")e.data=c.param(e.data,e.traditional);if(e.dataType==="jsonp"){if(m==="GET")N.test(e.url)||(e.url+=(ja.test(e.url)?"&":"?")+(e.jsonp||"callback")+"=?");else if(!e.data||!N.test(e.data))e.data=(e.data?e.data+"&":"")+(e.jsonp||"callback")+"=?";e.dataType="json"}if(e.dataType==="json"&&(e.data&&N.test(e.data)||
-N.test(e.url))){i=e.jsonpCallback||"jsonp"+pb++;if(e.data)e.data=(e.data+"").replace(N,"="+i+"$1");e.url=e.url.replace(N,"="+i+"$1");e.dataType="script";z[i]=z[i]||function(q){n=q;b();d();z[i]=v;try{delete z[i]}catch(p){}A&&A.removeChild(B)}}if(e.dataType==="script"&&e.cache===null)e.cache=false;if(e.cache===false&&m==="GET"){var s=J(),x=e.url.replace(tb,"$1_="+s+"$2");e.url=x+(x===e.url?(ja.test(e.url)?"&":"?")+"_="+s:"")}if(e.data&&m==="GET")e.url+=(ja.test(e.url)?"&":"?")+e.data;e.global&&!c.active++&&
-c.event.trigger("ajaxStart");s=(s=ub.exec(e.url))&&(s[1]&&s[1]!==location.protocol||s[2]!==location.host);if(e.dataType==="script"&&m==="GET"&&s){var A=r.getElementsByTagName("head")[0]||r.documentElement,B=r.createElement("script");B.src=e.url;if(e.scriptCharset)B.charset=e.scriptCharset;if(!i){var C=false;B.onload=B.onreadystatechange=function(){if(!C&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){C=true;b();d();B.onload=B.onreadystatechange=null;A&&B.parentNode&&
-A.removeChild(B)}}}A.insertBefore(B,A.firstChild);return v}var E=false,w=e.xhr();if(w){e.username?w.open(m,e.url,e.async,e.username,e.password):w.open(m,e.url,e.async);try{if(e.data||a&&a.contentType)w.setRequestHeader("Content-Type",e.contentType);if(e.ifModified){c.lastModified[e.url]&&w.setRequestHeader("If-Modified-Since",c.lastModified[e.url]);c.etag[e.url]&&w.setRequestHeader("If-None-Match",c.etag[e.url])}s||w.setRequestHeader("X-Requested-With","XMLHttpRequest");w.setRequestHeader("Accept",
-e.dataType&&e.accepts[e.dataType]?e.accepts[e.dataType]+", */*":e.accepts._default)}catch(fa){}if(e.beforeSend&&e.beforeSend.call(o,w,e)===false){e.global&&!--c.active&&c.event.trigger("ajaxStop");w.abort();return false}e.global&&f("ajaxSend",[w,e]);var g=w.onreadystatechange=function(q){if(!w||w.readyState===0||q==="abort"){E||d();E=true;if(w)w.onreadystatechange=c.noop}else if(!E&&w&&(w.readyState===4||q==="timeout")){E=true;w.onreadystatechange=c.noop;j=q==="timeout"?"timeout":!c.httpSuccess(w)?
-"error":e.ifModified&&c.httpNotModified(w,e.url)?"notmodified":"success";var p;if(j==="success")try{n=c.httpData(w,e.dataType,e)}catch(u){j="parsererror";p=u}if(j==="success"||j==="notmodified")i||b();else c.handleError(e,w,j,p);d();q==="timeout"&&w.abort();if(e.async)w=null}};try{var h=w.abort;w.abort=function(){w&&h.call(w);g("abort")}}catch(k){}e.async&&e.timeout>0&&setTimeout(function(){w&&!E&&g("timeout")},e.timeout);try{w.send(m==="POST"||m==="PUT"||m==="DELETE"?e.data:null)}catch(l){c.handleError(e,
-w,null,l);d()}e.async||g();return w}},handleError:function(a,b,d,f){if(a.error)a.error.call(a.context||a,b,d,f);if(a.global)(a.context?c(a.context):c.event).trigger("ajaxError",[b,a,f])},active:0,httpSuccess:function(a){try{return!a.status&&location.protocol==="file:"||a.status>=200&&a.status<300||a.status===304||a.status===1223||a.status===0}catch(b){}return false},httpNotModified:function(a,b){var d=a.getResponseHeader("Last-Modified"),f=a.getResponseHeader("Etag");if(d)c.lastModified[b]=d;if(f)c.etag[b]=
-f;return a.status===304||a.status===0},httpData:function(a,b,d){var f=a.getResponseHeader("content-type")||"",e=b==="xml"||!b&&f.indexOf("xml")>=0;a=e?a.responseXML:a.responseText;e&&a.documentElement.nodeName==="parsererror"&&c.error("parsererror");if(d&&d.dataFilter)a=d.dataFilter(a,b);if(typeof a==="string")if(b==="json"||!b&&f.indexOf("json")>=0)a=c.parseJSON(a);else if(b==="script"||!b&&f.indexOf("javascript")>=0)c.globalEval(a);return a},param:function(a,b){function d(j,n){if(c.isArray(n))c.each(n,
-function(o,m){b?f(j,m):d(j+"["+(typeof m==="object"||c.isArray(m)?o:"")+"]",m)});else!b&&n!=null&&typeof n==="object"?c.each(n,function(o,m){d(j+"["+o+"]",m)}):f(j,n)}function f(j,n){n=c.isFunction(n)?n():n;e[e.length]=encodeURIComponent(j)+"="+encodeURIComponent(n)}var e=[];if(b===v)b=c.ajaxSettings.traditional;if(c.isArray(a)||a.jquery)c.each(a,function(){f(this.name,this.value)});else for(var i in a)d(i,a[i]);return e.join("&").replace(vb,"+")}});var ka={},wb=/toggle|show|hide/,xb=/^([+-]=)?([\d+-.]+)(.*)$/,
-W,ta=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];c.fn.extend({show:function(a,b){if(a||a===0)return this.animate(K("show",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");this[a].style.display=d||"";if(c.css(this[a],"display")==="none"){d=this[a].nodeName;var f;if(ka[d])f=ka[d];else{var e=c("<"+d+" />").appendTo("body");f=e.css("display");if(f==="none")f="block";e.remove();
-ka[d]=f}c.data(this[a],"olddisplay",f)}}a=0;for(b=this.length;a<b;a++)this[a].style.display=c.data(this[a],"olddisplay")||"";return this}},hide:function(a,b){if(a||a===0)return this.animate(K("hide",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");!d&&d!=="none"&&c.data(this[a],"olddisplay",c.css(this[a],"display"))}a=0;for(b=this.length;a<b;a++)this[a].style.display="none";return this}},_toggle:c.fn.toggle,toggle:function(a,b){var d=typeof a==="boolean";if(c.isFunction(a)&&
-c.isFunction(b))this._toggle.apply(this,arguments);else a==null||d?this.each(function(){var f=d?a:c(this).is(":hidden");c(this)[f?"show":"hide"]()}):this.animate(K("toggle",3),a,b);return this},fadeTo:function(a,b,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,d)},animate:function(a,b,d,f){var e=c.speed(b,d,f);if(c.isEmptyObject(a))return this.each(e.complete);return this[e.queue===false?"each":"queue"](function(){var i=c.extend({},e),j,n=this.nodeType===1&&c(this).is(":hidden"),
-o=this;for(j in a){var m=j.replace(ha,ia);if(j!==m){a[m]=a[j];delete a[j];j=m}if(a[j]==="hide"&&n||a[j]==="show"&&!n)return i.complete.call(this);if((j==="height"||j==="width")&&this.style){i.display=c.css(this,"display");i.overflow=this.style.overflow}if(c.isArray(a[j])){(i.specialEasing=i.specialEasing||{})[j]=a[j][1];a[j]=a[j][0]}}if(i.overflow!=null)this.style.overflow="hidden";i.curAnim=c.extend({},a);c.each(a,function(s,x){var A=new c.fx(o,i,s);if(wb.test(x))A[x==="toggle"?n?"show":"hide":x](a);
-else{var B=xb.exec(x),C=A.cur(true)||0;if(B){x=parseFloat(B[2]);var E=B[3]||"px";if(E!=="px"){o.style[s]=(x||1)+E;C=(x||1)/A.cur(true)*C;o.style[s]=C+E}if(B[1])x=(B[1]==="-="?-1:1)*x+C;A.custom(C,x,E)}else A.custom(C,x,"")}});return true})},stop:function(a,b){var d=c.timers;a&&this.queue([]);this.each(function(){for(var f=d.length-1;f>=0;f--)if(d[f].elem===this){b&&d[f](true);d.splice(f,1)}});b||this.dequeue();return this}});c.each({slideDown:K("show",1),slideUp:K("hide",1),slideToggle:K("toggle",
-1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(a,b){c.fn[a]=function(d,f){return this.animate(b,d,f)}});c.extend({speed:function(a,b,d){var f=a&&typeof a==="object"?a:{complete:d||!d&&b||c.isFunction(a)&&a,duration:a,easing:d&&b||b&&!c.isFunction(b)&&b};f.duration=c.fx.off?0:typeof f.duration==="number"?f.duration:c.fx.speeds[f.duration]||c.fx.speeds._default;f.old=f.complete;f.complete=function(){f.queue!==false&&c(this).dequeue();c.isFunction(f.old)&&f.old.call(this)};return f},easing:{linear:function(a,
-b,d,f){return d+f*a},swing:function(a,b,d,f){return(-Math.cos(a*Math.PI)/2+0.5)*f+d}},timers:[],fx:function(a,b,d){this.options=b;this.elem=a;this.prop=d;if(!b.orig)b.orig={}}});c.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this);(c.fx.step[this.prop]||c.fx.step._default)(this);if((this.prop==="height"||this.prop==="width")&&this.elem.style)this.elem.style.display="block"},cur:function(a){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==
-null))return this.elem[this.prop];return(a=parseFloat(c.css(this.elem,this.prop,a)))&&a>-10000?a:parseFloat(c.curCSS(this.elem,this.prop))||0},custom:function(a,b,d){function f(i){return e.step(i)}this.startTime=J();this.start=a;this.end=b;this.unit=d||this.unit||"px";this.now=this.start;this.pos=this.state=0;var e=this;f.elem=this.elem;if(f()&&c.timers.push(f)&&!W)W=setInterval(c.fx.tick,13)},show:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.show=true;this.custom(this.prop===
-"width"||this.prop==="height"?1:0,this.cur());c(this.elem).show()},hide:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(a){var b=J(),d=true;if(a||b>=this.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;for(var f in this.options.curAnim)if(this.options.curAnim[f]!==true)d=false;if(d){if(this.options.display!=null){this.elem.style.overflow=
-this.options.overflow;a=c.data(this.elem,"olddisplay");this.elem.style.display=a?a:this.options.display;if(c.css(this.elem,"display")==="none")this.elem.style.display="block"}this.options.hide&&c(this.elem).hide();if(this.options.hide||this.options.show)for(var e in this.options.curAnim)c.style(this.elem,e,this.options.orig[e]);this.options.complete.call(this.elem)}return false}else{e=b-this.startTime;this.state=e/this.options.duration;a=this.options.easing||(c.easing.swing?"swing":"linear");this.pos=
-c.easing[this.options.specialEasing&&this.options.specialEasing[this.prop]||a](this.state,e,0,1,this.options.duration);this.now=this.start+(this.end-this.start)*this.pos;this.update()}return true}};c.extend(c.fx,{tick:function(){for(var a=c.timers,b=0;b<a.length;b++)a[b]()||a.splice(b--,1);a.length||c.fx.stop()},stop:function(){clearInterval(W);W=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){c.style(a.elem,"opacity",a.now)},_default:function(a){if(a.elem.style&&a.elem.style[a.prop]!=
-null)a.elem.style[a.prop]=(a.prop==="width"||a.prop==="height"?Math.max(0,a.now):a.now)+a.unit;else a.elem[a.prop]=a.now}}});if(c.expr&&c.expr.filters)c.expr.filters.animated=function(a){return c.grep(c.timers,function(b){return a===b.elem}).length};c.fn.offset="getBoundingClientRect"in r.documentElement?function(a){var b=this[0];if(a)return this.each(function(e){c.offset.setOffset(this,a,e)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);var d=b.getBoundingClientRect(),
-f=b.ownerDocument;b=f.body;f=f.documentElement;return{top:d.top+(self.pageYOffset||c.support.boxModel&&f.scrollTop||b.scrollTop)-(f.clientTop||b.clientTop||0),left:d.left+(self.pageXOffset||c.support.boxModel&&f.scrollLeft||b.scrollLeft)-(f.clientLeft||b.clientLeft||0)}}:function(a){var b=this[0];if(a)return this.each(function(s){c.offset.setOffset(this,a,s)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);c.offset.initialize();var d=b.offsetParent,f=
-b,e=b.ownerDocument,i,j=e.documentElement,n=e.body;f=(e=e.defaultView)?e.getComputedStyle(b,null):b.currentStyle;for(var o=b.offsetTop,m=b.offsetLeft;(b=b.parentNode)&&b!==n&&b!==j;){if(c.offset.supportsFixedPosition&&f.position==="fixed")break;i=e?e.getComputedStyle(b,null):b.currentStyle;o-=b.scrollTop;m-=b.scrollLeft;if(b===d){o+=b.offsetTop;m+=b.offsetLeft;if(c.offset.doesNotAddBorder&&!(c.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(b.nodeName))){o+=parseFloat(i.borderTopWidth)||
-0;m+=parseFloat(i.borderLeftWidth)||0}f=d;d=b.offsetParent}if(c.offset.subtractsBorderForOverflowNotVisible&&i.overflow!=="visible"){o+=parseFloat(i.borderTopWidth)||0;m+=parseFloat(i.borderLeftWidth)||0}f=i}if(f.position==="relative"||f.position==="static"){o+=n.offsetTop;m+=n.offsetLeft}if(c.offset.supportsFixedPosition&&f.position==="fixed"){o+=Math.max(j.scrollTop,n.scrollTop);m+=Math.max(j.scrollLeft,n.scrollLeft)}return{top:o,left:m}};c.offset={initialize:function(){var a=r.body,b=r.createElement("div"),
-d,f,e,i=parseFloat(c.curCSS(a,"marginTop",true))||0;c.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"});b.innerHTML="<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";a.insertBefore(b,a.firstChild);
-d=b.firstChild;f=d.firstChild;e=d.nextSibling.firstChild.firstChild;this.doesNotAddBorder=f.offsetTop!==5;this.doesAddBorderForTableAndCells=e.offsetTop===5;f.style.position="fixed";f.style.top="20px";this.supportsFixedPosition=f.offsetTop===20||f.offsetTop===15;f.style.position=f.style.top="";d.style.overflow="hidden";d.style.position="relative";this.subtractsBorderForOverflowNotVisible=f.offsetTop===-5;this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==i;a.removeChild(b);c.offset.initialize=c.noop},
-bodyOffset:function(a){var b=a.offsetTop,d=a.offsetLeft;c.offset.initialize();if(c.offset.doesNotIncludeMarginInBodyOffset){b+=parseFloat(c.curCSS(a,"marginTop",true))||0;d+=parseFloat(c.curCSS(a,"marginLeft",true))||0}return{top:b,left:d}},setOffset:function(a,b,d){if(/static/.test(c.curCSS(a,"position")))a.style.position="relative";var f=c(a),e=f.offset(),i=parseInt(c.curCSS(a,"top",true),10)||0,j=parseInt(c.curCSS(a,"left",true),10)||0;if(c.isFunction(b))b=b.call(a,d,e);d={top:b.top-e.top+i,left:b.left-
-e.left+j};"using"in b?b.using.call(a,d):f.css(d)}};c.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),d=this.offset(),f=/^body|html$/i.test(b[0].nodeName)?{top:0,left:0}:b.offset();d.top-=parseFloat(c.curCSS(a,"marginTop",true))||0;d.left-=parseFloat(c.curCSS(a,"marginLeft",true))||0;f.top+=parseFloat(c.curCSS(b[0],"borderTopWidth",true))||0;f.left+=parseFloat(c.curCSS(b[0],"borderLeftWidth",true))||0;return{top:d.top-f.top,left:d.left-f.left}},offsetParent:function(){return this.map(function(){for(var a=
-this.offsetParent||r.body;a&&!/^body|html$/i.test(a.nodeName)&&c.css(a,"position")==="static";)a=a.offsetParent;return a})}});c.each(["Left","Top"],function(a,b){var d="scroll"+b;c.fn[d]=function(f){var e=this[0],i;if(!e)return null;if(f!==v)return this.each(function(){if(i=ua(this))i.scrollTo(!a?f:c(i).scrollLeft(),a?f:c(i).scrollTop());else this[d]=f});else return(i=ua(e))?"pageXOffset"in i?i[a?"pageYOffset":"pageXOffset"]:c.support.boxModel&&i.document.documentElement[d]||i.document.body[d]:e[d]}});
-c.each(["Height","Width"],function(a,b){var d=b.toLowerCase();c.fn["inner"+b]=function(){return this[0]?c.css(this[0],d,false,"padding"):null};c.fn["outer"+b]=function(f){return this[0]?c.css(this[0],d,false,f?"margin":"border"):null};c.fn[d]=function(f){var e=this[0];if(!e)return f==null?null:this;if(c.isFunction(f))return this.each(function(i){var j=c(this);j[d](f.call(this,i,j[d]()))});return"scrollTo"in e&&e.document?e.document.compatMode==="CSS1Compat"&&e.document.documentElement["client"+b]||
-e.document.body["client"+b]:e.nodeType===9?Math.max(e.documentElement["client"+b],e.body["scroll"+b],e.documentElement["scroll"+b],e.body["offset"+b],e.documentElement["offset"+b]):f===v?c.css(e,d):this.css(d,typeof f==="string"?f:f+"px")}});z.jQuery=z.$=c})(window);
diff --git a/chrome/common/extensions/docs/examples/extensions/gdocs/manifest.json b/chrome/common/extensions/docs/examples/extensions/gdocs/manifest.json
deleted file mode 100644
index 03d1758..0000000
--- a/chrome/common/extensions/docs/examples/extensions/gdocs/manifest.json
+++ /dev/null
@@ -1,25 +0,0 @@
-{
- "name": "Google Document List Viewer",
- "version": "1.0.2",
- "icons": {
- "48": "img/docs_spreadsheets-48.gif",
- "128": "img/docs_spreadsheets-128.gif"
- },
- "description": "Demonstrates how to use OAuth to connect the Google Documents List Data API.",
- "background": {
- "page": "background.html"
- },
- "options_page": "options.html",
- "browser_action": {
- "default_title": "List your Google Docs",
- "default_icon": "img/docs_spreadsheets-32.gif",
- "default_popup": "popup.html"
- },
- "permissions": [
- "tabs",
- "https://docs.google.com/feeds/*",
- "https://www.google.com/accounts/OAuthGetRequestToken",
- "https://www.google.com/accounts/OAuthAuthorizeToken",
- "https://www.google.com/accounts/OAuthGetAccessToken"
- ]
-}
diff --git a/chrome/common/extensions/docs/examples/extensions/gdocs/options.html b/chrome/common/extensions/docs/examples/extensions/gdocs/options.html
deleted file mode 100644
index fc5ab5bb6..0000000
--- a/chrome/common/extensions/docs/examples/extensions/gdocs/options.html
+++ /dev/null
@@ -1,44 +0,0 @@
-<!DOCTYPE html>
-<!--
- * Copyright (c) 2010 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.
- *
- * Author: Eric Bidelman <ericbidelman@chromium.org>
--->
-<html>
- <head>
- <title>Options</title>
- <script type="text/javascript" src="js/jquery-1.4.1.min.js"></script>
- </head>
- <body onload="initUI();">
- <p><button id="revoke" onclick="logout();">Revoke your OAuth token</button></p>
- <p>Refresh rate (seconds): <input id="refresh_rate" value="300"></p>
- <script type="text/javascript">
- var bgPage = chrome.extension.getBackgroundPage();
-
- $('#refresh_rate').change(function() {
- localStorage.refreshRate = $(this).val();
- bgPage.refreshRate = localStorage.refreshRate;
- bgPage.pollIntervalMin = bgPage.refreshRate * 1000;
- });
-
- function logout() {
- bgPage.logout();
- $('#revoke').get(0).disabled = true;
- }
-
- function initUI() {
- if (!bgPage.oauth.hasToken()) {
- $('#revoke').get(0).disabled = true;
- }
-
- if (localStorage.refreshRate) {
- $('#refresh_rate').val(localStorage.refreshRate);
- } else {
- $('#refresh_rate').val(bgPage.refreshRate);
- }
- }
- </script>
- </body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/extensions/gdocs/popup.html b/chrome/common/extensions/docs/examples/extensions/gdocs/popup.html
deleted file mode 100644
index f2d9933c..0000000
--- a/chrome/common/extensions/docs/examples/extensions/gdocs/popup.html
+++ /dev/null
@@ -1,579 +0,0 @@
-<!DOCTYPE html>
-<!--
- * Copyright (c) 2010 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.
- *
- * Author: Eric Bidelman <ericbidelman@chromium.org>
--->
-<html>
-<head>
-<title>Your Google Documents List</title>
-<script type="text/javascript" src="js/jquery-1.4.1.min.js"></script>
-<style type="text/css">
-body {
- font: 12px 'Myriad Pro', 'Tw Cen MT', Arial, Verdana, sans-serif;
- color: #666666;
- overflow-x: hidden;
-}
-ul {
- padding: 0;
- list-style: none;
-}
-li {
- clear: both;
- padding: 2px 0;
-}
-li div img {
- margin: 0 5px;
- vertical-align: middle;
-}
-li div {
- text-overflow: ellipsis;
- white-space: nowrap;
- overflow: hidden;
- width: 250px;
- float: left;
- padding: 2px 0;
-}
-li span {
- margin-left: 5px;
-}
-li:hover {
- background-color: #fffccc;
-}
-a {
- color: #4E7DC2;
- text-decoration: none;
-}
-a:hover {
- color: #880000;
- text-decoration: underline;
-}
-#butter {
- color: #fff;
- background-color: #000033;
- padding: 5px 20px;
- border-radius: 15px;
- width: auto;
- text-align: center;
- float: right;
- display: none;
-}
-#butter.error {
- background-color: red;
-}
-#new_doc_container {
- display: none;
-}
-#new_doc_container input[type='text'],textarea {
- width: 100%;
-}
-#output {
- width: 375px;
- clear: both;
-}
-[contenteditable]:hover {
- outline: 1px dotted #666;
-}
-.star {
- margin-top: 1px;
- margin-right: 3px;
- width: 16px;
- height: 16px;
- background: no-repeat url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAYAAAA71pVKAAAKT2lDQ1BQaG90b3Nob3AgSUNDIHByb2ZpbGUAAHjanVNnVFPpFj333vRCS4iAlEtvUhUIIFJCi4AUkSYqIQkQSoghodkVUcERRUUEG8igiAOOjoCMFVEsDIoK2AfkIaKOg6OIisr74Xuja9a89+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/GMzLdsAAAAGYktHRAA3ADcAN3PbifMAAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfZAwkAAh4LdI38AAAC00lEQVQoz42SS2hUZxzFz/d99zF35s7EScxEEzW1mkSlVkQJCNWSakDdxY2P0lKkSMi6G1uqbcVXF12WiiK4EMQixgeoGCMalWZRTYlG0kwNtebtzGQmmZk78937/7sQREWhB87m8DurcwTeo0Pn8xuFEN+A+djetkjnuxj5rvDbUxOLzCDTPkdOtlqU/nrvqYnG/13OZaY+rq3AZ9tb5qkP5qpPZtJTa99m2g92wXg96DjcLT2t6l2z8GVtZTwed23UVspYLFTcsfunWw8UFwaP799CAPDbd5sgdu+7XJPLl+LEosIJmYtjbqh5VWPN5zs3NyViEQszBY1z3UPPe/tHz87Olu4WvPKwEjzthu204TPtW7E0sbnCtSKGlOH51VFn9fIaGYtY0D5x1DHFhjULqlzH2DM6mftC+1TMzpYK/41nrxmaKJxIROt2tS6z41EbAMDMKJUDBlh4RFyfcMWH8xsNANFUzouevTGoh8enw2rZhp0DQ8/S1cxY2rQwbkopUNLExCwCAoghtE9MxMIrB+jsSXrXep9c1MQH1EDPmXTD+h39j5+m52nCwhX1VQ4xCx0wiF8aEIIZONeTzJ6/k7xS8unHS0faBiQAXD7clswHfOh638jIk7EclBQgYjADRIClJEZTedx6ODaeKuifrxzd9uiNnYvSnpa2FTKVhB8whABMQ0IIQAcMQwpIywp5ys69cZJP93eBlJEIlBmujNpQUiAICE8nZlDWAQwlMMe1QYbpBMqobvmhSwB4eZIcpAw7aklt3InGXQt9w2k+/cezzMBUIdNQ5VTsaq6ram6YK+oqHXcoVVwyVaZeAL4BAFoaUlpqdcRS9i9Xk8ULj1NDQUAnMvnyxWyJW+9f+qd9a1NmuQIsO2St0r7/+6uyNEzKBfjr6r/ebSG8P0tanHz4/fq/W37tx82OlSc+OnCvu3Mw+xUz1hHLPtuyfAB4AUJFSguX3LKbAAAAAElFTkSuQmCC) !important;
-}
-.star.selected {
- background: no-repeat url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAYAAAA71pVKAAAKT2lDQ1BQaG90b3Nob3AgSUNDIHByb2ZpbGUAAHjanVNnVFPpFj333vRCS4iAlEtvUhUIIFJCi4AUkSYqIQkQSoghodkVUcERRUUEG8igiAOOjoCMFVEsDIoK2AfkIaKOg6OIisr74Xuja9a89+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/GMzLdsAAAAGYktHRAA3ADcAN3PbifMAAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfZAwkAAB45Qu9+AAAC1ElEQVQoz42SWUhUYRzFz/+7986dVTPT0SzNFnHBJZHCKGmTAisJgooIIrJ87CGIHopKWp/qoYdAJIIg6qEUy/aiSMoWmpbJyjJCs3SacRZnrvfe7/t6KioKOo+H3+HA4RD+oYMXxpYQ0Q5IeXLXas/FvzHsb+b2tvH8bPaiudrXUZ+rPN2yvc0s+u+wiPdVZHi1xfVzJynZE9h8Huur+ZNpPnAD9KvRdKCbxU13QVXewJFV8+SakrICet8bkO33HZ09AxU7VRF7c2b/XPGDp817Ov2huJahwEr3umRh7gRjTlWRb8O6ZWnZ5ABk8j3a75ih7qDn3HAi434s5eznkkYz3fGwakuxp640vFx1ZXocCneXT7FcFUWSkcYgxyOSVKKlVR8y/W5j6/PB/I0py5ESppV8OZR/VbWEcM+cnMhbscivK66JALIAbkCaYUkiSpKPSG+aoNqaqFpb0+0TCe678niKFRjKcyvFdeuDPf1pWSolZ5ZOTWokDEhrVJIcJfBhEB8haX+TJMZJWsDFx8XGqQcLOkzBWpTgvbPhWXVrXwQ+IkcR8anlBSEXiSiBjwAiBPAICAYB47jwqCh6+kF1V8pW9nUeXhlkAHDpUGNfwtYOXg5og4lwH4BBgA8BPAxIAwDHWFzieu/0L1+T3qNXjzS8AgD1x+wp5hpVHAmnShGAK4C0AMYBLgDBoZENRYPTYI7YbydZuPcahMqyDdLdTpcFkA0IA1YsCdgGQDYcugmTaS6uKFlL9nXRz+aQ8LIsT3RGhf+TD7pAZMiUrY+qI7cHSiPzct6mN1V1Z/pzTCqb9MnbH0uf8XEs9yEAWwUAi2mMaTR7muezfu5eYer4s8XvmLRbB+ITO2K2Xt81WNm8teRmSa5z2OHUeaWVUs//DOsaF9/s9MCx3oa7BDxJWHpbcPect40nL6F9W0NraUvPrROvl20CUGsJ5VmaM2UDwHchqUbp2jdIoAAAAABJRU5ErkJggg==) !important;
-}
-</style>
-</head>
-<body>
-
-<div style="height:15px;">
- <div style="float:left;">
- <a href="javascript:void(0);" onclick="gdocs.refreshDocs();return false;">Refresh list</a>,
- <a href="javascript:void(0);" onclick="$('#new_doc_container').toggle();return false;">New Document</a>
- </div>
- <div id="butter">Fetching your docs</div>
-</div>
-<div id="new_doc_container">
- Create a: <select id="doc_type">
- <option value="document">document</option>
- <option value="presentation">presentation</option>
- <option value="spreadsheet">spreadsheet</option>
- </select>
- <input type="text" id="doc_title" placeholder="Enter a title"><br>
- <textarea id="doc_content" placeholder="Enter document content"></textarea>
- Star it? <input type="checkbox" id="doc_starred">
- <button onclick="gdocs.createDoc();" style="float:right;">Create new doc</button>
-</div>
-<div id="output"></div>
-
-<script type="text/javascript">
-// Protected namespaces.
-var util = {};
-var gdocs = {};
-
-var bgPage = chrome.extension.getBackgroundPage();
-var pollIntervalMax = 1000 * 60 * 60; // 1 hour
-var requestFailureCount = 0; // used for exponential backoff
-var requestTimeout = 1000 * 2; // 5 seconds
-
-var DEFAULT_MIMETYPES = {
- 'atom': 'application/atom+xml',
- 'document': 'text/plain',
- 'spreadsheet': 'text/csv',
- 'presentation': 'text/plain',
- 'pdf': 'application/pdf'
-};
-
-// Persistent click handler for star icons.
-$('#doc_type').change(function() {
- if ($(this).val() === 'presentation') {
- $('#doc_content').attr('disabled', 'true')
- .attr('placeholder', 'N/A for presentations');
- } else {
- $('#doc_content').removeAttr('disabled')
- .attr('placeholder', 'Enter document content');
- }
-});
-
-
-// Persistent click handler for changing the title of a document.
-$('[contenteditable="true"]').live('blur', function(index) {
- var index = $(this).parent().parent().attr('data-index');
-
- // Only make the XHR if the user chose a new title.
- if ($(this).text() != bgPage.docs[index].title) {
- bgPage.docs[index].title = $(this).text();
- gdocs.updateDoc(bgPage.docs[index]);
- }
-});
-
-// Persistent click handler for star icons.
-$('.star').live('click', function() {
- $(this).toggleClass('selected');
-
- var index = $(this).parent().attr('data-index');
- bgPage.docs[index].starred = $(this).hasClass('selected');
- gdocs.updateDoc(bgPage.docs[index]);
-});
-
-/**
- * Class to compartmentalize properties of a Google document.
- * @param {Object} entry A JSON representation of a DocList atom entry.
- * @constructor
- */
-gdocs.GoogleDoc = function(entry) {
- this.entry = entry;
- this.title = entry.title.$t;
- this.resourceId = entry.gd$resourceId.$t;
- this.type = gdocs.getCategory(
- entry.category, 'http://schemas.google.com/g/2005#kind');
- this.starred = gdocs.getCategory(
- entry.category, 'http://schemas.google.com/g/2005/labels',
- 'http://schemas.google.com/g/2005/labels#starred') ? true : false;
- this.link = {
- 'alternate': gdocs.getLink(entry.link, 'alternate').href
- };
- this.contentSrc = entry.content.src;
-};
-
-/**
- * Sets up a future poll for the user's document list.
- */
-util.scheduleRequest = function() {
- var exponent = Math.pow(2, requestFailureCount);
- var delay = Math.min(bgPage.pollIntervalMin * exponent,
- pollIntervalMax);
- delay = Math.round(delay);
-
- if (bgPage.oauth.hasToken()) {
- var req = bgPage.window.setTimeout(function() {
- gdocs.getDocumentList();
- util.scheduleRequest();
- }, delay);
- bgPage.requests.push(req);
- }
-};
-
-/**
- * Urlencodes a JSON object of key/value query parameters.
- * @param {Object} parameters Key value pairs representing URL parameters.
- * @return {string} query parameters concatenated together.
- */
-util.stringify = function(parameters) {
- var params = [];
- for(var p in parameters) {
- params.push(encodeURIComponent(p) + '=' +
- encodeURIComponent(parameters[p]));
- }
- return params.join('&');
-};
-
-/**
- * Creates a JSON object of key/value pairs
- * @param {string} paramStr A string of Url query parmeters.
- * For example: max-results=5&startindex=2&showfolders=true
- * @return {Object} The query parameters as key/value pairs.
- */
-util.unstringify = function(paramStr) {
- var parts = paramStr.split('&');
-
- var params = {};
- for (var i = 0, pair; pair = parts[i]; ++i) {
- var param = pair.split('=');
- params[decodeURIComponent(param[0])] = decodeURIComponent(param[1]);
- }
- return params;
-};
-
-/**
- * Utility for displaying a message to the user.
- * @param {string} msg The message.
- */
-util.displayMsg = function(msg) {
- $('#butter').removeClass('error').text(msg).show();
-};
-
-/**
- * Utility for removing any messages currently showing to the user.
- */
-util.hideMsg = function() {
- $('#butter').fadeOut(1500);
-};
-
-/**
- * Utility for displaying an error to the user.
- * @param {string} msg The message.
- */
-util.displayError = function(msg) {
- util.displayMsg(msg);
- $('#butter').addClass('error');
-};
-
-/**
- * Returns the correct atom link corresponding to the 'rel' value passed in.
- * @param {Array<Object>} links A list of atom link objects.
- * @param {string} rel The rel value of the link to return. For example: 'next'.
- * @return {string|null} The appropriate link for the 'rel' passed in, or null
- * if one is not found.
- */
-gdocs.getLink = function(links, rel) {
- for (var i = 0, link; link = links[i]; ++i) {
- if (link.rel === rel) {
- return link;
- }
- }
- return null;
-};
-
-/**
- * Returns the correct atom category corresponding to the scheme/term passed in.
- * @param {Array<Object>} categories A list of atom category objects.
- * @param {string} scheme The category's scheme to look up.
- * @param {opt_term?} An optional term value for the category to look up.
- * @return {string|null} The appropriate category, or null if one is not found.
- */
-gdocs.getCategory = function(categories, scheme, opt_term) {
- for (var i = 0, cat; cat = categories[i]; ++i) {
- if (opt_term) {
- if (cat.scheme === scheme && opt_term === cat.term) {
- return cat;
- }
- } else if (cat.scheme === scheme) {
- return cat;
- }
- }
- return null;
-};
-
-/**
- * A generic error handler for failed XHR requests.
- * @param {XMLHttpRequest} xhr The xhr request that failed.
- * @param {string} textStatus The server's returned status.
- */
-gdocs.handleError = function(xhr, textStatus) {
- util.displayError('Failed to fetch docs. Please try again.');
- ++requestFailureCount;
-};
-
-/**
- * A helper for constructing the raw Atom xml send in the body of an HTTP post.
- * @param {XMLHttpRequest} xhr The xhr request that failed.
- * @param {string} docTitle A title for the document.
- * @param {string} docType The type of document to create.
- * (eg. 'document', 'spreadsheet', etc.)
- * @param {boolean?} opt_starred Whether the document should be starred.
- * @return {string} The Atom xml as a string.
- */
-gdocs.constructAtomXml_ = function(docTitle, docType, opt_starred) {
- var starred = opt_starred || null;
-
- var starCat = ['<category scheme="http://schemas.google.com/g/2005/labels" ',
- 'term="http://schemas.google.com/g/2005/labels#starred" ',
- 'label="starred"/>'].join('');
-
- var atom = ["<?xml version='1.0' encoding='UTF-8'?>",
- '<entry xmlns="http://www.w3.org/2005/Atom">',
- '<category scheme="http://schemas.google.com/g/2005#kind"',
- ' term="http://schemas.google.com/docs/2007#', docType, '"/>',
- starred ? starCat : '',
- '<title>', docTitle, '</title>',
- '</entry>'].join('');
- return atom;
-};
-
-/**
- * A helper for constructing the body of a mime-mutlipart HTTP request.
- * @param {string} title A title for the new document.
- * @param {string} docType The type of document to create.
- * (eg. 'document', 'spreadsheet', etc.)
- * @param {string} body The body of the HTTP request.
- * @param {string} contentType The Content-Type of the (non-Atom) portion of the
- * http body.
- * @param {boolean?} opt_starred Whether the document should be starred.
- * @return {string} The Atom xml as a string.
- */
-gdocs.constructContentBody_ = function(title, docType, body, contentType,
- opt_starred) {
- var body = ['--END_OF_PART\r\n',
- 'Content-Type: application/atom+xml;\r\n\r\n',
- gdocs.constructAtomXml_(title, docType, opt_starred), '\r\n',
- '--END_OF_PART\r\n',
- 'Content-Type: ', contentType, '\r\n\r\n',
- body, '\r\n',
- '--END_OF_PART--\r\n'].join('');
- return body;
-};
-
-/**
- * Creates a new document in Google Docs.
- */
-gdocs.createDoc = function() {
- var title = $.trim($('#doc_title').val());
- if (!title) {
- alert('Please provide a title');
- return;
- }
- var content = $('#doc_content').val();
- var starred = $('#doc_starred').is(':checked');
- var docType = $('#doc_type').val();
-
- util.displayMsg('Creating doc...');
-
- var handleSuccess = function(resp, xhr) {
- bgPage.docs.splice(0, 0, new gdocs.GoogleDoc(JSON.parse(resp).entry));
-
- gdocs.renderDocList();
- bgPage.setIcon({'text': bgPage.docs.length.toString()});
-
- $('#new_doc_container').hide();
- $('#doc_title').val('');
- $('#doc_content').val('');
- util.displayMsg('Document created!');
- util.hideMsg();
-
- requestFailureCount = 0;
- };
-
- var params = {
- 'method': 'POST',
- 'headers': {
- 'GData-Version': '3.0',
- 'Content-Type': 'multipart/related; boundary=END_OF_PART',
- },
- 'parameters': {'alt': 'json'},
- 'body': gdocs.constructContentBody_(title, docType, content,
- DEFAULT_MIMETYPES[docType], starred)
- };
-
- // Presentation can only be created from binary content. Instead, create a
- // blank presentation.
- if (docType === 'presentation') {
- params['headers']['Content-Type'] = DEFAULT_MIMETYPES['atom'];
- params['body'] = gdocs.constructAtomXml_(title, docType, starred);
- }
-
- bgPage.oauth.sendSignedRequest(bgPage.DOCLIST_FEED, handleSuccess, params);
-};
-
-/**
- * Updates a document's metadata (title, starred, etc.).
- * @param {gdocs.GoogleDoc} googleDocObj An object containing the document to
- * update.
- */
-gdocs.updateDoc = function(googleDocObj) {
- var handleSuccess = function(resp) {
- util.displayMsg('Updated!');
- util.hideMsg();
- requestFailureCount = 0;
- };
-
- var params = {
- 'method': 'PUT',
- 'headers': {
- 'GData-Version': '3.0',
- 'Content-Type': 'application/atom+xml',
- 'If-Match': '*'
- },
- 'body': gdocs.constructAtomXml_(googleDocObj.title, googleDocObj.type,
- googleDocObj.starred)
- };
-
- var url = bgPage.DOCLIST_FEED + googleDocObj.resourceId;
- bgPage.oauth.sendSignedRequest(url, handleSuccess, params);
-};
-
-/**
- * Deletes a document from the user's document list.
- * @param {integer} index An index intro the background page's docs array.
- */
-gdocs.deleteDoc = function(index) {
- var handleSuccess = function(resp, xhr) {
- util.displayMsg('Document trashed!');
- util.hideMsg();
- requestFailureCount = 0;
- bgPage.docs.splice(index, 1);
- bgPage.setIcon({'text': bgPage.docs.length.toString()});
- }
-
- var params = {
- 'method': 'DELETE',
- 'headers': {
- 'GData-Version': '3.0',
- 'If-Match': '*'
- }
- };
-
- $('#output li').eq(index).fadeOut('slow');
-
- bgPage.oauth.sendSignedRequest(
- bgPage.DOCLIST_FEED + bgPage.docs[index].resourceId,
- handleSuccess, params);
-};
-
-/**
- * Callback for processing the JSON feed returned by the DocList API.
- * @param {string} response The server's response.
- * @param {XMLHttpRequest} xhr The xhr request that was made.
- */
-gdocs.processDocListResults = function(response, xhr) {
- if (xhr.status != 200) {
- gdocs.handleError(xhr, response);
- return;
- } else {
- requestFailureCount = 0;
- }
-
- var data = JSON.parse(response);
-
- for (var i = 0, entry; entry = data.feed.entry[i]; ++i) {
- bgPage.docs.push(new gdocs.GoogleDoc(entry));
- }
-
- var nextLink = gdocs.getLink(data.feed.link, 'next');
- if (nextLink) {
- gdocs.getDocumentList(nextLink.href); // Fetch next page of results.
- } else {
- gdocs.renderDocList();
- }
-};
-
-/**
- * Presents the in-memory documents that were fetched from the server as HTML.
- */
-gdocs.renderDocList = function() {
- util.hideMsg();
-
- // Construct the iframe's HTML.
- var html = [];
- for (var i = 0, doc; doc = bgPage.docs[i]; ++i) {
- // If we have an arbitrary file, use generic file icon.
- var type = doc.type.label;
- if (doc.type.term == 'http://schemas.google.com/docs/2007#file') {
- type = 'file';
- }
-
- var starred = doc.starred ? ' selected' : '';
- html.push(
- '<li data-index="', i , '"><div class="star', starred, '"></div>',
- '<div><img src="img/icons/', type, '.gif">',
- '<span contenteditable="true" class="doc_title"></span></div>',
- '<span>[<a href="', doc.link['alternate'],
- '" target="_new">view</a> | <a href="javascript:void(0);" ',
- 'onclick="gdocs.deleteDoc(',i,
- ');return false;">delete</a>]','</span></li>');
- }
- $('#output').html('<ul>' + html.join('') + '</ul>');
-
- // Set each span's innerText to be the doc title. We're filling this after
- // the html has been rendered to the page prevent XSS attacks when using
- // innerHTML.
- $('#output li span.doc_title').each(function(i, ul) {
- $(ul).text(bgPage.docs[i].title);
- });
-
- bgPage.setIcon({'text': bgPage.docs.length.toString()});
-};
-
-/**
- * Fetches the user's document list.
- * @param {string?} opt_url A url to query the doclist API with. If omitted,
- * the main doclist feed uri is used.
- */
-gdocs.getDocumentList = function(opt_url) {
- var url = opt_url || null;
-
- var params = {
- 'headers': {
- 'GData-Version': '3.0'
- }
- };
-
- if (!url) {
- util.displayMsg('Fetching your docs');
- bgPage.setIcon({'text': '...'});
-
- bgPage.docs = []; // Clear document list. We're doing a refresh.
-
- url = bgPage.DOCLIST_FEED;
- params['parameters'] = {
- 'alt': 'json',
- 'showfolders': 'true'
- };
- } else {
- util.displayMsg($('#butter').text() + '.');
-
- var parts = url.split('?');
- if (parts.length > 1) {
- url = parts[0]; // Extract base URI. Params are passed in separately.
- params['parameters'] = util.unstringify(parts[1]);
- }
- }
-
- bgPage.oauth.sendSignedRequest(url, gdocs.processDocListResults, params);
-};
-
-/**
- * Refreshes the user's document list.
- */
-gdocs.refreshDocs = function() {
- bgPage.clearPendingRequests();
- gdocs.getDocumentList();
- util.scheduleRequest();
-};
-
-
-bgPage.oauth.authorize(function() {
- if (!bgPage.docs.length) {
- gdocs.getDocumentList();
- } else {
- gdocs.renderDocList();
- }
- util.scheduleRequest();
-});
-</script>
-</body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/ar/messages.json b/chrome/common/extensions/docs/examples/extensions/gmail/_locales/ar/messages.json
deleted file mode 100644
index 87faf64..0000000
--- a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/ar/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"gmailcheck_name":{"message":"Google Mail Checker"},"gmailcheck_description":{"message":"\u0644\u0639\u0631\u0636 \u0639\u062f\u062f \u0627\u0644\u0631\u0633\u0627\u0626\u0644 \u063a\u064a\u0631 \u0627\u0644\u0645\u0642\u0631\u0648\u0621\u0629 \u0641\u064a \u0627\u0644\u0628\u0631\u064a\u062f \u0627\u0644\u0648\u0627\u0631\u062f \u0641\u064a Google Mail. \u0643\u0645\u0627 \u064a\u0645\u0643\u0646\u0643 \u0627\u0644\u0646\u0642\u0631 \u0639\u0644\u0649 \u0627\u0644\u0632\u0631 \u0644\u0641\u062a\u062d \u0628\u0631\u064a\u062f\u0643 \u0627\u0644\u0648\u0627\u0631\u062f."},"gmailcheck_node_error":{"message":"\u062e\u0637\u0623: \u062a\u0645 \u0627\u0633\u062a\u0631\u062f\u0627\u062f \u0627\u0644\u062e\u0644\u0627\u0635\u0629\u060c \u0648\u0644\u0643\u0646 \u0644\u0645 \u064a\u062a\u0645 \u0627\u0644\u0639\u062b\u0648\u0631 \u0639\u0644\u0649 <fullcount> \u0645\u0646 \u0627\u0644\u0639\u064f\u0642\u062f"},"gmailcheck_exception":{"message":"\u0627\u0633\u062a\u062b\u0646\u0627\u0621: $1","placeholders":{"1":{"content":"$1"}}}}
diff --git a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/bg/messages.json b/chrome/common/extensions/docs/examples/extensions/gmail/_locales/bg/messages.json
deleted file mode 100644
index 0903503..0000000
--- a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/bg/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"gmailcheck_name":{"message":"Google \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043d\u0430 \u043f\u043e\u0449\u0430\u0442\u0430"},"gmailcheck_description":{"message":"\u041f\u043e\u043a\u0430\u0437\u0432\u0430 \u0431\u0440\u043e\u044f \u043d\u0435\u043f\u0440\u043e\u0447\u0435\u0442\u0435\u043d\u0438 \u0441\u044a\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0432\u044a\u0432 \u0432\u0445\u043e\u0434\u044f\u0449\u0430\u0442\u0430 \u0432\u0438 \u043f\u043e\u0449\u0430 \u0432 Google Mail. \u041c\u043e\u0436\u0435\u0442\u0435 \u0441\u044a\u0449\u043e \u0434\u0430 \u043a\u043b\u0438\u043a\u043d\u0435\u0442\u0435 \u0432\u044a\u0440\u0445\u0443 \u0431\u0443\u0442\u043e\u043d\u0430, \u0437\u0430 \u0434\u0430 \u044f \u043e\u0442\u0432\u043e\u0440\u0438\u0442\u0435."},"gmailcheck_node_error":{"message":"\u0413\u0440\u0435\u0448\u043a\u0430: \u0415\u043c\u0438\u0441\u0438\u044f\u0442\u0430 \u0431\u0435 \u0438\u0437\u0432\u043b\u0435\u0447\u0435\u043d\u0430, \u043d\u043e \u043d\u044f\u043c\u0430 \u043d\u0430\u043c\u0435\u0440\u0435\u043d \u0432\u044a\u0437\u0435\u043b <fullcount>"},"gmailcheck_exception":{"message":"\u0438\u0437\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435: $1","placeholders":{"1":{"content":"$1"}}}}
diff --git a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/ca/messages.json b/chrome/common/extensions/docs/examples/extensions/gmail/_locales/ca/messages.json
deleted file mode 100644
index 6c2b1b2..0000000
--- a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/ca/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"gmailcheck_name":{"message":"Verificador de Google Mail"},"gmailcheck_description":{"message":"Mostra el nombre de missatges no llegits que hi ha a la vostra safata d'entrada de Google Mail. Tamb\u00e9 podeu fer clic al bot\u00f3 per obrir la safata d'entrada."},"gmailcheck_node_error":{"message":"Error: s'ha recuperat el feed, per\u00f2 no s'ha trobat cap node <fullcount>"},"gmailcheck_exception":{"message":"excepci\u00f3: $1","placeholders":{"1":{"content":"$1"}}}}
diff --git a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/cs/messages.json b/chrome/common/extensions/docs/examples/extensions/gmail/_locales/cs/messages.json
deleted file mode 100644
index 394e6add..0000000
--- a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/cs/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"gmailcheck_name":{"message":"Kontrola e-mailu Google"},"gmailcheck_description":{"message":"Zobraz\u00ed po\u010det nep\u0159e\u010dten\u00fdch zpr\u00e1v ve slo\u017ece Doru\u010den\u00e1 po\u0161ta slu\u017eby Google Mail. Kliknut\u00edm na tla\u010d\u00edtko tuto slo\u017eku otev\u0159ete."},"gmailcheck_node_error":{"message":"Chyba: Zdroj byl na\u010dten, nebyl v\u0161ak nalezen \u017e\u00e1dn\u00fd uzel <fullcount>."},"gmailcheck_exception":{"message":"v\u00fdjimka: $1","placeholders":{"1":{"content":"$1"}}}}
diff --git a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/da/messages.json b/chrome/common/extensions/docs/examples/extensions/gmail/_locales/da/messages.json
deleted file mode 100644
index e1c2f82..0000000
--- a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/da/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"gmailcheck_name":{"message":"Google E-mail-t\u00e6ller"},"gmailcheck_description":{"message":"Viser antallet af ul\u00e6ste meddelelser i din Google Mail-indbakke. Du kan ogs\u00e5 klikke p\u00e5 knappen for at \u00e5bne din indbakke."},"gmailcheck_node_error":{"message":"Fejl: Feedet blev hentet, men der blev ikke fundet nogen <fullcount>-node"},"gmailcheck_exception":{"message":"undtagelse: $1","placeholders":{"1":{"content":"$1"}}}}
diff --git a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/de/messages.json b/chrome/common/extensions/docs/examples/extensions/gmail/_locales/de/messages.json
deleted file mode 100644
index 6c21886..0000000
--- a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/de/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"gmailcheck_name":{"message":"Google Mail-Checker"},"gmailcheck_description":{"message":"Zeigt die Anzahl ungelesener Nachrichten in Ihrem Google Mail-Posteingang an. Sie k\u00f6nnen auch auf diese Schaltfl\u00e4che klicken, um Ihren Posteingang zu \u00f6ffnen."},"gmailcheck_node_error":{"message":"Fehler: Feed abgerufen, aber kein <fullcount> Knoten gefunden"},"gmailcheck_exception":{"message":"Ausnahme: $1","placeholders":{"1":{"content":"$1"}}}}
diff --git a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/el/messages.json b/chrome/common/extensions/docs/examples/extensions/gmail/_locales/el/messages.json
deleted file mode 100644
index 7db2714..0000000
--- a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/el/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"gmailcheck_name":{"message":"\u0388\u03bb\u03b5\u03b3\u03c7\u03bf\u03c2 \u03c4\u03bf\u03c5 Google Mail"},"gmailcheck_description":{"message":"\u0395\u03bc\u03c6\u03b1\u03bd\u03af\u03b6\u03b5\u03b9 \u03c4\u03bf\u03bd \u03b1\u03c1\u03b9\u03b8\u03bc\u03cc \u03c4\u03c9\u03bd \u03bc\u03b7 \u03b1\u03bd\u03b1\u03b3\u03bd\u03c9\u03c3\u03bc\u03ad\u03bd\u03c9\u03bd \u03bc\u03b7\u03bd\u03c5\u03bc\u03ac\u03c4\u03c9\u03bd \u03c3\u03c4\u03b1 \u03b5\u03b9\u03c3\u03b5\u03c1\u03c7\u03cc\u03bc\u03b5\u03bd\u03b1 \u03c4\u03bf\u03c5 Google Mail \u03c3\u03b1\u03c2. \u039c\u03c0\u03bf\u03c1\u03b5\u03af\u03c4\u03b5 \u03b5\u03c0\u03af\u03c3\u03b7\u03c2 \u03bd\u03b1 \u03ba\u03ac\u03bd\u03b5\u03c4\u03b5 \u03ba\u03bb\u03b9\u03ba \u03c3\u03c4\u03bf \u03ba\u03bf\u03c5\u03bc\u03c0\u03af \u03b3\u03b9\u03b1 \u03bd\u03b1 \u03b1\u03bd\u03bf\u03af\u03be\u03b5\u03c4\u03b5 \u03c4\u03b1 \u03b5\u03b9\u03c3\u03b5\u03c1\u03c7\u03cc\u03bc\u03b5\u03bd\u03ac \u03c3\u03b1\u03c2."},"gmailcheck_node_error":{"message":"\u03a3\u03c6\u03ac\u03bb\u03bc\u03b1: \u03ad\u03b3\u03b9\u03bd\u03b5 \u03b1\u03bd\u03ac\u03ba\u03c4\u03b7\u03c3\u03b7 \u03c1\u03bf\u03ae\u03c2, \u03b1\u03bb\u03bb\u03ac \u03b4\u03b5\u03bd \u03b2\u03c1\u03ad\u03b8\u03b7\u03ba\u03b5 \u03ba\u03cc\u03bc\u03b2\u03bf\u03c2 <fullcount>"},"gmailcheck_exception":{"message":"\u03b5\u03be\u03b1\u03af\u03c1\u03b5\u03c3\u03b7: $1","placeholders":{"1":{"content":"$1"}}}}
diff --git a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/en/messages.json b/chrome/common/extensions/docs/examples/extensions/gmail/_locales/en/messages.json
deleted file mode 100644
index 063b9ca..0000000
--- a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/en/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"gmailcheck_name":{"message":"Google Mail Checker"},"gmailcheck_description":{"message":"Displays the number of unread messages in your Google Mail inbox. You can also click the button to open your inbox."},"gmailcheck_node_error":{"message":"Error: feed retrieved, but no <fullcount> node found"},"gmailcheck_exception":{"message":"exception: $1","placeholders":{"1":{"content":"$1"}}}}
diff --git a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/en_GB/messages.json b/chrome/common/extensions/docs/examples/extensions/gmail/_locales/en_GB/messages.json
deleted file mode 100644
index d3fa3a3..0000000
--- a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/en_GB/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"gmailcheck_name":{"message":"Google Mail Checker"},"gmailcheck_description":{"message":"Displays the number of unread messages in your Google Mail inbox. You can also click the button to open your inbox."},"gmailcheck_node_error":{"message":"Error: Feed retrieved, but no <fullcount> node found"},"gmailcheck_exception":{"message":"exception: $1","placeholders":{"1":{"content":"$1"}}}}
diff --git a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/es/messages.json b/chrome/common/extensions/docs/examples/extensions/gmail/_locales/es/messages.json
deleted file mode 100644
index 4d8364f..0000000
--- a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/es/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"gmailcheck_name":{"message":"Google Mail Checker"},"gmailcheck_description":{"message":"Permite ver el n\u00famero de mensajes sin leer en la bandeja de entrada de Google Mail. Tambi\u00e9n puedes hacer clic en el bot\u00f3n para abrir la bandeja de entrada."},"gmailcheck_node_error":{"message":"Se ha producido un error: el feed se ha recuperado, pero no se ha encontrado ning\u00fan nodo <fullcount>."},"gmailcheck_exception":{"message":"excepci\u00f3n: $1","placeholders":{"1":{"content":"$1"}}}}
diff --git a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/es_419/messages.json b/chrome/common/extensions/docs/examples/extensions/gmail/_locales/es_419/messages.json
deleted file mode 100644
index 54bf2703..0000000
--- a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/es_419/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"gmailcheck_name":{"message":"Google Mail Checker"},"gmailcheck_description":{"message":"Muestra el n\u00famero de mensajes sin leer en tu bandeja de entrada de Google Mail. Tambi\u00e9n puedes hacer clic en el bot\u00f3n para abrir tu bandeja de entrada."},"gmailcheck_node_error":{"message":"Error: se recuper\u00f3 el feed, pero no se encontr\u00f3 el nodo <fullcount>"},"gmailcheck_exception":{"message":"excepci\u00f3n: $1","placeholders":{"1":{"content":"$1"}}}}
diff --git a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/et/messages.json b/chrome/common/extensions/docs/examples/extensions/gmail/_locales/et/messages.json
deleted file mode 100644
index 20b1e844..0000000
--- a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/et/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"gmailcheck_name":{"message":"Google'i meilikontrollija"},"gmailcheck_description":{"message":"Kuvab Google Maili postkastis olevate lugemata s\u00f5numite arvu. V\u00f5ite kl\u00f5psata ka nupul ja avada postkasti."},"gmailcheck_node_error":{"message":"Viga: voog vastuv\u00f5etud, kuid \u00fchtki <fullcount> s\u00f5lme ei leitud"},"gmailcheck_exception":{"message":"erand: $1","placeholders":{"1":{"content":"$1"}}}}
diff --git a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/fi/messages.json b/chrome/common/extensions/docs/examples/extensions/gmail/_locales/fi/messages.json
deleted file mode 100644
index f9da2c1..0000000
--- a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/fi/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"gmailcheck_name":{"message":"Google-s\u00e4hk\u00f6postin tarkistus"},"gmailcheck_description":{"message":"N\u00e4ytt\u00e4\u00e4, kuinka monta lukematonta viesti\u00e4 Google Mail -postilaatikossasi on. Voit my\u00f6s avata postilaatikkosi napsauttamalla painiketta."},"gmailcheck_node_error":{"message":"Virhe: sy\u00f6te haettiin, mutta <fullcount>-solmua ei l\u00f6ytynyt"},"gmailcheck_exception":{"message":"poikkeus: $1","placeholders":{"1":{"content":"$1"}}}}
diff --git a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/fil/messages.json b/chrome/common/extensions/docs/examples/extensions/gmail/_locales/fil/messages.json
deleted file mode 100644
index 1a019a60..0000000
--- a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/fil/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"gmailcheck_name":{"message":"Google Mail Checker"},"gmailcheck_description":{"message":"Ipinapakita ang bilang ng mga hindi pa nababasang mensahe sa inbox ng iyong Google Mail. Maaari mo ring i-click ang pindutan upang buksan ang iyong inbox."},"gmailcheck_node_error":{"message":"Error: nakuha ang feed, ngunit walang <fullcount> node na natagpuan"},"gmailcheck_exception":{"message":"pagbubukod: $1","placeholders":{"1":{"content":"$1"}}}}
diff --git a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/fr/messages.json b/chrome/common/extensions/docs/examples/extensions/gmail/_locales/fr/messages.json
deleted file mode 100644
index 2900819..0000000
--- a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/fr/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"gmailcheck_name":{"message":"V\u00e9rificateur de messages Google"},"gmailcheck_description":{"message":"Affiche le nombre de messages non lus dans votre bo\u00eete de r\u00e9ception Google\u00a0Mail. Vous avez \u00e9galement la possibilit\u00e9 de cliquer sur ce bouton pour ouvrir cette derni\u00e8re."},"gmailcheck_node_error":{"message":"Erreur\u00a0: flux r\u00e9cup\u00e9r\u00e9, mais aucun n\u0153ud <fullcount> trouv\u00e9"},"gmailcheck_exception":{"message":"exception\u00a0: $1","placeholders":{"1":{"content":"$1"}}}}
diff --git a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/he/messages.json b/chrome/common/extensions/docs/examples/extensions/gmail/_locales/he/messages.json
deleted file mode 100644
index c32e982..0000000
--- a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/he/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"gmailcheck_name":{"message":"Google Mail Checker"},"gmailcheck_description":{"message":"\u05de\u05e6\u05d9\u05d2 \u05d0\u05ea \u05de\u05e1\u05e4\u05e8 \u05d4\u05d4\u05d5\u05d3\u05e2\u05d5\u05ea \u05e9\u05dc\u05d0 \u05e0\u05e7\u05e8\u05d0\u05d5 \u05d1\u05ea\u05d9\u05d1\u05ea \u05d4\u05d3\u05d5\u05d0\u05e8 \u05d4\u05e0\u05db\u05e0\u05e1 \u05e9\u05dc\u05da \u05d1-Google Mail. \u05d1\u05e0\u05d5\u05e1\u05e3, \u05ea\u05d5\u05db\u05dc \u05dc\u05dc\u05d7\u05d5\u05e5 \u05e2\u05dc \u05d4\u05dc\u05d7\u05e6\u05df \u05db\u05d3\u05d9 \u05dc\u05e4\u05ea\u05d5\u05d7 \u05d0\u05ea \u05ea\u05d9\u05d1\u05ea \u05d4\u05d3\u05d5\u05d0\u05e8 \u05d4\u05e0\u05db\u05e0\u05e1."},"gmailcheck_node_error":{"message":"\u05e9\u05d2\u05d9\u05d0\u05d4: \u05d4\u05e2\u05d3\u05db\u05d5\u05df \u05d0\u05d5\u05d7\u05d6\u05e8, \u05d0\u05da \u05dc\u05d0 \u05e0\u05de\u05e6\u05d0\u05d5 \u05e6\u05de\u05ea\u05d9\u05dd \u05e9\u05dc <fullcount>"},"gmailcheck_exception":{"message":"\u05d7\u05e8\u05d9\u05d2: $1","placeholders":{"1":{"content":"$1"}}}}
diff --git a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/hi/messages.json b/chrome/common/extensions/docs/examples/extensions/gmail/_locales/hi/messages.json
deleted file mode 100644
index 0056c56..0000000
--- a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/hi/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"gmailcheck_name":{"message":"Google \u092e\u0947\u0932 \u091c\u093e\u0902\u091a\u0915\u0930\u094d\u0924\u093e"},"gmailcheck_description":{"message":"\u0906\u092a\u0915\u0947 Google \u092e\u0947\u0932 \u0907\u0928\u092c\u0949\u0915\u094d\u0938 \u092e\u0947\u0902 \u0928 \u092a\u095d\u0947 \u0917\u090f \u0938\u0902\u0926\u0947\u0936\u094b\u0902 \u0915\u0940 \u0938\u0902\u0916\u094d\u092f\u093e \u092a\u094d\u0930\u0926\u0930\u094d\u0936\u093f\u0924 \u0915\u0930\u0924\u093e \u0939\u0948. \u0906\u092a \u0905\u092a\u0928\u093e \u0907\u0928\u092c\u0949\u0915\u094d\u0938 \u0916\u094b\u0932\u0928\u0947 \u0915\u0947 \u0932\u093f\u090f \u092c\u091f\u0928 \u0915\u094d\u0932\u093f\u0915 \u092d\u0940 \u0915\u0930 \u0938\u0915\u0924\u0947 \u0939\u0948\u0902."},"gmailcheck_node_error":{"message":"\u0924\u094d\u0930\u0941\u091f\u093f: \u095e\u0940\u0921 \u092a\u0941\u0928\u0930\u094d\u092a\u094d\u0930\u093e\u092a\u094d\u0924 \u0915\u0940 \u0917\u0908, \u0932\u0947\u0915\u093f\u0928 \u0915\u094b\u0908 <fullcount> \u0928\u094b\u0921 \u0928\u0939\u0940\u0902 \u092e\u093f\u0932\u093e"},"gmailcheck_exception":{"message":"\u0905\u092a\u0935\u093e\u0926: $1","placeholders":{"1":{"content":"$1"}}}}
diff --git a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/hr/messages.json b/chrome/common/extensions/docs/examples/extensions/gmail/_locales/hr/messages.json
deleted file mode 100644
index 94dce1c..0000000
--- a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/hr/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"gmailcheck_name":{"message":"Google Provjera po\u0161te"},"gmailcheck_description":{"message":"Prikazuje broj nepro\u010ditanih poruka u ulaznom pretincu usluge Google Mail. Mo\u017eete tako\u0111er kliknuti gumb za otvaranje ulazne po\u0161te."},"gmailcheck_node_error":{"message":"Pogre\u0161ka: Feed je dohva\u0107en, ali nije prona\u0111eno \u010dvori\u0161te <fullcount>"},"gmailcheck_exception":{"message":"izuzetak: $1","placeholders":{"1":{"content":"$1"}}}}
diff --git a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/hu/messages.json b/chrome/common/extensions/docs/examples/extensions/gmail/_locales/hu/messages.json
deleted file mode 100644
index 8b3e6c9..0000000
--- a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/hu/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"gmailcheck_name":{"message":"Google Lev\u00e9lfigyel\u0151"},"gmailcheck_description":{"message":"Megjelen\u00edti az olvasatlan \u00fczeneteket a Google Mail be\u00e9rkez\u0151 levelei k\u00f6z\u00f6tt. A gombra kattintva is megnyithatja a be\u00e9rkez\u0151 leveleit."},"gmailcheck_node_error":{"message":"Hiba: h\u00edrcsatorna leh\u00edvva, de a csom\u00f3pont (<fullcount>) hi\u00e1nyzik"},"gmailcheck_exception":{"message":"kiv\u00e9tel: $1","placeholders":{"1":{"content":"$1"}}}}
diff --git a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/id/messages.json b/chrome/common/extensions/docs/examples/extensions/gmail/_locales/id/messages.json
deleted file mode 100644
index 4a8d09c..0000000
--- a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/id/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"gmailcheck_name":{"message":"Google Mail Checker"},"gmailcheck_description":{"message":"Menampilkan jumlah pesan yang belum dibaca dalam kotak masuk Google Mail. Anda juga dapat mengeklik tombol ini untuk membuka kotak masuk."},"gmailcheck_node_error":{"message":"Galat: umpan diperoleh, tetapi tidak ada <fullcount> node yang ditemukan"},"gmailcheck_exception":{"message":"pengecualian: $1","placeholders":{"1":{"content":"$1"}}}}
diff --git a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/it/messages.json b/chrome/common/extensions/docs/examples/extensions/gmail/_locales/it/messages.json
deleted file mode 100644
index 13b6e78..0000000
--- a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/it/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"gmailcheck_name":{"message":"Google Avvisi email"},"gmailcheck_description":{"message":"Visualizza il numero di messaggi da leggere nella posta in arrivo di Google Mail. Puoi anche fare clic sul pulsante per aprire la tua posta in arrivo."},"gmailcheck_node_error":{"message":"Errore: feed recuperato ma non sono stati trovati nodi <fullcount>"},"gmailcheck_exception":{"message":"eccezione: $1","placeholders":{"1":{"content":"$1"}}}}
diff --git a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/ja/messages.json b/chrome/common/extensions/docs/examples/extensions/gmail/_locales/ja/messages.json
deleted file mode 100644
index 3ce2669..0000000
--- a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/ja/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"gmailcheck_name":{"message":"Google Mail Checker"},"gmailcheck_description":{"message":"Google Mail \u306e\u53d7\u4fe1\u30c8\u30ec\u30a4\u306b\u3042\u308b\u672a\u8aad\u306e\u30e1\u30fc\u30eb\u6570\u3092\u8868\u793a\u3057\u307e\u3059\u3002\u3053\u306e\u30dc\u30bf\u30f3\u3092\u30af\u30ea\u30c3\u30af\u3057\u3066\u53d7\u4fe1\u30c8\u30ec\u30a4\u3092\u958b\u304f\u3053\u3068\u3082\u3067\u304d\u307e\u3059\u3002"},"gmailcheck_node_error":{"message":"\u30a8\u30e9\u30fc: \u53d6\u5f97\u3057\u305f\u30d5\u30a3\u30fc\u30c9\u306b <fullcount> \u30ce\u30fc\u30c9\u304c\u3042\u308a\u307e\u305b\u3093"},"gmailcheck_exception":{"message":"\u4f8b\u5916: $1","placeholders":{"1":{"content":"$1"}}}}
diff --git a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/ko/messages.json b/chrome/common/extensions/docs/examples/extensions/gmail/_locales/ko/messages.json
deleted file mode 100644
index 934e49e..0000000
--- a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/ko/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"gmailcheck_name":{"message":"Google Mail Checker"},"gmailcheck_description":{"message":"Gmaill \ubc1b\uc740\ud3b8\uc9c0\ud568\uc5d0\uc11c \uc77d\uc9c0 \uc54a\uc740 \uba54\uc77c\uc758 \uc218\ub97c \ub098\ud0c0\ub0c5\ub2c8\ub2e4. \ub610\ud55c \ubc84\ud2bc\uc744 \ud074\ub9ad\ud558\uc5ec \ubc1b\uc740\ud3b8\uc9c0\ud568\uc744 \uc5f4 \uc218\ub3c4 \uc788\uc2b5\ub2c8\ub2e4."},"gmailcheck_node_error":{"message":"\uc624\ub958: \ud53c\ub4dc\ub97c \uac80\uc0c9\ud588\uc73c\ub098 \ucd1d <fullcount>\uac1c\uc758 \ub178\ub4dc\ub97c \ucc3e\uc9c0 \ubabb\ud588\uc2b5\ub2c8\ub2e4."},"gmailcheck_exception":{"message":"\uc608\uc678: $1","placeholders":{"1":{"content":"$1"}}}}
diff --git a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/lt/messages.json b/chrome/common/extensions/docs/examples/extensions/gmail/_locales/lt/messages.json
deleted file mode 100644
index 7da57e1..0000000
--- a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/lt/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"gmailcheck_name":{"message":"\u201eGoogle\u201c pa\u0161to tikrintuvas"},"gmailcheck_description":{"message":"Pateikiamas \u201eGoogle\u201c pa\u0161to gaut\u0173 lai\u0161k\u0173 aplanke esan\u010di\u0173 neperskaityt\u0173 prane\u0161im\u0173 skai\u010dius. Be to, jei norite atidaryti gaut\u0173 lai\u0161k\u0173 aplank\u0105, galite spustel\u0117ti mygtuk\u0105."},"gmailcheck_node_error":{"message":"Klaida: sklaidos kanalas nuskaitytas, ta\u010diau nerastas joks <fullcount> mazgas"},"gmailcheck_exception":{"message":"i\u0161imtis: $1","placeholders":{"1":{"content":"$1"}}}}
diff --git a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/lv/messages.json b/chrome/common/extensions/docs/examples/extensions/gmail/_locales/lv/messages.json
deleted file mode 100644
index 52f2ca3..0000000
--- a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/lv/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"gmailcheck_name":{"message":"Google Mail Checker"},"gmailcheck_description":{"message":"Tiek r\u0101d\u012bts nelas\u012bto zi\u0146ojumu skaits Google Mail ies\u016btn\u0113. Varat ar\u012b noklik\u0161\u0137in\u0101t uz pogas, lai atv\u0113rtu ies\u016btni."},"gmailcheck_node_error":{"message":"K\u013c\u016bda: pl\u016bsma ir izg\u016bta, ta\u010du netika atrasts neviens <fullcount> mezgls"},"gmailcheck_exception":{"message":"iz\u0146\u0113mums: $1","placeholders":{"1":{"content":"$1"}}}}
diff --git a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/nb/messages.json b/chrome/common/extensions/docs/examples/extensions/gmail/_locales/nb/messages.json
deleted file mode 100644
index ad8a09d..0000000
--- a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/nb/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"gmailcheck_name":{"message":"Google e-post-sjekker"},"gmailcheck_description":{"message":"Viser antallet uleste meldinger i innboksen for Google Mail. Du kan ogs\u00e5 klikke p\u00e5 knappen for \u00e5 \u00e5pne innboksen."},"gmailcheck_node_error":{"message":"Feil: innmating hentet, men finner ingen <fullcount>-node"},"gmailcheck_exception":{"message":"unntak: $1","placeholders":{"1":{"content":"$1"}}}}
diff --git a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/nl/messages.json b/chrome/common/extensions/docs/examples/extensions/gmail/_locales/nl/messages.json
deleted file mode 100644
index c40d81fa..0000000
--- a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/nl/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"gmailcheck_name":{"message":"Google Mail Checker"},"gmailcheck_description":{"message":"Hiermee wordt het aantal ongelezen berichten in uw Postvak IN van Gmail weergegeven. U kunt ook op de knop klikken om het Postvak IN te openen."},"gmailcheck_node_error":{"message":"Fout: feed opgehaald, maar het knooppunt <fullcount> is niet gevonden"},"gmailcheck_exception":{"message":"uitzondering: $1","placeholders":{"1":{"content":"$1"}}}}
diff --git a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/pl/messages.json b/chrome/common/extensions/docs/examples/extensions/gmail/_locales/pl/messages.json
deleted file mode 100644
index d607a06..0000000
--- a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/pl/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"gmailcheck_name":{"message":"Sprawdzanie poczty Google"},"gmailcheck_description":{"message":"Wy\u015bwietla liczb\u0119 nieprzeczytanych wiadomo\u015bci w Twojej skrzynce odbiorczej Google Mail. Mo\u017cesz te\u017c klikn\u0105\u0107 przycisk, aby otworzy\u0107 swoj\u0105 skrzynk\u0119 odbiorcz\u0105."},"gmailcheck_node_error":{"message":"B\u0142\u0105d: pobrano kana\u0142, ale nie odnaleziono w\u0119z\u0142a <fullcount>"},"gmailcheck_exception":{"message":"wyj\u0105tek: $1","placeholders":{"1":{"content":"$1"}}}}
diff --git a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/pt_BR/messages.json b/chrome/common/extensions/docs/examples/extensions/gmail/_locales/pt_BR/messages.json
deleted file mode 100644
index 1175d0c..0000000
--- a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/pt_BR/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"gmailcheck_name":{"message":"Verificador de mensagens do Google"},"gmailcheck_description":{"message":"Exibe o n\u00famero de mensagens n\u00e3o lidas na sua Caixa de entrada do Gmail. Voc\u00ea tamb\u00e9m pode clicar no bot\u00e3o para abrir a sua caixa de entrada."},"gmailcheck_node_error":{"message":"Erro: feed recuperado, mas nenhum n\u00f3 <fullcount> encontrado"},"gmailcheck_exception":{"message":"exce\u00e7\u00e3o: $1","placeholders":{"1":{"content":"$1"}}}}
diff --git a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/pt_PT/messages.json b/chrome/common/extensions/docs/examples/extensions/gmail/_locales/pt_PT/messages.json
deleted file mode 100644
index e6d8992a..0000000
--- a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/pt_PT/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"gmailcheck_name":{"message":"Verificador do Google Mail"},"gmailcheck_description":{"message":"Apresenta o n\u00famero de mensagens n\u00e3o lidas existentes na sua caixa de entrada do Google Mail. Pode tamb\u00e9m clicar no bot\u00e3o para abrir a caixa de entrada."},"gmailcheck_node_error":{"message":"Erro: obteve-se o feed, mas n\u00e3o foi encontrado nenhum n\u00f3 <fullcount>"},"gmailcheck_exception":{"message":"excep\u00e7\u00e3o: $1","placeholders":{"1":{"content":"$1"}}}}
diff --git a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/ro/messages.json b/chrome/common/extensions/docs/examples/extensions/gmail/_locales/ro/messages.json
deleted file mode 100644
index d0d5838..0000000
--- a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/ro/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"gmailcheck_name":{"message":"Google Verificator de e-mail"},"gmailcheck_description":{"message":"Afi\u015feaz\u0103 num\u0103rul mesajelor necitite din folderul Mesaje primite al contului Google Mail. De asemenea, pute\u0163i s\u0103 face\u0163i clic pe buton pentru a deschide folderul Mesaje primite."},"gmailcheck_node_error":{"message":"Eroare: s-a preluat feedul, dar nu s-a g\u0103sit niciun nod <fullcount>"},"gmailcheck_exception":{"message":"excep\u0163ie: $1","placeholders":{"1":{"content":"$1"}}}}
diff --git a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/ru/messages.json b/chrome/common/extensions/docs/examples/extensions/gmail/_locales/ru/messages.json
deleted file mode 100644
index dedaef13..0000000
--- a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/ru/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"gmailcheck_name":{"message":"Google Mail Checker"},"gmailcheck_description":{"message":"\u041e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u043d\u0435\u043f\u0440\u043e\u0447\u0438\u0442\u0430\u043d\u043d\u044b\u0445 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0432 \u043f\u043e\u0447\u0442\u043e\u0432\u043e\u043c \u044f\u0449\u0438\u043a\u0435 Google Mail. \u041c\u043e\u0436\u043d\u043e \u0442\u0430\u043a\u0436\u0435 \u043d\u0430\u0436\u0430\u0442\u044c \u043a\u043d\u043e\u043f\u043a\u0443, \u0447\u0442\u043e\u0431\u044b \u043e\u0442\u043a\u0440\u044b\u0442\u044c \u043f\u0430\u043f\u043a\u0443 \"\u0412\u0445\u043e\u0434\u044f\u0449\u0438\u0435\"."},"gmailcheck_node_error":{"message":"\u041e\u0448\u0438\u0431\u043a\u0430: \u0444\u0438\u0434 \u0431\u044b\u043b \u043f\u043e\u043b\u0443\u0447\u0435\u043d, \u043d\u043e \u043d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u043d\u0430\u0439\u0442\u0438 \u0443\u0437\u0435\u043b <fullcount>"},"gmailcheck_exception":{"message":"\u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435: $1","placeholders":{"1":{"content":"$1"}}}}
diff --git a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/sk/messages.json b/chrome/common/extensions/docs/examples/extensions/gmail/_locales/sk/messages.json
deleted file mode 100644
index 13d902a7..0000000
--- a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/sk/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"gmailcheck_name":{"message":"Kontrola po\u0161ty Google"},"gmailcheck_description":{"message":"Zobraz\u00ed po\u010det nepre\u010d\u00edtan\u00fdch spr\u00e1v v prie\u010dinku doru\u010denej po\u0161ty v slu\u017ebe Gmail. Kliknut\u00edm na tla\u010didlo prie\u010dinok doru\u010denej po\u0161ty otvor\u00edte."},"gmailcheck_node_error":{"message":"Chyba: informa\u010dn\u00fd kan\u00e1l bol na\u010d\u00edtan\u00fd, nena\u0161iel sa v\u0161ak \u017eiadny uzol <fullcount>."},"gmailcheck_exception":{"message":"v\u00fdnimka: $1","placeholders":{"1":{"content":"$1"}}}}
diff --git a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/sl/messages.json b/chrome/common/extensions/docs/examples/extensions/gmail/_locales/sl/messages.json
deleted file mode 100644
index 962a8c6e..0000000
--- a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/sl/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"gmailcheck_name":{"message":"Preverjevalnik za Google Mail"},"gmailcheck_description":{"message":"Prika\u017ee \u0161tevilo neprebranih sporo\u010dil v nabiralniku storitve Google Mail. Nabiralnik lahko odprete tudi s klikom gumba."},"gmailcheck_node_error":{"message":"Napaka: vir prejet, vendar ni bilo najdeno nobeno vozli\u0161\u010de <fullcount>"},"gmailcheck_exception":{"message":"izjema: $1","placeholders":{"1":{"content":"$1"}}}}
diff --git a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/sr/messages.json b/chrome/common/extensions/docs/examples/extensions/gmail/_locales/sr/messages.json
deleted file mode 100644
index a2cfdb4..0000000
--- a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/sr/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"gmailcheck_name":{"message":"Google \u043f\u0440\u043e\u0432\u0435\u0440\u0430 \u043f\u043e\u0448\u0442\u0435"},"gmailcheck_description":{"message":"\u041f\u0440\u0438\u043a\u0430\u0437\u0443\u0458\u0435 \u0431\u0440\u043e\u0458 \u043d\u0435\u043f\u0440\u043e\u0447\u0438\u0442\u0430\u043d\u0438\u0445 \u043f\u0440\u0438\u043c\u0459\u0435\u043d\u0438\u0445 \u043f\u043e\u0440\u0443\u043a\u0430 Google Mail-\u0430. \u041c\u043e\u0436\u0435\u0442\u0435 \u0438 \u0434\u0430 \u043a\u043b\u0438\u043a\u043d\u0435\u0442\u0435 \u043d\u0430 \u0434\u0443\u0433\u043c\u0435 \u0438 \u043e\u0442\u0432\u043e\u0440\u0438\u0442\u0435 \u043f\u0440\u0438\u043c\u0459\u0435\u043d\u0435 \u043f\u043e\u0440\u0443\u043a\u0435."},"gmailcheck_node_error":{"message":"\u0413\u0440\u0435\u0448\u043a\u0430: \u0424\u0438\u0434 \u0458\u0435 \u043f\u0440\u0435\u0443\u0437\u0435\u0442, \u0430\u043b\u0438 \u0447\u0432\u043e\u0440 <fullcount> \u043d\u0438\u0458\u0435 \u043f\u0440\u043e\u043d\u0430\u0452\u0435\u043d"},"gmailcheck_exception":{"message":"\u0438\u0437\u0443\u0437\u0435\u0442\u0430\u043a: $1","placeholders":{"1":{"content":"$1"}}}}
diff --git a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/sv/messages.json b/chrome/common/extensions/docs/examples/extensions/gmail/_locales/sv/messages.json
deleted file mode 100644
index b4359f35..0000000
--- a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/sv/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"gmailcheck_name":{"message":"Google Mail Checker"},"gmailcheck_description":{"message":"Visar hur m\u00e5nga ol\u00e4sta meddelanden du har i inkorgen i Google Mail. Du kan ocks\u00e5 klicka p\u00e5 knappen om du vill \u00f6ppna inkorgen."},"gmailcheck_node_error":{"message":"Fel: feeden h\u00e4mtades, men ingen <fullcount>-nod hittades"},"gmailcheck_exception":{"message":"undantag: $1","placeholders":{"1":{"content":"$1"}}}}
diff --git a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/th/messages.json b/chrome/common/extensions/docs/examples/extensions/gmail/_locales/th/messages.json
deleted file mode 100644
index e5bef6c..0000000
--- a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/th/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"gmailcheck_name":{"message":"Google Mail Checker"},"gmailcheck_description":{"message":"\u0e41\u0e2a\u0e14\u0e07\u0e08\u0e33\u0e19\u0e27\u0e19\u0e02\u0e2d\u0e07\u0e02\u0e49\u0e2d\u0e04\u0e27\u0e32\u0e21\u0e17\u0e35\u0e48\u0e22\u0e31\u0e07\u0e44\u0e21\u0e48\u0e44\u0e14\u0e49\u0e2d\u0e48\u0e32\u0e19\u0e43\u0e19\u0e01\u0e25\u0e48\u0e2d\u0e07\u0e08\u0e14\u0e2b\u0e21\u0e32\u0e22 Google Mail \u0e02\u0e2d\u0e07\u0e04\u0e38\u0e13 \u0e41\u0e25\u0e30\u0e04\u0e38\u0e13\u0e2a\u0e32\u0e21\u0e32\u0e23\u0e16\u0e04\u0e25\u0e34\u0e01\u0e1b\u0e38\u0e48\u0e21\u0e40\u0e1e\u0e37\u0e48\u0e2d\u0e40\u0e1b\u0e34\u0e14\u0e01\u0e25\u0e48\u0e2d\u0e07\u0e08\u0e14\u0e2b\u0e21\u0e32\u0e22\u0e02\u0e2d\u0e07\u0e04\u0e38\u0e13\u0e44\u0e14\u0e49\u0e40\u0e0a\u0e48\u0e19\u0e01\u0e31\u0e19"},"gmailcheck_node_error":{"message":"\u0e02\u0e49\u0e2d\u0e1c\u0e34\u0e14\u0e1e\u0e25\u0e32\u0e14: \u0e40\u0e23\u0e35\u0e22\u0e01\u0e04\u0e37\u0e19\u0e1f\u0e35\u0e14\u0e41\u0e25\u0e49\u0e27 \u0e41\u0e15\u0e48\u0e44\u0e21\u0e48\u0e1e\u0e1a\u0e42\u0e2b\u0e19\u0e14 <fullcount>"},"gmailcheck_exception":{"message":"\u0e02\u0e49\u0e2d\u0e22\u0e01\u0e40\u0e27\u0e49\u0e19: $1","placeholders":{"1":{"content":"$1"}}}}
diff --git a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/tr/messages.json b/chrome/common/extensions/docs/examples/extensions/gmail/_locales/tr/messages.json
deleted file mode 100644
index 593057d..0000000
--- a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/tr/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"gmailcheck_name":{"message":"Google Mail Checker"},"gmailcheck_description":{"message":"Google Mail gelen kutunuzdaki okunmam\u0131\u015f iletilerin say\u0131s\u0131n\u0131 g\u00f6r\u00fcnt\u00fcler. Ayr\u0131ca, d\u00fc\u011fmeyi t\u0131klayarak gelen kutunuzu da a\u00e7abilirsiniz."},"gmailcheck_node_error":{"message":"Hata: yay\u0131n al\u0131nd\u0131, ancak <fullcount> d\u00fc\u011f\u00fcm\u00fc bulunamad\u0131"},"gmailcheck_exception":{"message":"\u00f6zel durum: $1","placeholders":{"1":{"content":"$1"}}}}
diff --git a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/uk/messages.json b/chrome/common/extensions/docs/examples/extensions/gmail/_locales/uk/messages.json
deleted file mode 100644
index 0d196cc..0000000
--- a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/uk/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"gmailcheck_name":{"message":"\u041f\u0435\u0440\u0435\u0432\u0456\u0440\u043a\u0430 \u043f\u043e\u0448\u0442\u0438 Google"},"gmailcheck_description":{"message":"\u0412\u0456\u0434\u043e\u0431\u0440\u0430\u0436\u0430\u0454 \u043a\u0456\u043b\u044c\u043a\u0456\u0441\u0442\u044c \u043d\u0435\u043f\u0440\u043e\u0447\u0438\u0442\u0430\u043d\u0438\u0445 \u043f\u043e\u0432\u0456\u0434\u043e\u043c\u043b\u0435\u043d\u044c \u0443 \u043f\u0430\u043f\u0446\u0456 \u0437 \u0432\u0445\u0456\u0434\u043d\u0438\u043c\u0438 \u043f\u043e\u0432\u0456\u0434\u043e\u043c\u043b\u0435\u043d\u043d\u044f\u043c\u0438 \u0441\u043b\u0443\u0436\u0431\u0438 Google Mail. \u0429\u043e\u0431 \u0432\u0456\u0434\u043a\u0440\u0438\u0442\u0438 \u043f\u0430\u043f\u043a\u0443 \u0437 \u0432\u0445\u0456\u0434\u043d\u0438\u043c\u0438 \u043f\u043e\u0432\u0456\u0434\u043e\u043c\u043b\u0435\u043d\u043d\u044f\u043c\u0438, \u043c\u043e\u0436\u043d\u0430 \u0442\u0430\u043a\u043e\u0436 \u043d\u0430\u0442\u0438\u0441\u043d\u0443\u0442\u0438 \u0446\u044e \u043a\u043d\u043e\u043f\u043a\u0443."},"gmailcheck_node_error":{"message":"\u041f\u043e\u043c\u0438\u043b\u043a\u0430: \u043a\u0430\u043d\u0430\u043b \u0432\u0456\u0434\u043d\u043e\u0432\u043b\u0435\u043d\u043e, \u0430\u043b\u0435 \u0436\u043e\u0434\u043d\u043e\u0433\u043e \u0432\u0443\u0437\u043b\u0430 <fullcount> \u043d\u0435 \u0437\u043d\u0430\u0439\u0434\u0435\u043d\u043e"},"gmailcheck_exception":{"message":"\u0432\u0438\u043d\u044f\u0442\u043e\u043a: $1","placeholders":{"1":{"content":"$1"}}}}
diff --git a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/vi/messages.json b/chrome/common/extensions/docs/examples/extensions/gmail/_locales/vi/messages.json
deleted file mode 100644
index d26050f..0000000
--- a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/vi/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"gmailcheck_name":{"message":"Tr\u00ecnh Ki\u1ec3m tra Th\u01b0 c\u1ee7a Google"},"gmailcheck_description":{"message":"Hi\u1ec3n th\u1ecb s\u1ed1 th\u01b0 ch\u01b0a \u0111\u1ecdc trong h\u1ed9p th\u01b0 \u0111\u1ebfn Gmail c\u1ee7a b\u1ea1n. B\u1ea1n c\u0169ng c\u00f3 th\u1ec3 nh\u1ea5p v\u00e0o n\u00fat \u0111\u1ec3 m\u1edf h\u1ed9p th\u01b0 \u0111\u1ebfn c\u1ee7a m\u00ecnh."},"gmailcheck_node_error":{"message":"L\u1ed7i: ngu\u1ed3n c\u1ea5p d\u1eef li\u1ec7u \u0111\u00e3 \u0111\u01b0\u1ee3c truy xu\u1ea5t nh\u01b0ng kh\u00f4ng t\u00ecm th\u1ea5y n\u00fat <fullcount> n\u00e0o"},"gmailcheck_exception":{"message":"ngo\u1ea1i l\u1ec7: $1","placeholders":{"1":{"content":"$1"}}}}
diff --git a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/zh_CN/messages.json b/chrome/common/extensions/docs/examples/extensions/gmail/_locales/zh_CN/messages.json
deleted file mode 100644
index ae6227f..0000000
--- a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/zh_CN/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"gmailcheck_name":{"message":"Google Mail Checker"},"gmailcheck_description":{"message":"\u663e\u793a Google Mail \u6536\u4ef6\u7bb1\u4e2d\u7684\u672a\u8bfb\u90ae\u4ef6\u6570\u3002\u70b9\u51fb\u8be5\u6309\u94ae\u8fd8\u53ef\u4ee5\u6253\u5f00\u60a8\u7684\u6536\u4ef6\u7bb1\u3002"},"gmailcheck_node_error":{"message":"\u9519\u8bef\uff1a\u7cfb\u7edf\u5df2\u68c0\u7d22\u4f9b\u7a3f\uff0c\u4f46\u672a\u53d1\u73b0 <fullcount> \u8282\u70b9"},"gmailcheck_exception":{"message":"\u5f02\u5e38\uff1a$1","placeholders":{"1":{"content":"$1"}}}}
diff --git a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/zh_TW/messages.json b/chrome/common/extensions/docs/examples/extensions/gmail/_locales/zh_TW/messages.json
deleted file mode 100644
index 4c317934..0000000
--- a/chrome/common/extensions/docs/examples/extensions/gmail/_locales/zh_TW/messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{"gmailcheck_name":{"message":"Google Mail Checker"},"gmailcheck_description":{"message":"\u5728 Google Mail \u6536\u4ef6\u5323\u4e2d\u986f\u793a\u672a\u8b80\u90f5\u4ef6\u7684\u6578\u76ee\u3002\u6309\u4e00\u4e0b\u6309\u9215\u4e5f\u53ef\u4ee5\u958b\u555f\u6536\u4ef6\u5323\u3002"},"gmailcheck_node_error":{"message":"\u932f\u8aa4\uff1a\u64f7\u53d6\u5230\u8cc7\u8a0a\u63d0\u4f9b\uff0c\u4f46\u627e\u4e0d\u5230 <fullcount> \u7bc0\u9ede"},"gmailcheck_exception":{"message":"\u4f8b\u5916\u72c0\u6cc1\uff1a$1","placeholders":{"1":{"content":"$1"}}}}
diff --git a/chrome/common/extensions/docs/examples/extensions/gmail/background.html b/chrome/common/extensions/docs/examples/extensions/gmail/background.html
deleted file mode 100644
index d7aa811..0000000
--- a/chrome/common/extensions/docs/examples/extensions/gmail/background.html
+++ /dev/null
@@ -1,3 +0,0 @@
-<img id="logged_in" src="gmail_logged_in.png">
-<canvas id="canvas" width="19" height="19">
-<script src="background.js"></script>
diff --git a/chrome/common/extensions/docs/examples/extensions/gmail/background.js b/chrome/common/extensions/docs/examples/extensions/gmail/background.js
deleted file mode 100644
index 8d2c355d..0000000
--- a/chrome/common/extensions/docs/examples/extensions/gmail/background.js
+++ /dev/null
@@ -1,351 +0,0 @@
-// Copyright (c) 2012 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.
-
-var animationFrames = 36;
-var animationSpeed = 10; // ms
-var canvas = document.getElementById('canvas');
-var loggedInImage = document.getElementById('logged_in');
-var canvasContext = canvas.getContext('2d');
-var pollIntervalMin = 1; // 1 minute
-var pollIntervalMax = 60; // 1 hour
-var requestTimeout = 1000 * 2; // 2 seconds
-var rotation = 0;
-var loadingAnimation = new LoadingAnimation();
-
-// Legacy support for pre-event-pages.
-var oldChromeVersion = !chrome.runtime;
-var requestTimerId;
-
-function getGmailUrl() {
- return "https://mail.google.com/mail/";
-}
-
-// Identifier used to debug the possibility of multiple instances of the
-// extension making requests on behalf of a single user.
-function getInstanceId() {
- if (!localStorage.hasOwnProperty("instanceId"))
- localStorage.instanceId = 'gmc' + parseInt(Date.now() * Math.random(), 10);
- return localStorage.instanceId;
-}
-
-function getFeedUrl() {
- // "zx" is a Gmail query parameter that is expected to contain a random
- // string and may be ignored/stripped.
- return getGmailUrl() + "feed/atom?zx=" + encodeURIComponent(getInstanceId());
-}
-
-function isGmailUrl(url) {
- // Return whether the URL starts with the Gmail prefix.
- return url.startsWith(getGmailUrl());
-}
-
-// 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;
-}
-
-function updateIcon() {
- if (!localStorage.hasOwnProperty('unreadCount')) {
- chrome.browserAction.setIcon({path:"gmail_not_logged_in.png"});
- chrome.browserAction.setBadgeBackgroundColor({color:[190, 190, 190, 230]});
- chrome.browserAction.setBadgeText({text:"?"});
- } else {
- chrome.browserAction.setIcon({path: "gmail_logged_in.png"});
- chrome.browserAction.setBadgeBackgroundColor({color:[208, 0, 24, 255]});
- chrome.browserAction.setBadgeText({
- text: localStorage.unreadCount != "0" ? localStorage.unreadCount : ""
- });
- }
-}
-
-function scheduleRequest() {
- console.log('scheduleRequest');
- var randomness = Math.random() * 2;
- var exponent = Math.pow(2, localStorage.requestFailureCount || 0);
- var multiplier = Math.max(randomness * exponent, 1);
- var delay = Math.min(multiplier * pollIntervalMin, pollIntervalMax);
- delay = Math.round(delay);
- console.log('Scheduling for: ' + delay);
-
- if (oldChromeVersion) {
- if (requestTimerId) {
- window.clearTimeout(requestTimerId);
- }
- requestTimerId = window.setTimeout(onAlarm, delay*60*1000);
- } else {
- console.log('Creating alarm');
- // Use a repeating alarm so that it fires again if there was a problem
- // setting the next alarm.
- chrome.alarms.create('refresh', {periodInMinutes: delay});
- }
-}
-
-// ajax stuff
-function startRequest(params) {
- // Schedule request immediately. We want to be sure to reschedule, even in the
- // case where the extension process shuts down while this request is
- // outstanding.
- if (params && params.scheduleRequest) scheduleRequest();
-
- function stopLoadingAnimation() {
- if (params && params.showLoadingAnimation) loadingAnimation.stop();
- }
-
- if (params && params.showLoadingAnimation)
- loadingAnimation.start();
-
- getInboxCount(
- function(count) {
- stopLoadingAnimation();
- updateUnreadCount(count);
- },
- function() {
- stopLoadingAnimation();
- delete localStorage.unreadCount;
- updateIcon();
- }
- );
-}
-
-function getInboxCount(onSuccess, onError) {
- var xhr = new XMLHttpRequest();
- var abortTimerId = window.setTimeout(function() {
- xhr.abort(); // synchronously calls onreadystatechange
- }, requestTimeout);
-
- function handleSuccess(count) {
- localStorage.requestFailureCount = 0;
- window.clearTimeout(abortTimerId);
- if (onSuccess)
- onSuccess(count);
- }
-
- var invokedErrorCallback = false;
- function handleError() {
- ++localStorage.requestFailureCount;
- window.clearTimeout(abortTimerId);
- if (onError && !invokedErrorCallback)
- onError();
- invokedErrorCallback = true;
- }
-
- try {
- xhr.onreadystatechange = function() {
- if (xhr.readyState != 4)
- return;
-
- 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);
- return;
- } else {
- console.error(chrome.i18n.getMessage("gmailcheck_node_error"));
- }
- }
-
- handleError();
- };
-
- xhr.onerror = function(error) {
- handleError();
- };
-
- xhr.open("GET", getFeedUrl(), true);
- xhr.send(null);
- } catch(e) {
- console.error(chrome.i18n.getMessage("gmailcheck_exception", e));
- handleError();
- }
-}
-
-function gmailNSResolver(prefix) {
- if(prefix == 'gmail') {
- return 'http://purl.org/atom/ns#';
- }
-}
-
-function updateUnreadCount(count) {
- var changed = localStorage.unreadCount != count;
- localStorage.unreadCount = count;
- updateIcon();
- if (changed)
- 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;
- updateIcon();
- }
-}
-
-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() {
- console.log('Going to inbox...');
- chrome.tabs.getAllInWindow(undefined, function(tabs) {
- for (var i = 0, tab; tab = tabs[i]; i++) {
- if (tab.url && isGmailUrl(tab.url)) {
- console.log('Found Gmail tab: ' + tab.url + '. ' +
- 'Focusing and refreshing count...');
- chrome.tabs.update(tab.id, {selected: true});
- startRequest({scheduleRequest:false, showLoadingAnimation:false});
- return;
- }
- }
- console.log('Could not find Gmail tab. Creating one...');
- chrome.tabs.create({url: getGmailUrl()});
- });
-}
-
-function onInit() {
- console.log('onInit');
- localStorage.requestFailureCount = 0; // used for exponential backoff
- startRequest({scheduleRequest:true, showLoadingAnimation:true});
- if (!oldChromeVersion) {
- // TODO(mpcomplete): We should be able to remove this now, but leaving it
- // for a little while just to be sure the refresh alarm is working nicely.
- chrome.alarms.create('watchdog', {periodInMinutes:5});
- }
-}
-
-function onAlarm(alarm) {
- console.log('Got alarm', alarm);
- // |alarm| can be undefined because onAlarm also gets called from
- // window.setTimeout on old chrome versions.
- if (alarm && alarm.name == 'watchdog') {
- onWatchdog();
- } else {
- startRequest({scheduleRequest:true, showLoadingAnimation:false});
- }
-}
-
-function onWatchdog() {
- chrome.alarms.get('refresh', function(alarm) {
- if (alarm) {
- console.log('Refresh alarm exists. Yay.');
- } else {
- console.log('Refresh alarm doesn\'t exist!? ' +
- 'Refreshing now and rescheduling.');
- startRequest({scheduleRequest:true, showLoadingAnimation:false});
- }
- });
-}
-
-if (oldChromeVersion) {
- updateIcon();
- onInit();
-} else {
- chrome.runtime.onInstalled.addListener(onInit);
- chrome.alarms.onAlarm.addListener(onAlarm);
-}
-
-var filters = {
- // TODO(aa): Cannot use urlPrefix because all the url fields lack the protocol
- // part. See crbug.com/140238.
- url: [{urlContains: getGmailUrl().replace(/^https?\:\/\//, '')}]
-};
-
-function onNavigate(details) {
- if (details.url && isGmailUrl(details.url)) {
- console.log('Recognized Gmail navigation to: ' + details.url + '.' +
- 'Refreshing count...');
- startRequest({scheduleRequest:false, showLoadingAnimation:false});
- }
-}
-if (chrome.webNavigation && chrome.webNavigation.onDOMContentLoaded &&
- chrome.webNavigation.onReferenceFragmentUpdated) {
- chrome.webNavigation.onDOMContentLoaded.addListener(onNavigate, filters);
- chrome.webNavigation.onReferenceFragmentUpdated.addListener(
- onNavigate, filters);
-} else {
- chrome.tabs.onUpdated.addListener(function(_, details) {
- onNavigate(details);
- });
-}
-
-chrome.browserAction.onClicked.addListener(goToInbox);
-
-if (chrome.runtime && chrome.runtime.onStartup) {
- chrome.runtime.onStartup.addListener(function() {
- console.log('Starting browser... updating icon.');
- startRequest({scheduleRequest:false, showLoadingAnimation:false});
- updateIcon();
- });
-} else {
- // This hack is needed because Chrome 22 does not persist browserAction icon
- // state, and also doesn't expose onStartup. So the icon always starts out in
- // wrong state. We don't actually use onStartup except as a clue that we're
- // in a version of Chrome that has this problem.
- chrome.windows.onCreated.addListener(function() {
- console.log('Window created... updating icon.');
- startRequest({scheduleRequest:false, showLoadingAnimation:false});
- updateIcon();
- });
-}
diff --git a/chrome/common/extensions/docs/examples/extensions/gmail/gmail_logged_in.png b/chrome/common/extensions/docs/examples/extensions/gmail/gmail_logged_in.png
deleted file mode 100644
index 3d3a086..0000000
--- a/chrome/common/extensions/docs/examples/extensions/gmail/gmail_logged_in.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/gmail/gmail_not_logged_in.png b/chrome/common/extensions/docs/examples/extensions/gmail/gmail_not_logged_in.png
deleted file mode 100644
index 9c6df0b..0000000
--- a/chrome/common/extensions/docs/examples/extensions/gmail/gmail_not_logged_in.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/gmail/icon_128.png b/chrome/common/extensions/docs/examples/extensions/gmail/icon_128.png
deleted file mode 100644
index e65ccb5c..0000000
--- a/chrome/common/extensions/docs/examples/extensions/gmail/icon_128.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/gmail/manifest.json b/chrome/common/extensions/docs/examples/extensions/gmail/manifest.json
deleted file mode 100644
index c181dcd..0000000
--- a/chrome/common/extensions/docs/examples/extensions/gmail/manifest.json
+++ /dev/null
@@ -1,23 +0,0 @@
-{
- "background": {
- "persistent": false,
- "page": "background.html"
- },
- "browser_action": {
- "default_icon": "gmail_not_logged_in.png"
- },
- "default_locale": "en",
- "description": "__MSG_gmailcheck_description__",
- "icons": {
- "128": "icon_128.png"
- },
- "name": "__MSG_gmailcheck_name__",
- "permissions": [
- "alarms",
- "tabs",
- "webNavigation",
- "*://*.google.com/"
- ],
- "version": "4.4.0",
- "manifest_version": 2
-}
diff --git a/chrome/common/extensions/docs/examples/extensions/imageinfo/NOTICE b/chrome/common/extensions/docs/examples/extensions/imageinfo/NOTICE
deleted file mode 100644
index ecc55f6d..0000000
--- a/chrome/common/extensions/docs/examples/extensions/imageinfo/NOTICE
+++ /dev/null
@@ -1,5 +0,0 @@
-This extension uses code from the following JavaScript library:
-
-ImageInfo - A JavaScript library for reading image metadata.
-Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/
-MIT License [http://www.nihilogic.dk/licenses/mit-license.txt]
diff --git a/chrome/common/extensions/docs/examples/extensions/imageinfo/background.js b/chrome/common/extensions/docs/examples/extensions/imageinfo/background.js
deleted file mode 100644
index 41147e4..0000000
--- a/chrome/common/extensions/docs/examples/extensions/imageinfo/background.js
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 2011 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.
-
-/**
- * Returns a handler which will open a new window when activated.
- */
-function getClickHandler() {
- return function(info, tab) {
-
- // The srcUrl property is only available for image elements.
- var url = 'info.html#' + info.srcUrl;
-
- // Create a new window to the info page.
- chrome.windows.create({ url: url, width: 520, height: 660 });
- };
-};
-
-/**
- * Create a context menu which will only show up for images.
- */
-chrome.contextMenus.create({
- "title" : "Get image info",
- "type" : "normal",
- "contexts" : ["image"],
- "onclick" : getClickHandler()
-});
diff --git a/chrome/common/extensions/docs/examples/extensions/imageinfo/imageinfo-128.png b/chrome/common/extensions/docs/examples/extensions/imageinfo/imageinfo-128.png
deleted file mode 100644
index 80645d1..0000000
--- a/chrome/common/extensions/docs/examples/extensions/imageinfo/imageinfo-128.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/imageinfo/imageinfo-16.png b/chrome/common/extensions/docs/examples/extensions/imageinfo/imageinfo-16.png
deleted file mode 100644
index 39295a73..0000000
--- a/chrome/common/extensions/docs/examples/extensions/imageinfo/imageinfo-16.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/imageinfo/imageinfo-48.png b/chrome/common/extensions/docs/examples/extensions/imageinfo/imageinfo-48.png
deleted file mode 100644
index 76a9f2e..0000000
--- a/chrome/common/extensions/docs/examples/extensions/imageinfo/imageinfo-48.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/imageinfo/imageinfo/binaryajax.js b/chrome/common/extensions/docs/examples/extensions/imageinfo/imageinfo/binaryajax.js
deleted file mode 100644
index f4e0426..0000000
--- a/chrome/common/extensions/docs/examples/extensions/imageinfo/imageinfo/binaryajax.js
+++ /dev/null
@@ -1,235 +0,0 @@
-
-/*
- * Binary Ajax 0.1.5
- * Copyright (c) 2008 Jacob Seidelin, cupboy@gmail.com, http://blog.nihilogic.dk/
- * MIT License [http://www.opensource.org/licenses/mit-license.php]
- */
-
-
-var BinaryFile = function(strData, iDataOffset, iDataLength) {
- var data = strData;
- var dataOffset = iDataOffset || 0;
- var dataLength = 0;
-
- this.getRawData = function() {
- return data;
- }
-
- if (typeof strData == "string") {
- dataLength = iDataLength || data.length;
-
- this.getByteAt = function(iOffset) {
- return data.charCodeAt(iOffset + dataOffset) & 0xFF;
- }
- } else if (typeof strData == "unknown") {
- dataLength = iDataLength || IEBinary_getLength(data);
-
- this.getByteAt = function(iOffset) {
- return IEBinary_getByteAt(data, iOffset + dataOffset);
- }
- }
-
- this.getLength = function() {
- return dataLength;
- }
-
- this.getSByteAt = function(iOffset) {
- var iByte = this.getByteAt(iOffset);
- if (iByte > 127)
- return iByte - 256;
- else
- return iByte;
- }
-
- this.getShortAt = function(iOffset, bBigEndian) {
- var iShort = bBigEndian ?
- (this.getByteAt(iOffset) << 8) + this.getByteAt(iOffset + 1)
- : (this.getByteAt(iOffset + 1) << 8) + this.getByteAt(iOffset)
- if (iShort < 0) iShort += 65536;
- return iShort;
- }
- this.getSShortAt = function(iOffset, bBigEndian) {
- var iUShort = this.getShortAt(iOffset, bBigEndian);
- if (iUShort > 32767)
- return iUShort - 65536;
- else
- return iUShort;
- }
- this.getLongAt = function(iOffset, bBigEndian) {
- var iByte1 = this.getByteAt(iOffset),
- iByte2 = this.getByteAt(iOffset + 1),
- iByte3 = this.getByteAt(iOffset + 2),
- iByte4 = this.getByteAt(iOffset + 3);
-
- var iLong = bBigEndian ?
- (((((iByte1 << 8) + iByte2) << 8) + iByte3) << 8) + iByte4
- : (((((iByte4 << 8) + iByte3) << 8) + iByte2) << 8) + iByte1;
- if (iLong < 0) iLong += 4294967296;
- return iLong;
- }
- this.getSLongAt = function(iOffset, bBigEndian) {
- var iULong = this.getLongAt(iOffset, bBigEndian);
- if (iULong > 2147483647)
- return iULong - 4294967296;
- else
- return iULong;
- }
- this.getStringAt = function(iOffset, iLength) {
- var aStr = [];
- for (var i=iOffset,j=0;i<iOffset+iLength;i++,j++) {
- aStr[j] = String.fromCharCode(this.getByteAt(i));
- }
- return aStr.join("");
- }
-
- this.getCharAt = function(iOffset) {
- return String.fromCharCode(this.getByteAt(iOffset));
- }
- this.toBase64 = function() {
- return window.btoa(data);
- }
- this.fromBase64 = function(strBase64) {
- data = window.atob(strBase64);
- }
-}
-
-
-var BinaryAjax = (function() {
-
- function createRequest() {
- var oHTTP = null;
- if (window.XMLHttpRequest) {
- oHTTP = new XMLHttpRequest();
- } else if (window.ActiveXObject) {
- oHTTP = new ActiveXObject("Microsoft.XMLHTTP");
- }
- return oHTTP;
- }
-
- function getHead(strURL, fncCallback, fncError) {
- var oHTTP = createRequest();
- if (oHTTP) {
- if (fncCallback) {
- if (typeof(oHTTP.onload) != "undefined") {
- oHTTP.onload = function() {
- if (oHTTP.status == "200") {
- fncCallback(this);
- } else {
- if (fncError) fncError();
- }
- oHTTP = null;
- };
- } else {
- oHTTP.onreadystatechange = function() {
- if (oHTTP.readyState == 4) {
- if (oHTTP.status == "200") {
- fncCallback(this);
- } else {
- if (fncError) fncError();
- }
- oHTTP = null;
- }
- };
- }
- }
- oHTTP.open("HEAD", strURL, true);
- oHTTP.send(null);
- } else {
- if (fncError) fncError();
- }
- }
-
- function sendRequest(strURL, fncCallback, fncError, aRange, bAcceptRanges, iFileSize) {
- var oHTTP = createRequest();
- if (oHTTP) {
-
- var iDataOffset = 0;
- if (aRange && !bAcceptRanges) {
- iDataOffset = aRange[0];
- }
- var iDataLen = 0;
- if (aRange) {
- iDataLen = aRange[1]-aRange[0]+1;
- }
-
- if (fncCallback) {
- if (typeof(oHTTP.onload) != "undefined") {
- oHTTP.onload = function() {
-
- if (oHTTP.status == "200" || oHTTP.status == "206") {
- this.binaryResponse = new BinaryFile(this.responseText, iDataOffset, iDataLen);
- this.fileSize = iFileSize || this.getResponseHeader("Content-Length");
- fncCallback(this);
- } else {
- if (fncError) fncError();
- }
- oHTTP = null;
- };
- } else {
- oHTTP.onreadystatechange = function() {
- if (oHTTP.readyState == 4) {
- if (oHTTP.status == "200" || oHTTP.status == "206") {
- this.binaryResponse = new BinaryFile(oHTTP.responseBody, iDataOffset, iDataLen);
- this.fileSize = iFileSize || this.getResponseHeader("Content-Length");
- fncCallback(this);
- } else {
- if (fncError) fncError();
- }
- oHTTP = null;
- }
- };
- }
- }
- oHTTP.open("GET", strURL, true);
-
- if (oHTTP.overrideMimeType) oHTTP.overrideMimeType('text/plain; charset=x-user-defined');
-
- if (aRange && bAcceptRanges) {
- oHTTP.setRequestHeader("Range", "bytes=" + aRange[0] + "-" + aRange[1]);
- }
-
- oHTTP.setRequestHeader("If-Modified-Since", "Sat, 1 Jan 1970 00:00:00 GMT");
-
- oHTTP.send(null);
- } else {
- if (fncError) fncError();
- }
- }
-
- return function(strURL, fncCallback, fncError, aRange) {
-
- if (aRange) {
- getHead(
- strURL,
- function(oHTTP) {
- var iLength = parseInt(oHTTP.getResponseHeader("Content-Length"),10);
- var strAcceptRanges = oHTTP.getResponseHeader("Accept-Ranges");
-
- var iStart, iEnd;
- iStart = aRange[0];
- if (aRange[0] < 0)
- iStart += iLength;
- iEnd = iStart + aRange[1] - 1;
-
- sendRequest(strURL, fncCallback, fncError, [iStart, iEnd], (strAcceptRanges == "bytes"), iLength);
- }
- );
-
- } else {
- sendRequest(strURL, fncCallback, fncError);
- }
- }
-
-}());
-
-
-document.write(
- "<script type='text/vbscript'>\r\n"
- + "Function IEBinary_getByteAt(strBinary, iOffset)\r\n"
- + " IEBinary_getByteAt = AscB(MidB(strBinary,iOffset+1,1))\r\n"
- + "End Function\r\n"
- + "Function IEBinary_getLength(strBinary)\r\n"
- + " IEBinary_getLength = LenB(strBinary)\r\n"
- + "End Function\r\n"
- + "</script>\r\n"
-);
diff --git a/chrome/common/extensions/docs/examples/extensions/imageinfo/imageinfo/exif.js b/chrome/common/extensions/docs/examples/extensions/imageinfo/imageinfo/exif.js
deleted file mode 100644
index 29a2782..0000000
--- a/chrome/common/extensions/docs/examples/extensions/imageinfo/imageinfo/exif.js
+++ /dev/null
@@ -1,615 +0,0 @@
-/*
- * Javascript EXIF Reader 0.1.2
- * Copyright (c) 2008 Jacob Seidelin, cupboy@gmail.com, http://blog.nihilogic.dk/
- * MIT License [http://www.opensource.org/licenses/mit-license.php]
- */
-
-
-var EXIF = {};
-
-(function() {
-
-var bDebug = false;
-
-EXIF.Tags = {
-
- // version tags
- 0x9000 : "ExifVersion", // EXIF version
- 0xA000 : "FlashpixVersion", // Flashpix format version
-
- // colorspace tags
- 0xA001 : "ColorSpace", // Color space information tag
-
- // image configuration
- 0xA002 : "PixelXDimension", // Valid width of meaningful image
- 0xA003 : "PixelYDimension", // Valid height of meaningful image
- 0x9101 : "ComponentsConfiguration", // Information about channels
- 0x9102 : "CompressedBitsPerPixel", // Compressed bits per pixel
-
- // user information
- 0x927C : "MakerNote", // Any desired information written by the manufacturer
- 0x9286 : "UserComment", // Comments by user
-
- // related file
- 0xA004 : "RelatedSoundFile", // Name of related sound file
-
- // date and time
- 0x9003 : "DateTimeOriginal", // Date and time when the original image was generated
- 0x9004 : "DateTimeDigitized", // Date and time when the image was stored digitally
- 0x9290 : "SubsecTime", // Fractions of seconds for DateTime
- 0x9291 : "SubsecTimeOriginal", // Fractions of seconds for DateTimeOriginal
- 0x9292 : "SubsecTimeDigitized", // Fractions of seconds for DateTimeDigitized
-
- // picture-taking conditions
- 0x829A : "ExposureTime", // Exposure time (in seconds)
- 0x829D : "FNumber", // F number
- 0x8822 : "ExposureProgram", // Exposure program
- 0x8824 : "SpectralSensitivity", // Spectral sensitivity
- 0x8827 : "ISOSpeedRatings", // ISO speed rating
- 0x8828 : "OECF", // Optoelectric conversion factor
- 0x9201 : "ShutterSpeedValue", // Shutter speed
- 0x9202 : "ApertureValue", // Lens aperture
- 0x9203 : "BrightnessValue", // Value of brightness
- 0x9204 : "ExposureBias", // Exposure bias
- 0x9205 : "MaxApertureValue", // Smallest F number of lens
- 0x9206 : "SubjectDistance", // Distance to subject in meters
- 0x9207 : "MeteringMode", // Metering mode
- 0x9208 : "LightSource", // Kind of light source
- 0x9209 : "Flash", // Flash status
- 0x9214 : "SubjectArea", // Location and area of main subject
- 0x920A : "FocalLength", // Focal length of the lens in mm
- 0xA20B : "FlashEnergy", // Strobe energy in BCPS
- 0xA20C : "SpatialFrequencyResponse", //
- 0xA20E : "FocalPlaneXResolution", // Number of pixels in width direction per FocalPlaneResolutionUnit
- 0xA20F : "FocalPlaneYResolution", // Number of pixels in height direction per FocalPlaneResolutionUnit
- 0xA210 : "FocalPlaneResolutionUnit", // Unit for measuring FocalPlaneXResolution and FocalPlaneYResolution
- 0xA214 : "SubjectLocation", // Location of subject in image
- 0xA215 : "ExposureIndex", // Exposure index selected on camera
- 0xA217 : "SensingMethod", // Image sensor type
- 0xA300 : "FileSource", // Image source (3 == DSC)
- 0xA301 : "SceneType", // Scene type (1 == directly photographed)
- 0xA302 : "CFAPattern", // Color filter array geometric pattern
- 0xA401 : "CustomRendered", // Special processing
- 0xA402 : "ExposureMode", // Exposure mode
- 0xA403 : "WhiteBalance", // 1 = auto white balance, 2 = manual
- 0xA404 : "DigitalZoomRation", // Digital zoom ratio
- 0xA405 : "FocalLengthIn35mmFilm", // Equivalent foacl length assuming 35mm film camera (in mm)
- 0xA406 : "SceneCaptureType", // Type of scene
- 0xA407 : "GainControl", // Degree of overall image gain adjustment
- 0xA408 : "Contrast", // Direction of contrast processing applied by camera
- 0xA409 : "Saturation", // Direction of saturation processing applied by camera
- 0xA40A : "Sharpness", // Direction of sharpness processing applied by camera
- 0xA40B : "DeviceSettingDescription", //
- 0xA40C : "SubjectDistanceRange", // Distance to subject
-
- // other tags
- 0xA005 : "InteroperabilityIFDPointer",
- 0xA420 : "ImageUniqueID" // Identifier assigned uniquely to each image
-};
-
-EXIF.TiffTags = {
- 0x0100 : "ImageWidth",
- 0x0101 : "ImageHeight",
- 0x8769 : "ExifIFDPointer",
- 0x8825 : "GPSInfoIFDPointer",
- 0xA005 : "InteroperabilityIFDPointer",
- 0x0102 : "BitsPerSample",
- 0x0103 : "Compression",
- 0x0106 : "PhotometricInterpretation",
- 0x0112 : "Orientation",
- 0x0115 : "SamplesPerPixel",
- 0x011C : "PlanarConfiguration",
- 0x0212 : "YCbCrSubSampling",
- 0x0213 : "YCbCrPositioning",
- 0x011A : "XResolution",
- 0x011B : "YResolution",
- 0x0128 : "ResolutionUnit",
- 0x0111 : "StripOffsets",
- 0x0116 : "RowsPerStrip",
- 0x0117 : "StripByteCounts",
- 0x0201 : "JPEGInterchangeFormat",
- 0x0202 : "JPEGInterchangeFormatLength",
- 0x012D : "TransferFunction",
- 0x013E : "WhitePoint",
- 0x013F : "PrimaryChromaticities",
- 0x0211 : "YCbCrCoefficients",
- 0x0214 : "ReferenceBlackWhite",
- 0x0132 : "DateTime",
- 0x010E : "ImageDescription",
- 0x010F : "Make",
- 0x0110 : "Model",
- 0x0131 : "Software",
- 0x013B : "Artist",
- 0x8298 : "Copyright"
-}
-
-EXIF.GPSTags = {
- 0x0000 : "GPSVersionID",
- 0x0001 : "GPSLatitudeRef",
- 0x0002 : "GPSLatitude",
- 0x0003 : "GPSLongitudeRef",
- 0x0004 : "GPSLongitude",
- 0x0005 : "GPSAltitudeRef",
- 0x0006 : "GPSAltitude",
- 0x0007 : "GPSTimeStamp",
- 0x0008 : "GPSSatellites",
- 0x0009 : "GPSStatus",
- 0x000A : "GPSMeasureMode",
- 0x000B : "GPSDOP",
- 0x000C : "GPSSpeedRef",
- 0x000D : "GPSSpeed",
- 0x000E : "GPSTrackRef",
- 0x000F : "GPSTrack",
- 0x0010 : "GPSImgDirectionRef",
- 0x0011 : "GPSImgDirection",
- 0x0012 : "GPSMapDatum",
- 0x0013 : "GPSDestLatitudeRef",
- 0x0014 : "GPSDestLatitude",
- 0x0015 : "GPSDestLongitudeRef",
- 0x0016 : "GPSDestLongitude",
- 0x0017 : "GPSDestBearingRef",
- 0x0018 : "GPSDestBearing",
- 0x0019 : "GPSDestDistanceRef",
- 0x001A : "GPSDestDistance",
- 0x001B : "GPSProcessingMethod",
- 0x001C : "GPSAreaInformation",
- 0x001D : "GPSDateStamp",
- 0x001E : "GPSDifferential"
-}
-
-EXIF.StringValues = {
- ExposureProgram : {
- 0 : "Not defined",
- 1 : "Manual",
- 2 : "Normal program",
- 3 : "Aperture priority",
- 4 : "Shutter priority",
- 5 : "Creative program",
- 6 : "Action program",
- 7 : "Portrait mode",
- 8 : "Landscape mode"
- },
- MeteringMode : {
- 0 : "Unknown",
- 1 : "Average",
- 2 : "CenterWeightedAverage",
- 3 : "Spot",
- 4 : "MultiSpot",
- 5 : "Pattern",
- 6 : "Partial",
- 255 : "Other"
- },
- LightSource : {
- 0 : "Unknown",
- 1 : "Daylight",
- 2 : "Fluorescent",
- 3 : "Tungsten (incandescent light)",
- 4 : "Flash",
- 9 : "Fine weather",
- 10 : "Cloudy weather",
- 11 : "Shade",
- 12 : "Daylight fluorescent (D 5700 - 7100K)",
- 13 : "Day white fluorescent (N 4600 - 5400K)",
- 14 : "Cool white fluorescent (W 3900 - 4500K)",
- 15 : "White fluorescent (WW 3200 - 3700K)",
- 17 : "Standard light A",
- 18 : "Standard light B",
- 19 : "Standard light C",
- 20 : "D55",
- 21 : "D65",
- 22 : "D75",
- 23 : "D50",
- 24 : "ISO studio tungsten",
- 255 : "Other"
- },
- Flash : {
- 0x0000 : "Flash did not fire",
- 0x0001 : "Flash fired",
- 0x0005 : "Strobe return light not detected",
- 0x0007 : "Strobe return light detected",
- 0x0009 : "Flash fired, compulsory flash mode",
- 0x000D : "Flash fired, compulsory flash mode, return light not detected",
- 0x000F : "Flash fired, compulsory flash mode, return light detected",
- 0x0010 : "Flash did not fire, compulsory flash mode",
- 0x0018 : "Flash did not fire, auto mode",
- 0x0019 : "Flash fired, auto mode",
- 0x001D : "Flash fired, auto mode, return light not detected",
- 0x001F : "Flash fired, auto mode, return light detected",
- 0x0020 : "No flash function",
- 0x0041 : "Flash fired, red-eye reduction mode",
- 0x0045 : "Flash fired, red-eye reduction mode, return light not detected",
- 0x0047 : "Flash fired, red-eye reduction mode, return light detected",
- 0x0049 : "Flash fired, compulsory flash mode, red-eye reduction mode",
- 0x004D : "Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected",
- 0x004F : "Flash fired, compulsory flash mode, red-eye reduction mode, return light detected",
- 0x0059 : "Flash fired, auto mode, red-eye reduction mode",
- 0x005D : "Flash fired, auto mode, return light not detected, red-eye reduction mode",
- 0x005F : "Flash fired, auto mode, return light detected, red-eye reduction mode"
- },
- SensingMethod : {
- 1 : "Not defined",
- 2 : "One-chip color area sensor",
- 3 : "Two-chip color area sensor",
- 4 : "Three-chip color area sensor",
- 5 : "Color sequential area sensor",
- 7 : "Trilinear sensor",
- 8 : "Color sequential linear sensor"
- },
- SceneCaptureType : {
- 0 : "Standard",
- 1 : "Landscape",
- 2 : "Portrait",
- 3 : "Night scene"
- },
- SceneType : {
- 1 : "Directly photographed"
- },
- CustomRendered : {
- 0 : "Normal process",
- 1 : "Custom process"
- },
- WhiteBalance : {
- 0 : "Auto white balance",
- 1 : "Manual white balance"
- },
- GainControl : {
- 0 : "None",
- 1 : "Low gain up",
- 2 : "High gain up",
- 3 : "Low gain down",
- 4 : "High gain down"
- },
- Contrast : {
- 0 : "Normal",
- 1 : "Soft",
- 2 : "Hard"
- },
- Saturation : {
- 0 : "Normal",
- 1 : "Low saturation",
- 2 : "High saturation"
- },
- Sharpness : {
- 0 : "Normal",
- 1 : "Soft",
- 2 : "Hard"
- },
- SubjectDistanceRange : {
- 0 : "Unknown",
- 1 : "Macro",
- 2 : "Close view",
- 3 : "Distant view"
- },
- FileSource : {
- 3 : "DSC"
- },
-
- Components : {
- 0 : "",
- 1 : "Y",
- 2 : "Cb",
- 3 : "Cr",
- 4 : "R",
- 5 : "G",
- 6 : "B"
- }
-}
-
-function addEvent(oElement, strEvent, fncHandler)
-{
- if (oElement.addEventListener) {
- oElement.addEventListener(strEvent, fncHandler, false);
- } else if (oElement.attachEvent) {
- oElement.attachEvent("on" + strEvent, fncHandler);
- }
-}
-
-
-function imageHasData(oImg)
-{
- return !!(oImg.exifdata);
-}
-
-function getImageData(oImg, fncCallback)
-{
- BinaryAjax(
- oImg.src,
- function(oHTTP) {
- var oEXIF = findEXIFinJPEG(oHTTP.binaryResponse);
- oImg.exifdata = oEXIF || {};
- if (fncCallback) fncCallback();
- }
- )
-}
-
-function findEXIFinJPEG(oFile) {
- var aMarkers = [];
-
- if (oFile.getByteAt(0) != 0xFF || oFile.getByteAt(1) != 0xD8) {
- return false; // not a valid jpeg
- }
-
- var iOffset = 2;
- var iLength = oFile.getLength();
- while (iOffset < iLength) {
- if (oFile.getByteAt(iOffset) != 0xFF) {
- if (bDebug) console.log("Not a valid marker at offset " + iOffset + ", found: " + oFile.getByteAt(iOffset));
- return false; // not a valid marker, something is wrong
- }
-
- var iMarker = oFile.getByteAt(iOffset+1);
-
- // we could implement handling for other markers here,
- // but we're only looking for 0xFFE1 for EXIF data
-
- if (iMarker == 22400) {
- if (bDebug) console.log("Found 0xFFE1 marker");
- return readEXIFData(oFile, iOffset + 4, oFile.getShortAt(iOffset+2, true)-2);
- iOffset += 2 + oFile.getShortAt(iOffset+2, true);
-
- } else if (iMarker == 225) {
- // 0xE1 = Application-specific 1 (for EXIF)
- if (bDebug) console.log("Found 0xFFE1 marker");
- return readEXIFData(oFile, iOffset + 4, oFile.getShortAt(iOffset+2, true)-2);
-
- } else {
- iOffset += 2 + oFile.getShortAt(iOffset+2, true);
- }
-
- }
-
-}
-
-
-function readTags(oFile, iTIFFStart, iDirStart, oStrings, bBigEnd)
-{
- var iEntries = oFile.getShortAt(iDirStart, bBigEnd);
- var oTags = {};
- for (var i=0;i<iEntries;i++) {
- var iEntryOffset = iDirStart + i*12 + 2;
- var strTag = oStrings[oFile.getShortAt(iEntryOffset, bBigEnd)];
- if (!strTag && bDebug) console.log("Unknown tag: " + oFile.getShortAt(iEntryOffset, bBigEnd));
- oTags[strTag] = readTagValue(oFile, iEntryOffset, iTIFFStart, iDirStart, bBigEnd);
- }
- return oTags;
-}
-
-
-function readTagValue(oFile, iEntryOffset, iTIFFStart, iDirStart, bBigEnd)
-{
- var iType = oFile.getShortAt(iEntryOffset+2, bBigEnd);
- var iNumValues = oFile.getLongAt(iEntryOffset+4, bBigEnd);
- var iValueOffset = oFile.getLongAt(iEntryOffset+8, bBigEnd) + iTIFFStart;
-
- switch (iType) {
- case 1: // byte, 8-bit unsigned int
- case 7: // undefined, 8-bit byte, value depending on field
- if (iNumValues == 1) {
- return oFile.getByteAt(iEntryOffset + 8, bBigEnd);
- } else {
- var iValOffset = iNumValues > 4 ? iValueOffset : (iEntryOffset + 8);
- var aVals = [];
- for (var n=0;n<iNumValues;n++) {
- aVals[n] = oFile.getByteAt(iValOffset + n);
- }
- return aVals;
- }
- break;
-
- case 2: // ascii, 8-bit byte
- var iStringOffset = iNumValues > 4 ? iValueOffset : (iEntryOffset + 8);
- return oFile.getStringAt(iStringOffset, iNumValues-1);
- break;
-
- case 3: // short, 16 bit int
- if (iNumValues == 1) {
- return oFile.getShortAt(iEntryOffset + 8, bBigEnd);
- } else {
- var iValOffset = iNumValues > 2 ? iValueOffset : (iEntryOffset + 8);
- var aVals = [];
- for (var n=0;n<iNumValues;n++) {
- aVals[n] = oFile.getShortAt(iValOffset + 2*n, bBigEnd);
- }
- return aVals;
- }
- break;
-
- case 4: // long, 32 bit int
- if (iNumValues == 1) {
- return oFile.getLongAt(iEntryOffset + 8, bBigEnd);
- } else {
- var aVals = [];
- for (var n=0;n<iNumValues;n++) {
- aVals[n] = oFile.getLongAt(iValueOffset + 4*n, bBigEnd);
- }
- return aVals;
- }
- break;
- case 5: // rational = two long values, first is numerator, second is denominator
- if (iNumValues == 1) {
- return oFile.getLongAt(iValueOffset, bBigEnd) / oFile.getLongAt(iValueOffset+4, bBigEnd);
- } else {
- var aVals = [];
- for (var n=0;n<iNumValues;n++) {
- aVals[n] = oFile.getLongAt(iValueOffset + 8*n, bBigEnd) / oFile.getLongAt(iValueOffset+4 + 8*n, bBigEnd);
- }
- return aVals;
- }
- break;
- case 9: // slong, 32 bit signed int
- if (iNumValues == 1) {
- return oFile.getSLongAt(iEntryOffset + 8, bBigEnd);
- } else {
- var aVals = [];
- for (var n=0;n<iNumValues;n++) {
- aVals[n] = oFile.getSLongAt(iValueOffset + 4*n, bBigEnd);
- }
- return aVals;
- }
- break;
- case 10: // signed rational, two slongs, first is numerator, second is denominator
- if (iNumValues == 1) {
- return oFile.getSLongAt(iValueOffset, bBigEnd) / oFile.getSLongAt(iValueOffset+4, bBigEnd);
- } else {
- var aVals = [];
- for (var n=0;n<iNumValues;n++) {
- aVals[n] = oFile.getSLongAt(iValueOffset + 8*n, bBigEnd) / oFile.getSLongAt(iValueOffset+4 + 8*n, bBigEnd);
- }
- return aVals;
- }
- break;
- }
-}
-
-
-function readEXIFData(oFile, iStart, iLength)
-{
- if (oFile.getStringAt(iStart, 4) != "Exif") {
- if (bDebug) console.log("Not valid EXIF data! " + oFile.getStringAt(iStart, 4));
- return false;
- }
-
- var bBigEnd;
-
- var iTIFFOffset = iStart + 6;
-
- // test for TIFF validity and endianness
- if (oFile.getShortAt(iTIFFOffset) == 0x4949) {
- bBigEnd = false;
- } else if (oFile.getShortAt(iTIFFOffset) == 0x4D4D) {
- bBigEnd = true;
- } else {
- if (bDebug) console.log("Not valid TIFF data! (no 0x4949 or 0x4D4D)");
- return false;
- }
-
- if (oFile.getShortAt(iTIFFOffset+2, bBigEnd) != 0x002A) {
- if (bDebug) console.log("Not valid TIFF data! (no 0x002A)");
- return false;
- }
-
- if (oFile.getLongAt(iTIFFOffset+4, bBigEnd) != 0x00000008) {
- if (bDebug) console.log("Not valid TIFF data! (First offset not 8)", oFile.getShortAt(iTIFFOffset+4, bBigEnd));
- return false;
- }
-
- var oTags = readTags(oFile, iTIFFOffset, iTIFFOffset+8, EXIF.TiffTags, bBigEnd);
-
- if (oTags.ExifIFDPointer) {
- var oEXIFTags = readTags(oFile, iTIFFOffset, iTIFFOffset + oTags.ExifIFDPointer, EXIF.Tags, bBigEnd);
- for (var strTag in oEXIFTags) {
- switch (strTag) {
- case "LightSource" :
- case "Flash" :
- case "MeteringMode" :
- case "ExposureProgram" :
- case "SensingMethod" :
- case "SceneCaptureType" :
- case "SceneType" :
- case "CustomRendered" :
- case "WhiteBalance" :
- case "GainControl" :
- case "Contrast" :
- case "Saturation" :
- case "Sharpness" :
- case "SubjectDistanceRange" :
- case "FileSource" :
- oEXIFTags[strTag] = EXIF.StringValues[strTag][oEXIFTags[strTag]];
- break;
-
- case "ExifVersion" :
- case "FlashpixVersion" :
- oEXIFTags[strTag] = String.fromCharCode(oEXIFTags[strTag][0], oEXIFTags[strTag][1], oEXIFTags[strTag][2], oEXIFTags[strTag][3]);
- break;
-
- case "ComponentsConfiguration" :
- oEXIFTags[strTag] =
- EXIF.StringValues.Components[oEXIFTags[strTag][0]]
- + EXIF.StringValues.Components[oEXIFTags[strTag][1]]
- + EXIF.StringValues.Components[oEXIFTags[strTag][2]]
- + EXIF.StringValues.Components[oEXIFTags[strTag][3]];
- break;
- }
- oTags[strTag] = oEXIFTags[strTag];
- }
- }
-
- if (oTags.GPSInfoIFDPointer) {
- var oGPSTags = readTags(oFile, iTIFFOffset, iTIFFOffset + oTags.GPSInfoIFDPointer, EXIF.GPSTags, bBigEnd);
- for (var strTag in oGPSTags) {
- switch (strTag) {
- case "GPSVersionID" :
- oGPSTags[strTag] = oGPSTags[strTag][0]
- + "." + oGPSTags[strTag][1]
- + "." + oGPSTags[strTag][2]
- + "." + oGPSTags[strTag][3];
- break;
- }
- oTags[strTag] = oGPSTags[strTag];
- }
- }
-
- return oTags;
-}
-
-
-EXIF.getData = function(oImg, fncCallback)
-{
- if (!oImg.complete) return false;
- if (!imageHasData(oImg)) {
- getImageData(oImg, fncCallback);
- } else {
- if (fncCallback) fncCallback();
- }
- return true;
-}
-
-EXIF.getTag = function(oImg, strTag)
-{
- if (!imageHasData(oImg)) return;
- return oImg.exifdata[strTag];
-}
-
-EXIF.pretty = function(oImg)
-{
- if (!imageHasData(oImg)) return "";
- var oData = oImg.exifdata;
- var strPretty = "";
- for (var a in oData) {
- if (oData.hasOwnProperty(a)) {
- if (typeof oData[a] == "object") {
- strPretty += a + " : [" + oData[a].length + " values]\r\n";
- } else {
- strPretty += a + " : " + oData[a] + "\r\n";
- }
- }
- }
- return strPretty;
-}
-
-EXIF.readFromBinaryFile = function(oFile) {
- return findEXIFinJPEG(oFile);
-}
-
-function loadAllImages()
-{
- var aImages = document.getElementsByTagName("img");
- for (var i=0;i<aImages.length;i++) {
- if (aImages[i].getAttribute("exif") == "true") {
- if (!aImages[i].complete) {
- addEvent(aImages[i], "load",
- function() {
- EXIF.getData(this);
- }
- );
- } else {
- EXIF.getData(aImages[i]);
- }
- }
- }
-}
-
-addEvent(window, "load", loadAllImages);
-
-})();
-
diff --git a/chrome/common/extensions/docs/examples/extensions/imageinfo/imageinfo/imageinfo.js b/chrome/common/extensions/docs/examples/extensions/imageinfo/imageinfo/imageinfo.js
deleted file mode 100644
index 5a35c766..0000000
--- a/chrome/common/extensions/docs/examples/extensions/imageinfo/imageinfo/imageinfo.js
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * ImageInfo 0.1.2 - A JavaScript library for reading image metadata.
- * Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/
- * MIT License [http://www.nihilogic.dk/licenses/mit-license.txt]
- */
-
-
-var ImageInfo = {};
-
-ImageInfo.useRange = false;
-ImageInfo.range = 10240;
-
-(function() {
-
- var files = [];
-
- function readFileData(url, callback) {
- BinaryAjax(
- url,
- function(http) {
- var tags = readInfoFromData(http.binaryResponse);
- var mime = http.getResponseHeader("Content-Type");
-
- tags["mimeType"] = mime;
- tags["byteSize"] = http.fileSize;
-
- files[url] = tags;
- if (callback) callback();
- },
- null,
- ImageInfo.useRange ? [0, ImageInfo.range] : null
- )
- }
-
- function readInfoFromData(data) {
-
- var offset = 0;
-
- if (data.getByteAt(0) == 0xFF && data.getByteAt(1) == 0xD8) {
- return readJPEGInfo(data);
- }
- if (data.getByteAt(0) == 0x89 && data.getStringAt(1, 3) == "PNG") {
- return readPNGInfo(data);
- }
- if (data.getStringAt(0,3) == "GIF") {
- return readGIFInfo(data);
- }
- if (data.getByteAt(0) == 0x42 && data.getByteAt(1) == 0x4D) {
- return readBMPInfo(data);
- }
- if (data.getByteAt(0) == 0x00 && data.getByteAt(1) == 0x00) {
- return readICOInfo(data);
- }
-
- return {
- format : "UNKNOWN"
- };
- }
-
-
- function readPNGInfo(data) {
- var w = data.getLongAt(16,true);
- var h = data.getLongAt(20,true);
-
- var bpc = data.getByteAt(24);
- var ct = data.getByteAt(25);
-
- var bpp = bpc;
- if (ct == 4) bpp *= 2;
- if (ct == 2) bpp *= 3;
- if (ct == 6) bpp *= 4;
-
- var alpha = data.getByteAt(25) >= 4;
-
- return {
- format : "PNG",
- version : "",
- width : w,
- height : h,
- bpp : bpp,
- alpha : alpha,
- exif : {}
- }
- }
-
- function readGIFInfo(data) {
- var version = data.getStringAt(3,3);
- var w = data.getShortAt(6);
- var h = data.getShortAt(8);
-
- var bpp = ((data.getByteAt(10) >> 4) & 7) + 1;
-
- return {
- format : "GIF",
- version : version,
- width : w,
- height : h,
- bpp : bpp,
- alpha : false,
- exif : {}
- }
- }
-
- function readJPEGInfo(data) {
-
- var w = 0;
- var h = 0;
- var comps = 0;
- var len = data.getLength();
- var offset = 2;
- while (offset < len) {
- var marker = data.getShortAt(offset, true);
- offset += 2;
- if (marker == 0xFFC0) {
- h = data.getShortAt(offset + 3, true);
- w = data.getShortAt(offset + 5, true);
- comps = data.getByteAt(offset + 7, true)
- break;
- } else {
- offset += data.getShortAt(offset, true)
- }
- }
-
- var exif = {};
-
- if (typeof EXIF != "undefined" && EXIF.readFromBinaryFile) {
- exif = EXIF.readFromBinaryFile(data);
- }
-
- return {
- format : "JPEG",
- version : "",
- width : w,
- height : h,
- bpp : comps * 8,
- alpha : false,
- exif : exif
- }
- }
-
- function readBMPInfo(data) {
- var w = data.getLongAt(18);
- var h = data.getLongAt(22);
- var bpp = data.getShortAt(28);
- return {
- format : "BMP",
- version : "",
- width : w,
- height : h,
- bpp : bpp,
- alpha : false,
- exif : {}
- }
- }
-
- ImageInfo.loadInfo = function(url, cb) {
- if (!files[url]) {
- readFileData(url, cb);
- } else {
- if (cb) cb();
- }
- }
-
- ImageInfo.getAllFields = function(url) {
- if (!files[url]) return null;
-
- var tags = {};
- for (var a in files[url]) {
- if (files[url].hasOwnProperty(a))
- tags[a] = files[url][a];
- }
- return tags;
- }
-
- ImageInfo.getField = function(url, field) {
- if (!files[url]) return null;
- return files[url][field];
- }
-
-
-})();
-
diff --git a/chrome/common/extensions/docs/examples/extensions/imageinfo/imageinfo/readme.txt b/chrome/common/extensions/docs/examples/extensions/imageinfo/imageinfo/readme.txt
deleted file mode 100644
index 21865b1c..0000000
--- a/chrome/common/extensions/docs/examples/extensions/imageinfo/imageinfo/readme.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-
-ImageInfo - A JavaScript library for reading image metadata.
-Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/
-MIT License [http://www.nihilogic.dk/licenses/mit-license.txt]
-
-For detailed information and code samples please refer to the blog post at:
-http://blog.nihilogic.dk/2008/07/imageinfo-reading-image-info-with-javascript.html
diff --git a/chrome/common/extensions/docs/examples/extensions/imageinfo/info.css b/chrome/common/extensions/docs/examples/extensions/imageinfo/info.css
deleted file mode 100644
index 0989945..0000000
--- a/chrome/common/extensions/docs/examples/extensions/imageinfo/info.css
+++ /dev/null
@@ -1,56 +0,0 @@
-/**
- * Copyright (c) 2011 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.
- */
-
-body {
- font: 14px Arial;
-}
-
-h1 {
- margin: 30px 0 5px 0;
- padding: 0;
-}
-code {
- padding: 0;
- margin: 5px 0;
- display: block;
-}
-table {
- border-collapse: collapse;
- width: 100%;
- margin: 15px 0;
-}
-td, th {
- padding: 4px;
-}
-th {
- text-align: left;
- width: 130px;
-}
-tr {
- display: none;
-}
-tr.rendered {
- display: block;
-}
-tr.rendered:nth-child(odd) {
- background: #eee;
-}
-#thumbnail {
- position: fixed;
- right: 20px;
- top: 20px;
- -webkit-box-shadow: 1px 1px 6px #000;
- border: 4px solid #fff;
- background: #fff;
-}
-#loader {
- font: 30px Arial;
- text-align: center;
- padding: 100px;
-}
-#exif, #output {
- display: none;
-}
diff --git a/chrome/common/extensions/docs/examples/extensions/imageinfo/info.html b/chrome/common/extensions/docs/examples/extensions/imageinfo/info.html
deleted file mode 100644
index 4ca3a2e..0000000
--- a/chrome/common/extensions/docs/examples/extensions/imageinfo/info.html
+++ /dev/null
@@ -1,102 +0,0 @@
-<!DOCTYPE html>
-<!--
- * Copyright (c) 2010 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 src="imageinfo/binaryajax.js"></script>
- <script src="imageinfo/imageinfo.js" ></script>
- <script src="imageinfo/exif.js" ></script>
- <link href="info.css" rel="stylesheet" type="text/css"></link>
- <script src="info.js"></script>
- </head>
- <body>
- <div id="loader">
- Loading... <img src="loader.gif" />
- </div>
- <div id="output">
- <div id="info">
- <h1>Image Information</h1>
- <code id="url"></code>
- <canvas id="thumbnail"></canvas>
- <table>
- <tr>
- <th>Format</th>
- <td>format</td>
- </tr>
- <tr>
- <th>Version</th>
- <td>version</td>
- </tr>
- <tr>
- <th>Width</th>
- <td>width</td>
- </tr>
- <tr>
- <th>Height</th>
- <td>height</td>
- </tr>
- <tr>
- <th>Mime Type</th>
- <td>mimeType</td>
- </tr>
- <tr>
- <th>Size (Bytes)</th>
- <td>byteSize</td>
- </tr>
- </table>
- </div>
- <div id="exif">
- <h2>EXIF Information</h2>
- <table>
- <tr>
- <th>Date</th>
- <td>DateTime</td>
- </tr>
- <tr>
- <th>Aperture</th>
- <td>ApertureValue</td>
- </tr>
- <tr>
- <th>Exposure</th>
- <td>ExposureTime</td>
- </tr>
- <tr>
- <th>Shutter Speed</th>
- <td>ShutterSpeedValue</td>
- </tr>
- <tr>
- <th>ISO</th>
- <td>ISOSpeedRatings</td>
- </tr>
- <tr>
- <th>Camera Make</th>
- <td>Make</td>
- </tr>
- <tr>
- <th>Camera Model</th>
- <td>Model</td>
- </tr>
- <tr>
- <th>Software</th>
- <td>Software</td>
- </tr>
- <tr>
- <th>XResolution</th>
- <td>XResolution</td>
- </tr>
- <tr>
- <th>YResolution</th>
- <td>YResolution</td>
- </tr>
- <tr>
- <th>Flash</th>
- <td>Flash</td>
- </tr>
- </table>
- </div>
- </div>
- </body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/extensions/imageinfo/info.js b/chrome/common/extensions/docs/examples/extensions/imageinfo/info.js
deleted file mode 100644
index 40f3b27..0000000
--- a/chrome/common/extensions/docs/examples/extensions/imageinfo/info.js
+++ /dev/null
@@ -1,145 +0,0 @@
-// Copyright (c) 2011 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.
-
-
-/**
- * Quick template rendering function. For each cell passed to it, check
- * to see if the cell's text content is a key in the supplied data array.
- * If yes, replace the cell's contents with the corresponding value and
- * unhide the cell. If no, then remove the cell's parent (tr) from the
- * DOM.
- */
-function renderCells(cells, data) {
- for (var i = 0; i < cells.length; i++) {
- var cell = cells[i];
- var key = cell.innerText;
- if (data[key]) {
- cell.innerText = data[key];
- cell.parentElement.className = "rendered";
- } else {
- cell.parentElement.parentElement.removeChild(cell.parentElement);
- }
- }
-};
-
-/**
- * Returns true if the supplies object has no properties.
- */
-function isEmpty(obj) {
- for (var key in obj) {
- if (obj.hasOwnProperty(key)) {
- return false;
- }
- }
- return true;
-};
-
-/**
- * Resizes the window to the current dimensions of this page's body.
- */
-function resizeWindow() {
- window.setTimeout(function() {
- chrome.tabs.getCurrent(function (tab) {
- var newHeight = Math.min(document.body.offsetHeight + 140, 700);
- chrome.windows.update(tab.windowId, {
- height: newHeight,
- width: 520
- });
- });
- }, 150);
-};
-
-/**
- * Called directly by the background page with information about the
- * image. Outputs image data to the DOM.
- */
-function renderImageInfo(imageinfo) {
- console.log('imageinfo', imageinfo);
-
- var divloader = document.querySelector('#loader');
- var divoutput = document.querySelector('#output');
- divloader.style.display = "none";
- divoutput.style.display = "block";
-
- var divinfo = document.querySelector('#info');
- var divexif = document.querySelector('#exif');
-
- // Render general image data.
- var datacells = divinfo.querySelectorAll('td');
- renderCells(datacells, imageinfo);
-
- // If EXIF data exists, unhide the EXIF table and render.
- if (imageinfo['exif'] && !isEmpty(imageinfo['exif'])) {
- divexif.style.display = 'block';
- var exifcells = divexif.querySelectorAll('td');
- renderCells(exifcells, imageinfo['exif']);
- }
-};
-
-/**
- * Renders the URL for the image, trimming if the length is too long.
- */
-function renderUrl(url) {
- var divurl = document.querySelector('#url');
- var urltext = (url.length < 45) ? url : url.substr(0, 42) + '...';
- var anchor = document.createElement('a');
- anchor.href = url;
- anchor.innerText = urltext;
- divurl.appendChild(anchor);
-};
-
-/**
- * Renders a thumbnail view of the image.
- */
-function renderThumbnail(url) {
- var canvas = document.querySelector('#thumbnail');
- var context = canvas.getContext('2d');
-
- canvas.width = 100;
- canvas.height = 100;
-
- var image = new Image();
- image.addEventListener('load', function() {
- var src_w = image.width;
- var src_h = image.height;
- var new_w = canvas.width;
- var new_h = canvas.height;
- var ratio = src_w / src_h;
- if (src_w > src_h) {
- new_h /= ratio;
- } else {
- new_w *= ratio;
- }
- canvas.width = new_w;
- canvas.height = new_h;
- context.drawImage(image, 0, 0, src_w, src_h, 0, 0, new_w, new_h);
- });
- image.src = url;
-};
-
-/**
- * Returns a function which will handle displaying information about the
- * image once the ImageInfo class has finished loading.
- */
-function getImageInfoHandler(url) {
- return function() {
- renderUrl(url);
- renderThumbnail(url);
- var imageinfo = ImageInfo.getAllFields(url);
- renderImageInfo(imageinfo);
- resizeWindow();
- };
-};
-
-/**
- * Load the image in question and display it, along with its metadata.
- */
-document.addEventListener("DOMContentLoaded", function () {
- // The URL of the image to load is passed on the URL fragment.
- var imageUrl = window.location.hash.substring(1);
- if (imageUrl) {
- // Use the ImageInfo library to load the image and parse it.
- ImageInfo.loadInfo(imageUrl, getImageInfoHandler(imageUrl));
- }
-});
diff --git a/chrome/common/extensions/docs/examples/extensions/imageinfo/loader.gif b/chrome/common/extensions/docs/examples/extensions/imageinfo/loader.gif
deleted file mode 100644
index c494f28..0000000
--- a/chrome/common/extensions/docs/examples/extensions/imageinfo/loader.gif
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/imageinfo/manifest.json b/chrome/common/extensions/docs/examples/extensions/imageinfo/manifest.json
deleted file mode 100644
index ecda1b1..0000000
--- a/chrome/common/extensions/docs/examples/extensions/imageinfo/manifest.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- "name" : "Imageinfo",
- "version" : "1.0.1",
- "description" : "Get image info for images, including EXIF data",
- "background" : { "scripts": ["background.js"] },
- "permissions" : [
- "contextMenus",
- "tabs",
- "http://*/*",
- "https://*/*"
- ],
- "minimum_chrome_version" : "6.0.0.0",
- "icons" : {
- "16" : "imageinfo-16.png",
- "48" : "imageinfo-48.png",
- "128" : "imageinfo-128.png"
- },
- "manifest_version": 2
-}
diff --git a/chrome/common/extensions/docs/examples/extensions/irc/README.txt b/chrome/common/extensions/docs/examples/extensions/irc/README.txt
deleted file mode 100644
index 692beb9e3..0000000
--- a/chrome/common/extensions/docs/examples/extensions/irc/README.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-This directory contains a simple irc app which is a work in progress.
-
-/app - contains the manifest and any additional resources which are to be
- packaged in a crx.
-
-/servlet - contains the java servlet which will serve the live resources and
- also proxy the irc traffic between the client and irc servers
-
-/conf - contains configuration files for running the servlet.
-
-This example depends on WebSockets, so it must be run inside a servlet container
-which supports WebSockets.
-
-The following are instructions for setting up a development jetty server to
-host the servlet.
-
-1) Get the jetty 7.x distribution from eclipse.org. Unpack it anywhere. We'll
- call that directory JETTY_HOME
-2) Delete the contents of JETTY_HOME/webapps.
-3) Copy /conf/irc.xml to JETTY_HOME/contexts, edit the value of resourceBase in
- irc.xml to point to the contents of /servlet.
-4) Copy jetty.xml and webdefault.xml to JETTY_HOME/etc
-5) Copy the following jars from JETTY_HOME/lib to /servlet/WEB-INF/lib:
-
- jetty-client, jetty-continuation, jetty-http, jetty-io, jetty-servlets,
- jetty-util
-
-6) Compile /servlet/src/org/chromium/IRCProxyWebSocket.java and put the
- resulting class file in /servlet/WEB-INF/classes
diff --git a/chrome/common/extensions/docs/examples/extensions/irc/app/manifest.json b/chrome/common/extensions/docs/examples/extensions/irc/app/manifest.json
deleted file mode 100644
index 9c6b31e..0000000
--- a/chrome/common/extensions/docs/examples/extensions/irc/app/manifest.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "name": "Chromium IRC App",
- "version": "0.1",
- "app": {
- "launch" : {
- "url": "http://localhost:8080"
- },
- "origins": ["http://localhost:8080"]
- },
- "manifest_version": 2
-}
diff --git a/chrome/common/extensions/docs/examples/extensions/irc/conf/irc.xml b/chrome/common/extensions/docs/examples/extensions/irc/conf/irc.xml
deleted file mode 100644
index 13441c9..0000000
--- a/chrome/common/extensions/docs/examples/extensions/irc/conf/irc.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
-<Configure class="org.eclipse.jetty.webapp.WebAppContext">
- <Set name="contextPath">/</Set>
- <Set name="resourceBase">file:/D:/eclipse/irc-proxy</Set>
- <Set name="defaultsDescriptor"><SystemProperty name="jetty.home" default="."/>/etc/webdefault.xml</Set>
-</Configure>
diff --git a/chrome/common/extensions/docs/examples/extensions/irc/conf/jetty.xml b/chrome/common/extensions/docs/examples/extensions/irc/conf/jetty.xml
deleted file mode 100644
index 5883d61..0000000
--- a/chrome/common/extensions/docs/examples/extensions/irc/conf/jetty.xml
+++ /dev/null
@@ -1,197 +0,0 @@
-<?xml version="1.0"?>
-<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
-
-<!-- =============================================================== -->
-<!-- Configure the Jetty Server -->
-<!-- -->
-<!-- Documentation of this file format can be found at: -->
-<!-- http://docs.codehaus.org/display/JETTY/jetty.xml -->
-<!-- -->
-<!-- =============================================================== -->
-
-
-<Configure id="Server" class="org.eclipse.jetty.server.Server">
-
- <!-- =========================================================== -->
- <!-- Server Thread Pool -->
- <!-- =========================================================== -->
- <Set name="ThreadPool">
- <!-- Default queued blocking threadpool
- -->
- <New class="org.eclipse.jetty.util.thread.QueuedThreadPool">
- <Set name="minThreads">10</Set>
- <Set name="maxThreads">200</Set>
- </New>
-
- <!-- Optional Java 5 bounded threadpool with job queue
- <New class="org.eclipse.thread.concurrent.ThreadPool">
- <Set name="corePoolSize">50</Set>
- <Set name="maximumPoolSize">50</Set>
- </New>
- -->
- </Set>
-
-
-
- <!-- =========================================================== -->
- <!-- Set connectors -->
- <!-- =========================================================== -->
-
- <Call name="addConnector">
- <Arg>
- <New class="org.eclipse.jetty.server.nio.SelectChannelConnector">
- <Set name="host"><SystemProperty name="jetty.host" /></Set>
- <Set name="port"><SystemProperty name="jetty.port" default="8080"/></Set>
- <Set name="maxIdleTime">300000</Set>
- <Set name="Acceptors">2</Set>
- <Set name="statsOn">false</Set>
- <Set name="confidentialPort">8443</Set>
- <Set name="lowResourcesConnections">20000</Set>
- <Set name="lowResourcesMaxIdleTime">5000</Set>
- </New>
- </Arg>
- </Call>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
- <!-- To add a HTTPS SSL connector -->
- <!-- mixin jetty-ssl.xml: -->
- <!-- java -jar start.jar etc/jetty.xml etc/jetty-ssl.xml -->
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
- <!-- To add a HTTP blocking connector -->
- <!-- mixin jetty-bio.xml: -->
- <!-- java -jar start.jar etc/jetty.xml etc/jetty-bio.xml -->
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
- <!-- To allow Jetty to be started from xinetd -->
- <!-- mixin jetty-xinetd.xml: -->
- <!-- java -jar start.jar etc/jetty.xml etc/jetty-xinetd.xml -->
- <!-- -->
- <!-- See jetty-xinetd.xml for further instructions. -->
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <!-- =========================================================== -->
- <!-- Set handler Collection Structure -->
- <!-- =========================================================== -->
- <Set name="handler">
- <New id="Handlers" class="org.eclipse.jetty.server.handler.HandlerCollection">
- <Set name="handlers">
- <Array type="org.eclipse.jetty.server.Handler">
- <Item>
- <New id="Contexts" class="org.eclipse.jetty.server.handler.ContextHandlerCollection"/>
- </Item>
- <Item>
- <New id="DefaultHandler" class="org.eclipse.jetty.server.handler.DefaultHandler"/>
- </Item>
- <Item>
- <New id="RequestLog" class="org.eclipse.jetty.server.handler.RequestLogHandler"/>
- </Item>
- </Array>
- </Set>
- </New>
- </Set>
-
- <!-- =========================================================== -->
- <!-- Configure the context deployer -->
- <!-- A context deployer will deploy contexts described in -->
- <!-- configuration files discovered in a directory. -->
- <!-- The configuration directory can be scanned for hot -->
- <!-- deployments at the configured scanInterval. -->
- <!-- -->
- <!-- This deployer is configured to deploy contexts configured -->
- <!-- in the $JETTY_HOME/contexts directory -->
- <!-- -->
- <!-- =========================================================== -->
- <Call name="addBean">
- <Arg>
- <New class="org.eclipse.jetty.deploy.ContextDeployer">
- <Set name="contexts"><Ref id="Contexts"/></Set>
- <Set name="configurationDir"><SystemProperty name="jetty.home" default="."/>/contexts</Set>
- <Set name="scanInterval">5</Set>
- <Call name="setAttribute">
- <Arg>org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern</Arg>
- <Arg>.*/jsp-api-[^/]*\.jar$|.*/jsp-[^/]*\.jar$</Arg>
- </Call>
- </New>
- </Arg>
- </Call>
-
- <!-- =========================================================== -->
- <!-- Configure the webapp deployer. -->
- <!-- A webapp deployer will deploy standard webapps discovered -->
- <!-- in a directory at startup, without the need for additional -->
- <!-- configuration files. It does not support hot deploy or -->
- <!-- non standard contexts (see ContextDeployer above). -->
- <!-- -->
- <!-- This deployer is configured to deploy webapps from the -->
- <!-- $JETTY_HOME/webapps directory -->
- <!-- -->
- <!-- Normally only one type of deployer need be used. -->
- <!-- -->
- <!-- =========================================================== -->
- <Call name="addBean">
- <Arg>
- <New class="org.eclipse.jetty.deploy.WebAppDeployer">
- <Set name="contexts"><Ref id="Contexts"/></Set>
- <Set name="webAppDir"><SystemProperty name="jetty.home" default="."/>/webapps</Set>
- <Set name="parentLoaderPriority">false</Set>
- <Set name="extract">true</Set>
- <Set name="allowDuplicates">false</Set>
- <Set name="defaultsDescriptor"><SystemProperty name="jetty.home" default="."/>/etc/webdefault.xml</Set>
- <Call name="setAttribute">
- <Arg>org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern</Arg>
- <Arg>.*/jsp-api-[^/]*\.jar$|.*/jsp-[^/]*\.jar$</Arg>
- </Call>
- </New>
- </Arg>
- </Call>
-
- <!-- =========================================================== -->
- <!-- Configure Authentication Login Service -->
- <!-- Realms may be configured for the entire server here, or -->
- <!-- they can be configured for a specific web app in a context -->
- <!-- configuration (see $(jetty.home)/contexts/test.xml for an -->
- <!-- example). -->
- <!-- =========================================================== -->
- <Call name="addBean">
- <Arg>
- <New class="org.eclipse.jetty.security.HashLoginService">
- <Set name="name">Test Realm</Set>
- <Set name="config"><SystemProperty name="jetty.home" default="."/>/etc/realm.properties</Set>
- <Set name="refreshInterval">0</Set>
- </New>
- </Arg>
- </Call>
-
- <!-- =========================================================== -->
- <!-- Configure Request Log -->
- <!-- Request logs may be configured for the entire server here, -->
- <!-- or they can be configured for a specific web app in a -->
- <!-- contexts configuration (see $(jetty.home)/contexts/test.xml -->
- <!-- for an example). -->
- <!-- =========================================================== -->
- <Ref id="RequestLog">
- <Set name="requestLog">
- <New id="RequestLogImpl" class="org.eclipse.jetty.server.NCSARequestLog">
- <Set name="filename"><SystemProperty name="jetty.home" default="."/>/logs/yyyy_mm_dd.request.log</Set>
- <Set name="filenameDateFormat">yyyy_MM_dd</Set>
- <Set name="retainDays">90</Set>
- <Set name="append">true</Set>
- <Set name="extended">false</Set>
- <Set name="logCookies">false</Set>
- <Set name="LogTimeZone">GMT</Set>
- </New>
- </Set>
- </Ref>
-
- <!-- =========================================================== -->
- <!-- extra options -->
- <!-- =========================================================== -->
- <Set name="stopAtShutdown">true</Set>
- <Set name="sendServerVersion">true</Set>
- <Set name="sendDateHeader">true</Set>
- <Set name="gracefulShutdown">1000</Set>
-
-</Configure>
diff --git a/chrome/common/extensions/docs/examples/extensions/irc/conf/webdefault.xml b/chrome/common/extensions/docs/examples/extensions/irc/conf/webdefault.xml
deleted file mode 100644
index b52cadd..0000000
--- a/chrome/common/extensions/docs/examples/extensions/irc/conf/webdefault.xml
+++ /dev/null
@@ -1,404 +0,0 @@
-<?xml version="1.0" encoding="ISO-8859-1"?>
-
-<!-- ===================================================================== -->
-<!-- This file contains the default descriptor for web applications. -->
-<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-<!-- The intent of this descriptor is to include jetty specific or common -->
-<!-- configuration for all webapps. If a context has a webdefault.xml -->
-<!-- descriptor, it is applied before the contexts own web.xml file -->
-<!-- -->
-<!-- A context may be assigned a default descriptor by: -->
-<!-- + Calling WebApplicationContext.setDefaultsDescriptor -->
-<!-- + Passed an arg to addWebApplications -->
-<!-- -->
-<!-- This file is used both as the resource within the jetty.jar (which is -->
-<!-- used as the default if no explicit defaults descriptor is set) and it -->
-<!-- is copied to the etc directory of the Jetty distro and explicitly -->
-<!-- by the jetty.xml file. -->
-<!-- -->
-<!-- ===================================================================== -->
-<web-app
- xmlns="http://java.sun.com/xml/ns/javaee"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
- metadata-complete="true"
- version="2.5">
-
- <description>
- Default web.xml file.
- This file is applied to a Web application before it's own WEB_INF/web.xml file
- </description>
-
-
- <!-- ==================================================================== -->
- <!-- Context params to control Session Cookies -->
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
- <!-- UNCOMMENT TO ACTIVATE
- <context-param>
- <param-name>org.eclipse.jetty.servlet.SessionDomain</param-name>
- <param-value>127.0.0.1</param-value>
- </context-param>
-
- <context-param>
- <param-name>org.eclipse.jetty.servlet.SessionPath</param-name>
- <param-value>/</param-value>
- </context-param>
-
- <context-param>
- <param-name>org.eclipse.jetty.servlet.MaxAge</param-name>
- <param-value>-1</param-value>
- </context-param>
- -->
-
-
- <!-- ==================================================================== -->
- <!-- The default servlet. -->
- <!-- This servlet, normally mapped to /, provides the handling for static -->
- <!-- content, OPTIONS and TRACE methods for the context. -->
- <!-- The following initParameters are supported: -->
- <!-- -->
- <!-- acceptRanges If true, range requests and responses are -->
- <!-- supported -->
- <!-- -->
- <!-- dirAllowed If true, directory listings are returned if no -->
- <!-- welcome file is found. Else 403 Forbidden. -->
- <!-- -->
- <!-- welcomeServlets If true, attempt to dispatch to welcome files -->
- <!-- that are servlets, if no matching static -->
- <!-- resources can be found. -->
- <!-- -->
- <!-- redirectWelcome If true, redirect welcome file requests -->
- <!-- else use request dispatcher forwards -->
- <!-- -->
- <!-- gzip If set to true, then static content will be served-->
- <!-- as gzip content encoded if a matching resource is -->
- <!-- found ending with ".gz" -->
- <!-- -->
- <!-- resoureBase Can be set to replace the context resource base -->
- <!-- -->
- <!-- relativeResourceBase -->
- <!-- Set with a pathname relative to the base of the -->
- <!-- servlet context root. Useful for only serving -->
- <!-- static content from only specific subdirectories. -->
- <!-- -->
- <!-- useFileMappedBuffer -->
- <!-- If set to true (the default), a memory mapped -->
- <!-- file buffer will be used to serve static content -->
- <!-- when using an NIO connector. Setting this value -->
- <!-- to false means that a direct buffer will be used -->
- <!-- instead. If you are having trouble with Windows -->
- <!-- file locking, set this to false. -->
- <!-- -->
- <!-- cacheControl If set, all static content will have this value -->
- <!-- set as the cache-control header. -->
- <!-- -->
- <!-- maxCacheSize Maximum size of the static resource cache -->
- <!-- -->
- <!-- maxCachedFileSize Maximum size of any single file in the cache -->
- <!-- -->
- <!-- maxCachedFiles Maximum number of files in the cache -->
- <!-- -->
- <!-- cacheType "nio", "bio" or "both" to determine the type(s) -->
- <!-- of resource cache. A bio cached buffer may be used-->
- <!-- by nio but is not as efficient as a nio buffer. -->
- <!-- An nio cached buffer may not be used by bio. -->
- <!-- -->
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
- <servlet>
- <servlet-name>default</servlet-name>
- <servlet-class>org.eclipse.jetty.servlet.DefaultServlet</servlet-class>
- <init-param>
- <param-name>acceptRanges</param-name>
- <param-value>true</param-value>
- </init-param>
- <init-param>
- <param-name>dirAllowed</param-name>
- <param-value>true</param-value>
- </init-param>
- <init-param>
- <param-name>welcomeServlets</param-name>
- <param-value>false</param-value>
- </init-param>
- <init-param>
- <param-name>redirectWelcome</param-name>
- <param-value>false</param-value>
- </init-param>
- <init-param>
- <param-name>maxCacheSize</param-name>
- <param-value>256000000</param-value>
- </init-param>
- <init-param>
- <param-name>maxCachedFileSize</param-name>
- <param-value>10000000</param-value>
- </init-param>
- <init-param>
- <param-name>maxCachedFiles</param-name>
- <param-value>1000</param-value>
- </init-param>
- <init-param>
- <param-name>cacheType</param-name>
- <param-value>both</param-value>
- </init-param>
- <init-param>
- <param-name>gzip</param-name>
- <param-value>true</param-value>
- </init-param>
- <init-param>
- <param-name>useFileMappedBuffer</param-name>
- <param-value>false</param-value>
- </init-param>
- <!--
- <init-param>
- <param-name>cacheControl</param-name>
- <param-value>max-age=3600,public</param-value>
- </init-param>
- -->
- <load-on-startup>0</load-on-startup>
- </servlet>
-
- <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
-
-
- <!-- ==================================================================== -->
- <!-- JSP Servlet -->
- <!-- This is the jasper JSP servlet from the jakarta project -->
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
- <!-- The JSP page compiler and execution servlet, which is the mechanism -->
- <!-- used by Glassfish to support JSP pages. Traditionally, this servlet -->
- <!-- is mapped to URL patterh "*.jsp". This servlet supports the -->
- <!-- following initialization parameters (default values are in square -->
- <!-- brackets): -->
- <!-- -->
- <!-- checkInterval If development is false and reloading is true, -->
- <!-- background compiles are enabled. checkInterval -->
- <!-- is the time in seconds between checks to see -->
- <!-- if a JSP page needs to be recompiled. [300] -->
- <!-- -->
- <!-- compiler Which compiler Ant should use to compile JSP -->
- <!-- pages. See the Ant documenation for more -->
- <!-- information. [javac] -->
- <!-- -->
- <!-- classdebuginfo Should the class file be compiled with -->
- <!-- debugging information? [true] -->
- <!-- -->
- <!-- classpath What class path should I use while compiling -->
- <!-- generated servlets? [Created dynamically -->
- <!-- based on the current web application] -->
- <!-- Set to ? to make the container explicitly set -->
- <!-- this parameter. -->
- <!-- -->
- <!-- development Is Jasper used in development mode (will check -->
- <!-- for JSP modification on every access)? [true] -->
- <!-- -->
- <!-- enablePooling Determines whether tag handler pooling is -->
- <!-- enabled [true] -->
- <!-- -->
- <!-- fork Tell Ant to fork compiles of JSP pages so that -->
- <!-- a separate JVM is used for JSP page compiles -->
- <!-- from the one Tomcat is running in. [true] -->
- <!-- -->
- <!-- ieClassId The class-id value to be sent to Internet -->
- <!-- Explorer when using <jsp:plugin> tags. -->
- <!-- [clsid:8AD9C840-044E-11D1-B3E9-00805F499D93] -->
- <!-- -->
- <!-- javaEncoding Java file encoding to use for generating java -->
- <!-- source files. [UTF-8] -->
- <!-- -->
- <!-- keepgenerated Should we keep the generated Java source code -->
- <!-- for each page instead of deleting it? [true] -->
- <!-- -->
- <!-- logVerbosityLevel The level of detailed messages to be produced -->
- <!-- by this servlet. Increasing levels cause the -->
- <!-- generation of more messages. Valid values are -->
- <!-- FATAL, ERROR, WARNING, INFORMATION, and DEBUG. -->
- <!-- [WARNING] -->
- <!-- -->
- <!-- mappedfile Should we generate static content with one -->
- <!-- print statement per input line, to ease -->
- <!-- debugging? [false] -->
- <!-- -->
- <!-- -->
- <!-- reloading Should Jasper check for modified JSPs? [true] -->
- <!-- -->
- <!-- suppressSmap Should the generation of SMAP info for JSR45 -->
- <!-- debugging be suppressed? [false] -->
- <!-- -->
- <!-- dumpSmap Should the SMAP info for JSR45 debugging be -->
- <!-- dumped to a file? [false] -->
- <!-- False if suppressSmap is true -->
- <!-- -->
- <!-- scratchdir What scratch directory should we use when -->
- <!-- compiling JSP pages? [default work directory -->
- <!-- for the current web application] -->
- <!-- -->
- <!-- tagpoolMaxSize The maximum tag handler pool size [5] -->
- <!-- -->
- <!-- xpoweredBy Determines whether X-Powered-By response -->
- <!-- header is added by generated servlet [false] -->
- <!-- -->
- <!-- If you wish to use Jikes to compile JSP pages: -->
- <!-- Set the init parameter "compiler" to "jikes". Define -->
- <!-- the property "-Dbuild.compiler.emacs=true" when starting Jetty -->
- <!-- to cause Jikes to emit error messages in a format compatible with -->
- <!-- Jasper. -->
- <!-- If you get an error reporting that jikes can't use UTF-8 encoding, -->
- <!-- try setting the init parameter "javaEncoding" to "ISO-8859-1". -->
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
- <servlet id="jsp">
- <servlet-name>jsp</servlet-name>
- <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
- <init-param>
- <param-name>logVerbosityLevel</param-name>
- <param-value>DEBUG</param-value>
- </init-param>
- <init-param>
- <param-name>fork</param-name>
- <param-value>false</param-value>
- </init-param>
- <init-param>
- <param-name>xpoweredBy</param-name>
- <param-value>false</param-value>
- </init-param>
- <!--
- <init-param>
- <param-name>classpath</param-name>
- <param-value>?</param-value>
- </init-param>
- -->
- <load-on-startup>0</load-on-startup>
- </servlet>
-
- <servlet-mapping>
- <servlet-name>jsp</servlet-name>
- <url-pattern>*.jsp</url-pattern>
- <url-pattern>*.jspf</url-pattern>
- <url-pattern>*.jspx</url-pattern>
- <url-pattern>*.xsp</url-pattern>
- <url-pattern>*.JSP</url-pattern>
- <url-pattern>*.JSPF</url-pattern>
- <url-pattern>*.JSPX</url-pattern>
- <url-pattern>*.XSP</url-pattern>
- </servlet-mapping>
-
- <!-- ==================================================================== -->
- <!-- Dynamic Servlet Invoker. -->
- <!-- This servlet invokes anonymous servlets that have not been defined -->
- <!-- in the web.xml or by other means. The first element of the pathInfo -->
- <!-- of a request passed to the envoker is treated as a servlet name for -->
- <!-- an existing servlet, or as a class name of a new servlet. -->
- <!-- This servlet is normally mapped to /servlet/* -->
- <!-- This servlet support the following initParams: -->
- <!-- -->
- <!-- nonContextServlets If false, the invoker can only load -->
- <!-- servlets from the contexts classloader. -->
- <!-- This is false by default and setting this -->
- <!-- to true may have security implications. -->
- <!-- -->
- <!-- verbose If true, log dynamic loads -->
- <!-- -->
- <!-- * All other parameters are copied to the -->
- <!-- each dynamic servlet as init parameters -->
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
- <!-- Uncomment for dynamic invocation
- <servlet>
- <servlet-name>invoker</servlet-name>
- <servlet-class>org.eclipse.jetty.servlet.Invoker</servlet-class>
- <init-param>
- <param-name>verbose</param-name>
- <param-value>false</param-value>
- </init-param>
- <init-param>
- <param-name>nonContextServlets</param-name>
- <param-value>false</param-value>
- </init-param>
- <init-param>
- <param-name>dynamicParam</param-name>
- <param-value>anyValue</param-value>
- </init-param>
- <load-on-startup>0</load-on-startup>
- </servlet>
-
- <servlet-mapping> <servlet-name>invoker</servlet-name> <url-pattern>/servlet/*</url-pattern> </servlet-mapping>
- -->
-
-
-
- <!-- ==================================================================== -->
- <session-config>
- <session-timeout>30</session-timeout>
- </session-config>
-
- <!-- ==================================================================== -->
- <!-- Default MIME mappings -->
- <!-- The default MIME mappings are provided by the mime.properties -->
- <!-- resource in the org.eclipse.jetty.server.jar file. Additional or modified -->
- <!-- mappings may be specified here -->
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
- <!-- UNCOMMENT TO ACTIVATE
- <mime-mapping>
- <extension>mysuffix</extension>
- <mime-type>mymime/type</mime-type>
- </mime-mapping>
- -->
-
- <!-- ==================================================================== -->
- <welcome-file-list>
- <welcome-file>index.html</welcome-file>
- <welcome-file>index.htm</welcome-file>
- <welcome-file>index.jsp</welcome-file>
- </welcome-file-list>
-
- <!-- ==================================================================== -->
- <locale-encoding-mapping-list>
- <locale-encoding-mapping><locale>ar</locale><encoding>ISO-8859-6</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>be</locale><encoding>ISO-8859-5</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>bg</locale><encoding>ISO-8859-5</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>ca</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>cs</locale><encoding>ISO-8859-2</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>da</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>de</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>el</locale><encoding>ISO-8859-7</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>en</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>es</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>et</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>fi</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>fr</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>hr</locale><encoding>ISO-8859-2</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>hu</locale><encoding>ISO-8859-2</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>is</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>it</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>iw</locale><encoding>ISO-8859-8</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>ja</locale><encoding>Shift_JIS</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>ko</locale><encoding>EUC-KR</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>lt</locale><encoding>ISO-8859-2</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>lv</locale><encoding>ISO-8859-2</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>mk</locale><encoding>ISO-8859-5</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>nl</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>no</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>pl</locale><encoding>ISO-8859-2</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>pt</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>ro</locale><encoding>ISO-8859-2</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>ru</locale><encoding>ISO-8859-5</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>sh</locale><encoding>ISO-8859-5</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>sk</locale><encoding>ISO-8859-2</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>sl</locale><encoding>ISO-8859-2</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>sq</locale><encoding>ISO-8859-2</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>sr</locale><encoding>ISO-8859-5</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>sv</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>tr</locale><encoding>ISO-8859-9</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>uk</locale><encoding>ISO-8859-5</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>zh</locale><encoding>GB2312</encoding></locale-encoding-mapping>
- <locale-encoding-mapping><locale>zh_TW</locale><encoding>Big5</encoding></locale-encoding-mapping>
- </locale-encoding-mapping-list>
-
- <security-constraint>
- <web-resource-collection>
- <web-resource-name>Disable TRACE</web-resource-name>
- <url-pattern>/</url-pattern>
- <http-method>TRACE</http-method>
- </web-resource-collection>
- <auth-constraint/>
- </security-constraint>
-
-</web-app>
-
diff --git a/chrome/common/extensions/docs/examples/extensions/irc/servlet/WEB-INF/web.xml b/chrome/common/extensions/docs/examples/extensions/irc/servlet/WEB-INF/web.xml
deleted file mode 100644
index 151b76d..0000000
--- a/chrome/common/extensions/docs/examples/extensions/irc/servlet/WEB-INF/web.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<web-app
- xmlns="http://java.sun.com/xml/ns/javaee"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
- version="2.5">
- <display-name>IRC-Proxy</display-name>
- <context-param>
- <param-name>org.eclipse.jetty.server.context.ManagedAttributes</param-name>
- <param-value>org.eclipse.jetty.servlets.ProxyServlet.Logger,org.eclipse.jetty.servlets.ProxyServlet.ThreadPool,org.eclipse.jetty.servlets.ProxyServlet.HttpClient</param-value>
- </context-param>
- <servlet>
- <servlet-name>irc-proxy</servlet-name>
- <servlet-class>org.chromium.IRCProxyWebSocket</servlet-class>
- <load-on-startup>1</load-on-startup>
- </servlet>
- <servlet-mapping>
- <servlet-name>irc-proxy</servlet-name>
- <url-pattern>/ws/*</url-pattern>
- </servlet-mapping>
-</web-app>
-
-
diff --git a/chrome/common/extensions/docs/examples/extensions/irc/servlet/addChannel.html b/chrome/common/extensions/docs/examples/extensions/irc/servlet/addChannel.html
deleted file mode 100644
index c72cfab..0000000
--- a/chrome/common/extensions/docs/examples/extensions/irc/servlet/addChannel.html
+++ /dev/null
@@ -1,61 +0,0 @@
-<html>
- <head>
- <link rel="stylesheet" type="text/css" href="styles.css">
- <script src="jstemplate/util.js" type="text/javascript"></script>
- <script src="jstemplate/jsevalcontext.js" type="text/javascript"></script>
- <script src="jstemplate/jstemplate.js" type="text/javascript"></script>
- <script src="util.js" type="text/javascript"></script>
- <script>
-function addChannel() {
- try {
- var servers = JSON.parse(localStorage.servers || "[]");
- var channelName = $F('channel');
- var serverName = $F('serverSelect')
- servers.forEach(function(server) {
- if (server.name == serverName) {
- server.channels = server.channels || [];
- server.channels.forEach(function(channel) {
- if (channel == channelName) {
- throw channelName + " is already open";
- }
- });
- server.channels.push(channelName);
- }
- });
-
- localStorage.servers = JSON.stringify(servers);
- window.opener.syncChannelList();
- window.opener.joinChannel(serverName, channelName);
- window.close();
- } catch (ex) {
- alert(ex);
- }
-}
-
-window.onload = function() {
- var servers = JSON.parse(localStorage.servers || "[]");
- if (servers.length == 0) {
- alert("You must first add a server connection");
- close();
- }
-
- jstProcess(new JsEvalContext(servers), $('serverSelect'));
-}
-
- </script>
- </head>
- <body>
- <div>
- <select id="serverSelect">
- <option jsselect="$this" jscontent="name"></option>
- </select>
- <input id="channel" type="text" value="#channel">
- </div>
- <div>
- </div>
- <div>
- <input type="button" value="Add New Channel"
- onclick="addChannel();">
- </div>
- </body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/extensions/irc/servlet/addServer.html b/chrome/common/extensions/docs/examples/extensions/irc/servlet/addServer.html
deleted file mode 100644
index dd6ed2e..0000000
--- a/chrome/common/extensions/docs/examples/extensions/irc/servlet/addServer.html
+++ /dev/null
@@ -1,54 +0,0 @@
-<html>
- <head>
- <link rel="stylesheet" type="text/css" href="styles.css">
- <script src="util.js" type="text/javascript"></script>
- <script>
-function addServer() {
- try {
- var servers = JSON.parse(localStorage.servers || "[]");
- var serverName = $F('serverText');
-
- servers.forEach(function(server) {
- if (server.name == serverName) {
- throw "Connection to " + serverName + " already established";
- }
- });
-
- var portValue = parseInt($F('serverPort'));
- if (isNaN(portValue)) {
- throw $F('serverPort') + " is not a valid port value";
- }
-
- var nickValue = $F('nick');
- var newServer = {
- name: serverName,
- port: portValue,
- nick: nickValue,
- channels: []
- };
-
- servers.push(newServer);
-
- localStorage.servers = JSON.stringify(servers);
- window.opener.addServerConnection(newServer);
- close();
- } catch (ex) {
- alert(ex);
- }
-}
- </script>
- </head>
- <body>
- <div>
- <input id="serverText" type="text" value="irc.freenode.net">
- <input id="serverPort" type="text" value="6667">
- </div>
- <div>
- <input id="nick" type="text" value="nick">
- </div>
- <div>
- <input type="button" value="Add New Server"
- onclick="addServer();">
- </div>
- </body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/extensions/irc/servlet/index.html b/chrome/common/extensions/docs/examples/extensions/irc/servlet/index.html
deleted file mode 100644
index 8b817da7..0000000
--- a/chrome/common/extensions/docs/examples/extensions/irc/servlet/index.html
+++ /dev/null
@@ -1,408 +0,0 @@
-<html>
- <head>
- <title>ChromiumIRC</title>
- <link rel="stylesheet" type="text/css" href="styles.css">
- <script src="jstemplate/util.js" type="text/javascript"></script>
- <script src="jstemplate/jsevalcontext.js" type="text/javascript"></script>
- <script src="jstemplate/jstemplate.js" type="text/javascript"></script>
- <script src="util.js" type="text/javascript"></script>
- <script lang="JavaScript" src="irc.js"></script>
- <script>
-
-var ircConnections = {};
-
-// The server & channel configutation data is stored in localStorage.servers.
-// These are setters and getters for this structure.
-function servers() {
- return JSON.parse(localStorage.servers || "[]");
-}
-function setServers(servers) {
- localStorage.servers = JSON.stringify(servers);
-}
-
-// Channel list is a sorted list of "server#channel" strings. This maps to
-// channel slides as represented in the UI.
-function channelList() {
- var channelList = [];
- servers().forEach(function(server) {
- server.channels = server.channels || [];
- server.channels.forEach(function(channel) {
- channelList.push(server.name + channel);
- });
- });
-
- channelList.sort();
- return channelList;
-}
-
-window.onload = function() {
- // Setup notifications.
- window.onfocus = function() {
- windowHasFocus = true;
- clearNotifications();
- }
- window.onblur = function() {
- windowHasFocus = false;
- }
-
- syncChannelList();
-
- // Setup channel navigation and message entry.
- function handleBodyKeyDown(event) {
- switch (event.keyCode) {
- case 37: // left arrow
- slideTo(-1);
- break;
- case 39: // right arrow
- slideTo(1);
- break;
- }
- }
- document.body.addEventListener('keydown', handleBodyKeyDown, false);
-
- // We don't want left & right arrow inside the text entry to move the channel
- // slides.
- $('typingDiv').addEventListener('keydown', function(event) {
- event.stopPropagation();
- });
- $('entryText').addEventListener('keydown', function(event) {
- if (event.keyCode == 13) { // RETURN key.
- processEntryMessage();
- }
- });
-
- servers().forEach(addServerConnection);
-};
-
-window.onunload = function() {
- ircConnections.forEach(function(irc) {
- irc.disconnect();
- });
-}
-
-function addServerConnection(server) {
- var ws = new WebSocket("ws://" + location.host + "/ws");
- var irc = new IRCConnection(server.name, server.port, server.nick,
- ws.send.bind(ws), // sendFunc
- ws.close.bind(ws)); // closeFunc
- ws.onopen = irc.onOpened.bind(irc);
- ws.onclose = irc.onClosed.bind(irc);
- ws.onmessage = function(message) {
- irc.onMessage(message.data);
- };
- irc.onConnect = function(message) {
- server.channels.forEach(function(channel) {
- ircConnections[server.name].joinChannel(channel);
- });
- };
- irc.onDisconnect = function(message) {
- };
- irc.onText = function(channel, nick, message) {
- checkForNickReference(server, channel, nick, message);
- addMessage(server.name, channel, nick, new Date(), message);
- };
-
- ircConnections[server.name] = irc;
-}
-
-function joinChannel(serverName, channelName) {
- ircConnections[serverName].joinChannel(channelName);
-}
-
-function removeChannelListener(channelName) {
- return function(event) {
- event.stopPropagation();
-
- var servers = servers();
- servers.forEach(function(server) {
- if (channelName.indexOf(server.name) == 0) {
- for (var i = 0; server.channels.length; i++) {
- if (channelName == server.name + server.channels[i]) {
- ircConnections[server.name].quitChannel(server.channels[i]);
- server.channels.splice(i, 1);
- break;
- }
- }
- }
- });
-
- setServers(servers);
- syncChannelList();
- };
-}
-
-function syncChannelList() {
- var channels = channelList();
- var channelSlides = $('channelSlides');
- var channelSlideProto = $('channelSlideProto');
-
- var channelIndex = 0;
- var slideIndex = 0;
-
- while(channelIndex < channels.length ||
- channels.length != channelSlides.children.length) {
- var channel = channels[channelIndex];
- var slide = channelSlides.children[slideIndex];
-
- if (slideIndex == channelSlides.children.length ||
- channel < slideChannel(slide)) {
- // Add a new slide.
- var newSlide = channelSlideProto.cloneNode(true);
- jstProcess(new JsEvalContext({ name: channel }), newSlide);
- newSlide.setAttribute("id", "channel-" + channel);
- newSlide.style.display = "";
- if (slideIndex == channelSlides.children.length) {
- channelSlides.appendChild(newSlide);
- } else {
- channelSlides.insertBefore(newSlide, slide);
- }
- newSlide.addEventListener('click', onClickMoveSlide);
- childNodeWithClass(newSlide, "removeButton")
- .addEventListener('click', removeChannelListener(channel));
-
- slide = newSlide;
- } else if (!channel || channel > slideChannel(slide)) {
- // Delete a removed slide.
-
- // If the removed slide is the current slide, we have to pick a new
- // current slide.
- if (localStorage.currentSlide == slideChannel(slide)) {
- if (slide.nextSibling) {
- localStorage.currentSlide = slideChannel(slide.nextSibling);
- } else if (channels.length == 0) {
- localStorage.currentSlide = "";
- } else if (slideIndex < channelSlides.children.length) {
- localStorage.currentSlide =
- slideChannel(channelSlides.children[slideIndex - 1]);
- }
- }
- channelSlides.removeChild(slide);
- } else {
- channelIndex++;
- slideIndex++;
- }
-
- slide.setAttribute("slide", "" + slideIndex - 1);
- }
-
- slideTo();
-}
-
-function processEntryMessage() {
- var message = $('entryText').value;
- $('entryText').value = "";
-
- if (!localStorage.currentSlide) {
- alert('No current channel');
- return;
- }
-
- var server;
- var channel;
- var nick;
- servers().forEach(function(s) {
- if (localStorage.currentSlide.indexOf(s.name) == 0) {
- server = s.name;
- nick = s.nick;
- s.channels.forEach(function(c) {
- if (localStorage.currentSlide == s.name + c) {
- channel = c;
- }
- });
- }
- });
-
- addMessage(server, channel, nick, new Date(), message);
- ircConnections[server].sendMessage([channel], message);
-}
-
-function addMessage(server, channel, nick, time, body) {
- messageLine = childNodeWithClass($('channelSlideProto'), "messageLine");
- var newMessageLine = messageLine.cloneNode(true);
-
- jstProcess(new JsEvalContext({
- 'nick': nick,
- 'time': time,
- 'body': body
- }), newMessageLine);
- newMessageLine.style.display = "";
-
- var messageList =
- childNodeWithClass($("channel-" + server + channel), "messageList");
- messageList.appendChild(newMessageLine);
-}
-
-function formatTime(time) {
- return "";
-}
-
-/**
- * Slide Navigation.
- */
-
-// Returns the server#channel string value for a given |slide| element.
-function slideChannel(slide) {
- return childNodeWithClass(slide, "channel").innerText;
-}
-
-// Handler for clicking on the visible portions of the previous & next slides.
-function onClickMoveSlide() {
- if (localStorage.currentSlide != slideChannel(this)) {
- localStorage.currentSlide = slideChannel(this);
- slideTo();
- }
-}
-
-// Handles navigating between the channel slides. If |slideDelta| is given,
-// it should specify the number of slides to move left (negative value) or right
-// positive value. If |slideDelta| is not provided, It ensures that
-// |localStorage.currentSlide| is navigated to.
-function slideTo(slideDelta) {
- var slide;
- var slideNumber;
-
- if (localStorage.currentSlide) {
- slide = document.getElementById("channel-" + localStorage.currentSlide);
- if (slide) {
- slideNumber = parseInt(slide.getAttribute("slide"));
- }
- }
- if (isNaN(slideNumber) || !slide) {
- slideNumber = 0;
- }
- if (typeof(slideDelta) == "number") {
- slideNumber += slideDelta;
- }
-
- var slides = document.getElementsByClassName("channelSlide");
- if (slideNumber < 0 || slideNumber == slides.length - 1) {
- return;
- }
-
- for (var i = 0; i < slides.length; i++) {
- var slide = slides[i];
- var slideIndex = parseInt(slide.getAttribute("slide")) - slideNumber;
-
- if (slideIndex <= -2) {
- slide.className = "channelSlide far-left";
- }
- if (slideIndex >= 2) {
- slide.className = "channelSlide far-right";
- }
-
- switch(slideIndex) {
- case -1:
- slide.className = "channelSlide left";
- break;
- case 0:
- slide.className = "channelSlide center";
- localStorage.currentSlide = slideChannel(slide);
- break;
- case 1:
- slide.className = "channelSlide right";
- break;
- }
- }
-
- clearNotifications();
-}
-
-/**
- * Notifications
- */
-var windowHasFocus = false;
-var notifications = {};
-
-function clearNotifications() {
- for (property in notifications) {
- notifications[property].cancel();
- }
-
- notifications = {};
-}
-
-function checkForNickReference(server, channel, nick, message) {
- if (windowHasFocus || !message || message.indexOf(server.nick) < 0) {
- return;
- }
-
- // Notifications will be enabled by the app install. Otherwise, don't notity.
- if (Notification.permission != "granted") {
- return;
- }
-
- // Remove a previous notification from the same channel. Show the newer one.
- if (notifications[server.name + channel]) {
- notifications[server.name + channel].close();
- }
-
- var n = new Notification("On " + server.name + channel, {
- icon: "https://www.google.com/favicon.ico",
- body: nick + ": " + message,
- });
-
- n.onshow = function() {};
- n.onclose = function() {
- delete notifications[server.name + channel];
- };
-
- notifications[server.name + channel] = n;
-}
- </script>
- </head>
- <body>
- <!-- TEMPLATES -->
- <div id="channelSlideProto" style="display:none" class="channelSlide">
- <div class="channelControls">
- <div jscontent="name" class="channel">
- </div>
- <div class="removeButton">
- x
- </div>
- </div>
- <div class="channelSlideContainer">
- <div class="messageListContainer">
- <div class="messageList">
- <div jsselect="messages">
- <div class="messageLine">
- <div jscontent="nick" class="messageSender"></div>:
- <div jscontent="body" class="messageBody"></div>
- </div>
- </div>
- </div>
- </div>
- <div class="messageListSpacer">.</div>
- </div>
- </div>
-
- <div id="pageContainer">
- <div id="headerContainer">
- <div id="pageControls">
- <div onclick="window.open('addServer.html');">
- <div class="addControlLabel">
- add server
- </div>
- <div class="addButton">
- +
- </div>
- </div>
- <div onclick=" window.open('addChannel.html');">
- <div class="addControlLabel">
- add channel
- </div>
- <div class="addButton">
- +
- </div>
- </div>
- </div>
- </div>
- <div id="slideContainer">
- <div id="typingDiv">
- <input type="text" id="entryText" value="">
- </div>
- <div style="" id="channelSlides">
- </div>
- </div>
- </div>
- </body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/extensions/irc/servlet/irc.js b/chrome/common/extensions/docs/examples/extensions/irc/servlet/irc.js
deleted file mode 100644
index 05cae96..0000000
--- a/chrome/common/extensions/docs/examples/extensions/irc/servlet/irc.js
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * IRCConnection is a simple implementation of the IRC protocol. A small
- * subset of the IRC commands are implemented. To be functional, IRCConnection
- * needs some mechanism of transport to be hooked up by:
- * -Passing in |sendFunc| and |closeFunc| which an IRCConnection to use to send
- * an IRC message command and to close the connection respectively.
- * -Connecting the in-bound functions |onOpened|, |onMessage|, and |onClosed|,
- * to the transport so that the IRCConnection can respond to the connection
- * being opened, a message being received and the connection being closed.
- */
-
-function NoOp() {};
-function log(message) { console.log(message); };
-
-function IRCConnection(server, port, nick, sendFunc, closeFunc) {
- this.server = server;
- this.port = port;
- this.nick = nick;
- this.connected = false;
-
- var that = this;
-
- /**
- * Client API
- */
- this.onConnect = NoOp;
- this.onDisconnect = NoOp;
- this.onText = NoOp;
- this.onNotice = NoOp;
- this.onNickReferenced = NoOp;
-
- this.joinChannel = function(channel) {
- sendCommand(commands.JOIN, [channel], "");
- };
-
- this.sendMessage = function(recipient, message) {
- sendCommand(commands.PRIVMSG, [recipient], message);
- };
-
- this.quitChannel = function(channel) {
- sendCommand(commands.PART, [channel], "");
- }
-
- this.disconnect = function(message) {
- sendCommand(commands.QUIT, [], message);
- closeFunc();
- }
-
- /**
- * Transport Interface
- * Whatever transport is used must provide and connect to the following
- * in-bound events.
- */
- this.onOpened = function() {
- sendFunc(that.server + ":" + that.port);
- sendCommand(commands.NICK, [this.nick], "");
- sendCommand(commands.USER,
- ["chromium-irc-lib", "chromium-ircproxy", "*"],
- "indigo");
- };
-
- this.onMessage = function(message) {
- log("<< " + message);
- if (!message || !message.length) {
- return;
- }
-
- var parsed = parseMessage(message);
-
- // Respond to PING command.
- if (parsed.command == commands.PING) {
- sendCommand(commands.PONG, [], parsed.body);
- return;
- }
-
- // Process PRIVMSG.
- if (parsed.command == commands.PRIVMSG) {
- if (parsed.body.charCodeAt(0) == 1) {
- // Ignore CTCP.
- return;
- }
- that.onText(parsed.parameters[0],
- parsed.prefix.split("!")[0],
- parsed.body);
- return;
- }
-
- // TODO: Other IRC commands.
- var commandCode = parseInt(parsed.command);
- if (commandCode == NaN) {
- return;
- }
-
- switch(commandCode) {
- case 001: // Server welcome message.
- that.connected = true;
- that.onConnect(parsed.body);
- break;
- case 002:
- case 003:
- case 004:
- case 005:
- if (!that.connected) {
- that.connected = true;
- that.onConnect();
- }
- break;
- case 433: // TODO(rafaelw): Nickname in use.
- throw "NOT IMPLEMENTED";
- break;
- default:
- break;
- }
- }
-
- this.onClosed = function() {
- that.connected = false;
- that.onDisconnect();
- };
-
- /**
- * IRC Implementation
- * What follows in a minimal implementation of the IRC protocol.
- * Only |commands| are currently implemented.
- */
- var commands = {
- JOIN: "JOIN",
- NICK: "NICK",
- NOTICE: "NOTICE",
- PART: "PART",
- PING: "PING",
- PONG: "PONG",
- PRIVMSG: "PRIVMSG",
- QUIT: "QUIT",
- USER: "USER"
- };
-
- function parseMessage(message) {
- var parsed = {};
- parsed.prefix = "";
- parsed.command = "";
- parsed.parameters = [];
- parsed.body = "";
-
- // Trim trailing CRLF.
- var crlfIndex = message.indexOf("\r\n");
- if(crlfIndex >= 0) {
- message = message.substring(0, crlfIndex);
- }
-
- // If leading character is ':', the message starts with a prefix.
- if (message.indexOf(':') == 0) {
- parsed.prefix = message.substring(1, message.indexOf(" "));
- message = message.substring(parsed.prefix.length + 2);
-
- // Forward past extra whitespace.
- while(message.indexOf(" ") == 0) {
- message = message.substring(1);
- }
- }
-
- // If there is still a ':', then the message has trailing body.
- var bodyMarker = message.indexOf(':');
- if (bodyMarker >= 0) {
- parsed.body = message.substring(bodyMarker + 1);
- message = message.substring(0, bodyMarker);
- }
-
- parsed.parameters = message.split(" ");
- parsed.command = parsed.parameters.shift(); // First param is the command.
-
- return parsed;
- }
-
- function sendCommand(command, params, message) {
- var line = command;
- if (params && params.length > 0) {
- line += " " + params.join(" ");
- }
- if (message && message.length > 0) {
- line += " :" + message;
- }
-
- log(">> " + line);
- line += "\r\n";
- sendFunc(line);
- };
-};
diff --git a/chrome/common/extensions/docs/examples/extensions/irc/servlet/jstemplate/jsevalcontext.js b/chrome/common/extensions/docs/examples/extensions/irc/servlet/jstemplate/jsevalcontext.js
deleted file mode 100644
index e3abe78..0000000
--- a/chrome/common/extensions/docs/examples/extensions/irc/servlet/jstemplate/jsevalcontext.js
+++ /dev/null
@@ -1,409 +0,0 @@
-// Copyright 2006 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-// implied. See the License for the specific language governing
-// permissions and limitations under the License.
-/**
- * Author: Steffen Meschkat <mesch@google.com>
- *
- * @fileoverview This class is used to evaluate expressions in a local
- * context. Used by JstProcessor.
- */
-
-
-/**
- * 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_count = '$count';
-var VAR_this = '$this';
-var VAR_context = '$context';
-var VAR_top = '$top';
-
-
-/**
- * The name of the global variable which holds the value to be returned if
- * context evaluation results in an error.
- * Use JsEvalContext.setGlobal(GLOB_default, value) to set this.
- */
-var GLOB_default = '$default';
-
-
-/**
- * Un-inlined literals, to avoid object creation in IE6. TODO(mesch):
- * So far, these are only used here, but we could use them thoughout
- * the code and thus move them to constants.js.
- */
-var CHAR_colon = ':';
-var REGEXP_semicolon = /\s*;\s*/;
-
-
-/**
- * See constructor_()
- * @param {Object|null} opt_data
- * @param {Object} opt_parent
- * @constructor
- */
-function JsEvalContext(opt_data, opt_parent) {
- this.constructor_.apply(this, arguments);
-}
-
-/**
- * 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|null} 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.
- */
-JsEvalContext.prototype.constructor_ = function(opt_data, opt_parent) {
- var me = this;
-
- /**
- * 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_.
- *
- * If this instance is recycled from the cache, then the property is
- * already initialized.
- *
- * @type {Object}
- */
- if (!me.vars_) {
- me.vars_ = {};
- }
- if (opt_parent) {
- // If there is a parent node, inherit local variables from the
- // parent.
- copyProperties(me.vars_, opt_parent.vars_);
- } else {
- // If a root node, inherit global symbols. Since every parent
- // chain has a root with no parent, global variables will be
- // present in the case above too. This means that globals can be
- // overridden by locals, as it should be.
- copyProperties(me.vars_, JsEvalContext.globals_);
- }
-
- /**
- * The current context object is assigned to the special variable
- * $this so it is possible to use it in expressions.
- * @type Object
- */
- me.vars_[VAR_this] = opt_data;
-
- /**
- * The entire context structure is exposed as a variable so it can be
- * passed to javascript invocations through jseval.
- */
- me.vars_[VAR_context] = me;
-
- /**
- * 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 even be value,
- * undefined or null. Hence, we have to protect jsexec() from using
- * undefined or null, yet we want $this to reflect the true value of
- * the current context. Thus we assign the original value to $this,
- * above, but for the expression context we replace null and
- * undefined by the empty string.
- *
- * @type {Object|null}
- */
- me.data_ = getDefaultObject(opt_data, STRING_empty);
-
- if (!opt_parent) {
- // If this is a top-level context, create a variable reference to the data
- // to allow for accessing top-level properties of the original context
- // data from child contexts.
- me.vars_[VAR_top] = me.data_;
- }
-};
-
-
-/**
- * A map of globally defined symbols. Every instance of JsExprContext
- * inherits them in its vars_.
- * @type Object
- */
-JsEvalContext.globals_ = {}
-
-
-/**
- * Sets a global symbol. It will be available like a variable in every
- * JsEvalContext instance. This is intended mainly to register
- * immutable global objects, such as functions, at load time, and not
- * to add global data at runtime. I.e. the same objections as to
- * global variables in general apply also here. (Hence the name
- * "global", and not "global var".)
- * @param {string} name
- * @param {Object|null} value
- */
-JsEvalContext.setGlobal = function(name, value) {
- JsEvalContext.globals_[name] = value;
-};
-
-
-/**
- * Set the default value to be returned if context evaluation results in an
- * error. (This can occur if a non-existent value was requested).
- */
-JsEvalContext.setGlobal(GLOB_default, null);
-
-
-/**
- * A cache to reuse JsEvalContext instances. (IE6 perf)
- *
- * @type Array<JsEvalContext>
- */
-JsEvalContext.recycledInstances_ = [];
-
-
-/**
- * A factory to create a JsEvalContext instance, possibly reusing
- * one from recycledInstances_. (IE6 perf)
- *
- * @param {Object} opt_data
- * @param {JsEvalContext} opt_parent
- * @return {JsEvalContext}
- */
-JsEvalContext.create = function(opt_data, opt_parent) {
- if (jsLength(JsEvalContext.recycledInstances_) > 0) {
- var instance = JsEvalContext.recycledInstances_.pop();
- JsEvalContext.call(instance, opt_data, opt_parent);
- return instance;
- } else {
- return new JsEvalContext(opt_data, opt_parent);
- }
-};
-
-
-/**
- * Recycle a used JsEvalContext instance, so we can avoid creating one
- * the next time we need one. (IE6 perf)
- *
- * @param {JsEvalContext} instance
- */
-JsEvalContext.recycle = function(instance) {
- for (var i in instance.vars_) {
- // NOTE(mesch): We avoid object creation here. (IE6 perf)
- delete instance.vars_[i];
- }
- instance.data_ = null;
- JsEvalContext.recycledInstances_.push(instance);
-};
-
-
-/**
- * Executes a function created using jsEvalToFunction() in the context
- * of vars, data, and template.
- *
- * @param {Function} exprFunction A javascript function created from
- * a jstemplate attribute value.
- *
- * @param {Element} template DOM node of the template.
- *
- * @return {Object|null} The value of the expression from which
- * exprFunction was created in the current js expression context and
- * the context of template.
- */
-JsEvalContext.prototype.jsexec = function(exprFunction, template) {
- try {
- return exprFunction.call(template, this.vars_, this.data_);
- } catch (e) {
- log('jsexec EXCEPTION: ' + e + ' at ' + template +
- ' with ' + exprFunction);
- return JsEvalContext.globals_[GLOB_default];
- }
-};
-
-
-/**
- * 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().)
- *
- * @param {number} count The total number of contexts that were multiply
- * instantiated. (See implementation of jstSelect().)
- *
- * @return {JsEvalContext}
- */
-JsEvalContext.prototype.clone = function(data, index, count) {
- var ret = JsEvalContext.create(data, this);
- ret.setVariable(VAR_index, index);
- ret.setVariable(VAR_count, count);
- 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
- */
-JsEvalContext.prototype.setVariable = function(name, value) {
- this.vars_[name] = value;
-};
-
-
-/**
- * Returns the value bound to the local variable of the given name, or
- * undefined if it wasn't set. There is no way to distinguish a
- * variable that wasn't set from a variable that was set to
- * undefined. Used mostly for testing.
- *
- * @param {string} name
- *
- * @return {Object?} value
- */
-JsEvalContext.prototype.getVariable = function(name) {
- return this.vars_[name];
-};
-
-
-/**
- * Evaluates a string expression within the scope of this context
- * and returns the result.
- *
- * @param {string} expr A javascript expression
- * @param {Element} opt_template An optional node to serve as "this"
- *
- * @return {Object?} value
- */
-JsEvalContext.prototype.evalExpression = function(expr, opt_template) {
- var exprFunction = jsEvalToFunction(expr);
- return this.jsexec(exprFunction, opt_template);
-};
-
-
-/**
- * Uninlined string literals for jsEvalToFunction() (IE6 perf).
- */
-var STRING_a = 'a_';
-var STRING_b = 'b_';
-var STRING_with = 'with (a_) with (b_) return ';
-
-
-/**
- * Cache for jsEvalToFunction results.
- * @type Object
- */
-JsEvalContext.evalToFunctionCache_ = {};
-
-
-/**
- * Evaluates the given expression as the body of a function that takes
- * vars and data as arguments. Since the resulting function depends
- * only on expr, we cache the result so we save some Function
- * invocations, and some object creations in IE6.
- *
- * @param {string} expr A javascript expression.
- *
- * @return {Function} A function that returns the value of expr in the
- * context of vars and data.
- */
-function jsEvalToFunction(expr) {
- if (!JsEvalContext.evalToFunctionCache_[expr]) {
- try {
- // NOTE(mesch): The Function constructor is faster than eval().
- JsEvalContext.evalToFunctionCache_[expr] =
- new Function(STRING_a, STRING_b, STRING_with + expr);
- } catch (e) {
- log('jsEvalToFunction (' + expr + ') EXCEPTION ' + e);
- }
- }
- return JsEvalContext.evalToFunctionCache_[expr];
-}
-
-
-/**
- * Evaluates the given expression to itself. This is meant to pass
- * through string attribute values.
- *
- * @param {string} expr
- *
- * @return {string}
- */
-function jsEvalToSelf(expr) {
- return expr;
-}
-
-
-/**
- * Parses the value of the jsvalues attribute in jstemplates: splits
- * it up into a map of labels and expressions, and creates functions
- * from the expressions that are suitable for execution by
- * JsEvalContext.jsexec(). All that is returned as a flattened array
- * of pairs of a String and a Function.
- *
- * @param {string} expr
- *
- * @return {Array}
- */
-function jsEvalToValues(expr) {
- // TODO(mesch): It is insufficient to split the values by simply
- // finding semi-colons, as the semi-colon may be part of a string
- // constant or escaped.
- var ret = [];
- var values = expr.split(REGEXP_semicolon);
- for (var i = 0, I = jsLength(values); i < I; ++i) {
- var colon = values[i].indexOf(CHAR_colon);
- if (colon < 0) {
- continue;
- }
- var label = stringTrim(values[i].substr(0, colon));
- var value = jsEvalToFunction(values[i].substr(colon + 1));
- ret.push(label, value);
- }
- return ret;
-}
-
-
-/**
- * Parses the value of the jseval attribute of jstemplates: splits it
- * up into a list of expressions, and creates functions from the
- * expressions that are suitable for execution by
- * JsEvalContext.jsexec(). All that is returned as an Array of
- * Function.
- *
- * @param {string} expr
- *
- * @return {Array<Function>}
- */
-function jsEvalToExpressions(expr) {
- var ret = [];
- var values = expr.split(REGEXP_semicolon);
- for (var i = 0, I = jsLength(values); i < I; ++i) {
- if (values[i]) {
- var value = jsEvalToFunction(values[i]);
- ret.push(value);
- }
- }
- return ret;
-}
diff --git a/chrome/common/extensions/docs/examples/extensions/irc/servlet/jstemplate/jstemplate.js b/chrome/common/extensions/docs/examples/extensions/irc/servlet/jstemplate/jstemplate.js
deleted file mode 100644
index 4024892..0000000
--- a/chrome/common/extensions/docs/examples/extensions/irc/servlet/jstemplate/jstemplate.js
+++ /dev/null
@@ -1,1017 +0,0 @@
-// Copyright 2006 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-// implied. See the License for the specific language governing
-// permissions and limitations under the License.
-/**
- * Author: Steffen Meschkat <mesch@google.com>
- *
- * @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(mesch): IE DOM doesn't have importNode().
- *
- * NOTE(mesch): 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_vars = 'jsvars';
-var ATT_eval = 'jseval';
-var ATT_transclude = 'transclude';
-var ATT_content = 'jscontent';
-var ATT_skip = 'jsskip';
-
-
-/**
- * Name of the attribute that caches a reference to the parsed
- * template processing attribute values on a template node.
- */
-var ATT_jstcache = 'jstcache';
-
-
-/**
- * Name of the property that caches the parsed template processing
- * attribute values on a template node.
- */
-var PROP_jstcache = '__jstcache';
-
-
-/**
- * ID of the element that contains dynamically loaded jstemplates.
- */
-var STRING_jsts = 'jsts';
-
-
-/**
- * Un-inlined string literals, to avoid object creation in
- * IE6.
- */
-var CHAR_asterisk = '*';
-var CHAR_dollar = '$';
-var CHAR_period = '.';
-var CHAR_ampersand = '&';
-var STRING_div = 'div';
-var STRING_id = 'id';
-var STRING_asteriskzero = '*0';
-var STRING_zero = '0';
-
-
-/**
- * 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 {JsEvalContext} 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.
- *
- * @param {boolean} opt_debugging Optional flag to collect debugging
- * information while processing the template. Only takes effect
- * in MAPS_DEBUG.
- */
-function jstProcess(context, template, opt_debugging) {
- var processor = new JstProcessor;
- if (MAPS_DEBUG && opt_debugging) {
- processor.setDebugging(opt_debugging);
- }
- JstProcessor.prepareTemplate_(template);
-
- /**
- * Caches the document of the template node, so we don't have to
- * access it through ownerDocument.
- * @type Document
- */
- processor.document_ = ownerDocument(template);
-
- processor.run_(bindFully(processor, processor.jstProcessOuter_,
- context, template));
- if (MAPS_DEBUG && opt_debugging) {
- log('jstProcess:' + '\n' + processor.getLogs().join('\n'));
- }
-}
-
-
-/**
- * Internal class used by jstemplates to maintain context. This is
- * necessary to process deep templates in Safari which has a
- * relatively shallow maximum recursion depth of 100.
- * @class
- * @constructor
- */
-function JstProcessor() {
- if (MAPS_DEBUG) {
- /**
- * An array of logging messages. These are collected during processing
- * and dumped to the console at the end.
- * @type Array<string>
- */
- this.logs_ = [];
- }
-}
-
-
-/**
- * Counter to generate node ids. These ids will be stored in
- * ATT_jstcache and be used to lookup the preprocessed js attributes
- * from the jstcache_. The id is stored in an attribute so it
- * suvives cloneNode() and thus cloned template nodes can share the
- * same cache entry.
- * @type number
- */
-JstProcessor.jstid_ = 0;
-
-
-/**
- * Map from jstid to processed js attributes.
- * @type Object
- */
-JstProcessor.jstcache_ = {};
-
-/**
- * The neutral cache entry. Used for all nodes that don't have any
- * jst attributes. We still set the jsid attribute on those nodes so
- * we can avoid to look again for all the other jst attributes that
- * aren't there. Remember: not only the processing of the js
- * attribute values is expensive and we thus want to cache it. The
- * access to the attributes on the Node in the first place is
- * expensive too.
- */
-JstProcessor.jstcache_[0] = {};
-
-
-/**
- * Map from concatenated attribute string to jstid.
- * The key is the concatenation of all jst atributes found on a node
- * formatted as "name1=value1&name2=value2&...", in the order defined by
- * JST_ATTRIBUTES. The value is the id of the jstcache_ entry that can
- * be used for this node. This allows the reuse of cache entries in cases
- * when a cached entry already exists for a given combination of attribute
- * values. (For example when two different nodes in a template share the same
- * JST attributes.)
- * @type Object
- */
-JstProcessor.jstcacheattributes_ = {};
-
-
-/**
- * Map for storing temporary attribute values in prepareNode_() so they don't
- * have to be retrieved twice. (IE6 perf)
- * @type Object
- */
-JstProcessor.attributeValues_ = {};
-
-
-/**
- * A list for storing non-empty attributes found on a node in prepareNode_().
- * The array is global since it can be reused - this way there is no need to
- * construct a new array object for each invocation. (IE6 perf)
- * @type Array
- */
-JstProcessor.attributeList_ = [];
-
-
-/**
- * Prepares the template: preprocesses all jstemplate attributes.
- *
- * @param {Element} template
- */
-JstProcessor.prepareTemplate_ = function(template) {
- if (!template[PROP_jstcache]) {
- domTraverseElements(template, function(node) {
- JstProcessor.prepareNode_(node);
- });
- }
-};
-
-
-/**
- * A list of attributes we use to specify jst processing instructions,
- * and the functions used to parse their values.
- *
- * @type Array<Array>
- */
-var JST_ATTRIBUTES = [
- [ ATT_select, jsEvalToFunction ],
- [ ATT_display, jsEvalToFunction ],
- [ ATT_values, jsEvalToValues ],
- [ ATT_vars, jsEvalToValues ],
- [ ATT_eval, jsEvalToExpressions ],
- [ ATT_transclude, jsEvalToSelf ],
- [ ATT_content, jsEvalToFunction ],
- [ ATT_skip, jsEvalToFunction ]
-];
-
-
-/**
- * Prepares a single node: preprocesses all template attributes of the
- * node, and if there are any, assigns a jsid attribute and stores the
- * preprocessed attributes under the jsid in the jstcache.
- *
- * @param {Element} node
- *
- * @return {Object} The jstcache entry. The processed jst attributes
- * are properties of this object. If the node has no jst attributes,
- * returns an object with no properties (the jscache_[0] entry).
- */
-JstProcessor.prepareNode_ = function(node) {
- // If the node already has a cache property, return it.
- if (node[PROP_jstcache]) {
- return node[PROP_jstcache];
- }
-
- // If it is not found, we always set the PROP_jstcache property on the node.
- // Accessing the property is faster than executing getAttribute(). If we
- // don't find the property on a node that was cloned in jstSelect_(), we
- // will fall back to check for the attribute and set the property
- // from cache.
-
- // If the node has an attribute indexing a cache object, set it as a property
- // and return it.
- var jstid = domGetAttribute(node, ATT_jstcache);
- if (jstid != null) {
- return node[PROP_jstcache] = JstProcessor.jstcache_[jstid];
- }
-
- var attributeValues = JstProcessor.attributeValues_;
- var attributeList = JstProcessor.attributeList_;
- attributeList.length = 0;
-
- // Look for interesting attributes.
- for (var i = 0, I = jsLength(JST_ATTRIBUTES); i < I; ++i) {
- var name = JST_ATTRIBUTES[i][0];
- var value = domGetAttribute(node, name);
- attributeValues[name] = value;
- if (value != null) {
- attributeList.push(name + "=" + value);
- }
- }
-
- // If none found, mark this node to prevent further inspection, and return
- // an empty cache object.
- if (attributeList.length == 0) {
- domSetAttribute(node, ATT_jstcache, STRING_zero);
- return node[PROP_jstcache] = JstProcessor.jstcache_[0];
- }
-
- // If we already have a cache object corresponding to these attributes,
- // annotate the node with it, and return it.
- var attstring = attributeList.join(CHAR_ampersand);
- if (jstid = JstProcessor.jstcacheattributes_[attstring]) {
- domSetAttribute(node, ATT_jstcache, jstid);
- return node[PROP_jstcache] = JstProcessor.jstcache_[jstid];
- }
-
- // Otherwise, build a new cache object.
- var jstcache = {};
- for (var i = 0, I = jsLength(JST_ATTRIBUTES); i < I; ++i) {
- var att = JST_ATTRIBUTES[i];
- var name = att[0];
- var parse = att[1];
- var value = attributeValues[name];
- if (value != null) {
- jstcache[name] = parse(value);
- if (MAPS_DEBUG) {
- jstcache.jstAttributeValues = jstcache.jstAttributeValues || {};
- jstcache.jstAttributeValues[name] = value;
- }
- }
- }
-
- jstid = STRING_empty + ++JstProcessor.jstid_;
- domSetAttribute(node, ATT_jstcache, jstid);
- JstProcessor.jstcache_[jstid] = jstcache;
- JstProcessor.jstcacheattributes_[attstring] = jstid;
-
- return node[PROP_jstcache] = jstcache;
-};
-
-
-/**
- * Runs the given function in our state machine.
- *
- * It's informative to view the set of all function calls as a tree:
- * - nodes are states
- * - edges are state transitions, implemented as calls to the pending
- * functions in the stack.
- * - pre-order function calls are downward edges (recursion into call).
- * - post-order function calls are upward edges (return from call).
- * - leaves are nodes which do not recurse.
- * We represent the call tree as an array of array of calls, indexed as
- * stack[depth][index]. Here [depth] indexes into the call stack, and
- * [index] indexes into the call queue at that depth. We require a call
- * queue so that a node may branch to more than one child
- * (which will be called serially), typically due to a loop structure.
- *
- * @param {Function} f The first function to run.
- */
-JstProcessor.prototype.run_ = function(f) {
- var me = this;
-
- /**
- * A stack of queues of pre-order calls.
- * The inner arrays (constituent queues) are structured as
- * [ arg2, arg1, method, arg2, arg1, method, ...]
- * ie. a flattened array of methods with 2 arguments, in reverse order
- * for efficient push/pop.
- *
- * The outer array is a stack of such queues.
- *
- * @type Array<Array>
- */
- var calls = me.calls_ = [];
-
- /**
- * The index into the queue for each depth. NOTE: Alternative would
- * be to maintain the queues in reverse order (popping off of the
- * end) but the repeated calls to .pop() consumed 90% of this
- * function's execution time.
- * @type Array<number>
- */
- var queueIndices = me.queueIndices_ = [];
-
- /**
- * A pool of empty arrays. Minimizes object allocation for IE6's benefit.
- * @type Array<Array>
- */
- var arrayPool = me.arrayPool_ = [];
-
- f();
- var queue, queueIndex;
- var method, arg1, arg2;
- var temp;
- while (calls.length) {
- queue = calls[calls.length - 1];
- queueIndex = queueIndices[queueIndices.length - 1];
- if (queueIndex >= queue.length) {
- me.recycleArray_(calls.pop());
- queueIndices.pop();
- continue;
- }
-
- // Run the first function in the queue.
- method = queue[queueIndex++];
- arg1 = queue[queueIndex++];
- arg2 = queue[queueIndex++];
- queueIndices[queueIndices.length - 1] = queueIndex;
- method.call(me, arg1, arg2);
- }
-};
-
-
-/**
- * Pushes one or more functions onto the stack. These will be run in sequence,
- * interspersed with any recursive calls that they make.
- *
- * This method takes ownership of the given array!
- *
- * @param {Array} args Array of method calls structured as
- * [ method, arg1, arg2, method, arg1, arg2, ... ]
- */
-JstProcessor.prototype.push_ = function(args) {
- this.calls_.push(args);
- this.queueIndices_.push(0);
-};
-
-
-/**
- * Enable/disable debugging.
- * @param {boolean} debugging New state
- */
-JstProcessor.prototype.setDebugging = function(debugging) {
- if (MAPS_DEBUG) {
- this.debugging_ = debugging;
- }
-};
-
-
-JstProcessor.prototype.createArray_ = function() {
- if (this.arrayPool_.length) {
- return this.arrayPool_.pop();
- } else {
- return [];
- }
-};
-
-
-JstProcessor.prototype.recycleArray_ = function(array) {
- arrayClear(array);
- this.arrayPool_.push(array);
-};
-
-/**
- * Implements internals of jstProcess. This processes the two
- * attributes transclude and jsselect, which replace or multiply
- * elements, hence the name "outer". The remainder of the attributes
- * is processed in jstProcessInner_(), below. That function
- * jsProcessInner_() only processes attributes that affect an existing
- * node, but doesn't create or destroy nodes, hence the name
- * "inner". jstProcessInner_() is called through jstSelect_() if there
- * is a jsselect attribute (possibly for newly created clones of the
- * current template node), or directly from here if there is none.
- *
- * @param {JsEvalContext} context
- *
- * @param {Element} template
- */
-JstProcessor.prototype.jstProcessOuter_ = function(context, template) {
- var me = this;
-
- var jstAttributes = me.jstAttributes_(template);
- if (MAPS_DEBUG && me.debugging_) {
- me.logState_('Outer', template, jstAttributes.jstAttributeValues);
- }
-
- var transclude = jstAttributes[ATT_transclude];
- if (transclude) {
- var tr = jstGetTemplate(transclude);
- if (tr) {
- domReplaceChild(tr, template);
- var call = me.createArray_();
- call.push(me.jstProcessOuter_, context, tr);
- me.push_(call);
- } else {
- domRemoveNode(template);
- }
- return;
- }
-
- var select = jstAttributes[ATT_select];
- if (select) {
- me.jstSelect_(context, template, select);
- } else {
- me.jstProcessInner_(context, template);
- }
-};
-
-
-/**
- * Implements internals of jstProcess. This processes all attributes
- * except transclude and jsselect. It is called either from
- * jstSelect_() for nodes that have a jsselect attribute so that the
- * jsselect attribute will not be processed again, or else directly
- * from jstProcessOuter_(). See the comment on jstProcessOuter_() for
- * an explanation of the name.
- *
- * @param {JsEvalContext} context
- *
- * @param {Element} template
- */
-JstProcessor.prototype.jstProcessInner_ = function(context, template) {
- var me = this;
-
- var jstAttributes = me.jstAttributes_(template);
- if (MAPS_DEBUG && me.debugging_) {
- me.logState_('Inner', template, jstAttributes.jstAttributeValues);
- }
-
- // NOTE(mesch): See NOTE on ATT_content why this is a separate
- // attribute, and not a special value in ATT_values.
- var display = jstAttributes[ATT_display];
- if (display) {
- var shouldDisplay = context.jsexec(display, template);
- if (MAPS_DEBUG && me.debugging_) {
- me.logs_.push(ATT_display + ': ' + shouldDisplay + '<br/>');
- }
- if (!shouldDisplay) {
- displayNone(template);
- return;
- }
- displayDefault(template);
- }
-
- // NOTE(mesch): jsvars is evaluated before jsvalues, because it's
- // more useful to be able to use var values in attribute value
- // expressions than vice versa.
- var values = jstAttributes[ATT_vars];
- if (values) {
- me.jstVars_(context, template, values);
- }
-
- values = jstAttributes[ATT_values];
- if (values) {
- me.jstValues_(context, template, values);
- }
-
- // Evaluate expressions immediately. Useful for hooking callbacks
- // into jstemplates.
- //
- // NOTE(mesch): Evaluation order is sometimes significant, e.g. when
- // the expression evaluated in jseval relies on the values set in
- // jsvalues, so it needs to be evaluated *after*
- // jsvalues. TODO(mesch): This is quite arbitrary, it would be
- // better if this would have more necessity to it.
- var expressions = jstAttributes[ATT_eval];
- if (expressions) {
- for (var i = 0, I = jsLength(expressions); i < I; ++i) {
- context.jsexec(expressions[i], template);
- }
- }
-
- var skip = jstAttributes[ATT_skip];
- if (skip) {
- var shouldSkip = context.jsexec(skip, template);
- if (MAPS_DEBUG && me.debugging_) {
- me.logs_.push(ATT_skip + ': ' + shouldSkip + '<br/>');
- }
- if (shouldSkip) return;
- }
-
- // NOTE(mesch): content is a separate attribute, instead of just a
- // special value mentioned in values, for two reasons: (1) it is
- // fairly common to have only mapped content, and writing
- // content="expr" is shorter than writing values="content:expr", and
- // (2) the presence of content actually terminates traversal, and we
- // need to check for that. Display is a separate attribute for a
- // reason similar to the second, in that its presence *may*
- // terminate traversal.
- var content = jstAttributes[ATT_content];
- if (content) {
- me.jstContent_(context, template, content);
-
- } else {
- // Newly generated children should be ignored, so we explicitly
- // store the children to be processed.
- var queue = me.createArray_();
- for (var c = template.firstChild; c; c = c.nextSibling) {
- if (c.nodeType == DOM_ELEMENT_NODE) {
- queue.push(me.jstProcessOuter_, context, c);
- }
- }
- if (queue.length) me.push_(queue);
- }
-};
-
-
-/**
- * Implements the jsselect attribute: evalutes the value of the
- * jsselect attribute in the current context, with the current
- * variable bindings (see JsEvalContext.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 {JsEvalContext} context The current evaluation context.
- *
- * @param {Element} template The currently processed node of the template.
- *
- * @param {Function} select The javascript expression to evaluate.
- *
- * @notypecheck FIXME(hmitchell): See OCL6434950. instance and value need
- * type checks.
- */
-JstProcessor.prototype.jstSelect_ = function(context, template, select) {
- var me = this;
-
- var value = context.jsexec(select, template);
-
- // Enable reprocessing: if this template is reprocessed, then only
- // fill the section instance here. Otherwise do the cardinal
- // processing of a new template.
- var instance = domGetAttribute(template, ATT_instance);
-
- var instanceLast = false;
- if (instance) {
- if (instance.charAt(0) == CHAR_asterisk) {
- instance = parseInt10(instance.substr(1));
- instanceLast = true;
- } else {
- instance = parseInt10(/** @type string */(instance));
- }
- }
-
- // The expression value instanceof Array is occasionally false for
- // arrays, seen in Firefox. Thus we recognize an array as an object
- // which is not null that has a length property. Notice that this
- // also matches input data with a length property, so this property
- // name should be avoided in input data.
- var multiple = isArray(value);
- var count = multiple ? jsLength(value) : 1;
- var multipleEmpty = (multiple && count == 0);
-
- if (multiple) {
- if (multipleEmpty) {
- // For an empty array, keep the first template instance and mark
- // it last. Remove all other template instances.
- if (!instance) {
- domSetAttribute(template, ATT_instance, STRING_asteriskzero);
- displayNone(template);
- } else {
- domRemoveNode(template);
- }
-
- } else {
- displayDefault(template);
- // For a non empty array, create as many template instances as
- // are needed. If the template is first processed, as many
- // template instances are needed as there are values in the
- // array. If the template is reprocessed, new template instances
- // are only needed if there are more array values than template
- // instances. Those additional instances are created by
- // replicating the last template instance.
- //
- // When the template is first processed, there is no jsinstance
- // attribute. This is indicated by instance === null, except in
- // opera it is instance === "". Notice also that the === is
- // essential, because 0 == "", presumably via type coercion to
- // boolean.
- if (instance === null || instance === STRING_empty ||
- (instanceLast && instance < count - 1)) {
- // A queue of calls to push.
- var queue = me.createArray_();
-
- var instancesStart = instance || 0;
- var i, I, clone;
- for (i = instancesStart, I = count - 1; i < I; ++i) {
- var node = domCloneNode(template);
- domInsertBefore(node, template);
-
- jstSetInstance(/** @type Element */(node), value, i);
- clone = context.clone(value[i], i, count);
-
- queue.push(me.jstProcessInner_, clone, node,
- JsEvalContext.recycle, clone, null);
-
- }
- // Push the originally present template instance last to keep
- // the order aligned with the DOM order, because the newly
- // created template instances are inserted *before* the
- // original instance.
- jstSetInstance(template, value, i);
- clone = context.clone(value[i], i, count);
- queue.push(me.jstProcessInner_, clone, template,
- JsEvalContext.recycle, clone, null);
- me.push_(queue);
- } else if (instance < count) {
- var v = value[instance];
-
- jstSetInstance(template, value, instance);
- var clone = context.clone(v, instance, count);
- var queue = me.createArray_();
- queue.push(me.jstProcessInner_, clone, template,
- JsEvalContext.recycle, clone, null);
- me.push_(queue);
- } else {
- domRemoveNode(template);
- }
- }
- } else {
- if (value == null) {
- displayNone(template);
- } else {
- displayDefault(template);
- var clone = context.clone(value, 0, 1);
- var queue = me.createArray_();
- queue.push(me.jstProcessInner_, clone, template,
- JsEvalContext.recycle, clone, null);
- me.push_(queue);
- }
- }
-};
-
-
-/**
- * Implements the jsvars attribute: evaluates each of the values and
- * assigns them to variables in the current context. Similar to
- * jsvalues, except that all values are treated as vars, independent
- * of their names.
- *
- * @param {JsEvalContext} context Current evaluation context.
- *
- * @param {Element} template Currently processed template node.
- *
- * @param {Array} values Processed value of the jsvalues attribute: a
- * flattened array of pairs. The second element in the pair is a
- * function that can be passed to jsexec() for evaluation in the
- * current jscontext, and the first element is the variable name that
- * the value returned by jsexec is assigned to.
- */
-JstProcessor.prototype.jstVars_ = function(context, template, values) {
- for (var i = 0, I = jsLength(values); i < I; i += 2) {
- var label = values[i];
- var value = context.jsexec(values[i+1], template);
- context.setVariable(label, value);
- }
-};
-
-
-/**
- * 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 {JsEvalContext} context Current evaluation context.
- *
- * @param {Element} template Currently processed template node.
- *
- * @param {Array} values Processed value of the jsvalues attribute: a
- * flattened array of pairs. The second element in the pair is a
- * function that can be passed to jsexec() for evaluation in the
- * current jscontext, and the first element is the label that
- * determines where the value returned by jsexec is assigned to.
- */
-JstProcessor.prototype.jstValues_ = function(context, template, values) {
- for (var i = 0, I = jsLength(values); i < I; i += 2) {
- var label = values[i];
- var value = context.jsexec(values[i+1], template);
-
- if (label.charAt(0) == CHAR_dollar) {
- // A jsvalues entry whose name starts with $ sets a local
- // variable.
- context.setVariable(label, value);
-
- } else if (label.charAt(0) == CHAR_period) {
- // A jsvalues entry whose name starts with . sets a property of
- // the current template node. The name may have further dot
- // separated components, which are translated into namespace
- // objects. This specifically allows to set properties on .style
- // using jsvalues. NOTE(mesch): Setting the style attribute has
- // no effect in IE and hence should not be done anyway.
- var nameSpaceLabel = label.substr(1).split(CHAR_period);
- 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) {
- // Any other jsvalues entry sets an attribute of the current
- // template node.
- if (typeof value == TYPE_boolean) {
- // Handle boolean values that are set as attributes specially,
- // according to the XML/HTML convention.
- if (value) {
- domSetAttribute(template, label, label);
- } else {
- domRemoveAttribute(template, label);
- }
- } else {
- domSetAttribute(template, label, STRING_empty + 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 {JsEvalContext} context Current evaluation context.
- *
- * @param {Element} template Currently processed template node.
- *
- * @param {Function} content Processed value of the jscontent
- * attribute.
- */
-JstProcessor.prototype.jstContent_ = function(context, template, content) {
- // NOTE(mesch): Profiling shows that this method costs significant
- // time. In jstemplate_perf.html, it's about 50%. I tried to replace
- // by HTML escaping and assignment to innerHTML, but that was even
- // slower.
- var value = STRING_empty + context.jsexec(content, template);
- // Prevent flicker when refreshing a template and the value doesn't
- // change.
- if (template.innerHTML == value) {
- return;
- }
- while (template.firstChild) {
- domRemoveNode(template.firstChild);
- }
- var t = domCreateTextNode(this.document_, value);
- domAppendChild(template, t);
-};
-
-
-/**
- * Caches access to and parsing of template processing attributes. If
- * domGetAttribute() is called every time a template attribute value
- * is used, it takes more than 10% of the time.
- *
- * @param {Element} template A DOM element node of the template.
- *
- * @return {Object} A javascript object that has all js template
- * processing attribute values of the node as properties.
- */
-JstProcessor.prototype.jstAttributes_ = function(template) {
- if (template[PROP_jstcache]) {
- return template[PROP_jstcache];
- }
-
- var jstid = domGetAttribute(template, ATT_jstcache);
- if (jstid) {
- return template[PROP_jstcache] = JstProcessor.jstcache_[jstid];
- }
-
- return JstProcessor.prepareNode_(template);
-};
-
-
-/**
- * Helps to implement the transclude attribute, and is the initial
- * call to get hold of a template from its ID.
- *
- * If the ID is not present in the DOM, and opt_loadHtmlFn is specified, this
- * function will call that function and add the result to the DOM, before
- * returning the template.
- *
- * @param {string} name The ID of the HTML element used as template.
- * @param {Function} opt_loadHtmlFn A function which, when called, will return
- * HTML that contains an element whose ID is 'name'.
- *
- * @return {Element|null} The DOM node of the template. (Only element nodes
- * can be found by ID, hence it's a Element.)
- */
-function jstGetTemplate(name, opt_loadHtmlFn) {
- var doc = document;
- var section;
- if (opt_loadHtmlFn) {
- section = jstLoadTemplateIfNotPresent(doc, name, opt_loadHtmlFn);
- } else {
- section = domGetElementById(doc, name);
- }
- if (section) {
- JstProcessor.prepareTemplate_(section);
- var ret = domCloneElement(section);
- domRemoveAttribute(ret, STRING_id);
- return ret;
- } else {
- return null;
- }
-}
-
-/**
- * This function is the same as 'jstGetTemplate' but, if the template
- * does not exist, throw an exception.
- *
- * @param {string} name The ID of the HTML element used as template.
- * @param {Function} opt_loadHtmlFn A function which, when called, will return
- * HTML that contains an element whose ID is 'name'.
- *
- * @return {Element} The DOM node of the template. (Only element nodes
- * can be found by ID, hence it's a Element.)
- */
-function jstGetTemplateOrDie(name, opt_loadHtmlFn) {
- var x = jstGetTemplate(name, opt_loadHtmlFn);
- check(x !== null);
- return /** @type Element */(x);
-}
-
-
-/**
- * If an element with id 'name' is not present in the document, call loadHtmlFn
- * and insert the result into the DOM.
- *
- * @param {Document} doc
- * @param {string} name
- * @param {Function} loadHtmlFn A function that returns HTML to be inserted
- * into the DOM.
- * @param {string} opt_target The id of a DOM object under which to attach the
- * HTML once it's inserted. An object with this id is created if it does not
- * exist.
- * @return {Element} The node whose id is 'name'
- */
-function jstLoadTemplateIfNotPresent(doc, name, loadHtmlFn, opt_target) {
- var section = domGetElementById(doc, name);
- if (section) {
- return section;
- }
- // Load any necessary HTML and try again.
- jstLoadTemplate_(doc, loadHtmlFn(), opt_target || STRING_jsts);
- var section = domGetElementById(doc, name);
- if (!section) {
- log("Error: jstGetTemplate was provided with opt_loadHtmlFn, " +
- "but that function did not provide the id '" + name + "'.");
- }
- return /** @type Element */(section);
-}
-
-
-/**
- * Loads the given HTML text into the given document, so that
- * jstGetTemplate can find it.
- *
- * We append it to the element identified by targetId, which is hidden.
- * If it doesn't exist, it is created.
- *
- * @param {Document} doc The document to create the template in.
- *
- * @param {string} html HTML text to be inserted into the document.
- *
- * @param {string} targetId The id of a DOM object under which to attach the
- * HTML once it's inserted. An object with this id is created if it does not
- * exist.
- */
-function jstLoadTemplate_(doc, html, targetId) {
- var existing_target = domGetElementById(doc, targetId);
- var target;
- if (!existing_target) {
- target = domCreateElement(doc, STRING_div);
- target.id = targetId;
- displayNone(target);
- positionAbsolute(target);
- domAppendChild(doc.body, target);
- } else {
- target = existing_target;
- }
- var div = domCreateElement(doc, STRING_div);
- target.appendChild(div);
- div.innerHTML = html;
-}
-
-
-/**
- * Sets the jsinstance attribute on a node according to its context.
- *
- * @param {Element} template The template DOM node to set the instance
- * attribute on.
- *
- * @param {Array} values The current input context, the array of
- * values of which the template node will render one instance.
- *
- * @param {number} index The index of this template node in values.
- */
-function jstSetInstance(template, values, index) {
- if (index == jsLength(values) - 1) {
- domSetAttribute(template, ATT_instance, CHAR_asterisk + index);
- } else {
- domSetAttribute(template, ATT_instance, STRING_empty + index);
- }
-}
-
-
-/**
- * Log the current state.
- * @param {string} caller An identifier for the caller of .log_.
- * @param {Element} template The template node being processed.
- * @param {Object} jstAttributeValues The jst attributes of the template node.
- */
-JstProcessor.prototype.logState_ = function(
- caller, template, jstAttributeValues) {
- if (MAPS_DEBUG) {
- var msg = '<table>';
- msg += '<caption>' + caller + '</caption>';
- msg += '<tbody>';
- if (template.id) {
- msg += '<tr><td>' + 'id:' + '</td><td>' + template.id + '</td></tr>';
- }
- if (template.name) {
- msg += '<tr><td>' + 'name:' + '</td><td>' + template.name + '</td></tr>';
- }
- if (jstAttributeValues) {
- msg += '<tr><td>' + 'attr:' +
- '</td><td>' + jsToSource(jstAttributeValues) + '</td></tr>';
- }
- msg += '</tbody></table><br/>';
- this.logs_.push(msg);
- }
-};
-
-
-/**
- * Retrieve the processing logs.
- * @return {Array<string>} The processing logs.
- */
-JstProcessor.prototype.getLogs = function() {
- return this.logs_;
-};
diff --git a/chrome/common/extensions/docs/examples/extensions/irc/servlet/jstemplate/util.js b/chrome/common/extensions/docs/examples/extensions/irc/servlet/jstemplate/util.js
deleted file mode 100644
index f6c1f46..0000000
--- a/chrome/common/extensions/docs/examples/extensions/irc/servlet/jstemplate/util.js
+++ /dev/null
@@ -1,470 +0,0 @@
-// Copyright 2006 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-// implied. See the License for the specific language governing
-// permissions and limitations under the License.
-/**
- * @fileoverview Miscellaneous constants and functions referenced in
- * the main source files.
- *
- * @author Steffen Meschkat (mesch@google.com)
- */
-
-var MAPS_DEBUG = false;
-
-function log(msg) {}
-
-// String literals defined globally and not to be inlined. (IE6 perf)
-/** @const */ var STRING_empty = '';
-
-/** @const */ var CSS_display = 'display';
-/** @const */ var CSS_position = 'position';
-
-// Constants for possible values of the typeof operator.
-var TYPE_boolean = 'boolean';
-var TYPE_number = 'number';
-var TYPE_object = 'object';
-var TYPE_string = 'string';
-var TYPE_function = 'function';
-var TYPE_undefined = 'undefined';
-
-
-/**
- * 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 {
- // NOTE(mesch): An alternative idiom would be:
- //
- // eval('(' + expr + ')');
- //
- // Note that using the square brackets as below, "" evals to undefined.
- // The alternative of using parentheses does not work when evaluating
- // function literals in IE.
- // e.g. eval("(function() {})") returns undefined, and not a function
- // object, in IE.
- return eval('[' + expr + '][0]');
- } catch (e) {
- log('EVAL FAILED ' + expr + ': ' + e);
- return null;
- }
-}
-
-function jsLength(obj) {
- return obj.length;
-}
-
-function assert(obj) {}
-
-/**
- * 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) {
- for (var p in from) {
- to[p] = from[p];
- }
-}
-
-
-/**
- * @param {Object|null|undefined} value The possible value to use.
- * @param {Object} defaultValue The default if the value is not set.
- * @return {Object} The value, if it is
- * defined and not null; otherwise the default
- */
-function getDefaultObject(value, defaultValue) {
- if (typeof value != TYPE_undefined && value != null) {
- return /** @type Object */(value);
- } else {
- return defaultValue;
- }
-}
-
-/**
- * Detect if an object looks like an Array.
- * Note that instanceof Array is not robust; for example an Array
- * created in another iframe fails instanceof Array.
- * @param {Object|null} value Object to interrogate
- * @return {boolean} Is the object an array?
- */
-function isArray(value) {
- return value != null &&
- typeof value == TYPE_object &&
- typeof value.length == TYPE_number;
-}
-
-
-/**
- * Finds a slice of an array.
- *
- * @param {Array} array Array to be sliced.
- * @param {number} start The start of the slice.
- * @param {number} opt_end The end of the slice (optional).
- * @return {Array} array The slice of the array from start to end.
- */
-function arraySlice(array, start, opt_end) {
- // Use
- // return Function.prototype.call.apply(Array.prototype.slice, arguments);
- // instead of the simpler
- // return Array.prototype.slice.call(array, start, opt_end);
- // here because of a bug in the FF and IE implementations of
- // Array.prototype.slice which causes this function to return an empty list
- // if opt_end is not provided.
- return Function.prototype.call.apply(Array.prototype.slice, arguments);
-}
-
-
-/**
- * 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);
-}
-
-
-/**
- * Clears the array by setting the length property to 0. This usually
- * works, and if it should turn out not to work everywhere, here would
- * be the place to implement the browser specific workaround.
- *
- * @param {Array} array Array to be cleared.
- */
-function arrayClear(array) {
- array.length = 0;
-}
-
-
-/**
- * Prebinds "this" within the given method to an object, but ignores all
- * arguments passed to the resulting function.
- * I.e. var_args are all the arguments that method is invoked with when
- * invoking the bound function.
- *
- * @param {Object|null} object The object that the method call targets.
- * @param {Function} method The target method.
- * @return {Function} Method with the target object bound to it and curried by
- * the provided arguments.
- */
-function bindFully(object, method, var_args) {
- var args = arraySlice(arguments, 2);
- return function() {
- return method.apply(object, args);
- }
-}
-
-// Based on <http://www.w3.org/TR/2000/ REC-DOM-Level-2-Core-20001113/
-// core.html#ID-1950641247>.
-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;
-
-
-
-function domGetElementById(document, id) {
- return document.getElementById(id);
-}
-
-/**
- * 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);
-}
-
-/**
- * Traverses the element nodes in the DOM section underneath the given
- * node and invokes the given callback as a method on every element
- * node encountered.
- *
- * @param {Element} node Parent element of the subtree to traverse.
- * @param {Function} callback Called on each node in the traversal.
- */
-function domTraverseElements(node, callback) {
- var traverser = new DomTraverser(callback);
- traverser.run(node);
-}
-
-/**
- * A class to hold state for a dom traversal.
- * @param {Function} callback Called on each node in the traversal.
- * @constructor
- * @class
- */
-function DomTraverser(callback) {
- this.callback_ = callback;
-}
-
-/**
- * Processes the dom tree in breadth-first order.
- * @param {Element} root The root node of the traversal.
- */
-DomTraverser.prototype.run = function(root) {
- var me = this;
- me.queue_ = [ root ];
- while (jsLength(me.queue_)) {
- me.process_(me.queue_.shift());
- }
-}
-
-/**
- * Processes a single node.
- * @param {Element} node The current node of the traversal.
- */
-DomTraverser.prototype.process_ = function(node) {
- var me = this;
-
- me.callback_(node);
-
- for (var c = node.firstChild; c; c = c.nextSibling) {
- if (c.nodeType == DOM_ELEMENT_NODE) {
- me.queue_.push(c);
- }
- }
-}
-
-/**
- * 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|null} Resulting attribute.
- */
-function domGetAttribute(node, name) {
- return node.getAttribute(name);
- // NOTE(mesch): Neither in IE nor in Firefox, HTML DOM attributes
- // implement namespaces. All items in the attribute collection have
- // null localName and namespaceURI attribute values. In IE, we even
- // encounter DIV elements that don't implement the method
- // getAttributeNS().
-}
-
-
-/**
- * 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|number} 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);
- // NOTE(mesch): we never so far wanted to use cloneNode(false),
- // hence the default.
-}
-
-/**
- * Clone a element in the DOM.
- *
- * @param {Element} element Element to clone.
- * @return {Element} Cloned element.
- */
-function domCloneElement(element) {
- return /** @type {Element} */(domCloneNode(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. If the node is a document itself, returns
- * itself.
- *
- * @param {Node|null|undefined} node The node whose ownerDocument is required.
- * @returns {Document} The owner document or window.document if unsupported.
- */
-function ownerDocument(node) {
- if (!node) {
- return document;
- } else if (node.nodeType == DOM_DOCUMENT_NODE) {
- return /** @type Document */(node);
- } else {
- return node.ownerDocument || document;
- }
-}
-
-/**
- * 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);
-}
-
-/**
- * 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);
-}
-
-/**
- * Sets display to default.
- *
- * @param {Element} node The dom element to manipulate.
- */
-function displayDefault(node) {
- node.style[CSS_display] = '';
-}
-
-/**
- * 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[CSS_display] = 'none';
-}
-
-
-/**
- * Sets position style attribute to absolute.
- *
- * @param {Element} node The dom element to manipulate.
- */
-function positionAbsolute(node) {
- node.style[CSS_position] = 'absolute';
-}
-
-
-/**
- * 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);
-}
-
-/**
- * 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);
-}
-
-/**
- * Remove a 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);
-}
-
-
-/**
- * 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+$/, "");
-}
\ No newline at end of file
diff --git a/chrome/common/extensions/docs/examples/extensions/irc/servlet/notification.html b/chrome/common/extensions/docs/examples/extensions/irc/servlet/notification.html
deleted file mode 100644
index e068873..0000000
--- a/chrome/common/extensions/docs/examples/extensions/irc/servlet/notification.html
+++ /dev/null
@@ -1,62 +0,0 @@
-<html>
- <head>
- <script src="util.js" type="text/javascript"></script>
- <style>
-body {
- margin: 0px;
- padding: 0px;
- -webkit-user-select: none;
-}
-
-#notification {
- width: 300px;
- height: 50px;
- position: fixed;
- overflow: hidden;
- display: -webkit-box;
- -webkit-box-orient: vertical;
- -webkit-box-align: stretch;
-}
-
-#title {
- display: -webkit-box;
- -webkit-box-flex: 0;
- padding: 2px 4px 2px 4px;
- background-color: #AAAAAA;
- color: white;
- font-family: Verdana, sans-serif;
- font-size: 10px;
-}
-
-#content {
- display: -webkit-box;
- -webkit-box-flex: 1;
- color: #444444;
- font-family: "Lucida Console", Monospace;
- font-size: 12px;
- padding: 4px;
- text-overflow: ellipsis;
-}
- </style>
- <script>
-window.onload = function() {
- var argString = location.search.substring(location.search.indexOf("?") + 1);
- var tokens = argString.split("&");
- var args = {};
- tokens.forEach(function(token) {
- var keyVal = token.split("=");
- args[keyVal[0]] = decodeURIComponent(keyVal[1]);
- });
-
- $('title').innerText = args.title;
- $('content').innerText = args.content;
-}
- </script>
- </head>
- <body onclick="window.close();">
- <div id="notification">
- <div id="title"></div>
- <div id="content"></div>
- </div>
- </body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/extensions/irc/servlet/src/org/chromium/IRCProxyWebSocket.java b/chrome/common/extensions/docs/examples/extensions/irc/servlet/src/org/chromium/IRCProxyWebSocket.java
deleted file mode 100644
index 688e422..0000000
--- a/chrome/common/extensions/docs/examples/extensions/irc/servlet/src/org/chromium/IRCProxyWebSocket.java
+++ /dev/null
@@ -1,116 +0,0 @@
-package org.chromium;
-
-import org.eclipse.jetty.websocket.WebSocket;
-import org.eclipse.jetty.websocket.WebSocketServlet;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.OutputStreamWriter;
-import java.net.Socket;
-import java.net.UnknownHostException;
-import java.util.Set;
-import java.util.concurrent.CopyOnWriteArraySet;
-
-import javax.net.SocketFactory;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-public class IRCProxyWebSocket extends WebSocketServlet {
-
- private static final long serialVersionUID = 1L;
-
- private final Set<ChatWebSocket> members_ =
- new CopyOnWriteArraySet<ChatWebSocket>();
-
- protected void doGet(HttpServletRequest request, HttpServletResponse response)
- throws ServletException ,IOException {
- getServletContext().getNamedDispatcher("default").forward(request,response);
- }
-
- protected WebSocket doWebSocketConnect(HttpServletRequest request,
- String protocol) {
- return new ChatWebSocket();
- }
-
- class ChatWebSocket implements WebSocket, Runnable {
- Outbound outbound_;
- Socket socket_ = null;
- OutputStreamWriter out_;
- BufferedReader in_;
- Thread thread_;
- byte frame_ = 0;
-
- public void onConnect(Outbound outbound) {
- outbound_= outbound;
- }
-
- public void onMessage(byte frame, byte[] data,int offset, int length) {}
-
- public void onMessage(byte frame, String data) {
- try {
- if (socket_ == null) {
- try {
- // We assume the client is going to connect and initiate a
- // connection with the message "server:port".
- String tokens[] = data.split(":");
- socket_ = SocketFactory.getDefault().createSocket(tokens[0],
- Integer.parseInt(tokens[1]));
- out_ = new OutputStreamWriter(socket_.getOutputStream());
- InputStreamReader in = new InputStreamReader(
- socket_.getInputStream());
- in_ = new BufferedReader(in);
-
- members_.add(this);
- thread_ = new Thread(this);
- thread_.start();
-
- } catch (UnknownHostException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- } else {
- System.out.print(">> " + data);
- out_.write(data);
- out_.flush();
- }
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
-
- public void onDisconnect() {
- try {
- socket_.close();
- thread_.stop();
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- members_.remove(this);
- }
-
- @Override
- public void run() {
- while(true) {
- try {
- if (in_.ready()) {
- String line = in_.readLine();
- System.out.println("<< " + line);
- outbound_.sendMessage(frame_, line + "\r\n");
-
- } else {
- Thread.sleep(100);
- }
- } catch (IOException e) {
- } catch (InterruptedException e) {
- }
- }
- }
- }
-}
diff --git a/chrome/common/extensions/docs/examples/extensions/irc/servlet/styles.css b/chrome/common/extensions/docs/examples/extensions/irc/servlet/styles.css
deleted file mode 100644
index fc854c19..0000000
--- a/chrome/common/extensions/docs/examples/extensions/irc/servlet/styles.css
+++ /dev/null
@@ -1,159 +0,0 @@
-body {
- margin: 0;
- padding: 0;
-}
-
-#pageContainer {
- display: -webkit-box;
- position: fixed;
- -webkit-box-orient: vertical;
- -webkit-box-align: stretch;
- height: 100%;
- width: 100%;
- }
-
- #headerContainer {
- display: -webkit-box;
- height: 32px;
- -webkit-box-orient: horizontal;
- -webkit-box-align: stretch;
- }
-
-#pageControls {
- position: absolute;
- right: 0px;
- font-family: Verdana, sans-serif;
- font-size: 16px;
- color: #aaaaaa;
- padding: 8px;
-}
-
-#pageControls *, .removeButton, .channel, .messageLine * {
- display: inline-block;
-}
-
-.addControlLabel {
- margin-left: 20px;
-}
-
-.addButton {
- background-color: #aaaaaa;
- color: white;
-}
-
-#slideContainer {
- display: -webkit-box;
- -webkit-box-flex: 1;
- position: relative;
-}
-
-#channelSlides {
- position: absolute;
- width: 100%;
- height: 100%;
-}
-
-.channelSlide {
- position: absolute;
- width: 80%;
- height: 100%;
- background: -webkit-linear-gradient(#aaa, white);
- transition: margin 0.25s ease-in-out;
-}
-
-.channelSlide.far-left {
- margin-left: -160%;
-}
-
-.channelSlide.left {
- margin-left: -75%;
-}
-
-.channelSlide.center {
- margin-left: 10%;
-}
-
-.channelSlide.right {
- margin-left: 95%;
-}
-
-.channelSlide.far-right {
- margin-left: 180%;
-}
-
-.channelControls {
- position: absolute;
- z-index: 1;
- right: 0px;
- top:0px;
- color: white;
- text-align: right;
- padding: 8px;
- font-family: "Verdana", sans-serif;
- font-size: 20px;
-}
-
-.channelControls .removeButton {
- background-color: white;
- color: #999999;
- padding: 0px 6px 4px 6px;
- height:
-}
-
-.channelSlideContainer {
- position: relative;
- display: -webkit-box;
- -webkit-box-orient: vertical;
- -webkit-box-align: stretch;
- height: 100%;
- width: 100%;
-}
-
-.messageListContainer {
- overflow: hidden;
- position: relative;
- display: -webkit-box;
- -webkit-box-flex: 1;
-}
-
-.messageListSpacer {
- display: -webkit-box;
- -webkit-box-flex: 0;
- height: 40px;
- width: 100%;
-}
-
-.messageLine {
- margin: 6px;
- color: #999999;
- font-family: "Lucida Console", Monospace;
- font-size: 14px;
-}
-
-.messageList {
- position: absolute;
- bottom: 0;
-}
-
-#typingDiv {
- position: fixed;
- z-index: 4;
- width: 80%;
- height: 30px;
- margin: 10px;
- margin-left: 10%;
- bottom: 0px;
- -webkit-box-shadow: 3px 3px 5px #888;
-}
-
-#entryText {
- width: 100%;
- border: 0px;
- height: 100%;
- padding-left: 8px;
- padding-right: 8px;
- font-family: "Lucida Console", Monospace;
- color: white;
- border: 0px;
- background: #777777;
-}
diff --git a/chrome/common/extensions/docs/examples/extensions/irc/servlet/util.js b/chrome/common/extensions/docs/examples/extensions/irc/servlet/util.js
deleted file mode 100644
index f654d2c1..0000000
--- a/chrome/common/extensions/docs/examples/extensions/irc/servlet/util.js
+++ /dev/null
@@ -1,19 +0,0 @@
-function $(el) {
- return document.getElementById(el);
-}
-
-function $F(el) {
- return $(el).value;
-}
-
-function bind(obj, func) {
- return function() {
- return func.apply(obj, arguments);
- };
-}
-
-function childNodeWithClass(node, className) {
- var expression = ".//*[@class='" + className + "']";
- return document.evaluate(expression, node,
- null, XPathResult.ANY_TYPE, null).iterateNext();
-}
\ No newline at end of file
diff --git a/chrome/common/extensions/docs/examples/extensions/managed_bookmarks/_locales/en/messages.json b/chrome/common/extensions/docs/examples/extensions/managed_bookmarks/_locales/en/messages.json
deleted file mode 100644
index 958f786..0000000
--- a/chrome/common/extensions/docs/examples/extensions/managed_bookmarks/_locales/en/messages.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "extName": {
- "message": "Managed Bookmarks",
- "description": "The extension name."
- },
- "extDescription": {
- "message": "Adds bookmarks configured by your system administrator to Chrome.",
- "description": "The extension description."
- }
-}
diff --git a/chrome/common/extensions/docs/examples/extensions/managed_bookmarks/background.js b/chrome/common/extensions/docs/examples/extensions/managed_bookmarks/background.js
deleted file mode 100644
index 0778b7f..0000000
--- a/chrome/common/extensions/docs/examples/extensions/managed_bookmarks/background.js
+++ /dev/null
@@ -1,365 +0,0 @@
-// Copyright 2013 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.
-
-/**
- * Maps policy names to the root node that they affect.
- */
-var policyToNodeId = {
- 'Bookmarks Bar': '1',
- 'Other Bookmarks': '2'
-};
-
-/**
- * A function that fixes a URL. Turns e.g. "google.com" into
- * "http://google.com/". This is used to correctly match against the
- * canonicalized URLs stored in bookmarks created with the bookmarks API.
- */
-var fixURL = (function() {
- // An "a" element is used to parse the given URL and build the fixed version.
- var a = document.createElement('a');
- return function(url) {
- // Preserve null, undefined, etc.
- if (!url)
- return url;
- a.href = url;
- // Handle cases like "google.com", which will be relative to the extension.
- if (a.protocol === 'chrome-extension:' &&
- url.substr(0, 17) !== 'chrome-extension:') {
- a.href = 'http://' + url;
- }
- return a.href;
- }
-})();
-
-/**
- * A CallbackChain can be used to wrap other callbacks and perform a list of
- * actions at the end, once all the wrapped callbacks have been invoked.
- */
-var CallbackChain = function() {
- this._count = 0;
- this._callbacks = [];
-}
-
-CallbackChain.prototype.push = function(callback) {
- this._callbacks.push(callback);
-}
-
-CallbackChain.prototype.wrap = function(callback) {
- var self = this;
- self._count++;
- return function() {
- if (callback)
- callback.apply(null, arguments);
- self._count--;
- if (self._count == 0) {
- for (var i = 0; i < self._callbacks.length; ++i)
- self._callbacks[i]();
- }
- }
-}
-
-/**
- * Represents a managed bookmark.
- */
-var Node = function(nodesMap, id, title, url) {
- this._nodesMap = nodesMap;
- this._id = id;
- this._title = title;
- if (url !== undefined)
- this._url = url;
- else
- this._children = [];
- if (id)
- this._nodesMap[id] = this;
-}
-
-Node.prototype.isRoot = function() {
- return this._id in [ '0', '1', '2' ];
-}
-
-Node.prototype.getIndex = function() {
- return this._nodesMap[this._parentId]._children.indexOf(this);
-}
-
-Node.prototype.appendChild = function(node) {
- node._parentId = this._id;
- this._children.push(node);
-}
-
-Node.prototype.droppedFromParent = function() {
- // Remove |this| and its children from the |nodesMap|.
- var nodesMap = this._nodesMap;
- var removeFromNodesMap = function(node) {
- delete nodesMap[node._id];
- (node._children || []).forEach(removeFromNodesMap);
- }
- removeFromNodesMap(this);
-
- if (this._children)
- chrome.bookmarks.removeTree(this._id);
- else
- chrome.bookmarks.remove(this._id);
-}
-
-Node.prototype.matches = function(bookmark) {
- return this._title === bookmark.title &&
- this._url === bookmark.url &&
- typeof this._children === typeof bookmark.children;
-}
-
-/**
- * Makes this node's children match |wantedChildren|.
- */
-Node.prototype.updateChildren = function(wantedChildren, callbackChain) {
- // Rebuild the list of children to match |wantedChildren|.
- var currentChildren = this._children;
- this._children = [];
- for (var i = 0; i < wantedChildren.length; ++i) {
- var currentChild = currentChildren[i];
- var wantedChild = wantedChildren[i];
- wantedChild.url = fixURL(wantedChild.url);
-
- if (currentChild && currentChild.matches(wantedChild)) {
- this.appendChild(currentChild);
- if (wantedChild.children)
- currentChild.updateChildren(wantedChild.children, callbackChain);
- } else {
- // This child is either missing, invalid or misplaced; drop it and
- // generate it again. Note that the actual dropping is delayed so that
- // bookmarks.onRemoved is triggered after the changes have been persisted.
- if (currentChild)
- callbackChain.push(currentChild.droppedFromParent.bind(currentChild));
- // The "id" comes with the callback from bookmarks.create() but the Node
- // is created now so that the child is placed at the right position.
- var newChild = new Node(
- this._nodesMap, undefined, wantedChild.title, wantedChild.url);
- this.appendChild(newChild);
- chrome.bookmarks.create({
- 'parentId': this._id,
- 'title': newChild._title,
- 'url': newChild._url,
- 'index': i
- }, callbackChain.wrap((function(wantedChild, newChild, createdNode) {
- newChild._id = createdNode.id;
- newChild._nodesMap[newChild._id] = newChild;
- if (wantedChild.children)
- newChild.updateChildren(wantedChild.children, callbackChain);
- }).bind(null, wantedChild, newChild)));
- }
- }
-
- // Drop all additional bookmarks past the end that are not wanted anymore.
- if (currentChildren.length > wantedChildren.length) {
- var chainCounter = callbackChain.wrap();
- currentChildren.slice(wantedChildren.length).forEach(function(child) {
- callbackChain.push(child.droppedFromParent.bind(child));
- });
- // This wrapped nop makes sure that the callbacks appended to the chain
- // execute if nothing else was wrapped.
- chainCounter();
- }
-}
-
-/**
- * Creates new nodes in the bookmark model to represent this Node and its
- * children.
- */
-Node.prototype.regenerate = function(parentId, index, callbackChain) {
- var self = this;
- chrome.bookmarks.create({
- 'parentId': parentId,
- 'title': self._title,
- 'url': self._url,
- 'index': index
- }, callbackChain.wrap(function(newNode) {
- delete self._nodesMap[self._id];
- self._id = newNode.id;
- self._parentId = newNode.parentId;
- self._nodesMap[self._id] = self;
- (self._children || []).forEach(function(child, i) {
- child.regenerate(self._id, i, callbackChain);
- });
- }));
-}
-
-/**
- * Moves this node to the correct position in the model.
- * |currentParentId| and |currentIndex| indicate the current position in
- * the model, which may not match the expected position.
- */
-Node.prototype.moveInModel = function(currentParentId, currentIndex, callback) {
- var index = this.getIndex();
- if (currentParentId == this._parentId) {
- if (index == currentIndex) {
- // Nothing to do.
- callback();
- return;
- } else if (index > currentIndex) {
- // A bookmark moved is inserted at the new position before it is removed
- // from the previous position. So when moving forward in the same parent,
- // the index must be adjusted by one from the desired index.
- ++index;
- }
- }
- chrome.bookmarks.move(this._id, {
- 'parentId': this._parentId,
- 'index': index
- }, callback);
-}
-
-/**
- * Moves any misplaced child nodes into their expected positions.
- */
-Node.prototype.reorderChildren = function() {
- var self = this;
- chrome.bookmarks.getChildren(self._id, function(currentOrder) {
- for (var i = 0; i < currentOrder.length; ++i) {
- var node = currentOrder[i];
- var child = self._nodesMap[node.id];
- if (child && child.getIndex() != i) {
- // Check again after moving this child.
- child.moveInModel(
- node.parentId, node.index, self.reorderChildren.bind(self));
- return;
- }
- }
- });
-}
-
-var serializeNode = function(node) {
- var result = {
- 'id': node._id,
- 'title': node._title
- }
- if (node._url)
- result['url'] = node._url;
- else
- result['children'] = node._children.map(serializeNode);
- return result;
-}
-
-var unserializeNode = function(nodesMap, node) {
- var result = new Node(nodesMap, node['id'], node['title'], node['url']);
- if (node.children) {
- node.children.forEach(function(child) {
- result.appendChild(unserializeNode(nodesMap, child));
- });
- }
- return result;
-}
-
-/**
- * Tracks all the managed bookmarks, and persists the known state so that
- * managed bookmarks can be updated after restarts.
- */
-var ManagedBookmarkTree = function() {
- // Maps a string id to its Node. Used to lookup an entry by ID.
- this._nodesMap = {};
- this._root = new Node(this._nodesMap, '0', '');
- this._root.appendChild(new Node(this._nodesMap, '1', 'Bookmarks Bar'));
- this._root.appendChild(new Node(this._nodesMap, '2', 'Other Bookmarks'));
-}
-
-ManagedBookmarkTree.prototype.store = function() {
- chrome.storage.local.set({
- 'ManagedBookmarkTree': serializeNode(this._root)
- });
-}
-
-ManagedBookmarkTree.prototype.load = function(callback) {
- var self = this;
- chrome.storage.local.get('ManagedBookmarkTree', function(result) {
- if (result.hasOwnProperty('ManagedBookmarkTree')) {
- self._nodesMap = {};
- self._root = unserializeNode(self._nodesMap,
- result['ManagedBookmarkTree']);
- }
- callback();
- });
-}
-
-ManagedBookmarkTree.prototype.getById = function(id) {
- return this._nodesMap[id];
-}
-
-ManagedBookmarkTree.prototype.update = function(rootNodeId, currentPolicy) {
- // Note that the |callbackChain| is only invoked if a callback is wrapped,
- // otherwise its callbacks are never invoked. So store() is called only if
- // bookmarks.create() is actually used.
- var callbackChain = new CallbackChain();
- callbackChain.push(this.store.bind(this));
- this._nodesMap[rootNodeId].updateChildren(currentPolicy || [], callbackChain);
-}
-
-var tree = new ManagedBookmarkTree();
-
-chrome.runtime.onInstalled.addListener(function() {
- // Enforce the initial policy.
- // This load() should be empty on the first install, but is useful during
- // development to handle reloads.
- tree.load(function() {
- chrome.storage.managed.get(function(policy) {
- Object.keys(policyToNodeId).forEach(function(policyName) {
- tree.update(policyToNodeId[policyName], policy[policyName]);
- });
- });
- });
-});
-
-// Start observing policy changes. The tree is reloaded since this may be
-// called back while the page was inactive.
-chrome.storage.onChanged.addListener(function(changes, namespace) {
- if (namespace !== 'managed')
- return;
- tree.load(function() {
- Object.keys(changes).forEach(function(policyName) {
- tree.update(policyToNodeId[policyName], changes[policyName].newValue);
- });
- });
-});
-
-// Observe bookmark modifications and revert any modifications made to managed
-// bookmarks. The tree is always reloaded in case the events happened while the
-// page was inactive.
-
-chrome.bookmarks.onMoved.addListener(function(id, info) {
- tree.load(function() {
- var managedNode = tree.getById(id);
- if (managedNode && !managedNode.isRoot()) {
- managedNode.moveInModel(info.parentId, info.index, function(){});
- } else {
- // Check if the parent node has managed children that need to move.
- // Example: moving a non-managed bookmark in front of the managed
- // bookmarks.
- var parentNode = tree.getById(info.parentId);
- if (parentNode)
- parentNode.reorderChildren();
- }
- });
-});
-
-chrome.bookmarks.onChanged.addListener(function(id, info) {
- tree.load(function() {
- var managedNode = tree.getById(id);
- if (!managedNode || managedNode.isRoot())
- return;
- chrome.bookmarks.update(id, {
- 'title': managedNode._title,
- 'url': managedNode._url
- });
- });
-});
-
-chrome.bookmarks.onRemoved.addListener(function(id, info) {
- tree.load(function() {
- var managedNode = tree.getById(id);
- if (!managedNode || managedNode.isRoot())
- return;
- // A new tree.store() is needed at the end because the regenerated nodes
- // will have new IDs.
- var callbackChain = new CallbackChain();
- callbackChain.push(tree.store.bind(tree));
- managedNode.regenerate(info.parentId, info.index, callbackChain);
- });
-});
diff --git a/chrome/common/extensions/docs/examples/extensions/managed_bookmarks/manifest.json b/chrome/common/extensions/docs/examples/extensions/managed_bookmarks/manifest.json
deleted file mode 100644
index 6ee3f29b..0000000
--- a/chrome/common/extensions/docs/examples/extensions/managed_bookmarks/manifest.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
- "name": "__MSG_extName__",
- "description": "__MSG_extDescription__",
- "default_locale": "en",
- "version": "1.0",
- "manifest_version": 2,
- "minimum_chrome_version": "33",
- "background": {
- "scripts": ["background.js"],
- "persistent": false
- },
- "permissions": [
- "bookmarks"
- ],
- "storage": {
- "managed_schema": "schema.json"
- }
-}
diff --git a/chrome/common/extensions/docs/examples/extensions/managed_bookmarks/schema.json b/chrome/common/extensions/docs/examples/extensions/managed_bookmarks/schema.json
deleted file mode 100644
index 11e7aeb5..0000000
--- a/chrome/common/extensions/docs/examples/extensions/managed_bookmarks/schema.json
+++ /dev/null
@@ -1,36 +0,0 @@
-{
- "type": "object",
- "properties": {
- "Bookmarks Bar": {
- "title": "Bookmarks in the Bookmarks Bar",
- "description": "Configures bookmarks that will appear in the Bookmarks Bar and can't be removed by the user.",
- "type": "array",
- "id": "ListOfBookmarks",
- "items": {
- "type": "object",
- "properties": {
- "title": {
- "title": "Bookmark name",
- "description": "The name that appears on the bookmark.",
- "type": "string"
- },
- "url": {
- "title": "Bookmark URL",
- "description": "The URL for the bookmark. If a URL is not set then this bookmark will be a folder.",
- "type": "string"
- },
- "children": {
- "title": "Contents of this bookmark folder",
- "description": "A list of bookmarks that will be inside this bookmark folder. If this is set then the URL for this bookmark will be ignored.",
- "$ref": "ListOfBookmarks"
- }
- }
- }
- },
- "Other Bookmarks": {
- "title": "Bookmarks in the Other Bookmarks folder",
- "description": "Configures bookmarks that will appear in the Other Bookmarks folder and can't be removed by the user.",
- "$ref": "ListOfBookmarks"
- }
- }
-}
diff --git a/chrome/common/extensions/docs/examples/extensions/mappy/background.js b/chrome/common/extensions/docs/examples/extensions/mappy/background.js
deleted file mode 100644
index 959e7bd..0000000
--- a/chrome/common/extensions/docs/examples/extensions/mappy/background.js
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright (c) 2011 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.
-
-'use strict'
-
-chrome.runtime.onMessage.addListener(function(req, sender) {
- chrome.storage.local.set({address: req.address})
- chrome.pageAction.show(sender.tab.id);
- chrome.pageAction.setTitle({tabId: sender.tab.id, title: req.address});
-});
diff --git a/chrome/common/extensions/docs/examples/extensions/mappy/icon.png b/chrome/common/extensions/docs/examples/extensions/mappy/icon.png
deleted file mode 100644
index 7086d919c..0000000
--- a/chrome/common/extensions/docs/examples/extensions/mappy/icon.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/mappy/manifest.json b/chrome/common/extensions/docs/examples/extensions/mappy/manifest.json
deleted file mode 100644
index 2cacda9..0000000
--- a/chrome/common/extensions/docs/examples/extensions/mappy/manifest.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
- "name": "Mappy",
- "version": "1.0",
- "description": "Finds addresses in the web page you're on and pops up a map window.",
- "icons": { "128": "icon.png" },
- "background": {
- "scripts": ["background.js"],
- "persistent": false
- },
- "content_scripts": [
- {
- "matches": ["http://*/*"],
- "js": ["mappy_content_script.js"]
- }
- ],
- "permissions": [
- "storage",
- "https://maps.google.com/*",
- "https://maps.googleapis.com/*"
- ],
- "page_action": {
- "default_name": "Display Map",
- "default_icon": "marker.png",
- "default_popup": "popup.html"
- },
- "manifest_version": 2,
- "content_security_policy": "default-src 'none'; style-src 'self'; script-src 'self'; connect-src https://maps.googleapis.com; img-src https://maps.googleapis.com"
-}
diff --git a/chrome/common/extensions/docs/examples/extensions/mappy/mappy_content_script.js b/chrome/common/extensions/docs/examples/extensions/mappy/mappy_content_script.js
deleted file mode 100644
index 8bdf56e..0000000
--- a/chrome/common/extensions/docs/examples/extensions/mappy/mappy_content_script.js
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright (c) 2011 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.
-
-// Search the text nodes for a US-style mailing address.
-
-let findAddress = function() {
- let found;
- let re = /(\d+\s+[':.,\s\w]*,\s*[A-Za-z]+\s*\d{5}(-\d{4})?)/m;
- let node = document.body.textContent.match(re);
- if (document.body.textContent.match(re)) {
- found = node;
- }
- if (found) {
- let text = node;
- let match = re.exec(text);
- if (match && match.length) {
- console.log('found: ' + match[0]);
- let trim = /\s{2,}/g;
- let address = match[0].replace(trim, ' ')
- chrome.runtime.sendMessage({'address': address})
- } else {
- console.log('bad initial match: ' + found.textContent);
- console.log('no match in: ' + text);
- }
- }
-}
-
-findAddress();
diff --git a/chrome/common/extensions/docs/examples/extensions/mappy/marker.png b/chrome/common/extensions/docs/examples/extensions/mappy/marker.png
deleted file mode 100644
index 2bb34a18..0000000
--- a/chrome/common/extensions/docs/examples/extensions/mappy/marker.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/mappy/popup.css b/chrome/common/extensions/docs/examples/extensions/mappy/popup.css
deleted file mode 100644
index 8091788..0000000
--- a/chrome/common/extensions/docs/examples/extensions/mappy/popup.css
+++ /dev/null
@@ -1,15 +0,0 @@
-/**
- * Copyright (c) 2011 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.
- */
-
-body {
- margin: 0px;
- padding: 0px;
-}
-
-#map {
- width: 512px;
- height: 512px;
-}
diff --git a/chrome/common/extensions/docs/examples/extensions/mappy/popup.html b/chrome/common/extensions/docs/examples/extensions/mappy/popup.html
deleted file mode 100644
index c5d27fb0..0000000
--- a/chrome/common/extensions/docs/examples/extensions/mappy/popup.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<!doctype html>
-<html>
- <head>
- <title>Popup</title>
- <link href="popup.css" rel="stylesheet" type="text/css">
- </head>
- <body>
- <img id="map">
- <script src="popup.js"></script>
- </body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/extensions/mappy/popup.js b/chrome/common/extensions/docs/examples/extensions/mappy/popup.js
deleted file mode 100644
index 20486956..0000000
--- a/chrome/common/extensions/docs/examples/extensions/mappy/popup.js
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright (c) 2011 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.
-
-'use strict'
-
-const kMaps_key = 'AIzaSyBa5aieunaIp3Obco-dNVYMdbnTZGAVkKQ';
-
-function gclient_geocode(address) {
- let url = 'https://maps.googleapis.com/maps/api/geocode/json?address=' +
- encodeURIComponent(address) + '&sensor=false';
- let request = new XMLHttpRequest();
-
- request.open('GET', url, true);
- console.log(url);
- request.onreadystatechange = function (e) {
- console.log(request, e);
- if (request.readyState == 4) {
- if (request.status == 200) {
- let json = JSON.parse(request.responseText);
- let latlng = json.results[0].geometry.location;
- latlng = latlng.lat + ',' + latlng.lng;
- let src = 'https://maps.googleapis.com/maps/api/staticmap?center=' +
- latlng + '&markers=' + latlng + '&zoom=14' +
- '&size=512x512&sensor=false&key=' + kMaps_key;
- let map = document.getElementById('map');
- map.src = src;
- map.addEventListener('click', function () {
- window.close();
- });
- } else {
- console.log('Unable to resolve address into lat/lng');
- }
- }
- };
- request.send(null);
-}
-
-function map() {
- chrome.storage.local.get(['address'], function(value){
- gclient_geocode(value.address);
- })
-}
-
-window.onload = map;
diff --git a/chrome/common/extensions/docs/examples/extensions/maps_app/128.png b/chrome/common/extensions/docs/examples/extensions/maps_app/128.png
deleted file mode 100644
index a89b5c39..0000000
--- a/chrome/common/extensions/docs/examples/extensions/maps_app/128.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/maps_app/24.png b/chrome/common/extensions/docs/examples/extensions/maps_app/24.png
deleted file mode 100644
index 2fdbf44..0000000
--- a/chrome/common/extensions/docs/examples/extensions/maps_app/24.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/maps_app/manifest.json b/chrome/common/extensions/docs/examples/extensions/maps_app/manifest.json
deleted file mode 100644
index bb1f2e8..0000000
--- a/chrome/common/extensions/docs/examples/extensions/maps_app/manifest.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "name": "Google Maps",
- "version": "3",
- "icons": { "24": "24.png", "128": "128.png" },
- "app": {
- "urls": [
- "http://maps.google.com/"
- ],
- "launch": {
- "web_url": "http://maps.google.com/"
- }
- },
- "permissions": ["geolocation"],
- "manifest_version": 2
-}
diff --git a/chrome/common/extensions/docs/examples/extensions/news/_locales/en/messages.json b/chrome/common/extensions/docs/examples/extensions/news/_locales/en/messages.json
deleted file mode 100644
index 97e07c1..0000000
--- a/chrome/common/extensions/docs/examples/extensions/news/_locales/en/messages.json
+++ /dev/null
@@ -1,102 +0,0 @@
-{
- "extName": {
- "message": "News Reader (by Google)"
- },
- "extDesc": {
- "message": "Displays the latest stories from Google News in a popup."
- },
- "ext_default_title": {
- "message": "Google News"
- },
-
- "1": {
- "message": "Top Stories"
- },
- "n": {
- "message": "Nation"
- },
- "w": {
- "message": "World"
- },
- "b": {
- "message": "Business"
- },
- "t": {
- "message": "Science/Technology"
- },
- "e": {
- "message": "Entertainment"
- },
- "s": {
- "message": "Sports"
- },
- "m": {
- "message": "Health"
- },
- "po": {
- "message": "Most Popular"
- },
-
- "options": {
- "message": "Options"
- },
- "more_stories": {
- "message": "More stories"
- },
-
- "direction": {
- "message": "ltr"
- },
-
- "country": {
- "message": "Country:"
- },
- "topic": {
- "message": "Topics:"
- },
- "save": {
- "message": "Save"
- },
- "saveStatus": {
- "message": "Options saved"
- },
- "storyCount": {
- "message": "Number of stories:"
- },
- "newsOption": {
- "message": "Google News Options"
- },
- "customText": {
- "message": "Custom Topics:"
- },
- "maximumTopics": {
- "message": "(Maximum $count$)",
- "placeholders": {
- "count": {
- "content": "$1"
- }
- }
- },
- "submitButton": {
- "message": "Add"
- },
- "deleteTitle": {
- "message": "Delete"
- },
- "invalidChars": {
- "message": "Invalid character(s)"
- },
- "noTopic": {
- "message": "At least one Topic must be selected"
- },
-
- "fetchError": {
- "message": "Error: Failed to fetch news stories."
- },
- "wrongTopic": {
- "message": "Error: Not a valid feed."
- },
- "noStory": {
- "message": "No story right now"
- }
-}
diff --git a/chrome/common/extensions/docs/examples/extensions/news/css/feed.css b/chrome/common/extensions/docs/examples/extensions/news/css/feed.css
deleted file mode 100644
index 8206fb2..0000000
--- a/chrome/common/extensions/docs/examples/extensions/news/css/feed.css
+++ /dev/null
@@ -1,101 +0,0 @@
-/**
- * Copyright (c) 2010 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.
- *
- * Sets style of different elements in pop-up page.
- *
- * Author: navneetg@google.com (Navneet Goel).
- */
-
-body {
- font-family: arial, sans-serif;
- font-size: 12px;
- min-width: 500px;
- overflow: visible;
-}
-a {
- color: #0000CC;
- cursor: pointer;
- text-decoration: underline;
-}
-#noStories {
- background-color: rgb(255, 238, 136);
- font-size: 13px;
- font-weight: bold;
- margin-left: 140px;
- margin-right: 140px;
- text-align: center;
-}
-.open_box {
- background-image: url(/images/sprite_arrows.gif);
- background-position: 0px -24px;
- clear: left;
- cursor: pointer;
- display: block;
- height: 12px;
- margin-top: 2px;
- overflow: hidden;
- width: 12px;
- float: left;
-}
-.opened .open_box {
- background-position: -12px -24px;
-}
-.item {
- padding: 2px 0;
-}
-.item_title {
- cursor: pointer;
- display: block;
- min-width: 300px;
- padding: 0 0 0 17px;
-}
-.item_desc {
- border: none;
- display: block;
- height: 0;
- margin: 0;
- min-width: 500px;
- padding: 0;
- transition: height 0.2s ease-out;
-}
-#title {
- display: block;
-}
-.error {
- background-color: rgb(255, 238, 136);
- font-size: 13px;
- font-weight: bold;
- margin-left: 125px;
- margin-right: 125px;
- text-align: center;
- white-space: nowrap;
-}
-.more {
- color: #88C;
- display: block;
- margin-left: 385px;
- padding-right: 10px;
- padding-top: 5px;
- text-align: right;
-}
-.topicsLTR {
- direction: ltr;
- font-size: 13px;
- padding-left: 5px;
-}
-.topicsRTL {
- direction: rtl;
- font-size: 13px;
- padding-right: 5px;
-}
-body.rtl #feed {
- direction: rtl;
-}
-body.rtl .open_box {
- float: right;
-}
-body.rtl .item_title {
- padding: 0 17px 0 0;
-}
diff --git a/chrome/common/extensions/docs/examples/extensions/news/css/options.css b/chrome/common/extensions/docs/examples/extensions/news/css/options.css
deleted file mode 100644
index 91aff7ed..0000000
--- a/chrome/common/extensions/docs/examples/extensions/news/css/options.css
+++ /dev/null
@@ -1,121 +0,0 @@
-/**
- * Copyright (c) 2010 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.
- *
- * Sets style of different elements in options page.
- *
- * Author: navneetg@google.com (Navneet Goel).
- */
-
-@CHARSET "UTF-8";
-body {
- background-color: rgb(235, 239, 249);
- font-family: arial , sans-serif;
- font-size: 13px;
-}
-.suppr {
- background-image: url(/images/delete-icon.png);
- background-repeat: no-repeat;
- cursor: pointer;
- display: inline;
- float: left;
- height: 17px;
- margin-top: 3px;
- overflow: hidden;
- width: 14px;
-}
-.checkBoxTopic {
- float: left;
- padding-left: 2px;
- padding-top: 1px;
-}
-.checkBox {
- float: left;
-}
-.boxAndTopic {
- overflow: auto;
- padding-bottom: 5px;
-}
-#invalid_status, #save_status {
- background-color: rgb(255, 241, 168);
- font-weight: bold;
- margin-left: 10px;
- opacity: 0;
- padding-bottom: 3px;
- padding-left: 7px;
- padding-right: 7px;
- padding-top: 3px;
-}
-#all_content {
- background-color: white;
- border-bottom-left-radius: 12px 12px;
- border-bottom-right-radius: 12px 12px;
- border-color: #B5C7DE;
- border-style: solid;
- border-top-left-radius: 12px 12px;
- border-top-right-radius: 12px 12px;
- border-width: 4px;
- margin: 40px auto 20px;
- padding: 12px;
- width: 600px;
-}
-.col2 {
- padding-left: 20px;
-}
-body.rtl .col1, body.rtl .col2 {
- text-align: right;
-}
-body.rtl {
- direction: rtl;
-}
-body.rtl .col2 {
- padding-right: 20px;
-}
-body.rtl .checkBox, body.rtl .checkBoxTopic {
- float: right;
-}
-body.rtl table.contentTable {
- margin:0 55px 0 0;
-}
-body.rtl #save_div{
- margin: 0 220px 0 0;
-}
-body.rtl #countryList{
- margin:0 5px 0 0;
-}
-.col1 {
- padding-top: 3px;
- width: 115px;
-}
-.all_rows {
- height: 35px;
- vertical-align: top;
-}
-body.rtl .cusTopicsClass {
- float: right;
-}
-.cusTopicsClass {
- float: left;
- width: 225px;
-}
-#save_div {
- margin-left: 220px;
-}
-#countryList {
- padding-left: 5px;
-}
-#logo {
- font-size: 15px;
- font-weight: bold;
- text-align: center;
-}
-.noborder {
- border: 0;
- font-family: arial, sans-serif;
- height: 15px;
- outline: none;
- overflow: hidden;
- resize: none;
- width:205px;
-}
diff --git a/chrome/common/extensions/docs/examples/extensions/news/images/buzz.png b/chrome/common/extensions/docs/examples/extensions/news/images/buzz.png
deleted file mode 100644
index 09b446e9..0000000
--- a/chrome/common/extensions/docs/examples/extensions/news/images/buzz.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/news/images/delete-icon.png b/chrome/common/extensions/docs/examples/extensions/news/images/delete-icon.png
deleted file mode 100644
index 36a86fd..0000000
--- a/chrome/common/extensions/docs/examples/extensions/news/images/delete-icon.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/news/images/fb.png b/chrome/common/extensions/docs/examples/extensions/news/images/fb.png
deleted file mode 100644
index df35813..0000000
--- a/chrome/common/extensions/docs/examples/extensions/news/images/fb.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/news/images/news.gif b/chrome/common/extensions/docs/examples/extensions/news/images/news.gif
deleted file mode 100644
index 2d8df793..0000000
--- a/chrome/common/extensions/docs/examples/extensions/news/images/news.gif
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/news/images/news_action.png b/chrome/common/extensions/docs/examples/extensions/news/images/news_action.png
deleted file mode 100644
index e5ae7b13..0000000
--- a/chrome/common/extensions/docs/examples/extensions/news/images/news_action.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/news/images/news_icon.png b/chrome/common/extensions/docs/examples/extensions/news/images/news_icon.png
deleted file mode 100644
index aa864d98..0000000
--- a/chrome/common/extensions/docs/examples/extensions/news/images/news_icon.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/news/images/sprite_arrows.gif b/chrome/common/extensions/docs/examples/extensions/news/images/sprite_arrows.gif
deleted file mode 100644
index 4560faf4..0000000
--- a/chrome/common/extensions/docs/examples/extensions/news/images/sprite_arrows.gif
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/news/images/twitter.png b/chrome/common/extensions/docs/examples/extensions/news/images/twitter.png
deleted file mode 100644
index 31bd0e3..0000000
--- a/chrome/common/extensions/docs/examples/extensions/news/images/twitter.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/news/javascript/feed.js b/chrome/common/extensions/docs/examples/extensions/news/javascript/feed.js
deleted file mode 100644
index f4cc99a..0000000
--- a/chrome/common/extensions/docs/examples/extensions/news/javascript/feed.js
+++ /dev/null
@@ -1,388 +0,0 @@
-/**
- * Copyright (c) 2010 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.
- */
-
-/**
- * @fileoverview This file retrieves news feed and shows news in pop-up
- * page according to country, topics and no. of stories selected in the
- * option page.
- */
-
-// Store value retrieved from locale.
-var moreStoriesLocale = chrome.i18n.getMessage('more_stories') + ' \u00BB ';
-var directionLocale = chrome.i18n.getMessage('direction');
-
-// Feed URL.
-var feedUrl = DEFAULT_NEWS_URL;
-
-//The XMLHttpRequest object that tries to load and parse the feed.
-var req;
-
-/**
- * Sends request to Google News server
- */
-function main() {
- req = new XMLHttpRequest();
- req.onload = handleResponse;
- req.onerror = handleError;
- req.open('GET', feedUrl, true);
- req.send(null);
-}
-
-/**
- * Handles feed parsing errors.
- * @param {String} error The localized error message.
- */
-function handleFeedParsingFailed(error) {
- var feed = $('feed');
- $('noStories').style.display = 'none';
- feed.className = 'error';
- feed.innerText = error;
-}
-
-/**
- * Handles errors during the XMLHttpRequest.
- */
-function handleError() {
- handleFeedParsingFailed(chrome.i18n.getMessage('fetchError'));
- $('topics').style.display = 'none';
-}
-
-/**
- * Parses the feed response.
- */
-function handleResponse() {
- var doc = req.responseXML;
- if (!doc) {
- handleFeedParsingFailed(chrome.i18n.getMessage('wrongTopic'));
- var img = $('title');
- if(!img.src) {
- img.src = "/images/news.gif";
- }
-
- document.querySelector('body').style.minHeight = 0;
- return;
- }
- buildPreview(doc);
-}
-
-// Stores no. of stories selected in options page.
-var maxFeedItems = (window.localStorage.getItem('count')) ?
- window.localStorage.getItem('count') : 5;
-
-// Where the more stories link should navigate to.
-var moreStoriesUrl;
-
-/**
- * Generates news iframe in pop-up page by parsing retrieved feed.
- * @param {HTMLDocument} doc HTML Document received in feed.
- */
-function buildPreview(doc) {
- // Get the link to the feed source.
- var link = doc.querySelector('link');
- var parentTag = link.parentNode.tagName;
- if (parentTag != 'item' && parentTag != 'entry') {
- moreStoriesUrl = link.textContent;
- }
-
- // Setup the title image.
- var image = doc.querySelector('image');
- var titleImg;
-
- // Stores whether language script is Right to Left or not for setting style
- // of share buttons(Facebook, Twitter and Google Buzz) in iframe.
- var isRtl = 'lTR';
-
- if (image) {
- var url = image.querySelector('url');
- if (url) {
- titleImg = url.textContent;
-
- // Stores URL of title image to be shown on pop-up page.
- var titleImgUrl = titleImg;
- var pattern = /ar_/gi;
- var result = titleImgUrl.match(pattern);
- if (result != null || titleImgUrl == ISRAEL_IMAGE_URL) {
- isRtl = 'rTL';
- }
- }
- }
-
- var img = $('title');
- if (titleImg) {
- img.src = titleImg;
- if (moreStoriesUrl) {
- $('title_a').addEventListener('click', moreStories);
- }
- } else {
- img.style.display = 'none';
- }
-
- // Construct the iframe's HTML.
- var iframe_src = '<!doctype html><html><head><script>' +
- $('iframe_script').textContent + '<' +
- '/script><style> ' +
- '.rTL {margin-right: 102px; text-align: right;} ' +
- '.lTR {margin-left: 102px; text-align: left;} ' +
- '</style></head><body onload="frameLoaded();" ' +
- 'style="padding:0px;margin:0px;">';
-
- var feed = $('feed');
- feed.className = '';
- var entries = doc.getElementsByTagName('entry');
- if (entries.length == 0) {
- entries = doc.getElementsByTagName('item');
- }
- var count = Math.min(entries.length, maxFeedItems);
-
- // Stores required height by pop-up page.
- var minHeight = 19;
- minHeight = (minHeight * (count - 1)) + 100;
- document.querySelector('body').style.minHeight = minHeight + 'px';
- $('feed').innerHTML = '';
-
- for (var i = 0; i < count; i++) {
- item = entries.item(i);
-
- // Grab the title for the feed item.
- var itemTitle = item.querySelector('title');
- if (itemTitle) {
- itemTitle = itemTitle.textContent;
- } else {
- itemTitle = 'Unknown title';
- }
-
- // Grab the description.
- var itemDesc = item.querySelector('description');
- if (!itemDesc) {
- itemDesc = item.querySelector('summary');
- if (!itemDesc) {
- itemDesc = item.querySelector('content');
- }
- }
- if (itemDesc) {
- itemDesc = itemDesc.childNodes[0].nodeValue;
-
- } else {
- itemDesc = '';
- }
- var itemLink = item.querySelector('link');
- if (itemLink) {
- itemLink = itemLink.textContent;
- } else {
- itemLink = 'Unknown itemLink';
- }
- var item = document.createElement('div');
- item.className = 'item';
- var box = document.createElement('div');
- box.className = 'open_box';
- box.addEventListener('click', showDesc);
- item.appendChild(box);
-
- var title = document.createElement('a');
- title.className = 'item_title';
- title.innerText = itemTitle;
- title.addEventListener('click', showDesc);
- item.appendChild(title);
-
- var desc = document.createElement('iframe');
- desc.scrolling = 'no';
- desc.className = 'item_desc';
- item.appendChild(desc);
- feed.appendChild(item);
-
- // Adds share buttons images(Facebook, Twitter and Google Buzz).
- itemDesc += "<div class = '" + isRtl + "'>";
- itemDesc += "<a style='cursor: pointer' id='fb' " +
- "onclick='openNewsShareWindow(this.id,\"" + itemLink + "\")'>" +
- "<img src='" + chrome.extension.getURL('/images/fb.png') + "'/></a>";
- itemDesc += " <a style='cursor: pointer' id='twitter' " +
- "onclick='openNewsShareWindow(this.id,\"" + itemLink + "\")'>" +
- "<img src='" + chrome.extension.getURL('/images/twitter.png') + "'/></a>";
- itemDesc += " <a style='cursor: pointer' id='buzz' " +
- "onclick='openNewsShareWindow(this.id,\"" + itemLink + "\")'>" +
- "<img src='" + chrome.extension.getURL('/images/buzz.png') + "'/></a>";
- itemDesc += '</div>';
-
- // The story body is created as an iframe with a data: URL in order to
- // isolate it from this page and protect against XSS. As a data URL, it
- // has limited privileges and must communicate back using postMessage().
- desc.src = 'data:text/html;charset=utf-8,' + iframe_src + itemDesc +
- '</body></html>';
- }
- if (moreStoriesUrl && entries.length != 0) {
- var more = document.createElement('a');
- more.className = 'more';
- more.innerText = moreStoriesLocale;
- more.addEventListener('click', moreStories);
- feed.appendChild(more);
- }
- setStyleByLang(titleImgUrl);
-
- // Checks whether feed retrieved has news story or not. If not, then shows
- // error message accordingly.
- if (entries.length == 0) {
- $('noStories').innerText = chrome.i18n.getMessage('noStory');
- $('noStories').style.display = 'block';
- } else {
- $('noStories').style.display = 'none';
- }
-}
-
-/**
- * Show |url| in a new tab.
- * @param {String} url The news URL.
- */
-function showUrl(url) {
- // Only allow http and https URLs.
- if (url.indexOf('http:') != 0 && url.indexOf('https:') != 0) {
- return;
- }
- chrome.tabs.create({url: url});
-}
-
-/**
- * Redirects to Google news site for more stories.
- * @param {Object} event Onclick event.
- */
-function moreStories(event) {
- showUrl(moreStoriesUrl);
-}
-
-/**
- * Shows description of the news when users clicks on news title.
- * @param {Object} event Onclick event.
- */
-function showDesc(event) {
- var item_ = event.currentTarget.parentNode;
- var items = document.getElementsByClassName('item');
- for (var i = 0, item; item = items[i]; i++) {
- var iframe = item.querySelector('.item_desc');
- if (item == item_ && item.className == 'item') {
- item.className = 'item opened';
- iframe.contentWindow.postMessage('reportHeight', '*');
- } else {
- item.className = 'item';
- iframe.style.height = '0px';
- }
- }
-}
-
-/**
- * Handles messages between different iframes and sets the display of iframe.
- * @param {Object} e Onmessage event.
- */
-function iframeMessageHandler(e) {
- var iframes = document.getElementsByTagName('IFRAME');
- for (var i = 0, iframe; iframe = iframes[i]; i++) {
- if (iframe.contentWindow == e.source) {
- var msg = JSON.parse(e.data);
- if (msg) {
- if (msg.type == 'size') {
- iframe.style.height = msg.size + 'px';
- } else if (msg.type == 'show') {
- var url = msg.url;
- if (url.indexOf('http://news.google.com') == 0) {
- // If the URL is a redirect URL, strip of the destination and go to
- // that directly. This is necessary because the Google news
- // redirector blocks use of the redirects in this case.
- var index = url.indexOf('&url=');
- if (index >= 0) {
- url = url.substring(index + 5);
- index = url.indexOf('&');
- if (index >= 0)
- url = url.substring(0, index);
- }
- }
- showUrl(url);
- }
- }
- return;
- }
- }
-}
-
-/**
- * Saves last viewed topic by user in local storage on unload of pop-up page.
- */
-function saveLastTopic() {
- var topicVal = $('topics').value;
- window.localStorage.setItem('lastTopic', topicVal);
-}
-
-/**
- * Sets the URL according to selected topic(or default topic), then retrieves
- * feed and sets pop-up page.
- */
-function getNewsByTitle() {
- var country = window.localStorage.getItem('country');
- country = (country == 'noCountry' || !country) ? '' : country;
-
- // Sets direction of topics showed under dropdown in pop-up page according
- // to set language in browser.
- $('topics').className = (directionLocale == 'rtl') ? 'topicsRTL' :
- 'topicsLTR';
-
- var topicVal = $('topics').value;
-
- // Sets Feed URL in case of custom topic selected.
- var keywords = JSON.parse(window.localStorage.getItem('keywords'));
- var isFound = false;
- if (keywords) {
- for (i = 0; i < keywords.length; i++) {
- if (topicVal == keywords[i]) {
- isFound = true;
- feedUrl = DEFAULT_NEWS_URL + '&cf=all&ned=' + country + '&q=' + topicVal +
- '&hl=' + country;
- break;
- }
- }
- }
- if (!isFound) {
- feedUrl = DEFAULT_NEWS_URL + '&cf=all&ned=' + country +
- '&topic=' + topicVal;
- }
- main();
-}
-
-/**
- * Shows topic list retrieved from local storage(if any),else shows
- * default topics list.
- */
-function getTopics() {
- var topics = JSON.parse(window.localStorage.getItem('topics'));
- var keywords = JSON.parse(window.localStorage.getItem('keywords'));
- var element = $('topics');
-
- // Sets all topics as default list if no list is found from local storage.
- if (!topics && !keywords) {
- topics = [' ','n','w','b','t','e','s','m','po'];
- }
-
- if (topics) {
- for (var i = 0; i < (topics.length); i++) {
- var val = (topics[i] == ' ') ? '1' : topics[i];
- element.options[element.options.length] = new Option(
- chrome.i18n.getMessage(val), topics[i]);
- }
- }
-
- // Shows custom topics in list(if any).
- if (keywords) {
- for (i = 0; i < (keywords.length); i++) {
- element.options[element.options.length] = new Option(keywords[i],
- keywords[i]);
- }
- }
-
- $('option_link').innerText = chrome.i18n.getMessage('options');
-
- var topicVal = window.localStorage.getItem('lastTopic');
- if (topicVal) {
- $('topics').value = topicVal;
- }
-}
-
-window.addEventListener('message', iframeMessageHandler);
diff --git a/chrome/common/extensions/docs/examples/extensions/news/javascript/options.js b/chrome/common/extensions/docs/examples/extensions/news/javascript/options.js
deleted file mode 100644
index d030b367b..0000000
--- a/chrome/common/extensions/docs/examples/extensions/news/javascript/options.js
+++ /dev/null
@@ -1,395 +0,0 @@
-/**
- * Copyright (c) 2010 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.
- */
-
-/**
- * @fileoverview Includes the country selection, topics selection and
- * selection of no. of news stories to be shown. Include default settings also.
- * @author navneetg@google.com (Navneet Goel).
- */
-
-/**
- * Stores number of selected topics on the options page.
- */
-var checkCount = 0;
-
-/**
- * Stores maximum count of custom topics.
- */
-var MAX_CUS_TOPICS = 10;
-
-/**
- * Stores temporary added custom topics which are not yet saved.
- */
-var tempCusTopics = [];
-
-/**
- * Checks whether ENTER key is pressed or not.
- */
-function addCustomTopic() {
- if (window.event.keyCode == 13) {
- addCusTopic();
- }
-}
-
-/**
- * Retrieves and sets last saved country from local storage(if found),
- * else sets country retrieved from feed.
- */
-function setCountry() {
- var country = window.localStorage.getItem('country');
-
- // If country is not found in localstorage or default value is selected in
- // drop down menu.
- if ((!country) || country == 'noCountry') {
- // XMLHttpRequest object that tries to load the feed for the purpose of
- // retrieving the country value out of feed.
- var req = new XMLHttpRequest();
- req.onload = handleResponse;
- req.onerror = handleError;
- req.open('GET', DEFAULT_NEWS_URL, true);
- req.send(null);
-
- // Sets country to default Country in dropdown menu.
- function handleError() {
- $('countryList').value = 'noCountry';
- };
-
- // Handles parsing the feed data got back from XMLHttpRequest.
- function handleResponse() {
- // Feed document retrieved from URL.
- var doc = req.responseXML;
- if (!doc) {
- handleError();
- return;
- }
- var imageLink = doc.querySelector('image link');
- if (imageLink) {
- // Stores link to set value of country.
- var newsUrl = imageLink.textContent;
- }
-
- // Stores country value
- $('countryList').value = newsUrl.substring(newsUrl.indexOf('&ned=') + 5,
- newsUrl.indexOf('&hl='));
- };
- } else {
- $('countryList').value = country;
- }
-}
-
-/**
- * Displays various messages to user based on user input.
- * @param {String} id Id of status element.
- * @param {Number} timeOut Timeout value of message shown.
- * @param {String} message Message to be shown.
- */
-function showUserMessages(id, timeOut, message) {
- $(id).style.setProperty('transition',
- 'opacity 0s ease-in');
- $(id).style.opacity = 1;
- $(id).innerText = chrome.i18n.getMessage(message);
- window.setTimeout(function() {
- $(id).style.setProperty(
- 'transition', 'opacity' + timeOut + 's ease-in');
- $(id).style.opacity = 0;
- }, 1E3
- );
-}
-
-/**
- * Sets options page CSS according to the browser language(if found), else sets
- * to default locale.
- */
-function setOptionPageCSS() {
- if (chrome.i18n.getMessage('direction') == 'rtl') {
- document.querySelector('body').className = 'rtl';
- }
-}
-
-/**
- * Initializes the options page by retrieving country, topics and count of
- * stories from local storage if present, else sets to default settings.
- */
-function initialize() {
- setOptionPageCSS();
- setCountry();
- setCountAndTopicList();
- setLocalizedTopicList();
-
- // Adds a custom topic on press of Enter key.
- $('newKeyword').onkeypress = addCustomTopic;
-}
-
-/**
- * Retrieves locale values from locale file.
- */
-function setLocalizedTopicList() {
- var getI18nMsg = chrome.i18n.getMessage;
-
- $('top').innerText = getI18nMsg('1');
- $('nation').innerText = getI18nMsg('n');
- $('world').innerText = getI18nMsg('w');
- $('business').innerText = getI18nMsg('b');
- $('science').innerText = getI18nMsg('t');
- $('entertainment').innerText = getI18nMsg('e');
- $('sports').innerText = getI18nMsg('s');
- $('health').innerText = getI18nMsg('m');
- $('most').innerText = getI18nMsg('po');
- $('select_country').innerText = getI18nMsg('country');
- $('topic').innerText = getI18nMsg('topic');
- $('save_button').innerText = getI18nMsg('save');
- $('story_count').innerText = getI18nMsg('storyCount');
- $('logo').innerHTML = $('logo').innerHTML + getI18nMsg('newsOption');
- $('custom_text').innerHTML = getI18nMsg('customText') + '<br/>' +
- getI18nMsg('maximumTopics',[MAX_CUS_TOPICS]);
- $('submit_button').value = getI18nMsg('submitButton');
-}
-
-/**
- * Sets topic list and number of stories retrieved from localstorage(if any)
- * otherwise sets to default.
- */
-function setCountAndTopicList() {
- var topicLists = document.getElementsByClassName('checkBox');
-
- // Retrieves topics list from localStorage.
- var topics = JSON.parse(window.localStorage.getItem('topics'));
-
- // Runs if retrieved topic list from local storage contains topics.
- if (topics) {
- for (var x = 0, topicList; topicList = topicLists[x]; x++) {
-
- // Saves whether checkbox is checked or not.
- var isPresent = false;
- for (var y = 0; y < topics.length; y++) {
- if (topics[y] == topicList.value) {
- topicList.checked = true;
- isPresent = true;
- checkCount++;
- break;
- }
- }
- if (!isPresent) {
- topicList.checked = false;
- }
- }
- }
-
- // Retrieves list of custom topics from localstorage(if any) and shows it
- // in option page.
- var keywords = JSON.parse(window.localStorage.getItem('keywords'));
- if (keywords) {
-
- // Template to store custom topics in a table.
- var template = [];
- var title = chrome.i18n.getMessage('deleteTitle');
- for (var i = 0; i < keywords.length; i++) {
- checkCount++;
-
- template.push('<tr style = "height: 22px;">');
- template.push('<td id = "keyword_value" class = "cusTopicsClass">');
- template.push('<textarea class="noborder" readonly>');
- template.push(keywords[i]);
- template.push('</textarea>');
- template.push('<td class = "suppr" onclick = "delCusTopic(this)" ');
- template.push('title="');
- template.push(title);
- template.push('">');
- template.push('</td>');
- template.push('</tr>');
- }
- $('custom_topics').innerHTML = template.join('');
- if (keywords.length == MAX_CUS_TOPICS) {
- $('submit_button').disabled = true;
- $('newKeyword').readOnly = 'readonly';
- }
- }
- // Check all checkboxes(default settings) if no custom topic list and
- // checkbox topic list from local storage is found.
- if (!keywords && !topics) {
- for (var x = 0, topicList; topicList = topicLists[x]; x++) {
- topicList.checked = true;
- checkCount++;
- }
- }
-
- // Retrieves saved value of number of stories.
- var count = window.localStorage.getItem('count');
-
- // Sets number of stories in dropdown.
- if (count) {
- $('storyCount').value = count;
- }
-}
-
-/**
- * Saves checked topic list(if any), Custom topics(if any), number of
- * stories and country value in local storage.
- */
-function saveTopicsCountry() {
- var country = $('countryList').value;
- var topicLists = document.getElementsByClassName('checkBox');
-
- // Contains selected number of stories.
- var count = $('storyCount').value;
-
- // Stores checked topics list.
- var topicArr = [];
- for (var i = 0, topicList; topicList = topicLists[i]; i++) {
- if (topicList.checked) {
- topicArr.push(topicList.value);
- }
- }
- var keywords = JSON.parse(window.localStorage.getItem('keywords'));
-
- // Saves custom topics to local storage(if any).
- if (tempCusTopics.length > 0) {
- if (keywords) {
- keywords = keywords.concat(tempCusTopics);
- window.localStorage.setItem('keywords', JSON.stringify(keywords));
- } else {
- window.localStorage.setItem('keywords', JSON.stringify(tempCusTopics));
- }
- tempCusTopics.splice(0, tempCusTopics.length);
- }
-
- // Saves checkbox topics(if any).
- if (topicArr.length > 0) {
- window.localStorage.setItem('topics', JSON.stringify(topicArr));
- } else {
- window.localStorage.removeItem('topics');
- }
-
- window.localStorage.setItem('count', count);
- window.localStorage.setItem('country', country);
-
- showUserMessages('save_status', 0.5, 'saveStatus');
- $('save_button').disabled = true;
-}
-
-/**
- * Disables the save button on options page if no topic is selected by the user.
- * @param {String} id Id of checkbox checked or unchecked.
- */
-function manageCheckCount(id) {
- checkCount = ($(id).checked) ? (checkCount + 1) : (checkCount - 1);
- $('save_button').disabled = (checkCount == 0) ? true : false;
-}
-
-/**
- * Enables save button if at least one topic is selected.
- */
-function enableSaveButton() {
- if (checkCount != 0) {
- $('save_button').disabled = false;
- }
-}
-
-/**
- * Adds new entered custom topic.
- */
-function addCusTopic() {
- // Retrieves custom topic list from local storage(if any), else create new
- // array list.
- var keywords = JSON.parse(window.localStorage.getItem('keywords') || "[]");
-
- // Adds topic only if total number of added custom topics are less than 10.
- if (keywords.length + tempCusTopics.length <= (MAX_CUS_TOPICS - 1)) {
-
- // Stores new entered value in input textbox.
- var val = $('newKeyword').value;
- if (val) {
- val = val.trim();
- if (val.length > 0) {
- var pattern = /,/g;
-
- // Runs if comma(,) is not present in topic entered.
- if (val.match(pattern) == null) {
- checkCount++;
- tempCusTopics.push(val);
-
- // Template to store custom topics in a table.
- var template = [];
- var title = chrome.i18n.getMessage('deleteTitle');
-
- template.push('<tr style = "height: 22px;">');
- template.push('<td id = "keyword_value" class = "cusTopicsClass">');
- template.push('<textarea class="noborder" readonly>');
- template.push(val);
- template.push('</textarea>');
- template.push('<td class = "suppr" onclick = "delCusTopic(this)" ');
- template.push('title="');
- template.push(title);
- template.push('">');
- template.push('</td>');
- template.push('</tr>');
-
- $('custom_topics').innerHTML += template.join('');
- enableSaveButton();
- } else {
- showUserMessages('invalid_status', 2.5, 'invalidChars');
- }
- }
- $('newKeyword').value = '';
- }
- }
-
- if ((keywords.length + tempCusTopics.length) == (MAX_CUS_TOPICS)) {
- $('submit_button').disabled = true;
- $('newKeyword').readOnly = 'readonly';
- }
-}
-
-/**
- * Delete custom topic whenever users click on delete icon.
- * @param {HTMLTableColElement} obj HTML table column element to be deleted.
- */
-function delCusTopic(obj) {
- // Deletes only if total number of topics are greater than 1, else shows
- // error message.
- if (checkCount > 1) {
- var value;
-
- // Extract custom topic value.
- value = obj.parentNode.querySelector('.cusTopicsClass textarea').value;
-
- // Removes custom topic element from UI.
- $('custom_topics').removeChild(obj.parentNode);
-
- // Removes custom topic element either from temporary array(if topic is
- // not yet saved) or from saved topic list and saves new list to
- // local storage.
- var flag = 0;
- for (var i = 0; i < tempCusTopics.length; i++) {
- if (tempCusTopics[i] == value) {
- tempCusTopics.splice(i, 1);
- flag = 1;
- break;
- }
- }
-
- if (flag == 0) {
- var keywords = JSON.parse(window.localStorage.getItem('keywords'));
- for (i = 0; i < keywords.length; i++) {
- if (keywords[i] == value) {
- keywords.splice(i, 1);
- break;
- }
- }
- if (keywords.length > 0) {
- window.localStorage.setItem('keywords', JSON.stringify(keywords));
- } else {
- window.localStorage.removeItem('keywords');
- }
- }
-
- checkCount--;
- $('submit_button').disabled = false;
- } else {
- showUserMessages('save_status', 2.5, 'noTopic');
- }
- $('newKeyword').readOnly = false;
-}
diff --git a/chrome/common/extensions/docs/examples/extensions/news/javascript/util.js b/chrome/common/extensions/docs/examples/extensions/news/javascript/util.js
deleted file mode 100644
index f8e3880..0000000
--- a/chrome/common/extensions/docs/examples/extensions/news/javascript/util.js
+++ /dev/null
@@ -1,29 +0,0 @@
-/**
- * Copyright (c) 2010 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.
- */
-
-/**
- * @fileoverview Defines the constants and most commonly used functions.
- * @author navneetg@google.com (Navneet Goel).
- */
-
-/**
- * Default feed news URL.
- */
-var DEFAULT_NEWS_URL = 'http://news.google.com/news?output=rss';
-
-/**
- * Image URL of Israel country.
- */
-var ISRAEL_IMAGE_URL = 'http://www.gstatic.com/news/img/logo/iw_il/news.gif';
-
-/**
- * Alias for getElementById.
- * @param {String} elementId Element id of the HTML element to be fetched.
- * @return {Element} Element corresponding to the element id.
- */
-function $(elementId) {
- return document.getElementById(elementId);
-}
diff --git a/chrome/common/extensions/docs/examples/extensions/news/manifest.json b/chrome/common/extensions/docs/examples/extensions/news/manifest.json
deleted file mode 100644
index a64df9c..0000000
--- a/chrome/common/extensions/docs/examples/extensions/news/manifest.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
- "name": "__MSG_extName__",
- "version": "2.0",
- "description": "__MSG_extDesc__",
- "icons": { "128": "images/news_icon.png" },
- "default_locale":"en",
- "browser_action": {
- "default_title": "__MSG_ext_default_title__",
- "default_icon": "images/news_action.png",
- "default_popup": "views/feed.html"
- },
- "permissions": [
- "tabs",
- "http://news.google.com/*"
- ],
- "options_page": "views/options.html",
- "background": {
- "page": "views/background.html"
- }
-}
diff --git a/chrome/common/extensions/docs/examples/extensions/news/views/background.html b/chrome/common/extensions/docs/examples/extensions/news/views/background.html
deleted file mode 100644
index c97e977..0000000
--- a/chrome/common/extensions/docs/examples/extensions/news/views/background.html
+++ /dev/null
@@ -1,27 +0,0 @@
-<!DOCTYPE html>
-<!--
- * Copyright (c) 2010 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.
--->
-
-<!--
-@fileoverview Contains script for running at the background to open up the
-options page when the extension is reloaded.
--->
-
-<html>
- <body>
- <script>
- //Retrieves value from local storage(if found).
- var newsFlag = window.localStorage.getItem('newsFlag');
-
- //Runs if extension installation is done.
- if(!newsFlag) {
- var optionsPageURL = chrome.extension.getURL('/views/options.html');
- chrome.tabs.create({url: optionsPageURL});
- window.localStorage.setItem('newsFlag','1');
- }
- </script>
- </body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/extensions/news/views/feed.html b/chrome/common/extensions/docs/examples/extensions/news/views/feed.html
deleted file mode 100644
index 43d147b..0000000
--- a/chrome/common/extensions/docs/examples/extensions/news/views/feed.html
+++ /dev/null
@@ -1,146 +0,0 @@
-<!DOCTYPE html>
-<!--
- * Copyright (c) 2010 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.
--->
-
-<!--
-@fileoverview This file serves as the pop-up page for showing news
-according to the settings saved in options page otherwise shows default
-settings.
-@author navneetg@google.com (Navneet Goel).
--->
-
-<html>
-<head>
-<script src = "/javascript/util.js"></script>
-<link rel = "stylesheet" href = "/css/feed.css"/>
-
-<script id = "iframe_script">
-
-/**
- * Facebook share URL.
- */
-var FB_SHARE_URL = "http://www.facebook.com/sharer.php?u=";
-
-/**
- * Twitter share URL.
- */
-var TWITTER_SHARE_URL = "http://twitter.com/share?&url=";
-
-/**
- * Buzz share URL.
- */
-var BUZZ_SHARE_URL = "http://www.google.com/buzz/post?&url=";
-
-/**
- * Opens new window either of facebook, twitter or google buzz.
- * @param {String} id Specifies whether to share news on Facebook, Google Buzz
- * or Twitter.
- * @param {String} url Contains URL of the News to be shared.
- */
-function openNewsShareWindow(id, url) {
- var newsUrl = url.substring(url.indexOf('&url=') + 5);
- var openUrl;
- switch (id) {
- case 'fb':
- openUrl = FB_SHARE_URL;
- break;
- case 'buzz':
- openUrl = BUZZ_SHARE_URL;
- break;
- case 'twitter':
- openUrl = TWITTER_SHARE_URL;
- break;
- }
- window.open(openUrl + newsUrl, '_blank',
- 'resizable=0,scrollbars=0,width=690,height=415');
-}
-
-/**
- * Checks language in image url retrieved from feed and sets style of
- * title and openbox in pop-up page(if url is found), otherwise sets
- * to default styling.
- */
-function setStyleByLang(titleImgUrl) {
- var openBoxes = document.getElementsByClassName('open_box');
- var itemTitles = document.getElementsByClassName('item_title');
-
- if (titleImgUrl != 'NULL') {
- var pattern = /ar_/gi;
- var result = titleImgUrl.match(pattern);
- if (result != null || titleImgUrl == ISRAEL_IMAGE_URL) {
- document.querySelector('body').className = 'rtl';
- }
- }
-}
-
-/**
- * Reports the height.
- */
-function reportHeight() {
- var msg = JSON.stringify({type:"size", size:document.body.offsetHeight});
- parent.postMessage(msg, "*");
-}
-
-/**
- * Initialize the iframe body.
- */
-function frameLoaded() {
- var links = document.getElementsByTagName("A");
- for (var i = 0, link; link = links[i]; i++) {
- var class = link.className;
- if (class != "item_title" && class != "open_box") {
- link.addEventListener("click", showStory);
- }
- }
- window.addEventListener("message", messageHandler);
-}
-
-/**
- * Redirects to Google news site according to clicked URL.
- * @param {Object} event Onclick event.
- */
-function showStory(event) {
- var href = event.currentTarget.href;
- parent.postMessage(JSON.stringify({type:"show", url:href}), "*");
- event.preventDefault();
-}
-
-/**
- * Handles message.
- * @param {Object} event Onmessage event.
- */
-function messageHandler(event) {
- reportHeight();
-}
-</script>
-<script src = "/javascript/feed.js"></script>
-</head>
-
-<body onload = "getTopics();getNewsByTitle();" onunload = "saveLastTopic();">
-
-<div style = "margin-bottom: 15px;">
- <div style = "float: right;">
- <div style = "float: right; font-size: 11px">
- <a id = "option_link" onclick = "chrome.tabs.create({url: '/views/options.html', selected: true})">
- </a>
- </div>
- <div style = "margin-top: 27px">
- <select id = "topics" onchange = "getNewsByTitle();" style = "display: inline;">
- </select>
- </div>
- </div>
- <a id = "title_a">
- <img id = "title" style = "padding-top: 5px;">
- </a>
-</div>
-
-<div id = "feed">
-</div>
-
-<div id = "noStories">
-</div>
-</body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/extensions/news/views/options.html b/chrome/common/extensions/docs/examples/extensions/news/views/options.html
deleted file mode 100644
index 6bf99b3..0000000
--- a/chrome/common/extensions/docs/examples/extensions/news/views/options.html
+++ /dev/null
@@ -1,166 +0,0 @@
-<!DOCTYPE html>
-<!--
- * Copyright (c) 2010 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.
--->
-
-<!--
-@fileoverview This file serves as the option page of the extension for
-customizing the settings such as setting country, topics and number of
-news stories to be shown.
-@author navneetg@google.com (Navneet Goel).
--->
-
-<html>
- <head>
- <script src = "/javascript/util.js"></script>
- <meta http-equiv = "Content-Type" content = "text/html; charset = UTF-8">
- <link rel = "stylesheet" href = "/css/options.css"/>
- <script src = "/javascript/options.js"></script>
- </head>
- <body onload = "initialize();">
- <div id = "all_content">
- <div id = "logo">
- <img id = "title_image" src = "/images/news.gif"/>
- <br/>
- </div>
- <br/><br/>
-
- <table class = "contentTable" style = "margin-left: 55px;" width = "96%">
- <tr class = "all_rows">
- <td class = "col1"><b id = "select_country"></b></td>
- <td class = "col2">
- <select id = "countryList" onchange = "enableSaveButton();">
- <option value = "noCountry">-Select-</option>
- <option value = "es_ar">Argentina</option>
- <option value = "au">Australia</option>
- <option value = "nl_be">België</option>
- <option value = "fr_be">Belgique</option>
- <option value = "en_bw">Botswana</option>
- <option value = "pt-BR_br">Brasil</option>
- <option value = "ca">Canada English</option>
- <option value = "fr_ca">Canada Français</option>
- <option value = "cs_cz">Česká republika</option>
- <option value = "es_cl">Chile</option>
- <option value = "es_co">Colombia</option>
- <option value = "es_cu">Cuba</option>
- <option value = "de">Deutschland</option>
- <option value = "es">España</option>
- <option value = "es_us">Estados Unidos</option>
- <option value = "en_et">Ethiopia</option>
- <option value = "fr">France</option>
- <option value = "en_gh">Ghana</option>
- <option value = "in">India</option>
- <option value = "en_ie">Ireland</option>
- <option value = "en_il">Israel English</option>
- <option value = "it">Italia</option>
- <option value = "en_ke">Kenya</option>
- <option value = "hu_hu">Magyarország</option>
- <option value = "en_my">Malaysia</option>
- <option value = "es_mx">México</option>
- <option value = "en_na">Namibia</option>
- <option value = "nl_nl">Nederland</option>
- <option value = "nz">New Zealand</option>
- <option value = "en_ng">Nigeria</option>
- <option value = "no_no">Norge</option>
- <option value = "de_at">Österreich</option>
- <option value = "en_pk">Pakistan</option>
- <option value = "es_pe">Perú</option>
- <option value = "en_ph">Philippines</option>
- <option value = "pl_pl">Polska</option>
- <option value = "pt-PT_pt">Portugal</option>
- <option value = "de_ch">Schweiz</option>
- <option value = "fr_sn">Sénégal</option>
- <option value = "en_sg">Singapore</option>
- <option value = "en_za">South Africa</option>
- <option value = "fr_ch">Suisse</option>
- <option value = "sv_se">Sverige</option>
- <option value = "en_tz">Tanzania</option>
- <option value = "tr_tr">Türkiye</option>
- <option value = "uk">U.K.</option>
- <option value = "us">U.S.</option>
- <option value = "en_ug">Uganda</option>
- <option value = "es_ve">Venezuela</option>
- <option value = "vi_vn">Việt Nam (Vietnam)</option>
- <option value = "en_zw">Zimbabwe</option>
- <option value = "el_gr">Ελλάδα (Greece)</option>
- <option value = "ru_ru">Россия (Russia)</option>
- <option value = "ru_ua">Украина / русский (Ukraine)</option>
- <option value = "uk_ua">Україна / українська (Ukraine)</option>
- <option value = "iw_il">ישראל (Israel)</option>
- <option value = "ar_ae">الإمارات (UAE)</option>
- <option value = "ar_sa">السعودية (KSA)</option>
- <option value = "ar_me">العالم العربي (Arabic)</option>
- <option value = "ar_lb">لبنان (Lebanon)</option>
- <option value = "ar_eg">مصر (Egypt)</option>
- <option value = "hi_in">हिन्दी (India)</option>
- <option value = "ta_in">தமிழ்(India)</option>
- <option value = "te_in">తెలుగు (India)</option>
- <option value = "ml_in">മലയാളം (India)</option>
- <option value = "kr">한국 (Korea)</option>
- <option value = "cn">中国版 (China)</option>
- <option value = "tw">台灣版 (Taiwan)</option>
- <option value = "jp">日本 (Japan)</option>
- <option value = "hk">香港版 (Hong Kong)</option>
- </select>
- </td>
- </tr>
- <tr class = "all_rows">
- <td class = "col1"><b id = "story_count"></b></td>
- <td class = "col2">
- <select id = "storyCount" style = "padding-left: 3px;" onchange = "enableSaveButton();">
- <option value = "1">1</option>
- <option value = "2">2</option>
- <option value = "3">3</option>
- <option value = "4">4</option>
- <option value = "5" selected = "selected">5</option>
- <option value = "6">6</option>
- <option value = "7">7</option>
- <option value = "8">8</option>
- <option value = "9">9</option>
- <option value = "10">10</option>
- </select>
- </td>
- </tr>
- <tr class = "all_rows">
- <td class = "col1">
- <div id = "topic" style = "font-weight: bold;"></div>
- </td>
- <td class = "col2">
- <div>
- <div class = "boxAndTopic"><input class = "checkBox" type = "checkbox" value = " " id = "check11" onchange = "manageCheckCount(this.id)"/><div class = "checkBoxTopic" id = "top"></div><br/></div>
- <div class = "boxAndTopic"><input class = "checkBox" type = "checkbox" value = "n" id = "check13" onchange = "manageCheckCount(this.id)"/><div class = "checkBoxTopic" id = "nation"></div><br/></div>
- <div class = "boxAndTopic"><input class = "checkBox" type = "checkbox" value = "w" id = "check14" onchange = "manageCheckCount(this.id)"/><div class = "checkBoxTopic" id = "world"></div><br/></div>
- <div class = "boxAndTopic"><input class = "checkBox" type = "checkbox" value = "b" id = "check15" onchange = "manageCheckCount(this.id)"/><div class = "checkBoxTopic" id = "business"></div><br/></div>
- <div class = "boxAndTopic"><input class = "checkBox" type = "checkbox" value = "t" id = "check16" onchange = "manageCheckCount(this.id)"/><div class = "checkBoxTopic" id = "science"></div><br/></div>
- <div class = "boxAndTopic"><input class = "checkBox" type = "checkbox" value = "e" id = "check17" onchange = "manageCheckCount(this.id)"/><div class = "checkBoxTopic" id = "entertainment"></div><br/></div>
- <div class = "boxAndTopic"><input class = "checkBox" type = "checkbox" value = "s" id = "check18" onchange = "manageCheckCount(this.id)"/><div class = "checkBoxTopic" id = "sports"></div><br/></div>
- <div class = "boxAndTopic"><input class = "checkBox" type = "checkbox" value = "m" id = "check19" onchange = "manageCheckCount(this.id)"/><div class = "checkBoxTopic" id = "health"></div><br/></div>
- <div class = "boxAndTopic"><input class = "checkBox" type = "checkbox" value = "po" id = "check20" onchange = "manageCheckCount(this.id)"/><div class = "checkBoxTopic" id = "most"></div><br/></div>
- </div>
- </td>
- </tr>
- <tr class = "all_rows">
- <td class = "col1">
- <div id = "custom_text" style = "font-weight: bold;"></div>
- </td>
- <td class = "col2">
- <input id = "newKeyword" type = "text" maxlength = "20" style = "width: 205px;">
- <input id = "submit_button" type = "submit" onclick = "addCusTopic()" style = "width: 45px;">
- <span id = "invalid_status"></span>
- <table>
- <tbody id = "custom_topics"></tbody>
- </table>
- </td>
- </tr>
- </table>
- <br/>
- <div id = "save_div">
- <button id = "save_button" type = "button" disabled = "disabled" onclick = "saveTopicsCountry()" style = "width: 80px;">
- </button>
- <span id = "save_status"></span>
- </div>
- </div>
- </body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/extensions/news_a11y/feed.css b/chrome/common/extensions/docs/examples/extensions/news_a11y/feed.css
deleted file mode 100644
index ede6f47..0000000
--- a/chrome/common/extensions/docs/examples/extensions/news_a11y/feed.css
+++ /dev/null
@@ -1,74 +0,0 @@
-/**
- * Copyright (c) 2011 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.
- */
-
-body {
- font-family: helvetica, arial, sans-serif;
- font-size: 12px;
- overflow: hidden;
-}
-
-a {
- color:#0000CC;
- text-decoration: underline;
- cursor: pointer;
-}
-
-.open_box {
- display: block;
- overflow: hidden;
- margin-right: 4px;
- margin-top: 2px;
- height: 12px;
- width: 12px;
- float: left;
- clear: left;
- background-image: url(sprite_arrows.gif);
- background-position: 0px -24px;
- cursor: pointer;
-}
-
-.opened .open_box {
- background-position:-12px -24px;
-}
-
-.item {
- padding: 2px 0px;
-}
-
-.item_title {
- display: block;
- min-width: 300px;
- padding-left: 15px;
- cursor: pointer;
-}
-
-.item_desc {
- min-width: 500px;
- height: 0px;
- display: block;
- border: none;
- padding: 0px;
- margin: 0px;
- transition: height 0.2s ease-out;
-}
-
-#title {
- display: block;
- margin-left: auto;
-}
-
-.error {
- white-space: nowrap;
- color: red;
-}
-
-.more {
- display: block;
- text-align: right;
- padding-top: 20px;
- padding-right: 10px;
- color: #88C;
-}
diff --git a/chrome/common/extensions/docs/examples/extensions/news_a11y/feed.html b/chrome/common/extensions/docs/examples/extensions/news_a11y/feed.html
deleted file mode 100644
index 4451240..0000000
--- a/chrome/common/extensions/docs/examples/extensions/news_a11y/feed.html
+++ /dev/null
@@ -1,12 +0,0 @@
-<!DOCTYPE html>
-<html>
- <head>
- <link href="feed.css" rel="stylesheet" type="text/css">
- <script src="feed.js"></script>
- </head>
- <body>
- <a id="title_a" tabIndex="0"><img id='title' alt="Google News logo"></a>
- <div id="feed"></div>
- </body>
-</html>
-
diff --git a/chrome/common/extensions/docs/examples/extensions/news_a11y/feed.js b/chrome/common/extensions/docs/examples/extensions/news_a11y/feed.js
deleted file mode 100644
index 9c45bce..0000000
--- a/chrome/common/extensions/docs/examples/extensions/news_a11y/feed.js
+++ /dev/null
@@ -1,277 +0,0 @@
-// Copyright (c) 2011 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.
-
-// Feed
-var feedUrl = 'http://news.google.com/?output=rss';
-
-// The XMLHttpRequest object that tries to load and parse the feed.
-var req;
-
-function main() {
- req = new XMLHttpRequest();
- req.onload = handleResponse;
- req.onerror = handleError;
- req.open('GET', feedUrl, true);
- req.send(null);
-}
-
-// Handles feed parsing errors.
-function handleFeedParsingFailed(error) {
- var feed = document.getElementById('feed');
- feed.className = 'error';
- feed.innerText = 'Error: ' + error;
-}
-
-// Handles errors during the XMLHttpRequest.
-function handleError() {
- handleFeedParsingFailed('Failed to fetch RSS feed.');
-}
-
-// Handles parsing the feed data we got back from XMLHttpRequest.
-function handleResponse() {
- var doc = req.responseXML;
- if (!doc) {
- handleFeedParsingFailed('Not a valid feed.');
- return;
- }
- buildPreview(doc);
-}
-
-// The maximum number of feed items to show in the preview.
-var maxFeedItems = 5;
-
-// Where the more stories link should navigate to.
-var moreStoriesUrl;
-
-function buildPreview(doc) {
- // Get the link to the feed source.
- var link = doc.getElementsByTagName('link');
- var parentTag = link[0].parentNode.tagName;
- if (parentTag != 'item' && parentTag != 'entry') {
- moreStoriesUrl = link[0].textContent;
- }
-
- // Setup the title image.
- var images = doc.getElementsByTagName('image');
- var titleImg;
- if (images.length != 0) {
- var urls = images[0].getElementsByTagName('url');
- if (urls.length != 0) {
- titleImg = urls[0].textContent;
- }
- }
- var img = document.getElementById('title');
- // Listen for mouse and key events
- if (titleImg) {
- img.src = titleImg;
- if (moreStoriesUrl) {
- document.getElementById('title_a').addEventListener('click',
- moreStories);
- document.getElementById('title_a').addEventListener('keydown',
- function(event) {
- if (event.keyCode == 13) {
- moreStories(event);
- }});
- }
- } else {
- img.style.display = 'none';
- }
-
- // Construct the iframe's HTML.
- var iframe_src = '<!doctype html><html><head><script ' +
- 'src="chrome-extension://ldglnfnokeifbcaeppacaejckagballg/' +
- 'feed_iframe.js"><' + '/script><link href="chrome-extension://ldglnf' +
- 'nokeifbcaeppacaejckagballg/feed_iframe.css" rel="stylesheet" ' +
- 'type="text/css"></head><body>';
-
- var feed = document.getElementById('feed');
- // Set ARIA role indicating the feed element has a tree structure
- feed.setAttribute('role', 'tree');
-
- var entries = doc.getElementsByTagName('entry');
- if (entries.length == 0) {
- entries = doc.getElementsByTagName('item');
- }
- var count = Math.min(entries.length, maxFeedItems);
- for (var i = 0; i < count; i++) {
- item = entries.item(i);
-
- // Grab the title for the feed item.
- var itemTitle = item.getElementsByTagName('title')[0];
- if (itemTitle) {
- itemTitle = itemTitle.textContent;
- } else {
- itemTitle = 'Unknown title';
- }
-
- // Grab the description.
- var itemDesc = item.getElementsByTagName('description')[0];
- if (!itemDesc) {
- itemDesc = item.getElementsByTagName('summary')[0];
- if (!itemDesc) {
- itemDesc = item.getElementsByTagName('content')[0];
- }
- }
- if (itemDesc) {
- itemDesc = itemDesc.childNodes[0].nodeValue;
- } else {
- itemDesc = '';
- }
-
- var item = document.createElement('div');
- item.className = 'item';
- var box = document.createElement('div');
- box.className = 'open_box';
- box.addEventListener('click', showDesc);
- // Disable focusing on box image separately from rest of tree item
- box.tabIndex = -1;
- item.appendChild(box);
-
- var title = document.createElement('a');
- title.className = 'item_title';
- // Give title an ID for use with ARIA
- title.id = 'item' + i;
- title.innerText = itemTitle;
- title.addEventListener('click', showDesc);
- title.addEventListener('keydown', keyHandlerShowDesc);
- // Update aria-activedescendant property in response to focus change
- // within the tree
- title.addEventListener('focus', function(event) {
- feed.setAttribute(
- 'aria-activedescendant', this.id);
- });
- // Enable keyboard focus on the item title element
- title.tabIndex = 0;
- // Set ARIA role role indicating that the title element is a node in the
- // tree structure
- title.setAttribute('role', 'treeitem');
- // Set the ARIA state indicating this tree item is currently collapsed.
- title.setAttribute('aria-expanded', 'false');
- // Set ARIA property indicating that all items are at the same hierarchical
- // level (no nesting)
- title.setAttribute('aria-level', '1');
- item.appendChild(title);
-
- var desc = document.createElement('iframe');
- desc.scrolling = 'no';
- desc.className = 'item_desc';
- // Disable keyboard focus on elements in iFrames that have not been
- // displayed yet
- desc.tabIndex = -1;
-
- // The story body is created as an iframe with a data: URL in order to
- // isolate it from this page and protect against XSS. As a data URL, it
- // has limited privileges and must communicate back using postMessage().
- desc.src='data:text/html,' + iframe_src + itemDesc + '</body></html>';
-
- item.appendChild(desc);
- feed.appendChild(item);
- }
-
- if (moreStoriesUrl) {
- var more = document.createElement('a');
- more.className = 'more';
- more.innerText = 'More stories \u00BB';
- more.tabIndex = 0;
- more.addEventListener('click', moreStories);
- more.addEventListener('keydown', function(event) {
- if (event.keyCode == 13) {
- moreStories(event);
- }});
- feed.appendChild(more);
- }
-}
-
-// Show |url| in a new tab.
-function showUrl(url) {
- // Only allow http and https URLs.
- if (!url.startsWith('http:') && !url.startsWith('https:'))
- return;
-
- chrome.tabs.create({url: url});
-}
-
-function moreStories(event) {
- showUrl(moreStoriesUrl);
-}
-
-function keyHandlerShowDesc(event) {
-// Display content under heading when spacebar or right-arrow pressed
-// Hide content when spacebar pressed again or left-arrow pressed
-// Move to next heading when down-arrow pressed
-// Move to previous heading when up-arrow pressed
- if (event.keyCode == 32) {
- showDesc(event);
- } else if ((this.parentNode.className == 'item opened') &&
- (event.keyCode == 37)) {
- showDesc(event);
- } else if ((this.parentNode.className == 'item') && (event.keyCode == 39)) {
- showDesc(event);
- } else if (event.keyCode == 40) {
- if (this.parentNode.nextSibling) {
- this.parentNode.nextSibling.children[1].focus();
- }
- } else if (event.keyCode == 38) {
- if (this.parentNode.previousSibling) {
- this.parentNode.previousSibling.children[1].focus();
- }
- }
-}
-
-function showDesc(event) {
- var item = event.currentTarget.parentNode;
- var items = document.getElementsByClassName('item');
- for (var i = 0; i < items.length; i++) {
- var iframe = items[i].getElementsByClassName('item_desc')[0];
- if (items[i] == item && items[i].className == 'item') {
- items[i].className = 'item opened';
- iframe.contentWindow.postMessage('reportHeight', '*');
- // Set the ARIA state indicating the tree item is currently expanded.
- items[i].getElementsByClassName('item_title')[0].
- setAttribute('aria-expanded', 'true');
- iframe.tabIndex = 0;
- } else {
- items[i].className = 'item';
- iframe.style.height = '0px';
- // Set the ARIA state indicating the tree item is currently collapsed.
- items[i].getElementsByClassName('item_title')[0].
- setAttribute('aria-expanded', 'false');
- iframe.tabIndex = -1;
- }
- }
-}
-
-function iframeMessageHandler(e) {
- // Only listen to messages from one of our own iframes.
- var iframes = document.getElementsByTagName('IFRAME');
- for (var i = 0; i < iframes.length; i++) {
- if (iframes[i].contentWindow == e.source) {
- var msg = JSON.parse(e.data);
- if (msg) {
- if (msg.type == 'size') {
- iframes[i].style.height = msg.size + 'px';
- } else if (msg.type == 'show') {
- var url = msg.url;
- if (url.startsWith('http://news.google.com')) {
- // If the URL is a redirect URL, strip of the destination and go to
- // that directly. This is necessary because the Google news
- // redirector blocks use of the redirects in this case.
- var index = url.indexOf('&url=');
- if (index >= 0) {
- url = url.substring(index + 5);
- index = url.indexOf('&');
- if (index >= 0)
- url = url.substring(0, index);
- }
- }
- showUrl(url);
- }
- }
- return;
- }
- }
-}
-
-window.addEventListener('message', iframeMessageHandler);
-document.addEventListener('DOMContentLoaded', main);
diff --git a/chrome/common/extensions/docs/examples/extensions/news_a11y/feed_iframe.css b/chrome/common/extensions/docs/examples/extensions/news_a11y/feed_iframe.css
deleted file mode 100644
index 159417f..0000000
--- a/chrome/common/extensions/docs/examples/extensions/news_a11y/feed_iframe.css
+++ /dev/null
@@ -1,10 +0,0 @@
-/**
- * Copyright (c) 2011 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.
- */
-
-body {
- margin: 0;
- padding: 0;
-}
diff --git a/chrome/common/extensions/docs/examples/extensions/news_a11y/feed_iframe.js b/chrome/common/extensions/docs/examples/extensions/news_a11y/feed_iframe.js
deleted file mode 100644
index 0fcb590..0000000
--- a/chrome/common/extensions/docs/examples/extensions/news_a11y/feed_iframe.js
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) 2011 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.
-
-function reportHeight() {
- var msg = JSON.stringify({type:"size", size:document.body.offsetHeight});
- parent.postMessage(msg, "*");
-}
-
-function frameLoaded() {
- var links = document.getElementsByTagName("A");
- for (i = 0; i < links.length; i++) {
- var c = links[i].className;
- if (c != "item_title" && c != "open_box") {
- links[i].addEventListener("click", showStory);
- }
- }
- window.addEventListener("message", messageHandler);
-}
-
-function showStory(event) {
- var href = event.currentTarget.href;
- parent.postMessage(JSON.stringify({type:"show", url:href}), "*");
- event.preventDefault();
-}
-
-function messageHandler(event) {
- reportHeight();
-}
-
-document.addEventListener('DOMContentLoaded', frameLoaded);
diff --git a/chrome/common/extensions/docs/examples/extensions/news_a11y/manifest.json b/chrome/common/extensions/docs/examples/extensions/news_a11y/manifest.json
deleted file mode 100644
index 496ad4f..0000000
--- a/chrome/common/extensions/docs/examples/extensions/news_a11y/manifest.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- "name": "News Reader",
- "version": "1.1",
- "description": "Displays the first 5 items from the 'Google News - top news' RSS feed in a popup.",
- "icons": { "128": "news_icon.png" },
- "browser_action": {
- "default_title": "Google News",
- "default_icon": "news_action.png",
- "default_popup": "feed.html"
- },
- "permissions": [
- "tabs",
- "http://news.google.com/*"
- ],
- "manifest_version": 2,
- "content_security_policy": "img-src 'self' http://* https://*; script-src 'self'; connect-src http://news.google.com; frame-src data:"
-}
diff --git a/chrome/common/extensions/docs/examples/extensions/news_a11y/news_action.png b/chrome/common/extensions/docs/examples/extensions/news_a11y/news_action.png
deleted file mode 100644
index 7d6d9e08..0000000
--- a/chrome/common/extensions/docs/examples/extensions/news_a11y/news_action.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/news_a11y/news_icon.png b/chrome/common/extensions/docs/examples/extensions/news_a11y/news_icon.png
deleted file mode 100644
index aa864d98..0000000
--- a/chrome/common/extensions/docs/examples/extensions/news_a11y/news_icon.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/news_a11y/sprite_arrows.gif b/chrome/common/extensions/docs/examples/extensions/news_a11y/sprite_arrows.gif
deleted file mode 100644
index 4560faf4..0000000
--- a/chrome/common/extensions/docs/examples/extensions/news_a11y/sprite_arrows.gif
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/news_i18n/_locales/en/messages.json b/chrome/common/extensions/docs/examples/extensions/news_i18n/_locales/en/messages.json
deleted file mode 100644
index 9f5ea5d..0000000
--- a/chrome/common/extensions/docs/examples/extensions/news_i18n/_locales/en/messages.json
+++ /dev/null
@@ -1,63 +0,0 @@
-{
- "name": {
- "message": "News Reader",
- "description": "Extension name in manifest."
- },
- "description": {
- "message": "Displays the first 5 items from the '$Google$ News - top news' RSS feed in a popup.",
- "description": "Extension description in manifest.",
- "placeholders": {
- "google": {
- "content": "Google",
- "example": "Google"
- }
- }
- },
- "default_title": {
- "message": "$Google$ News",
- "description": "Extension browser action tooltip text in manifest.",
- "placeholders": {
- "google": {
- "content": "Google",
- "example": "Google"
- }
- }
- },
- "unknown_title": {
- "message": "Unknown title",
- "description": "Unknown news title."
- },
- "error": {
- "message": "Error: $error$",
- "description": "Generic error template. Expects error parameter to be passed in.",
- "placeholders": {
- "error": {
- "content": "$1",
- "example": "Failed to fetch RSS feed."
- }
- }
- },
- "failed_to_fetch_rss": {
- "message": "Failed to fetch RSS feed.",
- "description": "User visible error message."
- },
- "not_a_valid_feed": {
- "message": "Not a valid feed.",
- "description": "User visible error message."
- },
- "more_stories": {
- "message": "To $Google$ News \u00BB",
- "description": "Link name to more Google News.",
- "placeholders": {
- "google": {
- "content": "Google",
- "example": "Google"
- }
- }
- },
- "newsUrl": {
- "message": "http://news.google.com",
- "description": "Url to Google News."
- }
-}
-
diff --git a/chrome/common/extensions/docs/examples/extensions/news_i18n/_locales/es/messages.json b/chrome/common/extensions/docs/examples/extensions/news_i18n/_locales/es/messages.json
deleted file mode 100644
index 2093149..0000000
--- a/chrome/common/extensions/docs/examples/extensions/news_i18n/_locales/es/messages.json
+++ /dev/null
@@ -1,63 +0,0 @@
-{
- "name": {
- "message": "Lector de noticias",
- "description": "Nombre de la extensión en el manifiesto."
- },
- "description": {
- "message": "Muestra los primeros 5 eventos de '$Google$ noticias - destacados' RSS feed en una ventana.",
- "description": "Descripción de la extensión en el manifiesto.",
- "placeholders": {
- "google": {
- "content": "Google",
- "example": "Google"
- }
- }
- },
- "default_title": {
- "message": "$Google$ noticias",
- "description": "Texto de la accion de menú de la extension en el manifiesto.",
- "placeholders": {
- "google": {
- "content": "Google",
- "example": "Google"
- }
- }
- },
- "unknown_title": {
- "message": "Título desconocido",
- "description": "Noticia con título desconocido."
- },
- "error": {
- "message": "Error: $error$",
- "description": "Plantilla de error genérico. Hace falta pasar un parámetro de error.",
- "placeholders": {
- "error": {
- "content": "$1",
- "example": "Fallo al capturar el RSS feed."
- }
- }
- },
- "failed_to_fetch_rss": {
- "message": "Fallo al capturar el RSS feed.",
- "description": "Mensaje de error visible para el usuario."
- },
- "not_a_valid_feed": {
- "message": "Feed no válido.",
- "description": "Mensaje de error visible para el usuario."
- },
- "more_stories": {
- "message": "Ir a $Google$ noticias \u00BB",
- "description": "Nombre del enlace a Google noticias.",
- "placeholders": {
- "google": {
- "content": "Google",
- "example": "Google"
- }
- }
- },
- "newsUrl": {
- "message": "http://news.google.es",
- "description": "Dirección de Google News."
- }
-}
-
diff --git a/chrome/common/extensions/docs/examples/extensions/news_i18n/_locales/sr/messages.json b/chrome/common/extensions/docs/examples/extensions/news_i18n/_locales/sr/messages.json
deleted file mode 100644
index 7d43d7a..0000000
--- a/chrome/common/extensions/docs/examples/extensions/news_i18n/_locales/sr/messages.json
+++ /dev/null
@@ -1,59 +0,0 @@
-{
- "name": {
- "message": "Читач вести",
- "description": "Назив екстензије у манифесту."
- },
- "description": {
- "message": "Приказује првих 5 вести са '$Google$ Вести - главне вести' у прозорчићу.",
- "description": "Опис екстензије у манифесту.",
- "placeholders": {
- "google": {
- "content": "Google",
- "example": "Google"
- }
- }
- },
- "default_title": {
- "message": "$Google$ Вести",
- "description": "Назив дугмета екстензије.",
- "placeholders": {
- "google": {
- "content": "Google",
- "example": "Google"
- }
- }
- },
- "unknown_title": {
- "message": "Непознат наслов",
- "description": "Непознат наслов вести."
- },
- "error": {
- "message": "Грешка - $error$",
- "description": "Општи облик грешке.",
- "placeholders": {
- "error": {
- "content": "$1",
- "example": "фид је недоступан."
- }
- }
- },
- "failed_to_fetch_rss": {
- "message": "фид је недоступан.",
- "description": "Порука грешке коју види корисник када је фид недоступан."
- },
- "not_a_valid_feed": {
- "message": "неисправан фид.",
- "description": "Порука грешке коју види корисник када је фид неисправан."
- },
- "more_stories": {
- "message": "Ка $Google$ Вестима \u00BB",
- "description": "Назив везе ка још вести.",
- "placeholders": {
- "google": {
- "content": "Google",
- "example": "Google"
- }
- }
- }
-}
-
diff --git a/chrome/common/extensions/docs/examples/extensions/news_i18n/feed.html b/chrome/common/extensions/docs/examples/extensions/news_i18n/feed.html
deleted file mode 100644
index 07f54509..0000000
--- a/chrome/common/extensions/docs/examples/extensions/news_i18n/feed.html
+++ /dev/null
@@ -1,310 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<style>
-body {
- font-family: helvetica, arial, sans-serif;
- font-size: 12px;
- overflow: hidden;
-}
-
-a {
- color:#0000CC;
- text-decoration: underline;
- cursor: pointer;
-}
-
-.open_box {
- display: block;
- overflow: hidden;
- margin-right: 4px;
- margin-top: 2px;
- height: 12px;
- width: 12px;
- float: left;
- clear: left;
- background-image: url(sprite_arrows.gif);
- background-position: 0px -24px;
- cursor: pointer;
-}
-
-.opened .open_box {
- background-position:-12px -24px;
-}
-
-.item {
- padding: 2px 0px;
-}
-
-.item_title {
- display: block;
- min-width: 300px;
- padding-left: 15px;
- cursor: pointer;
-}
-
-.item_desc {
- min-width: 500px;
- height: 0px;
- display: block;
- border: none;
- padding: 0px;
- margin: 0px;
- transition: height 0.2s ease-out;
-}
-
-#title {
- display: block;
- margin-left: auto;
-}
-
-.error {
- white-space: nowrap;
- color: red;
-}
-
-.more {
- display: block;
- text-align: right;
- padding-top: 20px;
- padding-right: 10px;
- color: #88C;
-}
-
-</style>
-<script id="iframe_script">
-function reportHeight() {
- var msg = JSON.stringify({type:"size", size:document.body.offsetHeight});
- parent.postMessage(msg, "*");
-}
-
-function frameLoaded() {
- var links = document.getElementsByTagName("A");
- for (i = 0; i < links.length; i++) {
- var class = links[i].className;
- if (class != "item_title" && class != "open_box") {
- links[i].addEventListener("click", showStory);
- }
- }
- window.addEventListener("message", messageHandler);
-}
-
-function showStory(event) {
- var href = event.currentTarget.href;
- parent.postMessage(JSON.stringify({type:"show", url:href}), "*");
- event.preventDefault();
-}
-
-function messageHandler(event) {
- reportHeight();
-}
-
-</script>
-<script>
-// Feed URL.
-var feedUrl = chrome.i18n.getMessage('newsUrl') + '/?output=rss';
-
-// The XMLHttpRequest object that tries to load and parse the feed.
-var req;
-
-function main() {
- req = new XMLHttpRequest();
- req.onload = handleResponse;
- req.onerror = handleError;
- req.open("GET", feedUrl, true);
- req.send(null);
-}
-
-// Handles feed parsing errors.
-function handleFeedParsingFailed(error) {
- var feed = document.getElementById("feed");
- feed.className = "error";
- feed.innerText = chrome.i18n.getMessage("error", error);
-}
-
-// Handles errors during the XMLHttpRequest.
-function handleError() {
- handleFeedParsingFailed(chrome.i18n.getMessage('failed_to_fetch_rss'));
-}
-
-// Handles parsing the feed data we got back from XMLHttpRequest.
-function handleResponse() {
- var doc = req.responseXML;
- if (!doc) {
- handleFeedParsingFailed(chrome.i18n.getMessage('not_a_valid_feed'));
- return;
- }
- buildPreview(doc);
-}
-
-// The maximum number of feed items to show in the preview.
-var maxFeedItems = 5;
-
-// Where the more stories link should navigate to.
-var moreStoriesUrl;
-
-function buildPreview(doc) {
- // Get the link to the feed source.
- var link = doc.getElementsByTagName("link");
- var parentTag = link[0].parentNode.tagName;
- if (parentTag != "item" && parentTag != "entry") {
- moreStoriesUrl = link[0].textContent;
- }
-
- // Setup the title image.
- var images = doc.getElementsByTagName("image");
- var titleImg;
- if (images.length != 0) {
- var urls = images[0].getElementsByTagName("url");
- if (urls.length != 0) {
- titleImg = urls[0].textContent;
- }
- }
- var img = document.getElementById("title");
- if (titleImg) {
- img.src = titleImg;
- if (moreStoriesUrl) {
- document.getElementById("title_a").addEventListener("click", moreStories);
- }
- } else {
- img.style.display = "none";
- }
-
- // Construct the iframe's HTML.
- var iframe_src = "<!doctype html><html><head><script>" +
- document.getElementById("iframe_script").textContent + "<" +
- "/script></head><body onload='frameLoaded();' " +
- "style='padding:0px;margin:0px;'>";
-
- var feed = document.getElementById("feed");
- var entries = doc.getElementsByTagName('entry');
- if (entries.length == 0) {
- entries = doc.getElementsByTagName('item');
- }
- var count = Math.min(entries.length, maxFeedItems);
- for (var i = 0; i < count; i++) {
- item = entries.item(i);
-
- // Grab the title for the feed item.
- var itemTitle = item.getElementsByTagName('title')[0];
- if (itemTitle) {
- itemTitle = itemTitle.textContent;
- } else {
- itemTitle = chrome.i18n.getMessage("unknown_title");
- }
-
- // Grab the description.
- var itemDesc = item.getElementsByTagName('description')[0];
- if (!itemDesc) {
- itemDesc = item.getElementsByTagName('summary')[0];
- if (!itemDesc) {
- itemDesc = item.getElementsByTagName('content')[0];
- }
- }
- if (itemDesc) {
- itemDesc = itemDesc.childNodes[0].nodeValue;
- } else {
- itemDesc = '';
- }
-
- var item = document.createElement("div");
- item.className = "item";
- var box = document.createElement("div");
- box.className = "open_box";
- box.addEventListener("click", showDesc);
- item.appendChild(box);
-
- var title = document.createElement("a");
- title.className = "item_title";
- title.innerText = itemTitle;
- title.addEventListener("click", showDesc);
- item.appendChild(title);
-
- var desc = document.createElement("iframe");
- desc.scrolling = "no";
- desc.className = "item_desc";
- item.appendChild(desc);
- feed.appendChild(item);
-
- // The story body is created as an iframe with a data: URL in order to
- // isolate it from this page and protect against XSS. As a data URL, it
- // has limited privileges and must communicate back using postMessage().
- desc.src="data:text/html," + iframe_src + itemDesc + "</body></html>";
- }
-
- if (moreStoriesUrl) {
- var more = document.createElement("a");
- more.className = "more";
- more.innerText = chrome.i18n.getMessage("more_stories");
- more.addEventListener("click", moreStories);
- feed.appendChild(more);
- }
-}
-
-// Show |url| in a new tab.
-function showUrl(url) {
- // Only allow http and https URLs.
- if (url.indexOf("http:") != 0 && url.indexOf("https:") != 0) {
- return;
- }
- chrome.tabs.create({url: url});
-}
-
-function moreStories(event) {
- showUrl(moreStoriesUrl);
-}
-
-function showDesc(event) {
- var item = event.currentTarget.parentNode;
- var items = document.getElementsByClassName("item");
- for (var i = 0; i < items.length; i++) {
- var iframe = items[i].getElementsByClassName("item_desc")[0];
- if (items[i] == item && items[i].className == "item") {
- items[i].className = "item opened";
- iframe.contentWindow.postMessage("reportHeight", "*");
- } else {
- items[i].className = "item";
- iframe.style.height = "0px";
- }
- }
-}
-
-function iframeMessageHandler(e) {
- // Only listen to messages from one of our own iframes.
- var iframes = document.getElementsByTagName("IFRAME");
- for (var i = 0; i < iframes.length; i++) {
- if (iframes[i].contentWindow == e.source) {
- var msg = JSON.parse(e.data);
- if (msg) {
- if (msg.type == "size") {
- iframes[i].style.height = msg.size + "px";
- } else if (msg.type == "show") {
- var url = msg.url;
- if (url.indexOf(chrome.i18n.getMessage('newsUrl')) == 0) {
- // If the URL is a redirect URL, strip of the destination and go to
- // that directly. This is necessary because the Google news
- // redirector blocks use of the redirects in this case.
- var index = url.indexOf("&url=");
- if (index >= 0) {
- url = url.substring(index + 5);
- index = url.indexOf("&");
- if (index >= 0)
- url = url.substring(0, index);
- }
- }
- showUrl(url);
- }
- }
- return;
- }
- }
-}
-
-window.addEventListener("message", iframeMessageHandler);
-</script>
-</head>
-<body onload="main();">
-<a id="title_a"><img id='title'></a>
-<div id="feed"></div>
-</body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/extensions/news_i18n/manifest.json b/chrome/common/extensions/docs/examples/extensions/news_i18n/manifest.json
deleted file mode 100644
index 32b4cc0e..0000000
--- a/chrome/common/extensions/docs/examples/extensions/news_i18n/manifest.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- "name": "__MSG_name__",
- "version": "1.1",
- "description": "__MSG_description__",
- "icons": { "128": "news_icon.png" },
- "browser_action": {
- "default_title": "__MSG_default_title__",
- "default_icon": "news_action.png",
- "default_popup": "feed.html"
- },
- "permissions": [
- "tabs",
- "http://news.google.com/*",
- "http://news.google.es/*"
- ],
- "default_locale": "en"
-}
diff --git a/chrome/common/extensions/docs/examples/extensions/news_i18n/news_action.png b/chrome/common/extensions/docs/examples/extensions/news_i18n/news_action.png
deleted file mode 100644
index 7d6d9e08..0000000
--- a/chrome/common/extensions/docs/examples/extensions/news_i18n/news_action.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/news_i18n/news_icon.png b/chrome/common/extensions/docs/examples/extensions/news_i18n/news_icon.png
deleted file mode 100644
index aa864d98..0000000
--- a/chrome/common/extensions/docs/examples/extensions/news_i18n/news_icon.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/news_i18n/sprite_arrows.gif b/chrome/common/extensions/docs/examples/extensions/news_i18n/sprite_arrows.gif
deleted file mode 100644
index 4560faf4..0000000
--- a/chrome/common/extensions/docs/examples/extensions/news_i18n/sprite_arrows.gif
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/no_cookies/background.js b/chrome/common/extensions/docs/examples/extensions/no_cookies/background.js
deleted file mode 100644
index a226533b..0000000
--- a/chrome/common/extensions/docs/examples/extensions/no_cookies/background.js
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2018 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.
-
-'use strict';
-
-// Simple extension to remove 'Cookie' request header and 'Set-Cookie' response
-// header.
-
-function removeHeader(headers, name) {
- for (var i = 0; i < headers.length; i++) {
- if (headers[i].name.toLowerCase() == name) {
- console.log('Removing "' + name + '" header.');
- headers.splice(i, 1);
- break;
- }
- }
-}
-
-chrome.webRequest.onBeforeSendHeaders.addListener(
- function(details) {
- removeHeader(details.requestHeaders, 'cookie');
- return {requestHeaders: details.requestHeaders};
- },
- // filters
- {urls: ['https://*/*', 'http://*/*']},
- // extraInfoSpec
- ['blocking', 'requestHeaders', 'extraHeaders']);
-
-chrome.webRequest.onHeadersReceived.addListener(
- function(details) {
- removeHeader(details.responseHeaders, 'set-cookie');
- return {responseHeaders: details.responseHeaders};
- },
- // filters
- {urls: ['https://*/*', 'http://*/*']},
- // extraInfoSpec
- ['blocking', 'responseHeaders', 'extraHeaders']);
diff --git a/chrome/common/extensions/docs/examples/extensions/no_cookies/manifest.json b/chrome/common/extensions/docs/examples/extensions/no_cookies/manifest.json
deleted file mode 100644
index 1a0681c..0000000
--- a/chrome/common/extensions/docs/examples/extensions/no_cookies/manifest.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "name": "No Cookies",
- "description": "Removes 'Cookie' and 'Set-Cookie' headers.",
- "version": "1.0",
- "manifest_version": 2,
- "permissions": [
- "webRequest",
- "webRequestBlocking",
- "https://*/*",
- "http://*/*"
- ],
- "background": {
- "scripts": ["background.js"]
- }
-}
diff --git a/chrome/common/extensions/docs/examples/extensions/oauth_contacts/NOTICE b/chrome/common/extensions/docs/examples/extensions/oauth_contacts/NOTICE
deleted file mode 100644
index 8166d26b..0000000
--- a/chrome/common/extensions/docs/examples/extensions/oauth_contacts/NOTICE
+++ /dev/null
@@ -1,49 +0,0 @@
-This extension uses code from the following two JavaScript libraries:
-
-http://unitedheroes.net/OAuthSimple/js/OAuthSimple.js
-=====================================================
-/* OAuthSimple
- * A simpler version of OAuth
- *
- * author: jr conlin
- * mail: src@anticipatr.com
- * copyright: unitedHeroes.net
- * version: 1.0
- * url: http://unitedHeroes.net/OAuthSimple
- *
- * Copyright (c) 2009, unitedHeroes.net
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of the unitedHeroes.net nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY UNITEDHEROES.NET ''AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL UNITEDHEROES.NET BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
- http://pajhome.org.uk/crypt/md5/sha1.js
- =======================================
- /*
- * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined
- * in FIPS PUB 180-1
- * Version 2.1a Copyright Paul Johnston 2000 - 2002.
- * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
- * Distributed under the BSD License
- * See http://pajhome.org.uk/crypt/md5 for details.
- */
diff --git a/chrome/common/extensions/docs/examples/extensions/oauth_contacts/README b/chrome/common/extensions/docs/examples/extensions/oauth_contacts/README
deleted file mode 100644
index 9c0393b..0000000
--- a/chrome/common/extensions/docs/examples/extensions/oauth_contacts/README
+++ /dev/null
@@ -1,69 +0,0 @@
-Sample extension to demonstrate integration with an OAuth service.
-
-Overview
---------
-This sample demonstrates the use of OAuth to authorize against
-Google's Contacts API inside of an extension. It implements a library which
-may be reused generically to authorize requests to any 3-legged OAuth API.
-
-Library
--------
-The library files are:
- * chrome_ex_oauth.html
- * chrome_ex_oauth.js
- * chrome_ex_oauthsimple.js
-
-To use these files, place them in the root of your extension and include both
-.js files in your background page in the following order:
-
- <script type="text/javascript" src="chrome_ex_oauthsimple.js"></script>
- <script type="text/javascript" src="chrome_ex_oauth.js"></script>
-
-To initialize the API, create a ChromeExOAuth object in the background page:
-
- var oauth = ChromeExOAuth.initBackgroundPage({
- 'request_url' : <OAuth request URL>,
- 'authorize_url' : <OAuth authorize URL>,
- 'access_url' : <OAuth access token URL>,
- 'consumer_key' : <OAuth consumer key>,
- 'consumer_secret' : <OAuth consumer secret>,
- 'scope' : <scope parameter for this auth>,
- 'app_name' : <application name, not used by all OAuth providers>
- });
-
-Call the authorize() function to redirect the user to the OAuth provider in
-order to obtain an access token. The client library abstracts most of this
-process, so all you need to do is pass a callback to the authorize() function
-and a new tab will open and redirect the user. If the library already has
-stored an access token for the current scope, then no tab will be opened. In
-either case, the callback will be called with the resulting token and secret.
-
- oauth.authorize(onAuthorized);
-
-There is no need to store the token and secret, as this library already stores
-these values in localStorage. Once the callback you specified is called, you
-can call the sendSignedRequest function to send OAuth-signed requests to the
-API. The sendSignedRequest call takes an url to fetch, a callback function,
-and an optional parameter object as its arguments. The callback is passed
-the response text as well as the XMLHttpRequest object which was used to
-make the request as its arguments.
-
- function callback(text, xhr) {
- //...
- };
-
- function onAuthorized() {
- var url = <API url inside of the requested scope>;
- var request = {
- 'method' : 'GET',
- 'parameters' : {
- <Any request parameters as key : value pairs>
- }
- }
- oauth.sendSignedRequest(url, callback, request);
- };
- oauth.authorize(onAuthorized);
-
-
-
-
diff --git a/chrome/common/extensions/docs/examples/extensions/oauth_contacts/background.js b/chrome/common/extensions/docs/examples/extensions/oauth_contacts/background.js
deleted file mode 100644
index 2eef084..0000000
--- a/chrome/common/extensions/docs/examples/extensions/oauth_contacts/background.js
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright (c) 2012 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.
-
-var oauth = ChromeExOAuth.initBackgroundPage({
- 'request_url' : 'https://www.google.com/accounts/OAuthGetRequestToken',
- 'authorize_url' : 'https://www.google.com/accounts/OAuthAuthorizeToken',
- 'access_url' : 'https://www.google.com/accounts/OAuthGetAccessToken',
- 'consumer_key' : 'anonymous',
- 'consumer_secret' : 'anonymous',
- 'scope' : 'http://www.google.com/m8/feeds/',
- 'app_name' : 'Sample - OAuth Contacts'
-});
-
-var contacts = null;
-
-function setIcon() {
- if (oauth.hasToken()) {
- chrome.browserAction.setIcon({ 'path' : 'img/icon-19-on.png'});
- } else {
- chrome.browserAction.setIcon({ 'path' : 'img/icon-19-off.png'});
- }
-};
-
-function onContacts(text, xhr) {
- contacts = [];
- var data = JSON.parse(text);
- for (var i = 0, entry; entry = data.feed.entry[i]; i++) {
- var contact = {
- 'name' : entry['title']['$t'],
- 'id' : entry['id']['$t'],
- 'emails' : []
- };
-
- if (entry['gd$email']) {
- var emails = entry['gd$email'];
- for (var j = 0, email; email = emails[j]; j++) {
- contact['emails'].push(email['address']);
- }
- }
-
- if (!contact['name']) {
- contact['name'] = contact['emails'][0] || "<Unknown>";
- }
- contacts.push(contact);
- }
-
- chrome.tabs.create({ 'url' : 'contacts.html'});
-};
-
-function getContacts() {
- oauth.authorize(function() {
- console.log("on authorize");
- setIcon();
- var url = "http://www.google.com/m8/feeds/contacts/default/full";
- oauth.sendSignedRequest(url, onContacts, {
- 'parameters' : {
- 'alt' : 'json',
- 'max-results' : 100
- }
- });
- });
-};
-
-function logout() {
- oauth.clearTokens();
- setIcon();
-};
-
-setIcon();
-chrome.browserAction.onClicked.addListener(getContacts);
diff --git a/chrome/common/extensions/docs/examples/extensions/oauth_contacts/chrome_ex_oauth.html b/chrome/common/extensions/docs/examples/extensions/oauth_contacts/chrome_ex_oauth.html
deleted file mode 100644
index 4b03a3a4..0000000
--- a/chrome/common/extensions/docs/examples/extensions/oauth_contacts/chrome_ex_oauth.html
+++ /dev/null
@@ -1,23 +0,0 @@
-<!DOCTYPE html>
-<!--
- * 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>
- <title>OAuth Redirect Page</title>
- <style type="text/css">
- body {
- font: 16px Arial;
- color: #333;
- }
- </style>
- <script type="text/javascript" src="chrome_ex_oauthsimple.js"></script>
- <script type="text/javascript" src="chrome_ex_oauth.js"></script>
- <script type="text/javascript" src="onload.js"></script>
- </head>
- <body>
- Redirecting...
- </body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/extensions/oauth_contacts/chrome_ex_oauth.js b/chrome/common/extensions/docs/examples/extensions/oauth_contacts/chrome_ex_oauth.js
deleted file mode 100644
index 036820e8..0000000
--- a/chrome/common/extensions/docs/examples/extensions/oauth_contacts/chrome_ex_oauth.js
+++ /dev/null
@@ -1,591 +0,0 @@
-// Copyright (c) 2010 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.
-
-/**
- * Constructor - no need to invoke directly, call initBackgroundPage instead.
- * @constructor
- * @param {String} url_request_token The OAuth request token URL.
- * @param {String} url_auth_token The OAuth authorize token URL.
- * @param {String} url_access_token The OAuth access token URL.
- * @param {String} consumer_key The OAuth consumer key.
- * @param {String} consumer_secret The OAuth consumer secret.
- * @param {String} oauth_scope The OAuth scope parameter.
- * @param {Object} opt_args Optional arguments. Recognized parameters:
- * "app_name" {String} Name of the current application
- * "callback_page" {String} If you renamed chrome_ex_oauth.html, the name
- * this file was renamed to.
- */
-function ChromeExOAuth(url_request_token, url_auth_token, url_access_token,
- consumer_key, consumer_secret, oauth_scope, opt_args) {
- this.url_request_token = url_request_token;
- this.url_auth_token = url_auth_token;
- this.url_access_token = url_access_token;
- this.consumer_key = consumer_key;
- this.consumer_secret = consumer_secret;
- this.oauth_scope = oauth_scope;
- this.app_name = opt_args && opt_args['app_name'] ||
- "ChromeExOAuth Library";
- this.key_token = "oauth_token";
- this.key_token_secret = "oauth_token_secret";
- this.callback_page = opt_args && opt_args['callback_page'] ||
- "chrome_ex_oauth.html";
- this.auth_params = {};
- if (opt_args && opt_args['auth_params']) {
- for (key in opt_args['auth_params']) {
- if (opt_args['auth_params'].hasOwnProperty(key)) {
- this.auth_params[key] = opt_args['auth_params'][key];
- }
- }
- }
-};
-
-/*******************************************************************************
- * PUBLIC API METHODS
- * Call these from your background page.
- ******************************************************************************/
-
-/**
- * Initializes the OAuth helper from the background page. You must call this
- * before attempting to make any OAuth calls.
- * @param {Object} oauth_config Configuration parameters in a JavaScript object.
- * The following parameters are recognized:
- * "request_url" {String} OAuth request token URL.
- * "authorize_url" {String} OAuth authorize token URL.
- * "access_url" {String} OAuth access token URL.
- * "consumer_key" {String} OAuth consumer key.
- * "consumer_secret" {String} OAuth consumer secret.
- * "scope" {String} OAuth access scope.
- * "app_name" {String} Application name.
- * "auth_params" {Object} Additional parameters to pass to the
- * Authorization token URL. For an example, 'hd', 'hl', 'btmpl':
- * http://code.google.com/apis/accounts/docs/OAuth_ref.html#GetAuth
- * @return {ChromeExOAuth} An initialized ChromeExOAuth object.
- */
-ChromeExOAuth.initBackgroundPage = function(oauth_config) {
- window.chromeExOAuthConfig = oauth_config;
- window.chromeExOAuth = ChromeExOAuth.fromConfig(oauth_config);
- window.chromeExOAuthRedirectStarted = false;
- window.chromeExOAuthRequestingAccess = false;
-
- var url_match = chrome.extension.getURL(window.chromeExOAuth.callback_page);
- var tabs = {};
- chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
- if (changeInfo.url &&
- changeInfo.url.substr(0, url_match.length) === url_match &&
- changeInfo.url != tabs[tabId] &&
- window.chromeExOAuthRequestingAccess == false) {
- chrome.tabs.create({ 'url' : changeInfo.url }, function(tab) {
- tabs[tab.id] = tab.url;
- chrome.tabs.remove(tabId);
- });
- }
- });
-
- return window.chromeExOAuth;
-};
-
-/**
- * Authorizes the current user with the configued API. You must call this
- * before calling sendSignedRequest.
- * @param {Function} callback A function to call once an access token has
- * been obtained. This callback will be passed the following arguments:
- * token {String} The OAuth access token.
- * secret {String} The OAuth access token secret.
- */
-ChromeExOAuth.prototype.authorize = function(callback) {
- if (this.hasToken()) {
- callback(this.getToken(), this.getTokenSecret());
- } else {
- window.chromeExOAuthOnAuthorize = function(token, secret) {
- callback(token, secret);
- };
- chrome.tabs.create({ 'url' :chrome.extension.getURL(this.callback_page) });
- }
-};
-
-/**
- * Clears any OAuth tokens stored for this configuration. Effectively a
- * "logout" of the configured OAuth API.
- */
-ChromeExOAuth.prototype.clearTokens = function() {
- delete localStorage[this.key_token + encodeURI(this.oauth_scope)];
- delete localStorage[this.key_token_secret + encodeURI(this.oauth_scope)];
-};
-
-/**
- * Returns whether a token is currently stored for this configuration.
- * Effectively a check to see whether the current user is "logged in" to
- * the configured OAuth API.
- * @return {Boolean} True if an access token exists.
- */
-ChromeExOAuth.prototype.hasToken = function() {
- return !!this.getToken();
-};
-
-/**
- * Makes an OAuth-signed HTTP request with the currently authorized tokens.
- * @param {String} url The URL to send the request to. Querystring parameters
- * should be omitted.
- * @param {Function} callback A function to be called once the request is
- * completed. This callback will be passed the following arguments:
- * responseText {String} The text response.
- * xhr {XMLHttpRequest} The XMLHttpRequest object which was used to
- * send the request. Useful if you need to check response status
- * code, etc.
- * @param {Object} opt_params Additional parameters to configure the request.
- * The following parameters are accepted:
- * "method" {String} The HTTP method to use. Defaults to "GET".
- * "body" {String} A request body to send. Defaults to null.
- * "parameters" {Object} Query parameters to include in the request.
- * "headers" {Object} Additional headers to include in the request.
- */
-ChromeExOAuth.prototype.sendSignedRequest = function(url, callback,
- opt_params) {
- var method = opt_params && opt_params['method'] || 'GET';
- var body = opt_params && opt_params['body'] || null;
- var params = opt_params && opt_params['parameters'] || {};
- var headers = opt_params && opt_params['headers'] || {};
-
- var signedUrl = this.signURL(url, method, params);
-
- ChromeExOAuth.sendRequest(method, signedUrl, headers, body, function (xhr) {
- if (xhr.readyState == 4) {
- callback(xhr.responseText, xhr);
- }
- });
-};
-
-/**
- * Adds the required OAuth parameters to the given url and returns the
- * result. Useful if you need a signed url but don't want to make an XHR
- * request.
- * @param {String} method The http method to use.
- * @param {String} url The base url of the resource you are querying.
- * @param {Object} opt_params Query parameters to include in the request.
- * @return {String} The base url plus any query params plus any OAuth params.
- */
-ChromeExOAuth.prototype.signURL = function(url, method, opt_params) {
- var token = this.getToken();
- var secret = this.getTokenSecret();
- if (!token || !secret) {
- throw new Error("No oauth token or token secret");
- }
-
- var params = opt_params || {};
-
- var result = OAuthSimple().sign({
- action : method,
- path : url,
- parameters : params,
- signatures: {
- consumer_key : this.consumer_key,
- shared_secret : this.consumer_secret,
- oauth_secret : secret,
- oauth_token: token
- }
- });
-
- return result.signed_url;
-};
-
-/**
- * Generates the Authorization header based on the oauth parameters.
- * @param {String} url The base url of the resource you are querying.
- * @param {Object} opt_params Query parameters to include in the request.
- * @return {String} An Authorization header containing the oauth_* params.
- */
-ChromeExOAuth.prototype.getAuthorizationHeader = function(url, method,
- opt_params) {
- var token = this.getToken();
- var secret = this.getTokenSecret();
- if (!token || !secret) {
- throw new Error("No oauth token or token secret");
- }
-
- var params = opt_params || {};
-
- return OAuthSimple().getHeaderString({
- action: method,
- path : url,
- parameters : params,
- signatures: {
- consumer_key : this.consumer_key,
- shared_secret : this.consumer_secret,
- oauth_secret : secret,
- oauth_token: token
- }
- });
-};
-
-/*******************************************************************************
- * PRIVATE API METHODS
- * Used by the library. There should be no need to call these methods directly.
- ******************************************************************************/
-
-/**
- * Creates a new ChromeExOAuth object from the supplied configuration object.
- * @param {Object} oauth_config Configuration parameters in a JavaScript object.
- * The following parameters are recognized:
- * "request_url" {String} OAuth request token URL.
- * "authorize_url" {String} OAuth authorize token URL.
- * "access_url" {String} OAuth access token URL.
- * "consumer_key" {String} OAuth consumer key.
- * "consumer_secret" {String} OAuth consumer secret.
- * "scope" {String} OAuth access scope.
- * "app_name" {String} Application name.
- * "auth_params" {Object} Additional parameters to pass to the
- * Authorization token URL. For an example, 'hd', 'hl', 'btmpl':
- * http://code.google.com/apis/accounts/docs/OAuth_ref.html#GetAuth
- * @return {ChromeExOAuth} An initialized ChromeExOAuth object.
- */
-ChromeExOAuth.fromConfig = function(oauth_config) {
- return new ChromeExOAuth(
- oauth_config['request_url'],
- oauth_config['authorize_url'],
- oauth_config['access_url'],
- oauth_config['consumer_key'],
- oauth_config['consumer_secret'],
- oauth_config['scope'],
- {
- 'app_name' : oauth_config['app_name'],
- 'auth_params' : oauth_config['auth_params']
- }
- );
-};
-
-/**
- * Initializes chrome_ex_oauth.html and redirects the page if needed to start
- * the OAuth flow. Once an access token is obtained, this function closes
- * chrome_ex_oauth.html.
- */
-ChromeExOAuth.initCallbackPage = function() {
- var background_page = chrome.extension.getBackgroundPage();
- var oauth_config = background_page.chromeExOAuthConfig;
- var oauth = ChromeExOAuth.fromConfig(oauth_config);
- background_page.chromeExOAuthRedirectStarted = true;
- oauth.initOAuthFlow(function (token, secret) {
- background_page.chromeExOAuthOnAuthorize(token, secret);
- background_page.chromeExOAuthRedirectStarted = false;
- chrome.tabs.query({active: true, currentWindow: true}, function (tabs) {
- chrome.tabs.remove(tabs[0].id);
- });
- });
-};
-
-/**
- * Sends an HTTP request. Convenience wrapper for XMLHttpRequest calls.
- * @param {String} method The HTTP method to use.
- * @param {String} url The URL to send the request to.
- * @param {Object} headers Optional request headers in key/value format.
- * @param {String} body Optional body content.
- * @param {Function} callback Function to call when the XMLHttpRequest's
- * ready state changes. See documentation for XMLHttpRequest's
- * onreadystatechange handler for more information.
- */
-ChromeExOAuth.sendRequest = function(method, url, headers, body, callback) {
- var xhr = new XMLHttpRequest();
- xhr.onreadystatechange = function(data) {
- callback(xhr, data);
- }
- xhr.open(method, url, true);
- if (headers) {
- for (var header in headers) {
- if (headers.hasOwnProperty(header)) {
- xhr.setRequestHeader(header, headers[header]);
- }
- }
- }
- xhr.send(body);
-};
-
-/**
- * Decodes a URL-encoded string into key/value pairs.
- * @param {String} encoded An URL-encoded string.
- * @return {Object} An object representing the decoded key/value pairs found
- * in the encoded string.
- */
-ChromeExOAuth.formDecode = function(encoded) {
- var params = encoded.split("&");
- var decoded = {};
- for (var i = 0, param; param = params[i]; i++) {
- var keyval = param.split("=");
- if (keyval.length == 2) {
- var key = ChromeExOAuth.fromRfc3986(keyval[0]);
- var val = ChromeExOAuth.fromRfc3986(keyval[1]);
- decoded[key] = val;
- }
- }
- return decoded;
-};
-
-/**
- * Returns the current window's querystring decoded into key/value pairs.
- * @return {Object} A object representing any key/value pairs found in the
- * current window's querystring.
- */
-ChromeExOAuth.getQueryStringParams = function() {
- var urlparts = window.location.href.split("?");
- if (urlparts.length >= 2) {
- var querystring = urlparts.slice(1).join("?");
- return ChromeExOAuth.formDecode(querystring);
- }
- return {};
-};
-
-/**
- * Binds a function call to a specific object. This function will also take
- * a variable number of additional arguments which will be prepended to the
- * arguments passed to the bound function when it is called.
- * @param {Function} func The function to bind.
- * @param {Object} obj The object to bind to the function's "this".
- * @return {Function} A closure that will call the bound function.
- */
-ChromeExOAuth.bind = function(func, obj) {
- var newargs = Array.prototype.slice.call(arguments).slice(2);
- return function() {
- var combinedargs = newargs.concat(Array.prototype.slice.call(arguments));
- func.apply(obj, combinedargs);
- };
-};
-
-/**
- * Encodes a value according to the RFC3986 specification.
- * @param {String} val The string to encode.
- */
-ChromeExOAuth.toRfc3986 = function(val){
- return encodeURIComponent(val)
- .replace(/\!/g, "%21")
- .replace(/\*/g, "%2A")
- .replace(/'/g, "%27")
- .replace(/\(/g, "%28")
- .replace(/\)/g, "%29");
-};
-
-/**
- * Decodes a string that has been encoded according to RFC3986.
- * @param {String} val The string to decode.
- */
-ChromeExOAuth.fromRfc3986 = function(val){
- var tmp = val
- .replace(/%21/g, "!")
- .replace(/%2A/g, "*")
- .replace(/%27/g, "'")
- .replace(/%28/g, "(")
- .replace(/%29/g, ")");
- return decodeURIComponent(tmp);
-};
-
-/**
- * Adds a key/value parameter to the supplied URL.
- * @param {String} url An URL which may or may not contain querystring values.
- * @param {String} key A key
- * @param {String} value A value
- * @return {String} The URL with URL-encoded versions of the key and value
- * appended, prefixing them with "&" or "?" as needed.
- */
-ChromeExOAuth.addURLParam = function(url, key, value) {
- var sep = (url.indexOf('?') >= 0) ? "&" : "?";
- return url + sep +
- ChromeExOAuth.toRfc3986(key) + "=" + ChromeExOAuth.toRfc3986(value);
-};
-
-/**
- * Stores an OAuth token for the configured scope.
- * @param {String} token The token to store.
- */
-ChromeExOAuth.prototype.setToken = function(token) {
- localStorage[this.key_token + encodeURI(this.oauth_scope)] = token;
-};
-
-/**
- * Retrieves any stored token for the configured scope.
- * @return {String} The stored token.
- */
-ChromeExOAuth.prototype.getToken = function() {
- return localStorage[this.key_token + encodeURI(this.oauth_scope)];
-};
-
-/**
- * Stores an OAuth token secret for the configured scope.
- * @param {String} secret The secret to store.
- */
-ChromeExOAuth.prototype.setTokenSecret = function(secret) {
- localStorage[this.key_token_secret + encodeURI(this.oauth_scope)] = secret;
-};
-
-/**
- * Retrieves any stored secret for the configured scope.
- * @return {String} The stored secret.
- */
-ChromeExOAuth.prototype.getTokenSecret = function() {
- return localStorage[this.key_token_secret + encodeURI(this.oauth_scope)];
-};
-
-/**
- * Starts an OAuth authorization flow for the current page. If a token exists,
- * no redirect is needed and the supplied callback is called immediately.
- * If this method detects that a redirect has finished, it grabs the
- * appropriate OAuth parameters from the URL and attempts to retrieve an
- * access token. If no token exists and no redirect has happened, then
- * an access token is requested and the page is ultimately redirected.
- * @param {Function} callback The function to call once the flow has finished.
- * This callback will be passed the following arguments:
- * token {String} The OAuth access token.
- * secret {String} The OAuth access token secret.
- */
-ChromeExOAuth.prototype.initOAuthFlow = function(callback) {
- if (!this.hasToken()) {
- var params = ChromeExOAuth.getQueryStringParams();
- if (params['chromeexoauthcallback'] == 'true') {
- var oauth_token = params['oauth_token'];
- var oauth_verifier = params['oauth_verifier']
- this.getAccessToken(oauth_token, oauth_verifier, callback);
- } else {
- var request_params = {
- 'url_callback_param' : 'chromeexoauthcallback'
- }
- this.getRequestToken(function(url) {
- window.location.href = url;
- }, request_params);
- }
- } else {
- callback(this.getToken(), this.getTokenSecret());
- }
-};
-
-/**
- * Requests an OAuth request token.
- * @param {Function} callback Function to call once the authorize URL is
- * calculated. This callback will be passed the following arguments:
- * url {String} The URL the user must be redirected to in order to
- * approve the token.
- * @param {Object} opt_args Optional arguments. The following parameters
- * are accepted:
- * "url_callback" {String} The URL the OAuth provider will redirect to.
- * "url_callback_param" {String} A parameter to include in the callback
- * URL in order to indicate to this library that a redirect has
- * taken place.
- */
-ChromeExOAuth.prototype.getRequestToken = function(callback, opt_args) {
- if (typeof callback !== "function") {
- throw new Error("Specified callback must be a function.");
- }
- var url = opt_args && opt_args['url_callback'] ||
- window && window.top && window.top.location &&
- window.top.location.href;
-
- var url_param = opt_args && opt_args['url_callback_param'] ||
- "chromeexoauthcallback";
- var url_callback = ChromeExOAuth.addURLParam(url, url_param, "true");
-
- var result = OAuthSimple().sign({
- path : this.url_request_token,
- parameters: {
- "xoauth_displayname" : this.app_name,
- "scope" : this.oauth_scope,
- "oauth_callback" : url_callback
- },
- signatures: {
- consumer_key : this.consumer_key,
- shared_secret : this.consumer_secret
- }
- });
- var onToken = ChromeExOAuth.bind(this.onRequestToken, this, callback);
- ChromeExOAuth.sendRequest("GET", result.signed_url, null, null, onToken);
-};
-
-/**
- * Called when a request token has been returned. Stores the request token
- * secret for later use and sends the authorization url to the supplied
- * callback (for redirecting the user).
- * @param {Function} callback Function to call once the authorize URL is
- * calculated. This callback will be passed the following arguments:
- * url {String} The URL the user must be redirected to in order to
- * approve the token.
- * @param {XMLHttpRequest} xhr The XMLHttpRequest object used to fetch the
- * request token.
- */
-ChromeExOAuth.prototype.onRequestToken = function(callback, xhr) {
- if (xhr.readyState == 4) {
- if (xhr.status == 200) {
- var params = ChromeExOAuth.formDecode(xhr.responseText);
- var token = params['oauth_token'];
- this.setTokenSecret(params['oauth_token_secret']);
- var url = ChromeExOAuth.addURLParam(this.url_auth_token,
- "oauth_token", token);
- for (var key in this.auth_params) {
- if (this.auth_params.hasOwnProperty(key)) {
- url = ChromeExOAuth.addURLParam(url, key, this.auth_params[key]);
- }
- }
- callback(url);
- } else {
- throw new Error("Fetching request token failed. Status " + xhr.status);
- }
- }
-};
-
-/**
- * Requests an OAuth access token.
- * @param {String} oauth_token The OAuth request token.
- * @param {String} oauth_verifier The OAuth token verifier.
- * @param {Function} callback The function to call once the token is obtained.
- * This callback will be passed the following arguments:
- * token {String} The OAuth access token.
- * secret {String} The OAuth access token secret.
- */
-ChromeExOAuth.prototype.getAccessToken = function(oauth_token, oauth_verifier,
- callback) {
- if (typeof callback !== "function") {
- throw new Error("Specified callback must be a function.");
- }
- var bg = chrome.extension.getBackgroundPage();
- if (bg.chromeExOAuthRequestingAccess == false) {
- bg.chromeExOAuthRequestingAccess = true;
-
- var result = OAuthSimple().sign({
- path : this.url_access_token,
- parameters: {
- "oauth_token" : oauth_token,
- "oauth_verifier" : oauth_verifier
- },
- signatures: {
- consumer_key : this.consumer_key,
- shared_secret : this.consumer_secret,
- oauth_secret : this.getTokenSecret(this.oauth_scope)
- }
- });
-
- var onToken = ChromeExOAuth.bind(this.onAccessToken, this, callback);
- ChromeExOAuth.sendRequest("GET", result.signed_url, null, null, onToken);
- }
-};
-
-/**
- * Called when an access token has been returned. Stores the access token and
- * access token secret for later use and sends them to the supplied callback.
- * @param {Function} callback The function to call once the token is obtained.
- * This callback will be passed the following arguments:
- * token {String} The OAuth access token.
- * secret {String} The OAuth access token secret.
- * @param {XMLHttpRequest} xhr The XMLHttpRequest object used to fetch the
- * access token.
- */
-ChromeExOAuth.prototype.onAccessToken = function(callback, xhr) {
- if (xhr.readyState == 4) {
- var bg = chrome.extension.getBackgroundPage();
- if (xhr.status == 200) {
- var params = ChromeExOAuth.formDecode(xhr.responseText);
- var token = params["oauth_token"];
- var secret = params["oauth_token_secret"];
- this.setToken(token);
- this.setTokenSecret(secret);
- bg.chromeExOAuthRequestingAccess = false;
- callback(token, secret);
- } else {
- bg.chromeExOAuthRequestingAccess = false;
- throw new Error("Fetching access token failed with status " + xhr.status);
- }
- }
-};
\ No newline at end of file
diff --git a/chrome/common/extensions/docs/examples/extensions/oauth_contacts/chrome_ex_oauthsimple.js b/chrome/common/extensions/docs/examples/extensions/oauth_contacts/chrome_ex_oauthsimple.js
deleted file mode 100644
index af0fe8a..0000000
--- a/chrome/common/extensions/docs/examples/extensions/oauth_contacts/chrome_ex_oauthsimple.js
+++ /dev/null
@@ -1,458 +0,0 @@
-/* OAuthSimple
- * A simpler version of OAuth
- *
- * author: jr conlin
- * mail: src@anticipatr.com
- * copyright: unitedHeroes.net
- * version: 1.0
- * url: http://unitedHeroes.net/OAuthSimple
- *
- * Copyright (c) 2009, unitedHeroes.net
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of the unitedHeroes.net nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY UNITEDHEROES.NET ''AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL UNITEDHEROES.NET BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-var OAuthSimple;
-
-if (OAuthSimple === undefined)
-{
- /* Simple OAuth
- *
- * This class only builds the OAuth elements, it does not do the actual
- * transmission or reception of the tokens. It does not validate elements
- * of the token. It is for client use only.
- *
- * api_key is the API key, also known as the OAuth consumer key
- * shared_secret is the shared secret (duh).
- *
- * Both the api_key and shared_secret are generally provided by the site
- * offering OAuth services. You need to specify them at object creation
- * because nobody <explative>ing uses OAuth without that minimal set of
- * signatures.
- *
- * If you want to use the higher order security that comes from the
- * OAuth token (sorry, I don't provide the functions to fetch that because
- * sites aren't horribly consistent about how they offer that), you need to
- * pass those in either with .setTokensAndSecrets() or as an argument to the
- * .sign() or .getHeaderString() functions.
- *
- * Example:
- <code>
- var oauthObject = OAuthSimple().sign({path:'http://example.com/rest/',
- parameters: 'foo=bar&gorp=banana',
- signatures:{
- api_key:'12345abcd',
- shared_secret:'xyz-5309'
- }});
- document.getElementById('someLink').href=oauthObject.signed_url;
- </code>
- *
- * that will sign as a "GET" using "SHA1-MAC" the url. If you need more than
- * that, read on, McDuff.
- */
-
- /** OAuthSimple creator
- *
- * Create an instance of OAuthSimple
- *
- * @param api_key {string} The API Key (sometimes referred to as the consumer key) This value is usually supplied by the site you wish to use.
- * @param shared_secret (string) The shared secret. This value is also usually provided by the site you wish to use.
- */
- OAuthSimple = function (consumer_key,shared_secret)
- {
-/* if (api_key == undefined)
- throw("Missing argument: api_key (oauth_consumer_key) for OAuthSimple. This is usually provided by the hosting site.");
- if (shared_secret == undefined)
- throw("Missing argument: shared_secret (shared secret) for OAuthSimple. This is usually provided by the hosting site.");
-*/ this._secrets={};
- this._parameters={};
-
- // General configuration options.
- if (consumer_key !== undefined) {
- this._secrets['consumer_key'] = consumer_key;
- }
- if (shared_secret !== undefined) {
- this._secrets['shared_secret'] = shared_secret;
- }
- this._default_signature_method= "HMAC-SHA1";
- this._action = "GET";
- this._nonce_chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
-
-
- this.reset = function() {
- this._parameters={};
- this._path=undefined;
- return this;
- };
-
- /** set the parameters either from a hash or a string
- *
- * @param {string,object} List of parameters for the call, this can either be a URI string (e.g. "foo=bar&gorp=banana" or an object/hash)
- */
- this.setParameters = function (parameters) {
- if (parameters === undefined) {
- parameters = {};
- }
- if (typeof(parameters) == 'string') {
- parameters=this._parseParameterString(parameters);
- }
- this._parameters = parameters;
- if (this._parameters['oauth_nonce'] === undefined) {
- this._getNonce();
- }
- if (this._parameters['oauth_timestamp'] === undefined) {
- this._getTimestamp();
- }
- if (this._parameters['oauth_method'] === undefined) {
- this.setSignatureMethod();
- }
- if (this._parameters['oauth_consumer_key'] === undefined) {
- this._getApiKey();
- }
- if(this._parameters['oauth_token'] === undefined) {
- this._getAccessToken();
- }
-
- return this;
- };
-
- /** convienence method for setParameters
- *
- * @param parameters {string,object} See .setParameters
- */
- this.setQueryString = function (parameters) {
- return this.setParameters(parameters);
- };
-
- /** Set the target URL (does not include the parameters)
- *
- * @param path {string} the fully qualified URI (excluding query arguments) (e.g "http://example.org/foo")
- */
- this.setURL = function (path) {
- if (path == '') {
- throw ('No path specified for OAuthSimple.setURL');
- }
- this._path = path;
- return this;
- };
-
- /** convienence method for setURL
- *
- * @param path {string} see .setURL
- */
- this.setPath = function(path){
- return this.setURL(path);
- };
-
- /** set the "action" for the url, (e.g. GET,POST, DELETE, etc.)
- *
- * @param action {string} HTTP Action word.
- */
- this.setAction = function(action) {
- if (action === undefined) {
- action="GET";
- }
- action = action.toUpperCase();
- if (action.match('[^A-Z]')) {
- throw ('Invalid action specified for OAuthSimple.setAction');
- }
- this._action = action;
- return this;
- };
-
- /** set the signatures (as well as validate the ones you have)
- *
- * @param signatures {object} object/hash of the token/signature pairs {api_key:, shared_secret:, oauth_token: oauth_secret:}
- */
- this.setTokensAndSecrets = function(signatures) {
- if (signatures)
- {
- for (var i in signatures) {
- this._secrets[i] = signatures[i];
- }
- }
- // Aliases
- if (this._secrets['api_key']) {
- this._secrets.consumer_key = this._secrets.api_key;
- }
- if (this._secrets['access_token']) {
- this._secrets.oauth_token = this._secrets.access_token;
- }
- if (this._secrets['access_secret']) {
- this._secrets.oauth_secret = this._secrets.access_secret;
- }
- // Gauntlet
- if (this._secrets.consumer_key === undefined) {
- throw('Missing required consumer_key in OAuthSimple.setTokensAndSecrets');
- }
- if (this._secrets.shared_secret === undefined) {
- throw('Missing required shared_secret in OAuthSimple.setTokensAndSecrets');
- }
- if ((this._secrets.oauth_token !== undefined) && (this._secrets.oauth_secret === undefined)) {
- throw('Missing oauth_secret for supplied oauth_token in OAuthSimple.setTokensAndSecrets');
- }
- return this;
- };
-
- /** set the signature method (currently only Plaintext or SHA-MAC1)
- *
- * @param method {string} Method of signing the transaction (only PLAINTEXT and SHA-MAC1 allowed for now)
- */
- this.setSignatureMethod = function(method) {
- if (method === undefined) {
- method = this._default_signature_method;
- }
- //TODO: accept things other than PlainText or SHA-MAC1
- if (method.toUpperCase().match(/(PLAINTEXT|HMAC-SHA1)/) === undefined) {
- throw ('Unknown signing method specified for OAuthSimple.setSignatureMethod');
- }
- this._parameters['oauth_signature_method']= method.toUpperCase();
- return this;
- };
-
- /** sign the request
- *
- * note: all arguments are optional, provided you've set them using the
- * other helper functions.
- *
- * @param args {object} hash of arguments for the call
- * {action:, path:, parameters:, method:, signatures:}
- * all arguments are optional.
- */
- this.sign = function (args) {
- if (args === undefined) {
- args = {};
- }
- // Set any given parameters
- if(args['action'] !== undefined) {
- this.setAction(args['action']);
- }
- if (args['path'] !== undefined) {
- this.setPath(args['path']);
- }
- if (args['method'] !== undefined) {
- this.setSignatureMethod(args['method']);
- }
- this.setTokensAndSecrets(args['signatures']);
- if (args['parameters'] !== undefined){
- this.setParameters(args['parameters']);
- }
- // check the parameters
- var normParams = this._normalizedParameters();
- this._parameters['oauth_signature']=this._generateSignature(normParams);
- return {
- parameters: this._parameters,
- signature: this._oauthEscape(this._parameters['oauth_signature']),
- signed_url: this._path + '?' + this._normalizedParameters(),
- header: this.getHeaderString()
- };
- };
-
- /** Return a formatted "header" string
- *
- * NOTE: This doesn't set the "Authorization: " prefix, which is required.
- * I don't set it because various set header functions prefer different
- * ways to do that.
- *
- * @param args {object} see .sign
- */
- this.getHeaderString = function(args) {
- if (this._parameters['oauth_signature'] === undefined) {
- this.sign(args);
- }
-
- var result = 'OAuth ';
- for (var pName in this._parameters)
- {
- if (!pName.match(/^oauth/)) {
- continue;
- }
- if ((this._parameters[pName]) instanceof Array)
- {
- var pLength = this._parameters[pName].length;
- for (var j=0;j<pLength;j++)
- {
- result += pName +'="'+this._oauthEscape(this._parameters[pName][j])+'" ';
- }
- }
- else
- {
- result += pName + '="'+this._oauthEscape(this._parameters[pName])+'" ';
- }
- }
- return result;
- };
-
- // Start Private Methods.
-
- /** convert the parameter string into a hash of objects.
- *
- */
- this._parseParameterString = function(paramString){
- var elements = paramString.split('&');
- var result={};
- for(var element=elements.shift();element;element=elements.shift())
- {
- var keyToken=element.split('=');
- var value='';
- if (keyToken[1]) {
- value=decodeURIComponent(keyToken[1]);
- }
- if(result[keyToken[0]]){
- if (!(result[keyToken[0]] instanceof Array))
- {
- result[keyToken[0]] = Array(result[keyToken[0]],value);
- }
- else
- {
- result[keyToken[0]].push(value);
- }
- }
- else
- {
- result[keyToken[0]]=value;
- }
- }
- return result;
- };
-
- this._oauthEscape = function(string) {
- if (string === undefined) {
- return "";
- }
- if (string instanceof Array)
- {
- throw('Array passed to _oauthEscape');
- }
- return encodeURIComponent(string).replace(/\!/g, "%21").
- replace(/\*/g, "%2A").
- replace(/'/g, "%27").
- replace(/\(/g, "%28").
- replace(/\)/g, "%29");
- };
-
- this._getNonce = function (length) {
- if (length === undefined) {
- length=5;
- }
- var result = "";
- var cLength = this._nonce_chars.length;
- for (var i = 0; i < length;i++) {
- var rnum = Math.floor(Math.random() *cLength);
- result += this._nonce_chars.substring(rnum,rnum+1);
- }
- this._parameters['oauth_nonce']=result;
- return result;
- };
-
- this._getApiKey = function() {
- if (this._secrets.consumer_key === undefined) {
- throw('No consumer_key set for OAuthSimple.');
- }
- this._parameters['oauth_consumer_key']=this._secrets.consumer_key;
- return this._parameters.oauth_consumer_key;
- };
-
- this._getAccessToken = function() {
- if (this._secrets['oauth_secret'] === undefined) {
- return '';
- }
- if (this._secrets['oauth_token'] === undefined) {
- throw('No oauth_token (access_token) set for OAuthSimple.');
- }
- this._parameters['oauth_token'] = this._secrets.oauth_token;
- return this._parameters.oauth_token;
- };
-
- this._getTimestamp = function() {
- var d = new Date();
- var ts = Math.floor(d.getTime()/1000);
- this._parameters['oauth_timestamp'] = ts;
- return ts;
- };
-
- this.b64_hmac_sha1 = function(k,d,_p,_z){
- // heavily optimized and compressed version of http://pajhome.org.uk/crypt/md5/sha1.js
- // _p = b64pad, _z = character size; not used here but I left them available just in case
- if(!_p){_p='=';}if(!_z){_z=8;}function _f(t,b,c,d){if(t<20){return(b&c)|((~b)&d);}if(t<40){return b^c^d;}if(t<60){return(b&c)|(b&d)|(c&d);}return b^c^d;}function _k(t){return(t<20)?1518500249:(t<40)?1859775393:(t<60)?-1894007588:-899497514;}function _s(x,y){var l=(x&0xFFFF)+(y&0xFFFF),m=(x>>16)+(y>>16)+(l>>16);return(m<<16)|(l&0xFFFF);}function _r(n,c){return(n<<c)|(n>>>(32-c));}function _c(x,l){x[l>>5]|=0x80<<(24-l%32);x[((l+64>>9)<<4)+15]=l;var w=[80],a=1732584193,b=-271733879,c=-1732584194,d=271733878,e=-1009589776;for(var i=0;i<x.length;i+=16){var o=a,p=b,q=c,r=d,s=e;for(var j=0;j<80;j++){if(j<16){w[j]=x[i+j];}else{w[j]=_r(w[j-3]^w[j-8]^w[j-14]^w[j-16],1);}var t=_s(_s(_r(a,5),_f(j,b,c,d)),_s(_s(e,w[j]),_k(j)));e=d;d=c;c=_r(b,30);b=a;a=t;}a=_s(a,o);b=_s(b,p);c=_s(c,q);d=_s(d,r);e=_s(e,s);}return[a,b,c,d,e];}function _b(s){var b=[],m=(1<<_z)-1;for(var i=0;i<s.length*_z;i+=_z){b[i>>5]|=(s.charCodeAt(i/8)&m)<<(32-_z-i%32);}return b;}function _h(k,d){var b=_b(k);if(b.length>16){b=_c(b,k.length*_z);}var p=[16],o=[16];for(var i=0;i<16;i++){p[i]=b[i]^0x36363636;o[i]=b[i]^0x5C5C5C5C;}var h=_c(p.concat(_b(d)),512+d.length*_z);return _c(o.concat(h),512+160);}function _n(b){var t="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",s='';for(var i=0;i<b.length*4;i+=3){var r=(((b[i>>2]>>8*(3-i%4))&0xFF)<<16)|(((b[i+1>>2]>>8*(3-(i+1)%4))&0xFF)<<8)|((b[i+2>>2]>>8*(3-(i+2)%4))&0xFF);for(var j=0;j<4;j++){if(i*8+j*6>b.length*32){s+=_p;}else{s+=t.charAt((r>>6*(3-j))&0x3F);}}}return s;}function _x(k,d){return _n(_h(k,d));}return _x(k,d);
- }
-
-
- this._normalizedParameters = function() {
- var elements = new Array();
- var paramNames = [];
- var ra =0;
- for (var paramName in this._parameters)
- {
- if (ra++ > 1000) {
- throw('runaway 1');
- }
- paramNames.unshift(paramName);
- }
- paramNames = paramNames.sort();
- pLen = paramNames.length;
- for (var i=0;i<pLen; i++)
- {
- paramName=paramNames[i];
- //skip secrets.
- if (paramName.match(/\w+_secret/)) {
- continue;
- }
- if (this._parameters[paramName] instanceof Array)
- {
- var sorted = this._parameters[paramName].sort();
- var spLen = sorted.length;
- for (var j = 0;j<spLen;j++){
- if (ra++ > 1000) {
- throw('runaway 1');
- }
- elements.push(this._oauthEscape(paramName) + '=' +
- this._oauthEscape(sorted[j]));
- }
- continue;
- }
- elements.push(this._oauthEscape(paramName) + '=' +
- this._oauthEscape(this._parameters[paramName]));
- }
- return elements.join('&');
- };
-
- this._generateSignature = function() {
-
- var secretKey = this._oauthEscape(this._secrets.shared_secret)+'&'+
- this._oauthEscape(this._secrets.oauth_secret);
- if (this._parameters['oauth_signature_method'] == 'PLAINTEXT')
- {
- return secretKey;
- }
- if (this._parameters['oauth_signature_method'] == 'HMAC-SHA1')
- {
- var sigString = this._oauthEscape(this._action)+'&'+this._oauthEscape(this._path)+'&'+this._oauthEscape(this._normalizedParameters());
- return this.b64_hmac_sha1(secretKey,sigString);
- }
- return null;
- };
-
- return this;
- };
-}
diff --git a/chrome/common/extensions/docs/examples/extensions/oauth_contacts/contacts.html b/chrome/common/extensions/docs/examples/extensions/oauth_contacts/contacts.html
deleted file mode 100644
index 10f29e8..0000000
--- a/chrome/common/extensions/docs/examples/extensions/oauth_contacts/contacts.html
+++ /dev/null
@@ -1,29 +0,0 @@
-<!DOCTYPE html>
-<!--
- * 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>
- <title>Your Google Contacts List</title>
- <style type="text/css">
- body {
- font: 14px Arial;
- }
- p {
- font-weight: bold;
- }
- </style>
- </head>
- <body>
- <h1>Your Google Contacts List</h1>
- <h2>Listing the first 100 results of a standard query to
- <a href="http://code.google.com/apis/contacts/">Google's
- Contacts API</a></h2>
- <button id="clear">Click here to clear your OAuth token</button>
- <div id="output">
- </div>
- <script src="contacts.js"></script>
- </body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/extensions/oauth_contacts/contacts.js b/chrome/common/extensions/docs/examples/extensions/oauth_contacts/contacts.js
deleted file mode 100644
index 225cd9b..0000000
--- a/chrome/common/extensions/docs/examples/extensions/oauth_contacts/contacts.js
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright (c) 2012 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.
-
-var contacts = chrome.extension.getBackgroundPage().contacts;
-var output = document.getElementById('output');
-for (var i = 0, contact; contact = contacts[i]; i++) {
- var div = document.createElement('div');
- var pName = document.createElement('p');
- var ulEmails = document.createElement('ul');
-
- pName.innerText = contact['name'];
- div.appendChild(pName);
-
- for (var j = 0, email; email = contact['emails'][j]; j++) {
- var liEmail = document.createElement('li');
- liEmail.innerText = email;
- ulEmails.appendChild(liEmail);
- }
-
- div.appendChild(ulEmails);
- output.appendChild(div);
-}
-
-function logout() {
- chrome.extension.getBackgroundPage().logout();
- window.close();
-}
-
-document.addEventListener('DOMContentLoaded', function () {
- document.querySelector('#clear').addEventListener('click', logout);
-});
diff --git a/chrome/common/extensions/docs/examples/extensions/oauth_contacts/img/icon-128.png b/chrome/common/extensions/docs/examples/extensions/oauth_contacts/img/icon-128.png
deleted file mode 100644
index 8d0bc2f..0000000
--- a/chrome/common/extensions/docs/examples/extensions/oauth_contacts/img/icon-128.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/oauth_contacts/img/icon-19-off.png b/chrome/common/extensions/docs/examples/extensions/oauth_contacts/img/icon-19-off.png
deleted file mode 100644
index 06aae8a..0000000
--- a/chrome/common/extensions/docs/examples/extensions/oauth_contacts/img/icon-19-off.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/oauth_contacts/img/icon-19-on.png b/chrome/common/extensions/docs/examples/extensions/oauth_contacts/img/icon-19-on.png
deleted file mode 100644
index c1ba8a39..0000000
--- a/chrome/common/extensions/docs/examples/extensions/oauth_contacts/img/icon-19-on.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/oauth_contacts/img/icon-48.png b/chrome/common/extensions/docs/examples/extensions/oauth_contacts/img/icon-48.png
deleted file mode 100644
index bf2f4d4..0000000
--- a/chrome/common/extensions/docs/examples/extensions/oauth_contacts/img/icon-48.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/oauth_contacts/manifest.json b/chrome/common/extensions/docs/examples/extensions/oauth_contacts/manifest.json
deleted file mode 100644
index 5771b423..0000000
--- a/chrome/common/extensions/docs/examples/extensions/oauth_contacts/manifest.json
+++ /dev/null
@@ -1,26 +0,0 @@
-{
- "name": "Sample - OAuth Contacts",
- "version": "1.0.6",
- "icons": { "48": "img/icon-48.png",
- "128": "img/icon-128.png" },
- "description": "Uses OAuth to connect to Google's contacts service and display a list of your contacts.",
- "background": {
- "scripts": [
- "chrome_ex_oauthsimple.js",
- "chrome_ex_oauth.js",
- "background.js"
- ]
- },
- "browser_action": {
- "default_title": "",
- "default_icon": "img/icon-19-off.png"
- },
- "permissions": [
- "tabs",
- "http://www.google.com/m8/feeds/*",
- "https://www.google.com/accounts/OAuthGetRequestToken",
- "https://www.google.com/accounts/OAuthAuthorizeToken",
- "https://www.google.com/accounts/OAuthGetAccessToken"
- ],
- "manifest_version": 2
-}
diff --git a/chrome/common/extensions/docs/examples/extensions/oauth_contacts/onload.js b/chrome/common/extensions/docs/examples/extensions/oauth_contacts/onload.js
deleted file mode 100644
index 83ba522..0000000
--- a/chrome/common/extensions/docs/examples/extensions/oauth_contacts/onload.js
+++ /dev/null
@@ -1,7 +0,0 @@
-// Copyright (c) 2012 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.
-
-window.onload = function() {
- ChromeExOAuth.initCallbackPage();
-}
diff --git a/chrome/common/extensions/docs/examples/extensions/optional_permissions/images/optional_permissions128.png b/chrome/common/extensions/docs/examples/extensions/optional_permissions/images/optional_permissions128.png
deleted file mode 100644
index 8cf09db..0000000
--- a/chrome/common/extensions/docs/examples/extensions/optional_permissions/images/optional_permissions128.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/optional_permissions/images/optional_permissions16.png b/chrome/common/extensions/docs/examples/extensions/optional_permissions/images/optional_permissions16.png
deleted file mode 100644
index 5b9f847..0000000
--- a/chrome/common/extensions/docs/examples/extensions/optional_permissions/images/optional_permissions16.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/optional_permissions/images/optional_permissions32.png b/chrome/common/extensions/docs/examples/extensions/optional_permissions/images/optional_permissions32.png
deleted file mode 100644
index 99801964..0000000
--- a/chrome/common/extensions/docs/examples/extensions/optional_permissions/images/optional_permissions32.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/optional_permissions/images/optional_permissions48.png b/chrome/common/extensions/docs/examples/extensions/optional_permissions/images/optional_permissions48.png
deleted file mode 100644
index fa61a0e1..0000000
--- a/chrome/common/extensions/docs/examples/extensions/optional_permissions/images/optional_permissions48.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/optional_permissions/logic.js b/chrome/common/extensions/docs/examples/extensions/optional_permissions/logic.js
deleted file mode 100644
index 9c2b994..0000000
--- a/chrome/common/extensions/docs/examples/extensions/optional_permissions/logic.js
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright 2018 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.
-
-'use strict';
-
-const kPermissionObj = {
- permissions: ['topSites']
-};
-
-const sites_div = document.getElementById('display_top');
-
-const todo = document.getElementById('display_todo');
-
-const form = document.querySelector('form');
-
-const footer = document.querySelector('footer');
-
-function createTop(){chrome.topSites.get(function(topSites) {
- topSites.forEach(function(site) {
- let div = document.createElement('div');
- div.className = 'colorFun';
- let tooltip = document.createElement('span');
- tooltip.innerText = site.title;
- tooltip.className = 'tooltip';
- let url = document.createElement('a');
- url.href = site.url;
- let hostname = (new URL(site.url)).hostname;
- let image = document.createElement('img');
- image.title = site.title;
- image.src = 'https://logo.clearbit.com/' + hostname;
- url.appendChild(image);
- div.appendChild(url);
- div.appendChild(tooltip);
- sites_div.appendChild(div);
- })
-})};
-
-chrome.permissions.contains({permissions: ['topSites']}, function(result) {
- if (result) {
- // The extension has the permissions.
- createTop();
- } else {
- // The extension doesn't have the permissions.
- let button = document.createElement('button');
- button.innerText = 'Allow Extension to Access Top Sites';
- button.addEventListener('click', function() {
- chrome.permissions.request(kPermissionObj, function(granted) {
- if (granted) {
- console.log('granted');
- sites_div.innerText = '';
- createTop();
- } else {
- console.log('not granted');
- }
- });
- });
- footer.appendChild(button);
- }
-});
-
-form.addEventListener('submit', function() {
- let todo_value = document.getElementById('todo_value');
- chrome.storage.sync.set({todo: todo_value.value});
-});
-
-function setToDo() {
- chrome.storage.sync.get(['todo'], function(value) {
- if (!value.todo) {
- todo.innerText = '';
- } else {
- todo.innerText = value.todo;
- }
- });
-};
-
-setToDo();
diff --git a/chrome/common/extensions/docs/examples/extensions/optional_permissions/manifest.json b/chrome/common/extensions/docs/examples/extensions/optional_permissions/manifest.json
deleted file mode 100644
index ac62ef2d..0000000
--- a/chrome/common/extensions/docs/examples/extensions/optional_permissions/manifest.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- "name": "Optional Permissions New Tab",
- "version": "1.2.5.0",
- "description": "Demonstrates optional permissions in extensions",
- "permissions": ["storage"],
- "optional_permissions": [
- "topSites"
- ],
- "icons": {
- "16": "images/optional_permissions16.png",
- "32": "images/optional_permissions32.png",
- "48": "images/optional_permissions48.png",
- "128": "images/optional_permissions128.png"
- },
- "chrome_url_overrides": {
- "newtab": "newtab.html"
- },
- "manifest_version": 2
-}
diff --git a/chrome/common/extensions/docs/examples/extensions/optional_permissions/newtab.html b/chrome/common/extensions/docs/examples/extensions/optional_permissions/newtab.html
deleted file mode 100644
index 483d1c9..0000000
--- a/chrome/common/extensions/docs/examples/extensions/optional_permissions/newtab.html
+++ /dev/null
@@ -1,20 +0,0 @@
-<!DOCTYPE html>
-<html>
- <head>
- <meta charset="UTF-8">
- <title>New Tab - Optional Permissions</title>
- <link rel="stylesheet" type="text/css" href="style.css">
- </head>
- <body>
- <div id="todo_div" class="center colorFun">
- <h1 id="display_todo"></h1>
- </div>
- <div id="display_top"></div>
- <form class="center">
- <input id="todo_value" placeholder="My focus today is..." />
- <input type="submit" value="Submit">
- </form>
- <footer></footer>
- <script src="logic.js"></script>
- </body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/extensions/optional_permissions/style.css b/chrome/common/extensions/docs/examples/extensions/optional_permissions/style.css
deleted file mode 100644
index 2c94874..0000000
--- a/chrome/common/extensions/docs/examples/extensions/optional_permissions/style.css
+++ /dev/null
@@ -1,80 +0,0 @@
-/* Copyright 2018 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.*/
-
-h1 {
- font-family: "Courier New", Courier, monospaces;
-}
-
-#display_top {
- margin: auto;
- width: 600px;
-}
-
-#todo_div {
- margin-top: 0px;
- height: 100px;
- width: 100%;
- display: flex;
- align-items: center;
- justify-content: center;
-}
-
-.center {
- display: flex;
- align-items: center;
- justify-content: center;
-}
-
-@keyframes color-extravaganza {
- 0% {background-color: #4285F4;}
- 10% {background-color: #4285F4;}
- 25% {background-color: #EA4335;}
- 50% {background-color: #FBBC04;}
- 100% {background-color: #34A853;}
-}
-
-.colorFun {
- position: relative;
- height: 100px;
- width: 100px;
- padding: 10px;
- display: inline-block;
- margin-top: 60px;
-}
-
-.colorFun .tooltip {
- visibility: hidden;
- width: 120px;
- color: #fff;
- text-align: center;
- padding: 5px 0;
- border-radius: 6px;
- position: absolute;
- z-index: 1;
- bottom: 0%;
- left: 50%;
- margin-left: -60px;
- opacity: 0;
- transition: opacity 0.3s;
-}
-
-
-#todo_div, .colorFun:hover .tooltip {
- visibility: visible;
- opacity: 1;
- animation-name: color-extravaganza;
- animation-duration: 6s;
- animation-iteration-count: infinite;
- animation-direction: alternate;
-}
-
-img {
- width: 100px;
-}
-
-footer {
- position: absolute;
- bottom: 20px;
- left: 20px;
-}
diff --git a/chrome/common/extensions/docs/examples/extensions/plugin_settings/_locales/en/messages.json b/chrome/common/extensions/docs/examples/extensions/plugin_settings/_locales/en/messages.json
deleted file mode 100644
index f2bd7f5..0000000
--- a/chrome/common/extensions/docs/examples/extensions/plugin_settings/_locales/en/messages.json
+++ /dev/null
@@ -1,23 +0,0 @@
-{
- "extName": {
- "message": "Per-plugin content settings"
- },
- "extDescription": {
- "message": "Customize your content setting for different plugins."
- },
- "patternColumnHeader": {
- "message": "Hostname Pattern"
- },
- "settingColumnHeader": {
- "message": "Behavior"
- },
- "allowRule": {
- "message": "Allow"
- },
- "blockRule": {
- "message": "Block"
- },
- "addNewPattern": {
- "message": "Add a new hostname pattern"
- }
-}
\ No newline at end of file
diff --git a/chrome/common/extensions/docs/examples/extensions/plugin_settings/bunny128.png b/chrome/common/extensions/docs/examples/extensions/plugin_settings/bunny128.png
deleted file mode 100644
index 06e4668..0000000
--- a/chrome/common/extensions/docs/examples/extensions/plugin_settings/bunny128.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/plugin_settings/bunny48.png b/chrome/common/extensions/docs/examples/extensions/plugin_settings/bunny48.png
deleted file mode 100644
index 09ce0e4c9..0000000
--- a/chrome/common/extensions/docs/examples/extensions/plugin_settings/bunny48.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/plugin_settings/css/plugin_list.css b/chrome/common/extensions/docs/examples/extensions/plugin_settings/css/plugin_list.css
deleted file mode 100644
index acb72a76..0000000
--- a/chrome/common/extensions/docs/examples/extensions/plugin_settings/css/plugin_list.css
+++ /dev/null
@@ -1,83 +0,0 @@
-/* Copyright (c) 2011 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. */
-
-body {
- font-family: Helvetica, sans-serif;
- background-color: white;
- color: black;
- margin: 10px;
-}
-
-.plugin-list {
- border: 1px solid #d9d9d9;
- border-radius: 2px;
- width: 517px;
-}
-
-.plugin-list > li {
- padding: 3px;
-}
-
-.plugin-name {
- display: inline-block;
- overflow: hidden;
- text-overflow: ellipsis;
- font-weight: bold;
-}
-
-.num-rules:before {
- content: ' ';
-}
-
-.plugin-show-details .num-rules {
- display: none;
-}
-
-.plugin-description {
- display: inline-block;
- padding-inline-start: 7px;
- width: auto;
- overflow: hidden;
- text-overflow: ellipsis;
- font-size: 95%;
-}
-
-.plugin-details {
- background: #f5f8f8;
- border: 1px solid #b2b2b2;
- border-radius: 5px;
- padding: 5px;
- height: 0;
- width: 500px;
- opacity: 0;
- transition: height .5s ease-in-out;
-}
-
-.plugin-measure-details .plugin-details {
- height: auto;
- transition: none;
- visibility: hidden;
-}
-
-li.plugin-show-details {
- height: auto;
-}
-
-.plugin-show-details .plugin-description {
- height: auto;
-}
-
-.plugin-show-details .plugin-details {
- opacity: 1;
- height: auto;
-}
-
-.column-headers {
- display: -webkit-box;
- margin-inline-start: 17px;
-}
-
-.column-headers > div {
- font-weight: bold;
-}
diff --git a/chrome/common/extensions/docs/examples/extensions/plugin_settings/css/rule_list.css b/chrome/common/extensions/docs/examples/extensions/plugin_settings/css/rule_list.css
deleted file mode 100644
index 2d6c9c1e..0000000
--- a/chrome/common/extensions/docs/examples/extensions/plugin_settings/css/rule_list.css
+++ /dev/null
@@ -1,31 +0,0 @@
-/* Copyright (c) 2011 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. */
-
-.rule-pattern {
- -webkit-box-flex: 1;
- margin-inline-end: 10px;
- margin-inline-start: 14px;
-}
-
-.rule-behavior {
- display: inline-block;
- width: 120px;
-}
-
-select.rule-behavior {
- vertical-align: middle;
-}
-
-.rule-list {
- border: 1px solid #d9d9d9;
- border-radius: 2px;
-}
-
-.pattern-column-header {
- -webkit-box-flex: 1;
-}
-
-.setting-column-header {
- width: 145px;
-}
diff --git a/chrome/common/extensions/docs/examples/extensions/plugin_settings/domui/css/button.css b/chrome/common/extensions/docs/examples/extensions/plugin_settings/domui/css/button.css
deleted file mode 100644
index 5564f42..0000000
--- a/chrome/common/extensions/docs/examples/extensions/plugin_settings/domui/css/button.css
+++ /dev/null
@@ -1,43 +0,0 @@
-button,
-input[type='button'],
-input[type='submit'] {
- -webkit-border-radius: 2px;
- -webkit-box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.1);
- -webkit-user-select: none;
- background: -webkit-linear-gradient(#fafafa, #f4f4f4 40%, #e5e5e5);
- border: 1px solid #aaa;
- color: #444;
- font-size: inherit;
- margin-bottom: 0px;
- min-width: 4em;
- padding: 3px 12px 3px 12px;
-}
-
-button:hover,
-input[type='button']:hover,
-input[type='submit']:hover {
- -webkit-box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.2);
- background: #ebebeb -webkit-linear-gradient(#fefefe, #f8f8f8 40%, #e9e9e9);
- border-color: #999;
- color: #222;
-}
-
-button:active,
-input[type='button']:active,
-input[type='submit']:active {
- -webkit-box-shadow: inset 0px 1px 3px rgba(0, 0, 0, 0.2);
- background: #ebebeb -webkit-linear-gradient(#f4f4f4, #efefef 40%, #dcdcdc);
- color: #333;
-}
-
-button[disabled],
-input[type='button'][disabled],
-input[type='submit'][disabled],
-button[disabled]:hover,
-input[type='button'][disabled]:hover,
-input[type='submit'][disabled]:hover {
- -webkit-box-shadow: none;
- background: -webkit-linear-gradient(#fafafa, #f4f4f4 40%, #e5e5e5);
- border-color: #aaa;
- color: #888;
-}
diff --git a/chrome/common/extensions/docs/examples/extensions/plugin_settings/domui/css/chrome_shared.css b/chrome/common/extensions/docs/examples/extensions/plugin_settings/domui/css/chrome_shared.css
deleted file mode 100644
index dac22eb..0000000
--- a/chrome/common/extensions/docs/examples/extensions/plugin_settings/domui/css/chrome_shared.css
+++ /dev/null
@@ -1,261 +0,0 @@
-/* Copyright (c) 2011 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. */
-
-/* Styles common to WebUI pages that share the options pages style */
-body {
- cursor: default;
- font-size: 13px;
-}
-
-a:link {
- color: rgb(63, 110, 194);
-}
-
-a:active {
- color: rgb(37, 64, 113);
-}
-
-#navbar-content-title {
- -webkit-user-select: none;
- color: #53637d;
- cursor: pointer;
- font-size: 200%;
- font-weight: normal;
- margin: 0;
- padding-bottom: 14px;
- padding-inline-end: 24px;
- padding-top: 13px;
- text-align: end;
- text-shadow: white 0 1px 2px;
-}
-
-#main-content {
- display: -webkit-box;
- position: absolute;
- left: 0;
- right: 0;
- top: 0;
- bottom: 0;
-}
-
-#navbar {
- margin: 0;
-}
-
-#navbar-container {
- background: -webkit-linear-gradient(rgba(234, 238, 243, 0.2), #eaeef3),
- -webkit-linear-gradient(left, #eaeef3, #eaeef3 97%, #d3d7db);
- border-inline-end: 1px solid #c6c9ce;
- position: fixed;
- bottom: 0;
- /* We set both left and right for the sake of RTL. */
- left: 0;
- right: 0;
- top: 0;
- width: 216px;
- z-index: 2;
-}
-
-html[dir='rtl'] #navbar-container {
- background: -webkit-linear-gradient(rgba(234, 238, 243, 0), #EAEEF3),
- -webkit-linear-gradient(right, #EAEEF3, #EAEEF3 97%, #D3D7DB);
-}
-
-html.hide-menu #navbar-container {
- display: none;
-}
-
-#navbar-container > ul {
- -webkit-user-select: none;
- list-style-type: none;
- margin: 0;
- padding: 0;
-}
-
-.navbar-item {
- border-bottom: 1px solid transparent;
- border-top: 1px solid transparent;
- color: #426dc9;
- cursor: pointer;
- display: block;
- font-size: 105%;
- outline: none;
- padding: 7px 0;
- padding-inline-end: 24px;
- text-align: end;
- text-shadow: white 0 1px 1px;
-}
-
-.navbar-item:focus {
- border-bottom: 1px solid #8faad9;
- border-top: 1px solid #8faad9;
-}
-
-.navbar-item-selected {
- -webkit-box-shadow: 0px 1px 0px #f7f7f7;
- background: -webkit-linear-gradient(left, #bbcee9, #bbcee9 97%, #aabedc);
- border-bottom: 1px solid #8faad9;
- border-top: 1px solid #8faad9;
- color: black;
- text-shadow: #bbcee9 0 1px 1px;
-}
-
-#mainview {
- -webkit-box-align: stretch;
- margin: 0;
- position: absolute;
- left: 0;
- padding-inline-start: 216px;
- right: 0;
- top: 0;
- bottom: 0;
- z-index: 1;
-}
-
-html.hide-menu #mainview {
- padding-inline-start: 0;
-}
-
-#mainview-content {
- min-height: 100%;
- position: relative;
-}
-
-#page-container {
- box-sizing: border-box;
- max-width: 888px;
- min-width: 600px;
- padding: 0 24px;
-}
-
-div.checkbox,
-div.radio {
- margin: 5px 0;
- color: #444;
-}
-
-div.disabled {
- color: #888;
-}
-
-/* TEXT */
-input[type='password'],
-input[type='text'],
-input[type='url'],
-input:not([type]) {
- -webkit-border-radius: 2px;
- border: 1px solid #aaa;
- font-size: inherit;
- padding: 3px;
-}
-
-/* CHECKBOX, RADIO */
-input[type=checkbox],
-input[type=radio] {
- margin-left: 0;
- margin-right: 0;
- position: relative;
- top: 1px;
-}
-
-/* Checkbox and radio buttons have different sizes on different platforms. The
- * following rules have platform specific tweaks.
- * TODO(arv): Test the vertical position on Linux and CrOS as well.
- */
-
-label > input[type=checkbox],
-label > input[type=radio] {
- opacity: 0.7;
- margin-top: 1px;
-}
-
-html[os=mac] label > input[type=checkbox],
-html[os=mac] label > input[type=radio] {
- margin-top: 2px;
-}
-
-html[os=chromeos] label > input[type=checkbox],
-html[os=chromeos] label > input[type=radio] {
- top: 2px;
-}
-
-/* Checkbox and radio hover visuals.
- * Their appearance when checked is set to be the same.
- */
-label:hover > input[type=checkbox]:not([disabled]),
-label:hover > input[type=radio]:not([disabled]),
-label > input:not([disabled]):checked {
- opacity: 1;
-}
-
-label:hover > input[type=checkbox]:not([disabled]) ~ span,
-label:hover > input[type=radio]:not([disabled]) ~ span,
-label > input:not([disabled]):checked ~ span {
- color: #222;
-}
-
-/* This will 'disable' the label associated with any input whose next sibling is
- * the span containing the label (usually a checkbox or radio).
- */
-label > input[disabled] ~ span {
- color: #888;
-}
-
-/* Elements that need to be LTR even in an RTL context, but should align
- * right. (Namely, URLs, search engine names, etc.)
- */
-html[dir='rtl'] .weakrtl {
- direction: ltr;
- text-align: right;
-}
-
-/* Input fields in search engine table need to be weak-rtl. Since those input
- * fields are generated for all cr.ListItem elements (and we only want weakrtl
- * on some), the class needs to be on the enclosing div.
- */
-html[dir='rtl'] div.weakrtl input {
- direction: ltr;
- text-align: right;
-}
-
-html[dir='rtl'] .favicon-cell.weakrtl {
- padding-inline-end: 22px;
- padding-inline-start: 0;
-}
-
-/* weakrtl for selection drop downs needs to account for the fact that
- * Webkit does not honor the text-align attribute for the select element.
- * (See Webkit bug #40216)
- */
-html[dir='rtl'] select.weakrtl {
- direction: rtl;
-}
-
-html[dir='rtl'] select.weakrtl option {
- direction: ltr;
-}
-
-/* WebKit does not honor alignment for text specified via placeholder attrib.
- * This CSS is a workaround. Please remove once WebKit bug is fixed.
- * https://bugs.webkit.org/show_bug.cgi?id=63367
- */
-html[dir='rtl'] input.weakrtl::-webkit-input-placeholder,
-html[dir='rtl'] .weakrtl input::-webkit-input-placeholder {
- direction: rtl;
-}
-
-.page h1 {
- -webkit-user-select: none;
- border-bottom: 1px solid #eeeeee;
- color: #53637d;
- font-size: 200%;
- font-weight: normal;
- margin: 0;
- padding-bottom: 4px;
- padding-inline-end: 24px;
- padding-top: 13px;
- text-shadow: white 0 1px 2px;
-}
-
-
diff --git a/chrome/common/extensions/docs/examples/extensions/plugin_settings/domui/css/list.css b/chrome/common/extensions/docs/examples/extensions/plugin_settings/domui/css/list.css
deleted file mode 100644
index 75d2a92..0000000
--- a/chrome/common/extensions/docs/examples/extensions/plugin_settings/domui/css/list.css
+++ /dev/null
@@ -1,89 +0,0 @@
-
-list,
-grid {
- display: block;
- outline: none;
- overflow: auto;
- position: relative; /* Make sure that item offsets are relative to the
- list. */
-}
-
-list > *,
-grid > * {
- -webkit-user-select: none;
- background-color: rgba(255,255,255,0);
- border: 1px solid rgba(255,255,255,0); /* transparent white */
- border-radius: 2px;
- cursor: default;
- line-height: 20px;
- margin: -1px 0;
- overflow: hidden;
- padding: 0px 3px;
- position: relative; /* to allow overlap */
- text-overflow: ellipsis;
- white-space: pre;
-}
-
-list > * {
- display: block;
-}
-
-grid > * {
- display: inline-block;
-}
-
-list > [lead],
-grid > [lead] {
- border-color: transparent;
-}
-
-list:focus > [lead],
-grid:focus > [lead] {
- border-color: hsl(214, 91%, 65%);
- z-index: 2;
-}
-
-list > [anchor],
-grid > [anchor] {
-
-}
-
-list:not([disabled]) > :hover,
-grid:not([disabled]) > :hover {
- border-color: hsl(214, 91%, 85%);
- z-index: 1;
- background-color: hsl(214, 91%, 97%);
-}
-
-list > [selected],
-grid > [selected] {
- border-color: hsl(0, 0%, 85%);
- background-color: hsl(0,0%,90%);
- z-index: 2;
- background-image: -webkit-linear-gradient(rgba(255, 255, 255, 0.8),
- rgba(255, 255, 255, 0));
-}
-
-list:focus > [selected],
-grid:focus > [selected] {
- background-color: hsl(214,91%,89%);
- border-color: hsl(214, 91%, 65%);
-}
-
-list:focus > [lead][selected],
-list > [selected]:hover,
-grid:focus > [lead][selected],
-grid > [selected]:hover {
- background-color: hsl(214, 91%, 87%);
- border-color: hsl(214, 91%, 65%);
-}
-
-list > .spacer,
-grid > .spacer {
- border: 0;
- box-sizing: border-box;
- display: block;
- overflow: hidden;
- visibility: hidden;
- margin: 0;
-}
diff --git a/chrome/common/extensions/docs/examples/extensions/plugin_settings/domui/css/select.css b/chrome/common/extensions/docs/examples/extensions/plugin_settings/domui/css/select.css
deleted file mode 100644
index 24de2aaf..0000000
--- a/chrome/common/extensions/docs/examples/extensions/plugin_settings/domui/css/select.css
+++ /dev/null
@@ -1,51 +0,0 @@
-/* Copyright (c) 2011 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.
- *
- * This is the generic select css used on various WebUI implementations.
- */
-
-select {
- -webkit-appearance: button;
- -webkit-border-radius: 2px;
- -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
- -webkit-user-select: none;
- background-image: url("../images/select.png"),
- -webkit-linear-gradient(#fafafa, #f4f4f4 40%, #e5e5e5);
- background-position: center right;
- background-repeat: no-repeat;
- border: 1px solid #aaa;
- color: #555;
- font-size: inherit;
- margin: 0;
- overflow: hidden;
- padding-top: 2px;
- padding-inline-end: 20px;
- padding-inline-start: 2px;
- padding-bottom: 2px;
- text-overflow: ellipsis;
- white-space: nowrap;
-}
-
-html[dir='rtl'] select {
- background-position: center left;
-}
-
-
-select:disabled {
- color: graytext;
-}
-
-select:enabled:hover {
- -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
- background-image: url("../images/select.png"),
- -webkit-linear-gradient(#fefefe, #f8f8f8 40%, #e9e9e9);
- color: #333;
-}
-
-select:enabled:active {
- -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.2);
- background-image: url("../images/select.png"),
- -webkit-linear-gradient(#f4f4f4, #efefef 40%, #dcdcdc);
- color: #444;
-}
\ No newline at end of file
diff --git a/chrome/common/extensions/docs/examples/extensions/plugin_settings/domui/images/select.png b/chrome/common/extensions/docs/examples/extensions/plugin_settings/domui/images/select.png
deleted file mode 100644
index d5dcea3..0000000
--- a/chrome/common/extensions/docs/examples/extensions/plugin_settings/domui/images/select.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/plugin_settings/domui/js/cr.js b/chrome/common/extensions/docs/examples/extensions/plugin_settings/domui/js/cr.js
deleted file mode 100644
index a1d84ab..0000000
--- a/chrome/common/extensions/docs/examples/extensions/plugin_settings/domui/js/cr.js
+++ /dev/null
@@ -1,334 +0,0 @@
-// Copyright (c) 2011 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.
-
-const cr = (function() {
-
- /**
- * Whether we are using a Mac or not.
- * @type {boolean}
- */
- const isMac = /Mac/.test(navigator.platform);
-
- /**
- * Whether this is on the Windows platform or not.
- * @type {boolean}
- */
- const isWindows = /Win/.test(navigator.platform);
-
- /**
- * Whether this is on chromeOS or not.
- * @type {boolean}
- */
- const isChromeOS = /CrOS/.test(navigator.userAgent);
-
- /**
- * Whether this is on vanilla Linux (not chromeOS).
- * @type {boolean}
- */
- const isLinux = /Linux/.test(navigator.userAgent);
-
- /**
- * Sets the os and toolkit attributes in the <html> element so that platform
- * specific css rules can be applied.
- */
- function enablePlatformSpecificCSSRules() {
- if (isMac)
- doc.documentElement.setAttribute('os', 'mac');
- if (isWindows)
- doc.documentElement.setAttribute('os', 'windows');
- if (isChromeOS)
- doc.documentElement.setAttribute('os', 'chromeos');
- if (isLinux)
- doc.documentElement.setAttribute('os', 'linux');
- }
-
- /**
- * Builds an object structure for the provided namespace path,
- * ensuring that names that already exist are not overwritten. For
- * example:
- * "a.b.c" -> a = {};a.b={};a.b.c={};
- * @param {string} name Name of the object that this file defines.
- * @param {*=} opt_object The object to expose at the end of the path.
- * @param {Object=} opt_objectToExportTo The object to add the path to;
- * default is {@code window}.
- * @private
- */
- function exportPath(name, opt_object, opt_objectToExportTo) {
- var parts = name.split('.');
- var cur = opt_objectToExportTo || window /* global */;
-
- for (var part; parts.length && (part = parts.shift());) {
- if (!parts.length && opt_object !== undefined) {
- // last part and we have an object; use it
- cur[part] = opt_object;
- } else if (part in cur) {
- cur = cur[part];
- } else {
- cur = cur[part] = {};
- }
- }
- return cur;
- };
-
- /**
- * Fires a property change event on the target.
- * @param {EventTarget} target The target to dispatch the event on.
- * @param {string} propertyName The name of the property that changed.
- * @param {*} newValue The new value for the property.
- * @param {*} oldValue The old value for the property.
- */
- function dispatchPropertyChange(target, propertyName, newValue, oldValue) {
- var e = new CrEvent(propertyName + 'Change');
- e.propertyName = propertyName;
- e.newValue = newValue;
- e.oldValue = oldValue;
- target.dispatchEvent(e);
- }
-
- /**
- * The kind of property to define in {@code defineProperty}.
- * @enum {number}
- */
- const PropertyKind = {
- /**
- * Plain old JS property where the backing data is stored as a "private"
- * field on the object.
- */
- JS: 'js',
-
- /**
- * The property backing data is stored as an attribute on an element.
- */
- ATTR: 'attr',
-
- /**
- * The property backing data is stored as an attribute on an element. If the
- * element has the attribute then the value is true.
- */
- BOOL_ATTR: 'boolAttr'
- };
-
- /**
- * Helper function for defineProperty that returns the getter to use for the
- * property.
- * @param {string} name
- * @param {cr.PropertyKind} kind
- * @return {function():*} The getter for the property.
- */
- function getGetter(name, kind) {
- switch (kind) {
- case PropertyKind.JS:
- var privateName = name + '_';
- return function() {
- return this[privateName];
- };
- case PropertyKind.ATTR:
- return function() {
- return this.getAttribute(name);
- };
- case PropertyKind.BOOL_ATTR:
- return function() {
- return this.hasAttribute(name);
- };
- }
- }
-
- /**
- * Helper function for defineProperty that returns the setter of the right
- * kind.
- * @param {string} name The name of the property we are defining the setter
- * for.
- * @param {cr.PropertyKind} kind The kind of property we are getting the
- * setter for.
- * @param {function(*):void} opt_setHook A function to run after the property
- * is set, but before the propertyChange event is fired.
- * @return {function(*):void} The function to use as a setter.
- */
- function getSetter(name, kind, opt_setHook) {
- switch (kind) {
- case PropertyKind.JS:
- var privateName = name + '_';
- return function(value) {
- var oldValue = this[privateName];
- if (value !== oldValue) {
- this[privateName] = value;
- if (opt_setHook)
- opt_setHook.call(this, value, oldValue);
- dispatchPropertyChange(this, name, value, oldValue);
- }
- };
-
- case PropertyKind.ATTR:
- return function(value) {
- var oldValue = this[name];
- if (value !== oldValue) {
- if (value == undefined)
- this.removeAttribute(name);
- else
- this.setAttribute(name, value);
- if (opt_setHook)
- opt_setHook.call(this, value, oldValue);
- dispatchPropertyChange(this, name, value, oldValue);
- }
- };
-
- case PropertyKind.BOOL_ATTR:
- return function(value) {
- var oldValue = this[name];
- if (value !== oldValue) {
- if (value)
- this.setAttribute(name, name);
- else
- this.removeAttribute(name);
- if (opt_setHook)
- opt_setHook.call(this, value, oldValue);
- dispatchPropertyChange(this, name, value, oldValue);
- }
- };
- }
- }
-
- /**
- * Defines a property on an object. When the setter changes the value a
- * property change event with the type {@code name + 'Change'} is fired.
- * @param {!Object} obj The object to define the property for.
- * @param {string} name The name of the property.
- * @param {cr.PropertyKind=} opt_kind What kind of underlying storage to use.
- * @param {function(*):void} opt_setHook A function to run after the
- * property is set, but before the propertyChange event is fired.
- */
- function defineProperty(obj, name, opt_kind, opt_setHook) {
- if (typeof obj == 'function')
- obj = obj.prototype;
-
- var kind = opt_kind || PropertyKind.JS;
-
- if (!obj.__lookupGetter__(name)) {
- obj.__defineGetter__(name, getGetter(name, kind));
- }
-
- if (!obj.__lookupSetter__(name)) {
- obj.__defineSetter__(name, getSetter(name, kind, opt_setHook));
- }
- }
-
- /**
- * Counter for use with createUid
- */
- var uidCounter = 1;
-
- /**
- * @return {number} A new unique ID.
- */
- function createUid() {
- return uidCounter++;
- }
-
- /**
- * Returns a unique ID for the item. This mutates the item so it needs to be
- * an object
- * @param {!Object} item The item to get the unique ID for.
- * @return {number} The unique ID for the item.
- */
- function getUid(item) {
- if (item.hasOwnProperty('uid'))
- return item.uid;
- return item.uid = createUid();
- }
-
- /**
- * Dispatches a simple event on an event target.
- * @param {!EventTarget} target The event target to dispatch the event on.
- * @param {string} type The type of the event.
- * @param {boolean=} opt_bubbles Whether the event bubbles or not.
- * @param {boolean=} opt_cancelable Whether the default action of the event
- * can be prevented. Default is true.
- * @return {boolean} If any of the listeners called {@code preventDefault}
- * during the dispatch this will return false.
- */
- function dispatchSimpleEvent(target, type, opt_bubbles, opt_cancelable) {
- var e = new Event(type, {
- bubbles: opt_bubbles,
- cancelable: opt_cancelable === undefined || opt_cancelable
- });
- return target.dispatchEvent(e);
- }
-
- /**
- * @param {string} name
- * @param {!Function} fun
- */
- function define(name, fun) {
- var obj = exportPath(name);
- var exports = fun();
- for (var propertyName in exports) {
- // Maybe we should check the prototype chain here? The current usage
- // pattern is always using an object literal so we only care about own
- // properties.
- var propertyDescriptor = Object.getOwnPropertyDescriptor(exports,
- propertyName);
- if (propertyDescriptor)
- Object.defineProperty(obj, propertyName, propertyDescriptor);
- }
- }
-
- /**
- * Document used for various document related operations.
- * @type {!Document}
- */
- var doc = document;
-
-
- /**
- * Allows you to run func in the context of a different document.
- * @param {!Document} document The document to use.
- * @param {function():*} func The function to call.
- */
- function withDoc(document, func) {
- var oldDoc = doc;
- doc = document;
- try {
- func();
- } finally {
- doc = oldDoc;
- }
- }
-
- /**
- * Adds a {@code getInstance} static method that always return the same
- * instance object.
- * @param {!Function} ctor The constructor for the class to add the static
- * method to.
- */
- function addSingletonGetter(ctor) {
- ctor.getInstance = function() {
- return ctor.instance_ || (ctor.instance_ = new ctor());
- };
- }
-
- return {
- addSingletonGetter: addSingletonGetter,
- isChromeOS: isChromeOS,
- isMac: isMac,
- isWindows: isWindows,
- isLinux: isLinux,
- enablePlatformSpecificCSSRules: enablePlatformSpecificCSSRules,
- define: define,
- defineProperty: defineProperty,
- PropertyKind: PropertyKind,
- createUid: createUid,
- getUid: getUid,
- dispatchSimpleEvent: dispatchSimpleEvent,
- dispatchPropertyChange: dispatchPropertyChange,
-
- /**
- * The document that we are currently using.
- * @type {!Document}
- */
- get doc() {
- return doc;
- },
- withDoc: withDoc
- };
-})();
diff --git a/chrome/common/extensions/docs/examples/extensions/plugin_settings/domui/js/cr/event_target.js b/chrome/common/extensions/docs/examples/extensions/plugin_settings/domui/js/cr/event_target.js
deleted file mode 100644
index 5bcb41d..0000000
--- a/chrome/common/extensions/docs/examples/extensions/plugin_settings/domui/js/cr/event_target.js
+++ /dev/null
@@ -1,104 +0,0 @@
-// Copyright (c) 2010 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.
-
-/**
- * @fileoverview This contains an implementation of the EventTarget interface
- * as defined by DOM Level 2 Events.
- */
-
-cr.define('cr', function() {
-
- /**
- * Creates a new EventTarget. This class implements the DOM level 2
- * EventTarget interface and can be used wherever those are used.
- * @constructor
- */
- function EventTarget() {
- }
-
- EventTarget.prototype = {
-
- /**
- * Adds an event listener to the target.
- * @param {string} type The name of the event.
- * @param {!Function|{handleEvent:Function}} handler The handler for the
- * event. This is called when the event is dispatched.
- */
- addEventListener: function(type, handler) {
- if (!this.listeners_)
- this.listeners_ = Object.create(null);
- if (!(type in this.listeners_)) {
- this.listeners_[type] = [handler];
- } else {
- var handlers = this.listeners_[type];
- if (handlers.indexOf(handler) < 0)
- handlers.push(handler);
- }
- },
-
- /**
- * Removes an event listener from the target.
- * @param {string} type The name of the event.
- * @param {!Function|{handleEvent:Function}} handler The handler for the
- * event.
- */
- removeEventListener: function(type, handler) {
- if (!this.listeners_)
- return;
- if (type in this.listeners_) {
- var handlers = this.listeners_[type];
- var index = handlers.indexOf(handler);
- if (index >= 0) {
- // Clean up if this was the last listener.
- if (handlers.length == 1)
- delete this.listeners_[type];
- else
- handlers.splice(index, 1);
- }
- }
- },
-
- /**
- * Dispatches an event and calls all the listeners that are listening to
- * the type of the event.
- * @param {!cr.event.Event} event The event to dispatch.
- * @return {boolean} Whether the default action was prevented. If someone
- * calls preventDefault on the event object then this returns false.
- */
- dispatchEvent: function(event) {
- if (!this.listeners_)
- return true;
-
- // Since we are using DOM Event objects we need to override some of the
- // properties and methods so that we can emulate this correctly.
- var self = this;
- event.__defineGetter__('target', function() {
- return self;
- });
- event.preventDefault = function() {
- this.returnValue = false;
- };
-
- var type = event.type;
- var prevented = 0;
- if (type in this.listeners_) {
- // Clone to prevent removal during dispatch
- var handlers = this.listeners_[type].concat();
- for (var i = 0, handler; handler = handlers[i]; i++) {
- if (handler.handleEvent)
- prevented |= handler.handleEvent.call(handler, event) === false;
- else
- prevented |= handler.call(this, event) === false;
- }
- }
-
- return !prevented && event.returnValue;
- }
- };
-
- // Export
- return {
- EventTarget: EventTarget
- };
-});
diff --git a/chrome/common/extensions/docs/examples/extensions/plugin_settings/domui/js/cr/ui.js b/chrome/common/extensions/docs/examples/extensions/plugin_settings/domui/js/cr/ui.js
deleted file mode 100644
index ea286b2..0000000
--- a/chrome/common/extensions/docs/examples/extensions/plugin_settings/domui/js/cr/ui.js
+++ /dev/null
@@ -1,161 +0,0 @@
-// Copyright (c) 2010 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.
-
-cr.define('cr.ui', function() {
-
- /**
- * Decorates elements as an instance of a class.
- * @param {string|!Element} source The way to find the element(s) to decorate.
- * If this is a string then {@code querySeletorAll} is used to find the
- * elements to decorate.
- * @param {!Function} constr The constructor to decorate with. The constr
- * needs to have a {@code decorate} function.
- */
- function decorate(source, constr) {
- var elements;
- if (typeof source == 'string')
- elements = cr.doc.querySelectorAll(source);
- else
- elements = [source];
-
- for (var i = 0, el; el = elements[i]; i++) {
- if (!(el instanceof constr))
- constr.decorate(el);
- }
- }
-
- /**
- * Helper function for creating new element for define.
- */
- function createElementHelper(tagName, opt_bag) {
- // Allow passing in ownerDocument to create in a different document.
- var doc;
- if (opt_bag && opt_bag.ownerDocument)
- doc = opt_bag.ownerDocument;
- else
- doc = cr.doc;
- return doc.createElement(tagName);
- }
-
- /**
- * Creates the constructor for a UI element class.
- *
- * Usage:
- * <pre>
- * var List = cr.ui.define('list');
- * List.prototype = {
- * __proto__: HTMLUListElement.prototype,
- * decorate: function() {
- * ...
- * },
- * ...
- * };
- * </pre>
- *
- * @param {string|Function} tagNameOrFunction The tagName or
- * function to use for newly created elements. If this is a function it
- * needs to return a new element when called.
- * @return {function(Object=):Element} The constructor function which takes
- * an optional property bag. The function also has a static
- * {@code decorate} method added to it.
- */
- function define(tagNameOrFunction) {
- var createFunction, tagName;
- if (typeof tagNameOrFunction == 'function') {
- createFunction = tagNameOrFunction;
- tagName = '';
- } else {
- createFunction = createElementHelper;
- tagName = tagNameOrFunction;
- }
-
- /**
- * Creates a new UI element constructor.
- * @param {Object=} opt_propertyBag Optional bag of properties to set on the
- * object after created. The property {@code ownerDocument} is special
- * cased and it allows you to create the element in a different
- * document than the default.
- * @constructor
- */
- function f(opt_propertyBag) {
- var el = createFunction(tagName, opt_propertyBag);
- f.decorate(el);
- for (var propertyName in opt_propertyBag) {
- el[propertyName] = opt_propertyBag[propertyName];
- }
- return el;
- }
-
- /**
- * Decorates an element as a UI element class.
- * @param {!Element} el The element to decorate.
- */
- f.decorate = function(el) {
- el.__proto__ = f.prototype;
- el.decorate();
- };
-
- return f;
- }
-
- /**
- * Input elements do not grow and shrink with their content. This is a simple
- * (and not very efficient) way of handling shrinking to content with support
- * for min width and limited by the width of the parent element.
- * @param {HTMLElement} el The element to limit the width for.
- * @param {number} parentEl The parent element that should limit the size.
- * @param {number} min The minimum width.
- */
- function limitInputWidth(el, parentEl, min) {
- // Needs a size larger than borders
- el.style.width = '10px';
- var doc = el.ownerDocument;
- var win = doc.defaultView;
- var computedStyle = win.getComputedStyle(el);
- var parentComputedStyle = win.getComputedStyle(parentEl);
- var rtl = computedStyle.direction == 'rtl';
-
- // To get the max width we get the width of the treeItem minus the position
- // of the input.
- var inputRect = el.getBoundingClientRect(); // box-sizing
- var parentRect = parentEl.getBoundingClientRect();
- var startPos = rtl ? parentRect.right - inputRect.right :
- inputRect.left - parentRect.left;
-
- // Add up border and padding of the input.
- var inner = parseInt(computedStyle.borderLeftWidth, 10) +
- parseInt(computedStyle.paddingLeft, 10) +
- parseInt(computedStyle.paddingRight, 10) +
- parseInt(computedStyle.borderRightWidth, 10);
-
- // We also need to subtract the padding of parent to prevent it to overflow.
- var parentPadding = rtl ? parseInt(parentComputedStyle.paddingLeft, 10) :
- parseInt(parentComputedStyle.paddingRight, 10);
-
- var max = parentEl.clientWidth - startPos - inner - parentPadding;
-
- function limit() {
- if (el.scrollWidth > max) {
- el.style.width = max + 'px';
- } else {
- el.style.width = 0;
- var sw = el.scrollWidth;
- if (sw < min) {
- el.style.width = min + 'px';
- } else {
- el.style.width = sw + 'px';
- }
- }
- }
-
- el.addEventListener('input', limit);
- limit();
- }
-
- return {
- decorate: decorate,
- define: define,
- limitInputWidth: limitInputWidth
- };
-});
diff --git a/chrome/common/extensions/docs/examples/extensions/plugin_settings/domui/js/cr/ui/array_data_model.js b/chrome/common/extensions/docs/examples/extensions/plugin_settings/domui/js/cr/ui/array_data_model.js
deleted file mode 100644
index fa695f8e..0000000
--- a/chrome/common/extensions/docs/examples/extensions/plugin_settings/domui/js/cr/ui/array_data_model.js
+++ /dev/null
@@ -1,362 +0,0 @@
-// Copyright (c) 2011 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.
-
-/**
- * @fileoverview This is a data model representin
- */
-
-cr.define('cr.ui', function() {
- /** @const */ var EventTarget = cr.EventTarget;
-
- /**
- * A data model that wraps a simple array and supports sorting by storing
- * initial indexes of elements for each position in sorted array.
- * @param {!Array} array The underlying array.
- * @constructor
- * @extends {EventTarget}
- */
- function ArrayDataModel(array) {
- this.array_ = array;
- this.indexes_ = [];
- this.compareFunctions_ = {};
-
- for (var i = 0; i < array.length; i++) {
- this.indexes_.push(i);
- }
- }
-
- ArrayDataModel.prototype = {
- __proto__: EventTarget.prototype,
-
- /**
- * The length of the data model.
- * @type {number}
- */
- get length() {
- return this.array_.length;
- },
-
- /**
- * Returns the item at the given index.
- * This implementation returns the item at the given index in the sorted
- * array.
- * @param {number} index The index of the element to get.
- * @return {*} The element at the given index.
- */
- item: function(index) {
- if (index >= 0 && index < this.length)
- return this.array_[this.indexes_[index]];
- return undefined;
- },
-
- /**
- * Returns compare function set for given field.
- * @param {string} field The field to get compare function for.
- * @return {function(*, *): number} Compare function set for given field.
- */
- compareFunction: function(field) {
- return this.compareFunctions_[field];
- },
-
- /**
- * Sets compare function for given field.
- * @param {string} field The field to set compare function.
- * @param {function(*, *): number} Compare function to set for given field.
- */
- setCompareFunction: function(field, compareFunction) {
- if (!this.compareFunctions_) {
- this.compareFunctions_ = {};
- }
- this.compareFunctions_[field] = compareFunction;
- },
-
- /**
- * Returns current sort status.
- * @return {!Object} Current sort status.
- */
- get sortStatus() {
- if (this.sortStatus_) {
- return this.createSortStatus(
- this.sortStatus_.field, this.sortStatus_.direction);
- } else {
- return this.createSortStatus(null, null);
- }
- },
-
- /**
- * Returns the first matching item.
- * @param {*} item The item to find.
- * @param {number=} opt_fromIndex If provided, then the searching start at
- * the {@code opt_fromIndex}.
- * @return {number} The index of the first found element or -1 if not found.
- */
- indexOf: function(item, opt_fromIndex) {
- return this.array_.indexOf(item, opt_fromIndex);
- },
-
- /**
- * Returns an array of elements in a selected range.
- * @param {number=} opt_from The starting index of the selected range.
- * @param {number=} opt_to The ending index of selected range.
- * @return {Array} An array of elements in the selected range.
- */
- slice: function(opt_from, opt_to) {
- return this.array_.slice.apply(this.array_, arguments);
- },
-
- /**
- * This removes and adds items to the model.
- * This dispatches a splice event.
- * This implementation runs sort after splice and creates permutation for
- * the whole change.
- * @param {number} index The index of the item to update.
- * @param {number} deleteCount The number of items to remove.
- * @param {...*} The items to add.
- * @return {!Array} An array with the removed items.
- */
- splice: function(index, deleteCount, var_args) {
- var addCount = arguments.length - 2;
- var newIndexes = [];
- var deletePermutation = [];
- var deleted = 0;
- for (var i = 0; i < this.indexes_.length; i++) {
- var oldIndex = this.indexes_[i];
- if (oldIndex < index) {
- newIndexes.push(oldIndex);
- deletePermutation.push(i - deleted);
- } else if (oldIndex >= index + deleteCount) {
- newIndexes.push(oldIndex - deleteCount + addCount);
- deletePermutation.push(i - deleted);
- } else {
- deletePermutation.push(-1);
- deleted++;
- }
- }
- for (var i = 0; i < addCount; i++) {
- newIndexes.push(index + i);
- }
- this.indexes_ = newIndexes;
-
- var arr = this.array_;
-
- // TODO(arv): Maybe unify splice and change events?
- var spliceEvent = new Event('splice');
- spliceEvent.index = index;
- spliceEvent.removed = arr.slice(index, index + deleteCount);
- spliceEvent.added = Array.prototype.slice.call(arguments, 2);
-
- var rv = arr.splice.apply(arr, arguments);
-
- var status = this.sortStatus;
- // if sortStatus.field is null, this restores original order.
- var sortPermutation = this.doSort_(this.sortStatus.field,
- this.sortStatus.direction);
- if (sortPermutation) {
- var splicePermutation = deletePermutation.map(function(element) {
- return element != -1 ? sortPermutation[element] : -1;
- });
- this.dispatchPermutedEvent_(splicePermutation);
- } else {
- this.dispatchPermutedEvent_(deletePermutation);
- }
-
- this.dispatchEvent(spliceEvent);
-
- // If real sorting is needed, we should first call prepareSort (data may
- // change), and then sort again.
- // Still need to finish the sorting above (including events), so
- // list will not go to inconsistent state.
- if (status.field) {
- setTimeout(this.sort.bind(this, status.field, status.direction), 0);
- }
- return rv;
- },
-
- /**
- * Appends items to the end of the model.
- *
- * This dispatches a splice event.
- *
- * @param {...*} The items to append.
- * @return {number} The new length of the model.
- */
- push: function(var_args) {
- var args = Array.prototype.slice.call(arguments);
- args.unshift(this.length, 0);
- this.splice.apply(this, args);
- return this.length;
- },
-
- /**
- * Use this to update a given item in the array. This does not remove and
- * reinsert a new item.
- * This dispatches a change event.
- * This runs sort after updating.
- * @param {number} index The index of the item to update.
- */
- updateIndex: function(index) {
- if (index < 0 || index >= this.length)
- throw Error('Invalid index, ' + index);
-
- // TODO(arv): Maybe unify splice and change events?
- var e = new Event('change');
- e.index = index;
- this.dispatchEvent(e);
-
- if (this.sortStatus.field) {
- var status = this.sortStatus;
- var sortPermutation = this.doSort_(this.sortStatus.field,
- this.sortStatus.direction);
- if (sortPermutation)
- this.dispatchPermutedEvent_(sortPermutation);
- // We should first call prepareSort (data may change), and then sort.
- // Still need to finish the sorting above (including events), so
- // list will not go to inconsistent state.
- setTimeout(this.sort.bind(this, status.field, status.direction), 0);
- }
- },
-
- /**
- * Creates sort status with given field and direction.
- * @param {string} field Sort field.
- * @param {string} direction Sort direction.
- * @return {!Object} Created sort status.
- */
- createSortStatus: function(field, direction) {
- return {
- field: field,
- direction: direction
- };
- },
-
- /**
- * Called before a sort happens so that you may fetch additional data
- * required for the sort.
- *
- * @param {string} field Sort field.
- * @param {function()} callback The function to invoke when preparation
- * is complete.
- */
- prepareSort: function(field, callback) {
- callback();
- },
-
- /**
- * Sorts data model according to given field and direction and dispathes
- * sorted event.
- * @param {string} field Sort field.
- * @param {string} direction Sort direction.
- */
- sort: function(field, direction) {
- var self = this;
-
- this.prepareSort(field, function() {
- var sortPermutation = self.doSort_(field, direction);
- if (sortPermutation)
- self.dispatchPermutedEvent_(sortPermutation);
- self.dispatchSortEvent_();
- });
- },
-
- /**
- * Sorts data model according to given field and direction.
- * @param {string} field Sort field.
- * @param {string} direction Sort direction.
- */
- doSort_: function(field, direction) {
- var compareFunction = this.sortFunction_(field, direction);
- var positions = [];
- for (var i = 0; i < this.length; i++) {
- positions[this.indexes_[i]] = i;
- }
- this.indexes_.sort(compareFunction);
- this.sortStatus_ = this.createSortStatus(field, direction);
- var sortPermutation = [];
- var changed = false;
- for (var i = 0; i < this.length; i++) {
- if (positions[this.indexes_[i]] != i)
- changed = true;
- sortPermutation[positions[this.indexes_[i]]] = i;
- }
- if (changed)
- return sortPermutation;
- return null;
- },
-
- dispatchSortEvent_: function() {
- var e = new Event('sorted');
- this.dispatchEvent(e);
- },
-
- dispatchPermutedEvent_: function(permutation) {
- var e = new Event('permuted');
- e.permutation = permutation;
- e.newLength = this.length;
- this.dispatchEvent(e);
- },
-
- /**
- * Creates compare function for the field.
- * Returns the function set as sortFunction for given field
- * or default compare function
- * @param {string} field Sort field.
- * @param {function(*, *): number} Compare function.
- */
- createCompareFunction_: function(field) {
- var compareFunction =
- this.compareFunctions_ ? this.compareFunctions_[field] : null;
- var defaultValuesCompareFunction = this.defaultValuesCompareFunction;
- if (compareFunction) {
- return compareFunction;
- } else {
- return function(a, b) {
- return defaultValuesCompareFunction.call(null, a[field], b[field]);
- }
- }
- return compareFunction;
- },
-
- /**
- * Creates compare function for given field and direction.
- * @param {string} field Sort field.
- * @param {string} direction Sort direction.
- * @param {function(*, *): number} Compare function.
- */
- sortFunction_: function(field, direction) {
- var compareFunction = null;
- if (field !== null)
- compareFunction = this.createCompareFunction_(field);
- var dirMultiplier = direction == 'desc' ? -1 : 1;
-
- return function(index1, index2) {
- var item1 = this.array_[index1];
- var item2 = this.array_[index2];
-
- var compareResult = 0;
- if (typeof(compareFunction) === 'function')
- compareResult = compareFunction.call(null, item1, item2);
- if (compareResult != 0)
- return dirMultiplier * compareResult;
- return dirMultiplier * this.defaultValuesCompareFunction(index1,
- index2);
- }.bind(this);
- },
-
- /**
- * Default compare function.
- */
- defaultValuesCompareFunction: function(a, b) {
- // We could insert i18n comparisons here.
- if (a < b)
- return -1;
- if (a > b)
- return 1;
- return 0;
- }
- };
-
- return {
- ArrayDataModel: ArrayDataModel
- };
-});
diff --git a/chrome/common/extensions/docs/examples/extensions/plugin_settings/domui/js/cr/ui/list.js b/chrome/common/extensions/docs/examples/extensions/plugin_settings/domui/js/cr/ui/list.js
deleted file mode 100644
index bc71eb68..0000000
--- a/chrome/common/extensions/docs/examples/extensions/plugin_settings/domui/js/cr/ui/list.js
+++ /dev/null
@@ -1,971 +0,0 @@
-// Copyright (c) 2011 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.
-
-// require: array_data_model.js
-// require: list_selection_model.js
-// require: list_selection_controller.js
-// require: list_item.js
-
-/**
- * @fileoverview This implements a list control.
- */
-
-cr.define('cr.ui', function() {
- const ListSelectionModel = cr.ui.ListSelectionModel;
- const ListSelectionController = cr.ui.ListSelectionController;
- const ArrayDataModel = cr.ui.ArrayDataModel;
-
- /**
- * Whether a mouse event is inside the element viewport. This will return
- * false if the mouseevent was generated over a border or a scrollbar.
- * @param {!HTMLElement} el The element to test the event with.
- * @param {!Event} e The mouse event.
- * @param {boolean} Whether the mouse event was inside the viewport.
- */
- function inViewport(el, e) {
- var rect = el.getBoundingClientRect();
- var x = e.clientX;
- var y = e.clientY;
- return x >= rect.left + el.clientLeft &&
- x < rect.left + el.clientLeft + el.clientWidth &&
- y >= rect.top + el.clientTop &&
- y < rect.top + el.clientTop + el.clientHeight;
- }
-
- /**
- * Creates an item (dataModel.item(0)) and measures its height.
- * @param {!List} list The list to create the item for.
- * @param {ListItem=} opt_item The list item to use to do the measuring. If
- * this is not provided an item will be created based on the first value
- * in the model.
- * @return {{height: number, marginVertical: number, width: number,
- * marginHorizontal: number}} The height and width of the item, taking
- * margins into account, and the height and width of the margins
- * themselves.
- */
- function measureItem(list, opt_item) {
- var dataModel = list.dataModel;
- if (!dataModel || !dataModel.length)
- return 0;
- var item = opt_item || list.createItem(dataModel.item(0));
- if (!opt_item)
- list.appendChild(item);
-
- var rect = item.getBoundingClientRect();
- var cs = getComputedStyle(item);
- var mt = parseFloat(cs.marginTop);
- var mb = parseFloat(cs.marginBottom);
- var ml = parseFloat(cs.marginLeft);
- var mr = parseFloat(cs.marginRight);
- var h = rect.height;
- var w = rect.width;
- var mh = 0;
- var mv = 0;
-
- // Handle margin collapsing.
- if (mt < 0 && mb < 0) {
- mv = Math.min(mt, mb);
- } else if (mt >= 0 && mb >= 0) {
- mv = Math.max(mt, mb);
- } else {
- mv = mt + mb;
- }
- h += mv;
-
- if (ml < 0 && mr < 0) {
- mh = Math.min(ml, mr);
- } else if (ml >= 0 && mr >= 0) {
- mh = Math.max(ml, mr);
- } else {
- mh = ml + mr;
- }
- w += mh;
-
- if (!opt_item)
- list.removeChild(item);
- return {
- height: Math.max(0, h), marginVertical: mv,
- width: Math.max(0, w), marginHorizontal: mh};
- }
-
- function getComputedStyle(el) {
- return el.ownerDocument.defaultView.getComputedStyle(el);
- }
-
- /**
- * Creates a new list element.
- * @param {Object=} opt_propertyBag Optional properties.
- * @constructor
- * @extends {HTMLUListElement}
- */
- var List = cr.ui.define('list');
-
- List.prototype = {
- __proto__: HTMLUListElement.prototype,
-
- /**
- * Measured size of list items. This is lazily calculated the first time it
- * is needed. Note that lead item is allowed to have a different height, to
- * accommodate lists where a single item at a time can be expanded to show
- * more detail.
- * @type {{height: number, marginVertical: number, width: number,
- * marginHorizontal: number}}
- * @private
- */
- measured_: undefined,
-
- /**
- * The height of the lead item, which is allowed to have a different height
- * than other list items to accommodate lists where a single item at a time
- * can be expanded to show more detail. It is explicitly set by client code
- * when the height of the lead item is changed with {@code set
- * leadItemHeight}, and presumed equal to {@code itemHeight_} otherwise.
- * @type {number}
- * @private
- */
- leadItemHeight_: 0,
-
- /**
- * Whether or not the list is autoexpanding. If true, the list resizes
- * its height to accomadate all children.
- * @type {boolean}
- * @private
- */
- autoExpands_: false,
-
- /**
- * Function used to create grid items.
- * @type {function(): !ListItem}
- * @private
- */
- itemConstructor_: cr.ui.ListItem,
-
- /**
- * Function used to create grid items.
- * @type {function(): !ListItem}
- */
- get itemConstructor() {
- return this.itemConstructor_;
- },
- set itemConstructor(func) {
- if (func != this.itemConstructor_) {
- this.itemConstructor_ = func;
- this.cachedItems_ = {};
- this.redraw();
- }
- },
-
- dataModel_: null,
-
- /**
- * The data model driving the list.
- * @type {ArrayDataModel}
- */
- set dataModel(dataModel) {
- if (this.dataModel_ != dataModel) {
- if (!this.boundHandleDataModelPermuted_) {
- this.boundHandleDataModelPermuted_ =
- this.handleDataModelPermuted_.bind(this);
- this.boundHandleDataModelChange_ =
- this.handleDataModelChange_.bind(this);
- }
-
- if (this.dataModel_) {
- this.dataModel_.removeEventListener(
- 'permuted',
- this.boundHandleDataModelPermuted_);
- this.dataModel_.removeEventListener('change',
- this.boundHandleDataModelChange_);
- }
-
- this.dataModel_ = dataModel;
-
- this.cachedItems_ = {};
- this.selectionModel.clear();
- if (dataModel)
- this.selectionModel.adjustLength(dataModel.length);
-
- if (this.dataModel_) {
- this.dataModel_.addEventListener(
- 'permuted',
- this.boundHandleDataModelPermuted_);
- this.dataModel_.addEventListener('change',
- this.boundHandleDataModelChange_);
- }
-
- this.redraw();
- }
- },
-
- get dataModel() {
- return this.dataModel_;
- },
-
- /**
- * The selection model to use.
- * @type {cr.ui.ListSelectionModel}
- */
- get selectionModel() {
- return this.selectionModel_;
- },
- set selectionModel(sm) {
- var oldSm = this.selectionModel_;
- if (oldSm == sm)
- return;
-
- if (!this.boundHandleOnChange_) {
- this.boundHandleOnChange_ = this.handleOnChange_.bind(this);
- this.boundHandleLeadChange_ = this.handleLeadChange_.bind(this);
- }
-
- if (oldSm) {
- oldSm.removeEventListener('change', this.boundHandleOnChange_);
- oldSm.removeEventListener('leadIndexChange',
- this.boundHandleLeadChange_);
- }
-
- this.selectionModel_ = sm;
- this.selectionController_ = this.createSelectionController(sm);
-
- if (sm) {
- sm.addEventListener('change', this.boundHandleOnChange_);
- sm.addEventListener('leadIndexChange', this.boundHandleLeadChange_);
- }
- },
-
- /**
- * Whether or not the list auto-expands.
- * @type {boolean}
- */
- get autoExpands() {
- return this.autoExpands_;
- },
- set autoExpands(autoExpands) {
- if (this.autoExpands_ == autoExpands)
- return;
- this.autoExpands_ = autoExpands;
- this.redraw();
- },
-
- /**
- * Convenience alias for selectionModel.selectedItem
- * @type {cr.ui.ListItem}
- */
- get selectedItem() {
- var dataModel = this.dataModel;
- if (dataModel) {
- var index = this.selectionModel.selectedIndex;
- if (index != -1)
- return dataModel.item(index);
- }
- return null;
- },
- set selectedItem(selectedItem) {
- var dataModel = this.dataModel;
- if (dataModel) {
- var index = this.dataModel.indexOf(selectedItem);
- this.selectionModel.selectedIndex = index;
- }
- },
-
- /**
- * The height of the lead item.
- * If set to 0, resets to the same height as other items.
- * @type {number}
- */
- get leadItemHeight() {
- return this.leadItemHeight_ || this.getItemHeight_();
- },
- set leadItemHeight(height) {
- if (height) {
- var size = this.getItemSize_();
- this.leadItemHeight_ = Math.max(0, height + size.marginVertical);
- } else {
- this.leadItemHeight_ = 0;
- }
- },
-
- /**
- * Convenience alias for selectionModel.selectedItems
- * @type {!Array<cr.ui.ListItem>}
- */
- get selectedItems() {
- var indexes = this.selectionModel.selectedIndexes;
- var dataModel = this.dataModel;
- if (dataModel) {
- return indexes.map(function(i) {
- return dataModel.item(i);
- });
- }
- return [];
- },
-
- /**
- * The HTML elements representing the items. This is just all the list item
- * children but subclasses may override this to filter out certain elements.
- * @type {HTMLCollection}
- */
- get items() {
- return Array.prototype.filter.call(this.children, function(child) {
- return !child.classList.contains('spacer');
- });
- },
-
- batchCount_: 0,
-
- /**
- * When making a lot of updates to the list, the code could be wrapped in
- * the startBatchUpdates and finishBatchUpdates to increase performance. Be
- * sure that the code will not return without calling endBatchUpdates or the
- * list will not be correctly updated.
- */
- startBatchUpdates: function() {
- this.batchCount_++;
- },
-
- /**
- * See startBatchUpdates.
- */
- endBatchUpdates: function() {
- this.batchCount_--;
- if (this.batchCount_ == 0)
- this.redraw();
- },
-
- /**
- * Initializes the element.
- */
- decorate: function() {
- // Add fillers.
- this.beforeFiller_ = this.ownerDocument.createElement('div');
- this.afterFiller_ = this.ownerDocument.createElement('div');
- this.beforeFiller_.className = 'spacer';
- this.afterFiller_.className = 'spacer';
- this.appendChild(this.beforeFiller_);
- this.appendChild(this.afterFiller_);
-
- var length = this.dataModel ? this.dataModel.length : 0;
- this.selectionModel = new ListSelectionModel(length);
-
- this.addEventListener('dblclick', this.handleDoubleClick_);
- this.addEventListener('mousedown', this.handleMouseDownUp_);
- this.addEventListener('mouseup', this.handleMouseDownUp_);
- this.addEventListener('keydown', this.handleKeyDown);
- this.addEventListener('focus', this.handleElementFocus_, true);
- this.addEventListener('blur', this.handleElementBlur_, true);
- this.addEventListener('scroll', this.redraw.bind(this));
- this.setAttribute('role', 'listbox');
-
- // Make list focusable
- if (!this.hasAttribute('tabindex'))
- this.tabIndex = 0;
- },
-
- /**
- * @return {number} The height of an item, measuring it if necessary.
- * @private
- */
- getItemHeight_: function() {
- return this.getItemSize_().height;
- },
-
- /**
- * @return {number} The width of an item, measuring it if necessary.
- * @private
- */
- getItemWidth_: function() {
- return this.getItemSize_().width;
- },
-
- /**
- * @return {{height: number, width: number}} The height and width
- * of an item, measuring it if necessary.
- * @private
- */
- getItemSize_: function() {
- if (!this.measured_ || !this.measured_.height) {
- this.measured_ = measureItem(this);
- }
- return this.measured_;
- },
-
- /**
- * Callback for the double click event.
- * @param {Event} e The mouse event object.
- * @private
- */
- handleDoubleClick_: function(e) {
- if (this.disabled)
- return;
-
- var target = this.getListItemAncestor(e.target);
- if (target)
- this.activateItemAtIndex(this.getIndexOfListItem(target));
- },
-
- /**
- * Callback for mousedown and mouseup events.
- * @param {Event} e The mouse event object.
- * @private
- */
- handleMouseDownUp_: function(e) {
- if (this.disabled)
- return;
-
- var target = e.target;
-
- // If the target was this element we need to make sure that the user did
- // not click on a border or a scrollbar.
- if (target == this && !inViewport(target, e))
- return;
-
- target = this.getListItemAncestor(target);
-
- var index = target ? this.getIndexOfListItem(target) : -1;
- this.selectionController_.handleMouseDownUp(e, index);
- },
-
- /**
- * Called when an element in the list is focused. Marks the list as having
- * a focused element, and dispatches an event if it didn't have focus.
- * @param {Event} e The focus event.
- * @private
- */
- handleElementFocus_: function(e) {
- if (!this.hasElementFocus) {
- this.hasElementFocus = true;
- // Force styles based on hasElementFocus to take effect.
- this.forceRepaint_();
- }
- },
-
- /**
- * Called when an element in the list is blurred. If focus moves outside
- * the list, marks the list as no longer having focus and dispatches an
- * event.
- * @param {Event} e The blur event.
- * @private
- */
- handleElementBlur_: function(e) {
- // When the blur event happens we do not know who is getting focus so we
- // delay this a bit until we know if the new focus node is outside the
- // list.
- var list = this;
- var doc = e.target.ownerDocument;
- window.setTimeout(function() {
- var activeElement = doc.activeElement;
- if (!list.contains(activeElement)) {
- list.hasElementFocus = false;
- // Force styles based on hasElementFocus to take effect.
- list.forceRepaint_();
- }
- });
- },
-
- /**
- * Forces a repaint of the list. Changing custom attributes, even if there
- * are style rules depending on them, doesn't cause a repaint
- * (<https://bugs.webkit.org/show_bug.cgi?id=12519>), so this can be called
- * to force the list to repaint.
- * @private
- */
- forceRepaint_: function(e) {
- var dummyElement = document.createElement('div');
- this.appendChild(dummyElement);
- this.removeChild(dummyElement);
- },
-
- /**
- * Returns the list item element containing the given element, or null if
- * it doesn't belong to any list item element.
- * @param {HTMLElement} element The element.
- * @return {ListItem} The list item containing |element|, or null.
- */
- getListItemAncestor: function(element) {
- var container = element;
- while (container && container.parentNode != this) {
- container = container.parentNode;
- }
- return container;
- },
-
- /**
- * Handle a keydown event.
- * @param {Event} e The keydown event.
- * @return {boolean} Whether the key event was handled.
- */
- handleKeyDown: function(e) {
- if (this.disabled)
- return;
-
- return this.selectionController_.handleKeyDown(e);
- },
-
- /**
- * Callback from the selection model. We dispatch {@code change} events
- * when the selection changes.
- * @param {!Event} e Event with change info.
- * @private
- */
- handleOnChange_: function(ce) {
- ce.changes.forEach(function(change) {
- var listItem = this.getListItemByIndex(change.index);
- if (listItem)
- listItem.selected = change.selected;
- }, this);
-
- cr.dispatchSimpleEvent(this, 'change');
- },
-
- /**
- * Handles a change of the lead item from the selection model.
- * @property {Event} pe The property change event.
- * @private
- */
- handleLeadChange_: function(pe) {
- var element;
- if (pe.oldValue != -1) {
- if ((element = this.getListItemByIndex(pe.oldValue)))
- element.lead = false;
- }
-
- if (pe.newValue != -1) {
- if ((element = this.getListItemByIndex(pe.newValue)))
- element.lead = true;
- this.scrollIndexIntoView(pe.newValue);
- // If the lead item has a different height than other items, then we
- // may run into a problem that requires a second attempt to scroll
- // it into view. The first scroll attempt will trigger a redraw,
- // which will clear out the list and repopulate it with new items.
- // During the redraw, the list may shrink temporarily, which if the
- // lead item is the last item, will move the scrollTop up since it
- // cannot extend beyond the end of the list. (Sadly, being scrolled to
- // the bottom of the list is not "sticky.") So, we set a timeout to
- // rescroll the list after this all gets sorted out. This is perhaps
- // not the most elegant solution, but no others seem obvious.
- var self = this;
- window.setTimeout(function() {
- self.scrollIndexIntoView(pe.newValue);
- });
- }
- },
-
- /**
- * This handles data model 'permuted' event.
- * this event is dispatched as a part of sort or splice.
- * We need to
- * - adjust the cache.
- * - adjust selection.
- * - redraw.
- * - scroll the list to show selection.
- * It is important that the cache adjustment happens before selection model
- * adjustments.
- * @param {Event} e The 'permuted' event.
- */
- handleDataModelPermuted_: function(e) {
- var newCachedItems = {};
- for (var index in this.cachedItems_) {
- if (e.permutation[index] != -1)
- newCachedItems[e.permutation[index]] = this.cachedItems_[index];
- else
- delete this.cachedItems_[index];
- }
- this.cachedItems_ = newCachedItems;
-
- this.startBatchUpdates();
-
- var sm = this.selectionModel;
- sm.adjustLength(e.newLength);
- sm.adjustToReordering(e.permutation);
-
- this.endBatchUpdates();
-
- if (sm.leadIndex != -1)
- this.scrollIndexIntoView(sm.leadIndex);
- },
-
- handleDataModelChange_: function(e) {
- if (e.index >= this.firstIndex_ && e.index < this.lastIndex_) {
- if (this.cachedItems_[e.index])
- delete this.cachedItems_[e.index];
- this.redraw();
- }
- },
-
- /**
- * @param {number} index The index of the item.
- * @return {number} The top position of the item inside the list, not taking
- * into account lead item. May vary in the case of multiple columns.
- */
- getItemTop: function(index) {
- return index * this.getItemHeight_();
- },
-
- /**
- * @param {number} index The index of the item.
- * @return {number} The row of the item. May vary in the case
- * of multiple columns.
- */
- getItemRow: function(index) {
- return index;
- },
-
- /**
- * @param {number} row The row.
- * @return {number} The index of the first item in the row.
- */
- getFirstItemInRow: function(row) {
- return row;
- },
-
- /**
- * Ensures that a given index is inside the viewport.
- * @param {number} index The index of the item to scroll into view.
- * @return {boolean} Whether any scrolling was needed.
- */
- scrollIndexIntoView: function(index) {
- var dataModel = this.dataModel;
- if (!dataModel || index < 0 || index >= dataModel.length)
- return false;
-
- var itemHeight = this.getItemHeight_();
- var scrollTop = this.scrollTop;
- var top = this.getItemTop(index);
- var leadIndex = this.selectionModel.leadIndex;
-
- // Adjust for the lead item if it is above the given index.
- if (leadIndex > -1 && leadIndex < index)
- top += this.leadItemHeight - itemHeight;
- else if (leadIndex == index)
- itemHeight = this.leadItemHeight;
-
- if (top < scrollTop) {
- this.scrollTop = top;
- return true;
- } else {
- var clientHeight = this.clientHeight;
- var cs = getComputedStyle(this);
- var paddingY = parseInt(cs.paddingTop, 10) +
- parseInt(cs.paddingBottom, 10);
-
- if (top + itemHeight > scrollTop + clientHeight - paddingY) {
- this.scrollTop = top + itemHeight - clientHeight + paddingY;
- return true;
- }
- }
-
- return false;
- },
-
- /**
- * @return {!ClientRect} The rect to use for the context menu.
- */
- getRectForContextMenu: function() {
- // TODO(arv): Add trait support so we can share more code between trees
- // and lists.
- var index = this.selectionModel.selectedIndex;
- var el = this.getListItemByIndex(index);
- if (el)
- return el.getBoundingClientRect();
- return this.getBoundingClientRect();
- },
-
- /**
- * Takes a value from the data model and finds the associated list item.
- * @param {*} value The value in the data model that we want to get the list
- * item for.
- * @return {ListItem} The first found list item or null if not found.
- */
- getListItem: function(value) {
- var dataModel = this.dataModel;
- if (dataModel) {
- var index = dataModel.indexOf(value);
- return this.getListItemByIndex(index);
- }
- return null;
- },
-
- /**
- * Find the list item element at the given index.
- * @param {number} index The index of the list item to get.
- * @return {ListItem} The found list item or null if not found.
- */
- getListItemByIndex: function(index) {
- return this.cachedItems_[index] || null;
- },
-
- /**
- * Find the index of the given list item element.
- * @param {ListItem} item The list item to get the index of.
- * @return {number} The index of the list item, or -1 if not found.
- */
- getIndexOfListItem: function(item) {
- var index = item.listIndex;
- if (this.cachedItems_[index] == item) {
- return index;
- }
- return -1;
- },
-
- /**
- * Creates a new list item.
- * @param {*} value The value to use for the item.
- * @return {!ListItem} The newly created list item.
- */
- createItem: function(value) {
- var item = new this.itemConstructor_(value);
- item.label = value;
- if (typeof item.decorate == 'function')
- item.decorate();
- return item;
- },
-
- /**
- * Creates the selection controller to use internally.
- * @param {cr.ui.ListSelectionModel} sm The underlying selection model.
- * @return {!cr.ui.ListSelectionController} The newly created selection
- * controller.
- */
- createSelectionController: function(sm) {
- return new ListSelectionController(sm);
- },
-
- /**
- * Return the heights (in pixels) of the top of the given item index within
- * the list, and the height of the given item itself, accounting for the
- * possibility that the lead item may be a different height.
- * @param {number} index The index to find the top height of.
- * @return {{top: number, height: number}} The heights for the given index.
- * @private
- */
- getHeightsForIndex_: function(index) {
- var itemHeight = this.getItemHeight_();
- var top = this.getItemTop(index);
- if (this.selectionModel.leadIndex > -1 &&
- this.selectionModel.leadIndex < index) {
- top += this.leadItemHeight - itemHeight;
- } else if (this.selectionModel.leadIndex == index) {
- itemHeight = this.leadItemHeight;
- }
- return {top: top, height: itemHeight};
- },
-
- /**
- * Find the index of the list item containing the given y offset (measured
- * in pixels from the top) within the list. In the case of multiple columns,
- * returns the first index in the row.
- * @param {number} offset The y offset in pixels to get the index of.
- * @return {number} The index of the list item.
- * @private
- */
- getIndexForListOffset_: function(offset) {
- var itemHeight = this.getItemHeight_();
- var leadIndex = this.selectionModel.leadIndex;
- var leadItemHeight = this.leadItemHeight;
- if (leadIndex < 0 || leadItemHeight == itemHeight) {
- // Simple case: no lead item or lead item height is not different.
- return this.getFirstItemInRow(Math.floor(offset / itemHeight));
- }
- var leadTop = this.getItemTop(leadIndex);
- // If the given offset is above the lead item, it's also simple.
- if (offset < leadTop)
- return this.getFirstItemInRow(Math.floor(offset / itemHeight));
- // If the lead item contains the given offset, we just return its index.
- if (offset < leadTop + leadItemHeight)
- return this.getFirstItemInRow(this.getItemRow(leadIndex));
- // The given offset must be below the lead item. Adjust and recalculate.
- offset -= leadItemHeight - itemHeight;
- return this.getFirstItemInRow(Math.floor(offset / itemHeight));
- },
-
- /**
- * Return the number of items that occupy the range of heights between the
- * top of the start item and the end offset.
- * @param {number} startIndex The index of the first visible item.
- * @param {number} endOffset The y offset in pixels of the end of the list.
- * @return {number} The number of list items visible.
- * @private
- */
- countItemsInRange_: function(startIndex, endOffset) {
- var endIndex = this.getIndexForListOffset_(endOffset);
- return endIndex - startIndex + 1;
- },
-
- /**
- * Calculates the number of items fitting in viewport given the index of
- * first item and heights.
- * @param {number} itemHeight The height of the item.
- * @param {number} firstIndex Index of the first item in viewport.
- * @param {number} scrollTop The scroll top position.
- * @return {number} The number of items in view port.
- */
- getItemsInViewPort: function(itemHeight, firstIndex, scrollTop) {
- // This is a bit tricky. We take the minimum of the available items to
- // show and the number we want to show, so as not to go off the end of the
- // list. For the number we want to show, we take the maximum of the number
- // that would fit without a differently-sized lead item, and with one. We
- // do this so that if the size of the lead item changes without a scroll
- // event to trigger redrawing the list, we won't end up with empty space.
- var clientHeight = this.clientHeight;
- return this.autoExpands_ ? this.dataModel.length : Math.min(
- this.dataModel.length - firstIndex,
- Math.max(
- Math.ceil(clientHeight / itemHeight) + 1,
- this.countItemsInRange_(firstIndex, scrollTop + clientHeight)));
- },
-
- /**
- * Adds items to the list and {@code newCachedItems}.
- * @param {number} firstIndex The index of first item, inclusively.
- * @param {number} lastIndex The index of last item, exclusively.
- * @param {Object<string, ListItem>} cachedItems Old items cache.
- * @param {Object<string, ListItem>} newCachedItems New items cache.
- */
- addItems: function(firstIndex, lastIndex, cachedItems, newCachedItems) {
- var listItem;
- var dataModel = this.dataModel;
-
- window.l = this;
- for (var y = firstIndex; y < lastIndex; y++) {
- var dataItem = dataModel.item(y);
- listItem = cachedItems[y] || this.createItem(dataItem);
- listItem.listIndex = y;
- this.appendChild(listItem);
- newCachedItems[y] = listItem;
- }
- },
-
- /**
- * Returns the height of after filler in the list.
- * @param {number} lastIndex The index of item past the last in viewport.
- * @param {number} itemHeight The height of the item.
- * @return {number} The height of after filler.
- */
- getAfterFillerHeight: function(lastIndex, itemHeight) {
- return (this.dataModel.length - lastIndex) * itemHeight;
- },
-
- /**
- * Redraws the viewport.
- */
- redraw: function() {
- if (this.batchCount_ != 0)
- return;
-
- var dataModel = this.dataModel;
- if (!dataModel) {
- this.textContent = '';
- return;
- }
-
- var scrollTop = this.scrollTop;
- var clientHeight = this.clientHeight;
-
- var itemHeight = this.getItemHeight_();
-
- // We cache the list items since creating the DOM nodes is the most
- // expensive part of redrawing.
- var cachedItems = this.cachedItems_ || {};
- var newCachedItems = {};
-
- var desiredScrollHeight = this.getHeightsForIndex_(dataModel.length).top;
-
- var autoExpands = this.autoExpands_;
- var firstIndex = autoExpands ? 0 : this.getIndexForListOffset_(scrollTop);
- var itemsInViewPort = this.getItemsInViewPort(itemHeight, firstIndex,
- scrollTop);
- var lastIndex = firstIndex + itemsInViewPort;
-
- this.textContent = '';
-
- this.beforeFiller_.style.height =
- this.getHeightsForIndex_(firstIndex).top + 'px';
- this.appendChild(this.beforeFiller_);
-
- var sm = this.selectionModel;
- var leadIndex = sm.leadIndex;
-
- this.addItems(firstIndex, lastIndex, cachedItems, newCachedItems);
-
- var afterFillerHeight = this.getAfterFillerHeight(lastIndex, itemHeight);
- if (leadIndex >= lastIndex)
- afterFillerHeight += this.leadItemHeight - itemHeight;
- this.afterFiller_.style.height = afterFillerHeight + 'px';
- this.appendChild(this.afterFiller_);
-
- // We don't set the lead or selected properties until after adding all
- // items, in case they force relayout in response to these events.
- var listItem = null;
- if (newCachedItems[leadIndex])
- newCachedItems[leadIndex].lead = true;
- for (var y = firstIndex; y < lastIndex; y++) {
- if (sm.getIndexSelected(y))
- newCachedItems[y].selected = true;
- else if (y != leadIndex)
- listItem = newCachedItems[y];
- }
-
- this.firstIndex_ = firstIndex;
- this.lastIndex_ = lastIndex;
-
- this.cachedItems_ = newCachedItems;
-
- // Measure again in case the item height has changed due to a page zoom.
- //
- // The measure above is only done the first time but this measure is done
- // after every redraw. It is done in a timeout so it will not trigger
- // a reflow (which made the redraw speed 3 times slower on my system).
- // By using a timeout the measuring will happen later when there is no
- // need for a reflow.
- if (listItem) {
- var list = this;
- window.setTimeout(function() {
- if (listItem.parentNode == list) {
- list.measured_ = measureItem(list, listItem);
- }
- });
- }
- },
-
- /**
- * Invalidates list by removing cached items.
- */
- invalidate: function() {
- this.cachedItems_ = {};
- },
-
- /**
- * Redraws a single item.
- * @param {number} index The row index to redraw.
- */
- redrawItem: function(index) {
- if (index >= this.firstIndex_ && index < this.lastIndex_) {
- delete this.cachedItems_[index];
- this.redraw();
- }
- },
-
- /**
- * Called when a list item is activated, currently only by a double click
- * event.
- * @param {number} index The index of the activated item.
- */
- activateItemAtIndex: function(index) {
- },
- };
-
- cr.defineProperty(List, 'disabled', cr.PropertyKind.BOOL_ATTR);
-
- /**
- * Whether the list or one of its descendents has focus. This is necessary
- * because list items can contain controls that can be focused, and for some
- * purposes (e.g., styling), the list can still be conceptually focused at
- * that point even though it doesn't actually have the page focus.
- */
- cr.defineProperty(List, 'hasElementFocus', cr.PropertyKind.BOOL_ATTR);
-
- return {
- List: List
- }
-});
diff --git a/chrome/common/extensions/docs/examples/extensions/plugin_settings/domui/js/cr/ui/list_item.js b/chrome/common/extensions/docs/examples/extensions/plugin_settings/domui/js/cr/ui/list_item.js
deleted file mode 100644
index 68431bc..0000000
--- a/chrome/common/extensions/docs/examples/extensions/plugin_settings/domui/js/cr/ui/list_item.js
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright (c) 2011 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.
-
-cr.define('cr.ui', function() {
-
- /**
- * Creates a new list item element.
- * @param {string} opt_label The text label for the item.
- * @constructor
- * @extends {HTMLLIElement}
- */
- var ListItem = cr.ui.define('li');
-
- ListItem.prototype = {
- __proto__: HTMLLIElement.prototype,
-
- /**
- * Plain text label.
- * @type {string}
- */
- get label() {
- return this.textContent;
- },
- set label(label) {
- this.textContent = label;
- },
-
- /**
- * This item's index in the containing list.
- * @type {number}
- */
- listIndex_: -1,
-
- /**
- * Called when an element is decorated as a list item.
- */
- decorate: function() {
- this.setAttribute('role', 'listitem');
- },
-
- /**
- * Called when the selection state of this element changes.
- */
- selectionChanged: function() {
- },
- };
-
- /**
- * Whether the item is selected. Setting this does not update the underlying
- * selection model. This is only used for display purpose.
- * @type {boolean}
- */
- cr.defineProperty(ListItem, 'selected', cr.PropertyKind.BOOL_ATTR,
- function() {
- this.selectionChanged();
- });
-
- /**
- * Whether the item is the lead in a selection. Setting this does not update
- * the underlying selection model. This is only used for display purpose.
- * @type {boolean}
- */
- cr.defineProperty(ListItem, 'lead', cr.PropertyKind.BOOL_ATTR);
-
- /**
- * This item's index in the containing list.
- * @type {number}
- */
- cr.defineProperty(ListItem, 'listIndex');
-
- return {
- ListItem: ListItem
- };
-});
diff --git a/chrome/common/extensions/docs/examples/extensions/plugin_settings/domui/js/cr/ui/list_selection_controller.js b/chrome/common/extensions/docs/examples/extensions/plugin_settings/domui/js/cr/ui/list_selection_controller.js
deleted file mode 100644
index 74a8a24..0000000
--- a/chrome/common/extensions/docs/examples/extensions/plugin_settings/domui/js/cr/ui/list_selection_controller.js
+++ /dev/null
@@ -1,289 +0,0 @@
-// Copyright (c) 2010 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.
-
-cr.define('cr.ui', function() {
- /**
- * Creates a selection controller that is to be used with lists. This is
- * implemented for vertical lists but changing the behavior for horizontal
- * lists or icon views is a matter of overriding {@code getIndexBefore},
- * {@code getIndexAfter}, {@code getIndexAbove} as well as
- * {@code getIndexBelow}.
- *
- * @param {cr.ui.ListSelectionModel} selectionModel The selection model to
- * interact with.
- *
- * @constructor
- * @extends {!cr.EventTarget}
- */
- function ListSelectionController(selectionModel) {
- this.selectionModel_ = selectionModel;
- }
-
- ListSelectionController.prototype = {
-
- /**
- * The selection model we are interacting with.
- * @type {cr.ui.ListSelectionModel}
- */
- get selectionModel() {
- return this.selectionModel_;
- },
-
- /**
- * Returns the index below (y axis) the given element.
- * @param {number} index The index to get the index below.
- * @return {number} The index below or -1 if not found.
- */
- getIndexBelow: function(index) {
- if (index == this.getLastIndex())
- return -1;
- return index + 1;
- },
-
- /**
- * Returns the index above (y axis) the given element.
- * @param {number} index The index to get the index above.
- * @return {number} The index below or -1 if not found.
- */
- getIndexAbove: function(index) {
- return index - 1;
- },
-
- /**
- * Returns the index before (x axis) the given element. This returns -1
- * by default but override this for icon view and horizontal selection
- * models.
- *
- * @param {number} index The index to get the index before.
- * @return {number} The index before or -1 if not found.
- */
- getIndexBefore: function(index) {
- return -1;
- },
-
- /**
- * Returns the index after (x axis) the given element. This returns -1
- * by default but override this for icon view and horizontal selection
- * models.
- *
- * @param {number} index The index to get the index after.
- * @return {number} The index after or -1 if not found.
- */
- getIndexAfter: function(index) {
- return -1;
- },
-
- /**
- * Returns the next list index. This is the next logical and should not
- * depend on any kind of layout of the list.
- * @param {number} index The index to get the next index for.
- * @return {number} The next index or -1 if not found.
- */
- getNextIndex: function(index) {
- if (index == this.getLastIndex())
- return -1;
- return index + 1;
- },
-
- /**
- * Returns the prevous list index. This is the previous logical and should
- * not depend on any kind of layout of the list.
- * @param {number} index The index to get the previous index for.
- * @return {number} The previous index or -1 if not found.
- */
- getPreviousIndex: function(index) {
- return index - 1;
- },
-
- /**
- * @return {number} The first index.
- */
- getFirstIndex: function() {
- return 0;
- },
-
- /**
- * @return {number} The last index.
- */
- getLastIndex: function() {
- return this.selectionModel.length - 1;
- },
-
- /**
- * Called by the view when the user does a mousedown or mouseup on the list.
- * @param {!Event} e The browser mousedown event.
- * @param {number} index The index that was under the mouse pointer, -1 if
- * none.
- */
- handleMouseDownUp: function(e, index) {
- var sm = this.selectionModel;
- var anchorIndex = sm.anchorIndex;
- var isDown = e.type == 'mousedown';
-
- sm.beginChange();
-
- if (index == -1) {
- // On Mac we always clear the selection if the user clicks a blank area.
- // On Windows, we only clear the selection if neither Shift nor Ctrl are
- // pressed.
- if (cr.isMac) {
- sm.leadIndex = sm.anchorIndex = -1;
- if (sm.multiple)
- sm.unselectAll();
- } else if (!isDown && !e.shiftKey && !e.ctrlKey)
- // Keep anchor and lead indexes. Note that this is intentionally
- // different than on the Mac.
- if (sm.multiple)
- sm.unselectAll();
- } else {
- if (sm.multiple && (cr.isMac ? e.metaKey :
- (e.ctrlKey && !e.shiftKey))) {
- // Selection is handled at mouseUp on windows/linux, mouseDown on mac.
- if (cr.isMac? isDown : !isDown) {
- // Toggle the current one and make it anchor index.
- sm.setIndexSelected(index, !sm.getIndexSelected(index));
- sm.leadIndex = index;
- sm.anchorIndex = index;
- }
- } else if (e.shiftKey && anchorIndex != -1 && anchorIndex != index) {
- // Shift is done in mousedown.
- if (isDown) {
- sm.unselectAll();
- sm.leadIndex = index;
- if (sm.multiple)
- sm.selectRange(anchorIndex, index);
- else
- sm.setIndexSelected(index, true);
- }
- } else {
- // Right click for a context menu needs to not clear the selection.
- var isRightClick = e.button == 2;
-
- // If the index is selected this is handled in mouseup.
- var indexSelected = sm.getIndexSelected(index);
- if ((indexSelected && !isDown || !indexSelected && isDown) &&
- !(indexSelected && isRightClick)) {
- sm.unselectAll();
- sm.setIndexSelected(index, true);
- sm.leadIndex = index;
- sm.anchorIndex = index;
- }
- }
- }
-
- sm.endChange();
- },
-
- /**
- * Called by the view when it receives a keydown event.
- * @param {Event} e The keydown event.
- */
- handleKeyDown: function(e) {
- const SPACE_KEY_CODE = 32;
- var tagName = e.target.tagName;
- // If focus is in an input field of some kind, only handle navigation keys
- // that aren't likely to conflict with input interaction (e.g., text
- // editing, or changing the value of a checkbox or select).
- if (tagName == 'INPUT') {
- var inputType = e.target.type;
- // Just protect space (for toggling) for checkbox and radio.
- if (inputType == 'checkbox' || inputType == 'radio') {
- if (e.keyCode == SPACE_KEY_CODE)
- return;
- // Protect all but the most basic navigation commands in anything else.
- } else if (e.key != 'ArrowUp' && e.key != 'ArrowDown') {
- return;
- }
- }
- // Similarly, don't interfere with select element handling.
- if (tagName == 'SELECT')
- return;
-
- var sm = this.selectionModel;
- var newIndex = -1;
- var leadIndex = sm.leadIndex;
- var prevent = true;
-
- // Ctrl/Meta+A
- if (sm.multiple && e.keyCode == 65 &&
- (cr.isMac && e.metaKey || !cr.isMac && e.ctrlKey)) {
- sm.selectAll();
- e.preventDefault();
- return;
- }
-
- // Space
- if (e.keyCode == SPACE_KEY_CODE) {
- if (leadIndex != -1) {
- var selected = sm.getIndexSelected(leadIndex);
- if (e.ctrlKey || !selected) {
- sm.setIndexSelected(leadIndex, !selected || !sm.multiple);
- return;
- }
- }
- }
-
- switch (e.key) {
- case 'Home':
- newIndex = this.getFirstIndex();
- break;
- case 'End':
- newIndex = this.getLastIndex();
- break;
- case 'ArrowUp':
- newIndex = leadIndex == -1 ?
- this.getLastIndex() : this.getIndexAbove(leadIndex);
- break;
- case 'ArrowDown':
- newIndex = leadIndex == -1 ?
- this.getFirstIndex() : this.getIndexBelow(leadIndex);
- break;
- case 'ArrrowLeft':
- newIndex = leadIndex == -1 ?
- this.getLastIndex() : this.getIndexBefore(leadIndex);
- break;
- case 'ArrowRight':
- newIndex = leadIndex == -1 ?
- this.getFirstIndex() : this.getIndexAfter(leadIndex);
- break;
- default:
- prevent = false;
- }
-
- if (newIndex != -1) {
- sm.beginChange();
-
- sm.leadIndex = newIndex;
- if (e.shiftKey) {
- var anchorIndex = sm.anchorIndex;
- if (sm.multiple)
- sm.unselectAll();
- if (anchorIndex == -1) {
- sm.setIndexSelected(newIndex, true);
- sm.anchorIndex = newIndex;
- } else {
- sm.selectRange(anchorIndex, newIndex);
- }
- } else if (e.ctrlKey && !cr.isMac) {
- // Setting the lead index is done above.
- // Mac does not allow you to change the lead.
- } else {
- if (sm.multiple)
- sm.unselectAll();
- sm.setIndexSelected(newIndex, true);
- sm.anchorIndex = newIndex;
- }
-
- sm.endChange();
-
- if (prevent)
- e.preventDefault();
- }
- }
- };
-
- return {
- ListSelectionController: ListSelectionController
- };
-});
diff --git a/chrome/common/extensions/docs/examples/extensions/plugin_settings/domui/js/cr/ui/list_selection_model.js b/chrome/common/extensions/docs/examples/extensions/plugin_settings/domui/js/cr/ui/list_selection_model.js
deleted file mode 100644
index 8dba53a..0000000
--- a/chrome/common/extensions/docs/examples/extensions/plugin_settings/domui/js/cr/ui/list_selection_model.js
+++ /dev/null
@@ -1,274 +0,0 @@
-// Copyright (c) 2011 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.
-
-cr.define('cr.ui', function() {
- /** @const */ var EventTarget = cr.EventTarget;
-
- /**
- * Creates a new selection model that is to be used with lists.
- *
- * @param {number=} opt_length The number items in the selection.
- *
- * @constructor
- * @extends {!cr.EventTarget}
- */
- function ListSelectionModel(opt_length) {
- this.length_ = opt_length || 0;
- // Even though selectedIndexes_ is really a map we use an array here to get
- // iteration in the order of the indexes.
- this.selectedIndexes_ = [];
- }
-
- ListSelectionModel.prototype = {
- __proto__: EventTarget.prototype,
-
- /**
- * The number of items in the model.
- * @type {number}
- */
- get length() {
- return this.length_;
- },
-
- /**
- * @type {!Array} The selected indexes.
- */
- get selectedIndexes() {
- return Object.keys(this.selectedIndexes_).map(Number);
- },
- set selectedIndexes(selectedIndexes) {
- this.beginChange();
- this.unselectAll();
- for (var i = 0; i < selectedIndexes.length; i++) {
- this.setIndexSelected(selectedIndexes[i], true);
- }
- if (selectedIndexes.length) {
- this.leadIndex = this.anchorIndex = selectedIndexes[0];
- } else {
- this.leadIndex = this.anchorIndex = -1;
- }
- this.endChange();
- },
-
- /**
- * Convenience getter which returns the first selected index.
- * @type {number}
- */
- get selectedIndex() {
- for (var i in this.selectedIndexes_) {
- return Number(i);
- }
- return -1;
- },
- set selectedIndex(selectedIndex) {
- this.beginChange();
- this.unselectAll();
- if (selectedIndex != -1) {
- this.selectedIndexes = [selectedIndex];
- } else {
- this.leadIndex = this.anchorIndex = -1;
- }
- this.endChange();
- },
-
- /**
- * Selects a range of indexes, starting with {@code start} and ends with
- * {@code end}.
- * @param {number} start The first index to select.
- * @param {number} end The last index to select.
- */
- selectRange: function(start, end) {
- // Swap if starts comes after end.
- if (start > end) {
- var tmp = start;
- start = end;
- end = tmp;
- }
-
- this.beginChange();
-
- for (var index = start; index != end; index++) {
- this.setIndexSelected(index, true);
- }
- this.setIndexSelected(end, true);
-
- this.endChange();
- },
-
- /**
- * Selects all indexes.
- */
- selectAll: function() {
- this.selectRange(0, this.length - 1);
- },
-
- /**
- * Clears the selection
- */
- clear: function() {
- this.beginChange();
- this.length_ = 0;
- this.anchorIndex = this.leadIndex = -1;
- this.unselectAll();
- this.endChange();
- },
-
- /**
- * Unselects all selected items.
- */
- unselectAll: function() {
- this.beginChange();
- for (var i in this.selectedIndexes_) {
- this.setIndexSelected(i, false);
- }
- this.endChange();
- },
-
- /**
- * Sets the selected state for an index.
- * @param {number} index The index to set the selected state for.
- * @param {boolean} b Whether to select the index or not.
- */
- setIndexSelected: function(index, b) {
- var oldSelected = index in this.selectedIndexes_;
- if (oldSelected == b)
- return;
-
- if (b)
- this.selectedIndexes_[index] = true;
- else
- delete this.selectedIndexes_[index];
-
- this.beginChange();
-
- // Changing back?
- if (index in this.changedIndexes_ && this.changedIndexes_[index] == !b) {
- delete this.changedIndexes_[index];
- } else {
- this.changedIndexes_[index] = b;
- }
-
- // End change dispatches an event which in turn may update the view.
- this.endChange();
- },
-
- /**
- * Whether a given index is selected or not.
- * @param {number} index The index to check.
- * @return {boolean} Whether an index is selected.
- */
- getIndexSelected: function(index) {
- return index in this.selectedIndexes_;
- },
-
- /**
- * This is used to begin batching changes. Call {@code endChange} when you
- * are done making changes.
- */
- beginChange: function() {
- if (!this.changeCount_) {
- this.changeCount_ = 0;
- this.changedIndexes_ = {};
- }
- this.changeCount_++;
- },
-
- /**
- * Call this after changes are done and it will dispatch a change event if
- * any changes were actually done.
- */
- endChange: function() {
- this.changeCount_--;
- if (!this.changeCount_) {
- var indexes = Object.keys(this.changedIndexes_);
- if (indexes.length) {
- var e = new Event('change');
- e.changes = indexes.map(function(index) {
- return {
- index: index,
- selected: this.changedIndexes_[index]
- };
- }, this);
- this.dispatchEvent(e);
- }
- this.changedIndexes_ = {};
- }
- },
-
- leadIndex_: -1,
-
- /**
- * The leadIndex is used with multiple selection and it is the index that
- * the user is moving using the arrow keys.
- * @type {number}
- */
- get leadIndex() {
- return this.leadIndex_;
- },
- set leadIndex(leadIndex) {
- var li = Math.max(-1, Math.min(this.length_ - 1, leadIndex));
- if (li != this.leadIndex_) {
- var oldLeadIndex = this.leadIndex_;
- this.leadIndex_ = li;
- cr.dispatchPropertyChange(this, 'leadIndex', li, oldLeadIndex);
- }
- },
-
- anchorIndex_: -1,
-
- /**
- * The anchorIndex is used with multiple selection.
- * @type {number}
- */
- get anchorIndex() {
- return this.anchorIndex_;
- },
- set anchorIndex(anchorIndex) {
- var ai = Math.max(-1, Math.min(this.length_ - 1, anchorIndex));
- if (ai != this.anchorIndex_) {
- var oldAnchorIndex = this.anchorIndex_;
- this.anchorIndex_ = ai;
- cr.dispatchPropertyChange(this, 'anchorIndex', ai, oldAnchorIndex);
- }
- },
-
- /**
- * Whether the selection model supports multiple selected items.
- * @type {boolean}
- */
- get multiple() {
- return true;
- },
-
- /**
- * Adjusts the selection after reordering of items in the table.
- * @param {!Array<number>} permutation The reordering permutation.
- */
- adjustToReordering: function(permutation) {
- var oldLeadIndex = this.leadIndex;
-
- var oldSelectedIndexes = this.selectedIndexes;
- this.selectedIndexes = oldSelectedIndexes.map(function(oldIndex) {
- return permutation[oldIndex];
- }).filter(function(index) {
- return index != -1;
- });
-
- if (oldLeadIndex != -1)
- this.leadIndex = permutation[oldLeadIndex];
- },
-
- /**
- * Adjusts selection model length.
- * @param {number} length New selection model length.
- */
- adjustLength: function(length) {
- this.length_ = length;
- }
- };
-
- return {
- ListSelectionModel: ListSelectionModel
- };
-});
diff --git a/chrome/common/extensions/docs/examples/extensions/plugin_settings/domui/js/cr/ui/list_single_selection_model.js b/chrome/common/extensions/docs/examples/extensions/plugin_settings/domui/js/cr/ui/list_single_selection_model.js
deleted file mode 100644
index 8c5ef786..0000000
--- a/chrome/common/extensions/docs/examples/extensions/plugin_settings/domui/js/cr/ui/list_single_selection_model.js
+++ /dev/null
@@ -1,220 +0,0 @@
-// Copyright (c) 2011 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.
-
-cr.define('cr.ui', function() {
- /** @const */ var EventTarget = cr.EventTarget;
-
- /**
- * Creates a new selection model that is to be used with lists. This only
- * allows a single index to be selected.
- *
- * @param {number=} opt_length The number items in the selection.
- *
- * @constructor
- * @extends {!cr.EventTarget}
- */
- function ListSingleSelectionModel(opt_length) {
- this.length_ = opt_length || 0;
- this.selectedIndex = -1;
- }
-
- ListSingleSelectionModel.prototype = {
- __proto__: EventTarget.prototype,
-
- /**
- * The number of items in the model.
- * @type {number}
- */
- get length() {
- return this.length_;
- },
-
- /**
- * @type {!Array} The selected indexes.
- */
- get selectedIndexes() {
- var i = this.selectedIndex;
- return i != -1 ? [this.selectedIndex] : [];
- },
-
- /**
- * Convenience getter which returns the first selected index.
- * @type {number}
- */
- get selectedIndex() {
- return this.selectedIndex_;
- },
- set selectedIndex(selectedIndex) {
- var oldSelectedIndex = this.selectedIndex;
- var i = Math.max(-1, Math.min(this.length_ - 1, selectedIndex));
-
- if (i != oldSelectedIndex) {
- this.beginChange();
- this.selectedIndex_ = i
- this.endChange();
- }
- },
-
- /**
- * Selects a range of indexes, starting with {@code start} and ends with
- * {@code end}.
- * @param {number} start The first index to select.
- * @param {number} end The last index to select.
- */
- selectRange: function(start, end) {
- // Only select first index.
- this.selectedIndex = Math.min(start, end);
- },
-
- /**
- * Selects all indexes.
- */
- selectAll: function() {
- // Select all is not allowed on a single selection model
- },
-
- /**
- * Clears the selection
- */
- clear: function() {
- this.beginChange();
- this.length_ = 0;
- this.selectedIndex = this.anchorIndex = this.leadIndex = -1;
- this.endChange();
- },
-
- /**
- * Unselects all selected items.
- */
- unselectAll: function() {
- this.selectedIndex = -1;
- },
-
- /**
- * Sets the selected state for an index.
- * @param {number} index The index to set the selected state for.
- * @param {boolean} b Whether to select the index or not.
- */
- setIndexSelected: function(index, b) {
- // Only allow selection
- var oldSelected = index == this.selectedIndex_;
- if (oldSelected == b)
- return;
-
- if (b)
- this.selectedIndex = index;
- else if (index == this.selectedIndex_)
- this.selectedIndex = -1;
- },
-
- /**
- * Whether a given index is selected or not.
- * @param {number} index The index to check.
- * @return {boolean} Whether an index is selected.
- */
- getIndexSelected: function(index) {
- return index == this.selectedIndex_;
- },
-
- /**
- * This is used to begin batching changes. Call {@code endChange} when you
- * are done making changes.
- */
- beginChange: function() {
- if (!this.changeCount_) {
- this.changeCount_ = 0;
- this.selectedIndexBefore_ = this.selectedIndex_;
- }
- this.changeCount_++;
- },
-
- /**
- * Call this after changes are done and it will dispatch a change event if
- * any changes were actually done.
- */
- endChange: function() {
- this.changeCount_--;
- if (!this.changeCount_) {
- if (this.selectedIndexBefore_ != this.selectedIndex_) {
- var e = new Event('change');
- var indexes = [this.selectedIndexBefore_, this.selectedIndex_];
- e.changes = indexes.filter(function(index) {
- return index != -1;
- }).map(function(index) {
- return {
- index: index,
- selected: index == this.selectedIndex_
- };
- }, this);
- this.dispatchEvent(e);
- }
- }
- },
-
- leadIndex_: -1,
-
- /**
- * The leadIndex is used with multiple selection and it is the index that
- * the user is moving using the arrow keys.
- * @type {number}
- */
- get leadIndex() {
- return this.leadIndex_;
- },
- set leadIndex(leadIndex) {
- var li = Math.max(-1, Math.min(this.length_ - 1, leadIndex));
- if (li != this.leadIndex_) {
- var oldLeadIndex = this.leadIndex_;
- this.leadIndex_ = li;
- cr.dispatchPropertyChange(this, 'leadIndex', li, oldLeadIndex);
- cr.dispatchPropertyChange(this, 'anchorIndex', li, oldLeadIndex);
- }
- },
-
- /**
- * The anchorIndex is used with multiple selection.
- * @type {number}
- */
- get anchorIndex() {
- return this.leadIndex;
- },
- set anchorIndex(anchorIndex) {
- this.leadIndex = anchorIndex;
- },
-
- /**
- * Whether the selection model supports multiple selected items.
- * @type {boolean}
- */
- get multiple() {
- return false;
- },
-
- /**
- * Adjusts the selection after reordering of items in the table.
- * @param {!Array<number>} permutation The reordering permutation.
- */
- adjustToReordering: function(permutation) {
- if (this.leadIndex != -1)
- this.leadIndex = permutation[this.leadIndex];
-
- var oldSelectedIndex = this.selectedIndex;
- if (oldSelectedIndex != -1) {
- this.selectedIndex = permutation[oldSelectedIndex];
- }
- },
-
- /**
- * Adjusts selection model length.
- * @param {number} length New selection model length.
- */
- adjustLength: function(length) {
- this.length_ = length;
- }
- };
-
- return {
- ListSingleSelectionModel: ListSingleSelectionModel
- };
-});
diff --git a/chrome/common/extensions/docs/examples/extensions/plugin_settings/domui/js/util.js b/chrome/common/extensions/docs/examples/extensions/plugin_settings/domui/js/util.js
deleted file mode 100644
index 1efbf19..0000000
--- a/chrome/common/extensions/docs/examples/extensions/plugin_settings/domui/js/util.js
+++ /dev/null
@@ -1,151 +0,0 @@
-// Copyright (c) 2011 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.
-
-/**
- * The global object.
- * @type {!Object}
- */
-const global = this;
-
-/**
- * Alias for document.getElementById.
- * @param {string} id The ID of the element to find.
- * @return {HTMLElement} The found element or null if not found.
- */
-function $(id) {
- return document.getElementById(id);
-}
-
-/**
- * Calls chrome.send with a callback and restores the original afterwards.
- * @param {string} name The name of the message to send.
- * @param {!Array} params The parameters to send.
- * @param {string} callbackName The name of the function that the backend calls.
- * @param {!Function} The function to call.
- */
-function chromeSend(name, params, callbackName, callback) {
- var old = global[callbackName];
- global[callbackName] = function() {
- // restore
- global[callbackName] = old;
-
- var args = Array.prototype.slice.call(arguments);
- return callback.apply(global, args);
- };
- chrome.send(name, params);
-}
-
-/**
- * Generates a CSS url string.
- * @param {string} s The URL to generate the CSS url for.
- * @return {string} The CSS url string.
- */
-function url(s) {
- // http://www.w3.org/TR/css3-values/#uris
- // Parentheses, commas, whitespace characters, single quotes (') and double
- // quotes (") appearing in a URI must be escaped with a backslash
- var s2 = s.replace(/(\(|\)|\,|\s|\'|\"|\\)/g, '\\$1');
- // WebKit has a bug when it comes to URLs that end with \
- // https://bugs.webkit.org/show_bug.cgi?id=28885
- if (/\\\\$/.test(s2)) {
- // Add a space to work around the WebKit bug.
- s2 += ' ';
- }
- return 'url("' + s2 + '")';
-}
-
-/**
- * Parses query parameters from Location.
- * @param {string} s The URL to generate the CSS url for.
- * @return {object} Dictionary containing name value pairs for URL
- */
-function parseQueryParams(location) {
- var params = {};
- var query = unescape(location.search.substring(1));
- var vars = query.split("&");
- for (var i=0; i < vars.length; i++) {
- var pair = vars[i].split("=");
- params[pair[0]] = pair[1];
- }
- return params;
-}
-
-function findAncestorByClass(el, className) {
- return findAncestor(el, function(el) {
- if (el.classList)
- return el.classList.contains(className);
- return null;
- });
-}
-
-/**
- * Return the first ancestor for which the {@code predicate} returns true.
- * @param {Node} node The node to check.
- * @param {function(Node) : boolean} predicate The function that tests the
- * nodes.
- * @return {Node} The found ancestor or null if not found.
- */
-function findAncestor(node, predicate) {
- var last = false;
- while (node != null && !(last = predicate(node))) {
- node = node.parentNode;
- }
- return last ? node : null;
-}
-
-function swapDomNodes(a, b) {
- var afterA = a.nextSibling;
- if (afterA == b) {
- swapDomNodes(b, a);
- return;
- }
- var aParent = a.parentNode;
- b.parentNode.replaceChild(a, b);
- aParent.insertBefore(b, afterA);
-}
-
-/**
- * Disables text selection and dragging.
- */
-function disableTextSelectAndDrag() {
- // Disable text selection.
- document.onselectstart = function(e) {
- e.preventDefault();
- }
-
- // Disable dragging.
- document.ondragstart = function(e) {
- e.preventDefault();
- }
-}
-
-// Handle click on a link. If the link points to a chrome: or file: url, then
-// call into the browser to do the navigation.
-document.addEventListener('click', function(e) {
- // Allow preventDefault to work.
- if (!e.returnValue)
- return;
-
- var el = e.target;
- if (el.nodeType == Node.ELEMENT_NODE &&
- el.webkitMatchesSelector('A, A *')) {
- while (el.tagName != 'A') {
- el = el.parentElement;
- }
-
- if ((el.protocol == 'file:' || el.protocol == 'about:') &&
- (e.button == 0 || e.button == 1)) {
- chrome.send('navigateToUrl', [
- el.href,
- el.target,
- e.button,
- e.altKey,
- e.ctrlKey,
- e.metaKey,
- e.shiftKey
- ]);
- e.preventDefault();
- }
- }
-});
diff --git a/chrome/common/extensions/docs/examples/extensions/plugin_settings/js/chrome_stubs.js b/chrome/common/extensions/docs/examples/extensions/plugin_settings/js/chrome_stubs.js
deleted file mode 100644
index 63e61b2..0000000
--- a/chrome/common/extensions/docs/examples/extensions/plugin_settings/js/chrome_stubs.js
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright (c) 2012 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.
-
-/**
- * @fileoverview Stubs for Chrome extension APIs that aren't available to
- * regular web pages, to allow tests to run.
- */
-
-chrome = chrome || {};
-chrome.extension = chrome.extension || {};
-chrome.contentSettings = chrome.contentSettings || {};
-
-var _rules = {};
-chrome.contentSettings.plugins = {
- 'set': function(details, callback) {
- assertObjectEquals({'id': 'myplugin'}, details.resourceIdentifier);
- var pattern = details.primaryPattern;
- var setting = details.setting;
- if (pattern == '__invalid_pattern') {
- chrome.runtime.lastError = {'message': 'Invalid pattern'};
- } else if (setting == '__invalid_setting') {
- throw Error('Invalid setting');
- } else {
- chrome.runtime.lastError = undefined;
- _rules[pattern] = setting;
- }
- callback();
- },
-
- 'clear': function(details, callback) {
- assertObjectEquals({}, details);
- _rules = {};
- callback();
- }
-};
-
-chrome.i18n = chrome.i18n || {};
-chrome.i18n.getMessage = function(id) {
- var messages = {
- 'patternColumnHeader': 'Hostname Pattern',
- 'settingColumnHeader': 'Behavior',
- 'allowRule': 'Allow',
- 'blockRule': 'Block',
- 'addNewPattern': 'Add a new hostname pattern',
- };
- return messages[id];
-}
-
-/**
- * Creates a new Settings object with a set of rules for a dummy plugin.
- * Because we provide stub implementations for the Chrome contentSettings
- * extension API, we know that the methods will execute immediately instead of
- * asynchronously.
- * @param {!Object} rules A map from content settings pattern to setting.
- * @return {!pluginSettings.Settings} A newly created Settings object with the
- * passed in set of rules.
- */
-function createSettings(rules) {
- var settings = new pluginSettings.Settings('myplugin');
- if (rules) {
- for (var pattern in rules) {
- settings.set(pattern, rules[pattern], function() {});
- }
- }
- return settings;
-}
-
diff --git a/chrome/common/extensions/docs/examples/extensions/plugin_settings/js/main.js b/chrome/common/extensions/docs/examples/extensions/plugin_settings/js/main.js
deleted file mode 100644
index c731ff737..0000000
--- a/chrome/common/extensions/docs/examples/extensions/plugin_settings/js/main.js
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright (c) 2012 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.
-
-/**
- * @fileoverview Main entry point that creates a new plugin list on document
- * load.
- */
-
-document.addEventListener('DOMContentLoaded', function() {
- chrome.contentSettings.plugins.getResourceIdentifiers(function(r) {
- if (chrome.runtime.lastError) {
- $('error').textContent =
- 'Error: ' + chrome.runtime.lastError.message;
- return;
- }
- var pluginList = $('plugin-list');
- pluginSettings.ui.PluginList.decorate(pluginList);
- pluginList.dataModel = new cr.ui.ArrayDataModel(r);
- });
-});
-
diff --git a/chrome/common/extensions/docs/examples/extensions/plugin_settings/js/plugin_list.js b/chrome/common/extensions/docs/examples/extensions/plugin_settings/js/plugin_list.js
deleted file mode 100644
index a0dff4c7..0000000
--- a/chrome/common/extensions/docs/examples/extensions/plugin_settings/js/plugin_list.js
+++ /dev/null
@@ -1,297 +0,0 @@
-// Copyright (c) 2012 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.
-
-/**
- * @fileoverview Defines a list of plugins that shows for each plugin a list
- * of content setting rules.
- */
-
-cr.define('pluginSettings.ui', function() {
- const List = cr.ui.List;
- const ListItem = cr.ui.ListItem;
- const ListSingleSelectionModel = cr.ui.ListSingleSelectionModel;
-
- /**
- * CSS classes used by this class.
- * @enum {string}
- */
- const CSSClass = {
-
- /**
- * Hides an element.
- */
- HIDDEN: 'hidden',
-
- /**
- * A plugin list.
- */
- PLUGIN_LIST: 'plugin-list',
-
- /**
- * Set on a plugin list entry to show details about the plugin.
- */
- PLUGIN_SHOW_DETAILS: 'plugin-show-details',
-
- /**
- * The plugin name.
- */
- PLUGIN_NAME: 'plugin-name',
-
- /**
- * The number of rules set for a plugin.
- */
- NUM_RULES: 'num-rules',
-
- /**
- * The element containing details about a plugin.
- */
- PLUGIN_DETAILS: 'plugin-details',
-
- /**
- * The element containing the column headers for the list of rules.
- */
- COLUMN_HEADERS: 'column-headers',
-
- /**
- * The header for the pattern column.
- */
- PATTERN_COLUMN_HEADER: 'pattern-column-header',
-
- /**
- * The header for the setting column.
- */
- SETTING_COLUMN_HEADER: 'setting-column-header',
- };
-
- /**
- * Returns the item's height, like offsetHeight but such that it works better
- * when the page is zoomed. See the similar calculation in @{code cr.ui.List}.
- * This version also accounts for the animation done in this file.
- * @param {!Element} item The item to get the height of.
- * @return {number} The height of the item, calculated with zooming in mind.
- */
- function getItemHeight(item) {
- var height = item.style.height;
- // Use the fixed animation target height if set, in case the element is
- // currently being animated and we'd get an intermediate height below.
- if (height && height.substr(-2) == 'px') {
- return parseInt(height.substr(0, height.length - 2));
- }
- return item.getBoundingClientRect().height;
- }
-
- /**
- * Creates a new plugin list item element.
- * @param {!PluginList} list The plugin list containing this item.
- * @param {!Object} info Information about the plugin.
- * @constructor
- * @extends {cr.ui.ListItem}
- */
- function PluginListItem(list, info) {
- var el = cr.doc.createElement('li');
-
- /**
- * The plugin list containing this item.
- * @type {!PluginList}
- * @private
- */
- el.list_ = list;
-
- /**
- * Information about the plugin.
- * @type {!Object}
- * @private
- */
- el.info_ = info;
-
- el.__proto__ = PluginListItem.prototype;
- el.decorate();
- return el;
- }
-
- PluginListItem.prototype = {
- __proto__: ListItem.prototype,
-
- /**
- * The element containing details about the plugin. This is only null in
- * the prototype.
- * @type {?HTMLDivElement}
- * @private
- */
- detailsElement_: null,
-
- /**
- * Initializes the element.
- */
- decorate: function() {
- ListItem.prototype.decorate.call(this);
-
- var info = this.info_;
-
- var contentElement = this.ownerDocument.createElement('div');
-
- var titleEl = this.ownerDocument.createElement('div');
- var nameEl = this.ownerDocument.createElement('span');
- nameEl.className = CSSClass.PLUGIN_NAME;
- nameEl.textContent = info.description;
- nameEl.title = info.description;
- titleEl.appendChild(nameEl);
- this.numRulesEl_ = this.ownerDocument.createElement('span');
- this.numRulesEl_.className = CSSClass.NUM_RULES;
- titleEl.appendChild(this.numRulesEl_);
- contentElement.appendChild(titleEl);
-
- this.detailsElement_ = this.ownerDocument.createElement('div');
- this.detailsElement_.classList.add(CSSClass.PLUGIN_DETAILS);
- this.detailsElement_.classList.add(CSSClass.HIDDEN);
-
- var columnHeadersEl = this.ownerDocument.createElement('div');
- columnHeadersEl.className = CSSClass.COLUMN_HEADERS;
- var patternColumnEl = this.ownerDocument.createElement('div');
- patternColumnEl.textContent =
- chrome.i18n.getMessage('patternColumnHeader');
- patternColumnEl.className = CSSClass.PATTERN_COLUMN_HEADER;
- var settingColumnEl = this.ownerDocument.createElement('div');
- settingColumnEl.textContent =
- chrome.i18n.getMessage('settingColumnHeader');
- settingColumnEl.className = CSSClass.SETTING_COLUMN_HEADER;
- columnHeadersEl.appendChild(patternColumnEl);
- columnHeadersEl.appendChild(settingColumnEl);
- this.detailsElement_.appendChild(columnHeadersEl);
- contentElement.appendChild(this.detailsElement_);
-
- this.appendChild(contentElement);
-
- var settings = new pluginSettings.Settings(this.info_.id);
- this.updateRulesCount_(settings);
- settings.addEventListener(
- 'change',
- this.updateRulesCount_.bind(this, settings));
-
- // Create the rule list asynchronously, to make sure that it is already
- // fully integrated in the DOM tree.
- window.setTimeout(this.loadRules_.bind(this, settings), 0);
- },
-
- /**
- * Create the list of content setting rules applying to this plugin.
- * @param {!pluginSettings.Settings} The settings object storing the content
- * setting rules.
- * @private
- */
- loadRules_: function(settings) {
- var rulesEl = this.ownerDocument.createElement('list');
- this.detailsElement_.appendChild(rulesEl);
-
- pluginSettings.ui.RuleList.decorate(rulesEl);
- rulesEl.setPluginSettings(settings);
- },
-
- /**
- * Called when the list of rules changes to update the rule count shown when
- * the list is not expanded.
- * @param {!pluginSettings.Settings} The settings object storing the content
- * setting rules.
- * @private
- */
- updateRulesCount_: function(settings) {
- this.numRulesEl_.textContent = '(' + settings.getAll().length + ' rules)';
- },
-
- /**
- * Whether this item is expanded or not.
- * @type {boolean}
- */
- expanded_: false,
- /**
- * Whether this item is expanded or not.
- * @type {boolean}
- */
- get expanded() {
- return this.expanded_;
- },
- set expanded(expanded) {
- if (this.expanded_ == expanded) {
- return;
- }
- this.expanded_ = expanded;
- if (expanded) {
- var oldExpanded = this.list_.expandItem;
- this.list_.expandItem = this;
- this.detailsElement_.classList.remove(CSSClass.HIDDEN);
- if (oldExpanded) {
- oldExpanded.expanded = false;
- }
- this.classList.add(CSSClass.PLUGIN_SHOW_DETAILS);
- } else {
- if (this.list_.expandItem == this) {
- this.list_.leadItemHeight = 0;
- this.list_.expandItem = null;
- }
- this.style.height = '';
- this.detailsElement_.classList.add(CSSClass.HIDDEN);
- this.classList.remove(CSSClass.PLUGIN_SHOW_DETAILS);
- }
- },
- };
-
- /**
- * Creates a new plugin list.
- * @constructor
- * @extends {cr.ui.List}
- */
- var PluginList = cr.ui.define('list');
-
- PluginList.prototype = {
- __proto__: List.prototype,
-
- /**
- * Initializes the element.
- */
- decorate: function() {
- List.prototype.decorate.call(this);
- this.classList.add(CSSClass.PLUGIN_LIST);
- var sm = new ListSingleSelectionModel();
- sm.addEventListener('change', this.handleSelectionChange_.bind(this));
- this.selectionModel = sm;
- this.autoExpands = true;
- },
-
- /**
- * Creates a new plugin list item.
- * @param {!Object} info Information about the plugin.
- */
- createItem: function(info) {
- return new PluginListItem(this, info);
- },
-
- /**
- * Called when the selection changes.
- * @param {!Event} ce The change event.
- * @private
- */
- handleSelectionChange_: function(ce) {
- ce.changes.forEach(function(change) {
- var listItem = this.getListItemByIndex(change.index);
- if (listItem) {
- if (!change.selected) {
- // TODO(bsmith) explain window timeout (from cookies_list.js)
- window.setTimeout(function() {
- if (!listItem.selected || !listItem.lead) {
- listItem.expanded = false;
- }
- }, 0);
- } else if (listItem.lead) {
- listItem.expanded = true;
- }
- }
- }, this);
- },
- };
-
- return {
- PluginList: PluginList,
- PluginListItem: PluginListItem,
- };
-});
diff --git a/chrome/common/extensions/docs/examples/extensions/plugin_settings/js/plugin_list_test.html b/chrome/common/extensions/docs/examples/extensions/plugin_settings/js/plugin_list_test.html
deleted file mode 100644
index 9fd852a..0000000
--- a/chrome/common/extensions/docs/examples/extensions/plugin_settings/js/plugin_list_test.html
+++ /dev/null
@@ -1,68 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<style>
-#error {
- display: none;
-}
-</style>
-<link rel="stylesheet" href="../domui/css/button.css">
-<link rel="stylesheet" href="../domui/css/chrome_shared.css">
-<link rel="stylesheet" href="../domui/css/list.css">
-<link rel="stylesheet" href="../domui/css/select.css">
-
-<link rel="stylesheet" href="../options/css/list.css">
-
-<link rel="stylesheet" href="../css/plugin_list.css">
-<link rel="stylesheet" href="../css/rule_list.css">
-
-<script src="http://closure-library.googlecode.com/svn/trunk/closure/goog/base.js"></script>
-<script src="../domui/js/cr.js"></script>
-<script src="../domui/js/cr/event_target.js"></script>
-<script src="../domui/js/cr/ui.js"></script>
-<script src="../domui/js/cr/ui/array_data_model.js"></script>
-<script src="../domui/js/cr/ui/list_item.js"></script>
-<script src="../domui/js/cr/ui/list_selection_controller.js"></script>
-<script src="../domui/js/cr/ui/list_selection_model.js"></script>
-<script src="../domui/js/cr/ui/list_single_selection_model.js"></script>
-<script src="../domui/js/cr/ui/list.js"></script>
-<script src="../domui/js/util.js"></script>
-
-<script src="../options/js/deletable_item_list.js"></script>
-<script src="../options/js/inline_editable_list.js"></script>
-
-<script src="plugin_list.js" type="text/javascript"></script>
-<script src="plugin_settings.js" type="text/javascript"></script>
-<script src="rule_list.js" type="text/javascript"></script>
-
-<script>
-goog.require('goog.testing.jsunit');
-</script>
-<script src="chrome_stubs.js" type="text/javascript"></script>
-</head>
-<body>
-<div id="error"></div>
-<script>
-function testConstruction() {
- var pluginList = document.createElement('list');
- document.body.appendChild(pluginList);
- pluginSettings.ui.PluginList.decorate(pluginList);
- var plugins = [
- {
- 'id': 'myplugin',
- 'description': 'My Plugin'
- }
- ];
- var rules = {
- 'http://example.com/*': 'block',
- 'http://moose.org/*': 'allow',
- };
- createSettings(rules);
- pluginList.dataModel = new cr.ui.ArrayDataModel(plugins);
- assertEquals('My Plugin',
- pluginList.querySelector('.plugin-name').textContent);
- assertEquals('(2 rules)', pluginList.querySelector('.num-rules').textContent);
-}
-</script>
-</body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/extensions/plugin_settings/js/plugin_settings.js b/chrome/common/extensions/docs/examples/extensions/plugin_settings/js/plugin_settings.js
deleted file mode 100644
index 1727356..0000000
--- a/chrome/common/extensions/docs/examples/extensions/plugin_settings/js/plugin_settings.js
+++ /dev/null
@@ -1,219 +0,0 @@
-// Copyright (c) 2012 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.
-
-/**
- * @fileoverview Defines a class that provides some convenient wrapper methods
- * around the Chrome contentSettings extension API.
- */
-
-cr.define('pluginSettings', function() {
- /** @const */ var EventTarget = cr.EventTarget;
-
- /**
- * Creates a new content settings model.
- * @param {string} plugin Identifies the plugin for which this object stores
- * settings.
- * @constructor
- * @extends {cr.EventTarget}
- */
- function Settings(plugin) {
- /**
- * Identifies the plugin for which this object stores settings.
- * @type {string}
- * @private
- */
- this.plugin_ = plugin;
- }
-
- Settings.prototype = {
- __proto__: cr.EventTarget.prototype,
-
- /**
- * Clears all content settings, and recreates them from local storage. If a
- * content setting can't be set (which shouldn't really happen, as it has
- * been successfully set previously), it is removed from local storage as
- * well.
- * @param {function()} callback Called when the content settings have been
- * recreated, or on error.
- * @private
- */
- recreateRules_: function(callback) {
- chrome.contentSettings.plugins.clear(
- {}, this.didClearRules_.bind(this, callback));
- },
-
- /**
- * Recreates all content settings from local storage.
- * @param {function()} callback Called when the content settings have been
- * recreated, or on error.
- * @private
- */
- didClearRules_: function(callback) {
- if (chrome.runtime.lastError) {
- console.error('Error clearing rules');
- callback();
- return;
- }
- var length = window.localStorage.length;
- if (length == 0) {
- cr.dispatchSimpleEvent(settings, 'change');
- callback();
- return;
- }
- var counter = {
- 'value': length
- };
- for (var i = 0; i < length; i++) {
- var key = window.localStorage.key(i);
- var keyArray = JSON.parse(key);
- var plugin = keyArray[0];
- var pattern = keyArray[1];
- var setting = window.localStorage.getItem(key)
- chrome.contentSettings.plugins.set(
- {
- 'primaryPattern': pattern,
- 'resourceIdentifier': {'id': plugin},
- 'setting': setting,
- },
- this.didSetContentSetting_.bind(
- this, key, setting, counter, callback));
- }
- },
-
- /**
- * Checks if we're finished with recreating content settings and calls the
- * passed in callback if so.
- * @param {string} key The local storage key under which the content
- * setting was stored.
- * @param {string} value The content setting value in local storage.
- * @param {{value:number}} counter Contains the number of callbacks still
- * outstanding.
- * @param {function()} callback Called when the content settings have been
- * recreated, or on error.
- * @private
- */
- didSetContentSetting_: function(plugin, pattern, key, counter, callback) {
- if (chrome.runtime.lastError) {
- console.error(
- 'Error restoring [' + key + ': ' + value + ']: ' +
- chrome.runtime.lastError.message);
- window.localStorage.removeItem(key);
- }
- counter.value--;
- if (counter.value == 0) {
- cr.dispatchSimpleEvent(this, 'change');
- callback();
- }
- },
-
- /**
- * Creates a content setting rule and calls the passed in callback with the
- * result.
- * @param {string} pattern The content setting pattern for the rule.
- * @param {string} setting The setting for the rule.
- * @param {function(?string)} callback Called when the content settings
- * have been updated, or on error.
- */
- set: function(pattern, setting, callback) {
- var plugin = this.plugin_;
- var settings = this;
- chrome.contentSettings.plugins.set({
- 'primaryPattern': pattern,
- 'resourceIdentifier': { 'id': plugin },
- 'setting': setting,
- }, function() {
- if (chrome.runtime.lastError) {
- callback(chrome.runtime.lastError.message);
- } else {
- window.localStorage.setItem(JSON.stringify([plugin, pattern]),
- setting);
- cr.dispatchSimpleEvent(settings, 'change');
- callback();
- }
- });
- },
-
- /**
- * Removes the content setting rule with a given pattern, and calls the
- * passed in callback afterwards.
- * @param {string} pattern The content setting pattern for the rule.
- * @param {function()} callback Called when the content settings have
- * been updated.
- */
- clear: function(pattern, callback) {
- window.localStorage.removeItem(
- JSON.stringify([this.plugin_, pattern]));
- this.recreateRules_(callback);
- },
-
- /**
- * Updates the content setting rule with a given pattern to a new pattern
- * and setting and calls the passed in callback with the result.
- * @param {string} oldPattern The old content setting pattern for the rule.
- * @param {string} newPattern The new content setting pattern for the rule.
- * @param {string} setting The setting for the rule.
- * @param {function(?string)} callback Called when the content settings
- * have been updated, or on error.
- */
- update: function(oldPattern, newPattern, setting, callback) {
- if (oldPattern == newPattern) {
- // Avoid recreating all rules if only the setting changed.
- this.set(newPattern, setting, callback);
- return;
- }
- var oldSetting = this.get(oldPattern);
- var settings = this;
- // Remove the old rule.
- this.clear(oldPattern, function() {
- // Try to set the new rule.
- settings.set(newPattern, setting, function(error) {
- if (error) {
- // If setting the new rule failed, restore the old rule.
- settings.set(oldPattern, oldSetting, function(restoreError) {
- if (restoreError) {
- console.error('Error restoring [' + settings.plugin_ + ', ' +
- oldPattern + oldSetting + ']: ' + restoreError);
- }
- callback(error);
- });
- } else {
- callback();
- }
- });
- });
- },
-
- /**
- * Returns the content setting for a given pattern.
- * @param {string} pattern The content setting pattern for the rule.
- * @return {string} The setting for the rule.
- */
- get: function(primaryPattern) {
- return window.localStorage.getItem(
- JSON.stringify([this.plugin_, primaryPattern]));
- },
-
- /**
- * @return {!Array} A list of all content setting rules for this plugin.
- */
- getAll: function() {
- var rules = [];
- for (var i = 0; i < window.localStorage.length; i++) {
- var key = window.localStorage.key(i);
- var keyArray = JSON.parse(key);
- if (keyArray[0] == this.plugin_) {
- rules.push({
- 'primaryPattern': keyArray[1],
- 'setting': window.localStorage.getItem(key),
- });
- }
- }
- return rules;
- }
- };
-
- return {
- Settings: Settings,
- }
-});
diff --git a/chrome/common/extensions/docs/examples/extensions/plugin_settings/js/plugin_settings_test.html b/chrome/common/extensions/docs/examples/extensions/plugin_settings/js/plugin_settings_test.html
deleted file mode 100644
index 7bcad36b..0000000
--- a/chrome/common/extensions/docs/examples/extensions/plugin_settings/js/plugin_settings_test.html
+++ /dev/null
@@ -1,143 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<script src="http://closure-library.googlecode.com/svn/trunk/closure/goog/base.js"></script>
-<script src="../domui/js/cr.js"></script>
-<script src="../domui/js/cr/event_target.js"></script>
-<script src="plugin_settings.js" type="text/javascript"></script>
-<script>
-goog.require('goog.testing.jsunit');
-</script>
-<script src="chrome_stubs.js" type="text/javascript"></script>
-</head>
-<body>
-<script>
-function testConstruction() {
- var settings = createSettings();
-}
-
-function testSet() {
- var settings = createSettings();
- var rules = {
- 'http://example.com/*': 'block',
- 'http://google.com/*': 'allow',
- 'http://moose.org/*': 'allow',
- };
- var numCallbacks = 0;
- for (var pattern in rules) {
- settings.set(pattern, rules[pattern], function(error) {
- numCallbacks++;
- assertUndefined(error);
- });
- }
- assertEquals(Object.keys(rules).length, numCallbacks);
- assertObjectEquals(rules, _rules);
-}
-
-function testSetInvalid() {
- var settings = createSettings();
- // Attempting to set an invalid pattern should return an error in the
- // callback.
- var callbackCalled = false;
- settings.set('__invalid_pattern', 'block', function(error) {
- callbackCalled = true;
- assertEquals('Invalid pattern', error);
- });
- assertTrue(callbackCalled);
- assertObjectEquals({}, _rules);
-
- // Attempting to set an invalid setting should immediately throw an exception.
- callbackCalled = false;
- assertThrows(function() {
- settings.set('http://example.com/*', '__invalid_setting', function() {
- callbackCalled = true;
- });
- });
- assertFalse(callbackCalled);
- assertObjectEquals({}, _rules);
-}
-
-function testGet() {
- var rules = {
- 'http://example.com/*': 'block',
- 'http://google.com/*': 'allow',
- 'http://moose.org/*': 'allow',
- };
- var settings = createSettings(rules);
- for (var pattern in rules)
- assertEquals(rules[pattern], settings.get(pattern));
-}
-
-function testGetAll() {
- var settings = createSettings({
- 'http://example.com/*': 'block',
- 'http://google.com/*': 'allow',
- 'http://moose.org/*': 'allow',
- });
- var rules = settings.getAll();
- // Sort the rules lexicographically by their pattern.
- rules.sort(function(a, b) {
- if (a.primaryPattern == b.primaryPattern) {
- return 0;
- }
- if (a.primaryPattern > b.primaryPattern) {
- return 1;
- }
- return -1;
- });
- assertEquals(3, rules.length);
- assertObjectEquals({'primaryPattern': 'http://example.com/*',
- 'setting': 'block'},
- rules[0]);
- assertObjectEquals({'primaryPattern': 'http://google.com/*',
- 'setting': 'allow'},
- rules[1]);
- assertObjectEquals({'primaryPattern': 'http://moose.org/*',
- 'setting': 'allow'},
- rules[2]);
-}
-
-function testUpdate() {
- var settings = createSettings({
- 'http://example.com/*': 'block',
- 'http://google.com/*': 'allow',
- 'http://moose.org/*': 'allow',
- });
- var numCallbacks = 0;
- settings.update('http://google.com/*', 'http://google.com/*', 'ask',
- function(error) {
- numCallbacks++;
- assertUndefined(error);
- });
- assertEquals('ask', _rules['http://google.com/*']);
-
- settings.update('http://google.com/*', 'http://blurp.net/*', 'ask',
- function(error) {
- numCallbacks++;
- assertUndefined(error);
- });
- assertUndefined(_rules['http://google.com/*']);
- assertEquals('ask', _rules['http://blurp.net/*']);
-
- // Attempting to update a rule to an invalid pattern should return an error
- // and leave the rules unchanged.
- settings.update('http://example.com/*', '__invalid_pattern', 'ask',
- function(error) {
- numCallbacks++;
- assertEquals('Invalid pattern', error);
- });
- assertUndefined(_rules['__invalid_pattern']);
- assertEquals('block', _rules['http://example.com/*']);
-
- assertEquals(3, numCallbacks);
-}
-
-function tearDown() {
- // Clear local storage and |rules_| to make sure no state leaks into the next
- // test.
- window.localStorage.clear();
- _rules = {};
-}
-</script>
-</body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/extensions/plugin_settings/js/rule_list.js b/chrome/common/extensions/docs/examples/extensions/plugin_settings/js/rule_list.js
deleted file mode 100644
index 63cb846..0000000
--- a/chrome/common/extensions/docs/examples/extensions/plugin_settings/js/rule_list.js
+++ /dev/null
@@ -1,423 +0,0 @@
-// Copyright (c) 2012 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.
-
-/**
- * @fileoverview Defines a list of content setting rules.
- */
-
-cr.define('pluginSettings.ui', function() {
- const InlineEditableItemList = options.InlineEditableItemList;
- const InlineEditableItem = options.InlineEditableItem;
- const ArrayDataModel = cr.ui.ArrayDataModel;
-
- /**
- * CSS classes used by this class.
- * @enum {string}
- */
- const CSSClass = {
- /**
- * A list of content setting rules.
- */
- RULE_LIST: 'rule-list',
-
- /**
- * The element containing the content setting pattern for a rule.
- */
- RULE_PATTERN: 'rule-pattern',
-
- /**
- * The element containing the behavior (allow or block) for a rule.
- */
- RULE_BEHAVIOR: 'rule-behavior',
-
- /**
- * Static text (as opposed to an editable text field).
- */
- STATIC_TEXT: 'static-text',
- };
- /**
- * A single item in a list of rules.
- * @param {!RuleList} list The rule list containing this item.
- * @param {!Object} rule The content setting rule.
- * @constructor
- * @extends {options.InlineEditableItem}
- */
- function RuleListItem(list, rule) {
- var el = cr.doc.createElement('li');
-
- /**
- * The content setting rule.
- * @type {!Object}
- * @private
- */
- el.dataItem_ = rule;
-
- /**
- * The rule list containing this item.
- * @type {!RuleList}
- * @private
- */
- el.list_ = list;
- el.__proto__ = RuleListItem.prototype;
- el.decorate();
-
- return el;
- }
-
- RuleListItem.prototype = {
- __proto__: InlineEditableItem.prototype,
-
- /**
- * The text input element for the pattern. This is only null in the
- * prototype.
- * @type {?HTMLInputElement}
- * @private
- */
- input_: null,
-
- /**
- * The popup button for the setting. This is only null in the prototype.
- * @type {?HTMLSelectElement}
- * @private
- */
- select_: null,
-
- /**
- * The static text field containing the pattern.
- * @type {?HTMLDivElement}
- * @private
- */
- patternLabel_: null,
-
- /**
- * The static text field containing the setting.
- * @type {?HTMLDivElement}
- * @private
- */
- settingLabel_: null,
-
- /**
- * Decorates an elements as a list item.
- */
- decorate: function() {
- InlineEditableItem.prototype.decorate.call(this);
-
- this.isPlaceholder = !this.pattern;
- var patternCell = this.createEditableTextCell(this.pattern);
- patternCell.className = CSSClass.RULE_PATTERN;
- this.contentElement.appendChild(patternCell);
- var input = patternCell.querySelector('input');
- if (this.pattern) {
- this.patternLabel_ =
- patternCell.querySelector('.' + CSSClass.STATIC_TEXT);
- } else {
- input.placeholder = chrome.i18n.getMessage('addNewPattern');
- }
-
- // Setting label for display mode. |pattern| will be null for the 'add new
- // exception' row.
- if (this.pattern) {
- var settingLabel = cr.doc.createElement('span');
- settingLabel.textContent = this.settingForDisplay();
- settingLabel.className = CSSClass.RULE_BEHAVIOR;
- settingLabel.setAttribute('displaymode', 'static');
- this.contentElement.appendChild(settingLabel);
- this.settingLabel_ = settingLabel;
- }
-
- // Setting select element for edit mode.
- var select = cr.doc.createElement('select');
- var optionAllow = cr.doc.createElement('option');
- optionAllow.textContent = chrome.i18n.getMessage('allowRule');
- optionAllow.value = 'allow';
- select.appendChild(optionAllow);
-
- var optionBlock = cr.doc.createElement('option');
- optionBlock.textContent = chrome.i18n.getMessage('blockRule');
- optionBlock.value = 'block';
- select.appendChild(optionBlock);
-
- this.contentElement.appendChild(select);
- select.className = CSSClass.RULE_BEHAVIOR;
- if (this.pattern) {
- select.setAttribute('displaymode', 'edit');
- }
-
- this.input_ = input;
- this.select_ = select;
-
- this.updateEditables();
-
- // Listen for edit events.
- this.addEventListener('canceledit', this.onEditCancelled_);
- this.addEventListener('commitedit', this.onEditCommitted_);
- },
-
- /**
- * The pattern (e.g., a URL) for the rule.
- * @type {string}
- */
- get pattern() {
- return this.dataItem_['primaryPattern'];
- },
- set pattern(pattern) {
- this.dataItem_['primaryPattern'] = pattern;
- },
-
- /**
- * The setting (allow/block) for the rule.
- * @type {string}
- */
- get setting() {
- return this.dataItem_['setting'];
- },
- set setting(setting) {
- this.dataItem_['setting'] = setting;
- },
-
- /**
- * Gets a human-readable setting string.
- * @type {string}
- */
- settingForDisplay: function() {
- var setting = this.setting;
- if (setting == 'allow') {
- return chrome.i18n.getMessage('allowRule');
- }
- if (setting == 'block') {
- return chrome.i18n.getMessage('blockRule');
- }
- },
-
- /**
- * Set the <input> to its original contents. Used when the user quits
- * editing.
- */
- resetInput: function() {
- this.input_.value = this.pattern;
- },
-
- /**
- * Copy the data model values to the editable nodes.
- */
- updateEditables: function() {
- this.resetInput();
-
- var settingOption =
- this.select_.querySelector('[value=\'' + this.setting + '\']');
- if (settingOption) {
- settingOption.selected = true;
- }
- },
-
- /** @inheritDoc */
- get hasBeenEdited() {
- var livePattern = this.input_.value;
- var liveSetting = this.select_.value;
- return livePattern != this.pattern || liveSetting != this.setting;
- },
-
- /**
- * Called when committing an edit.
- * @param {!Event} e The end event.
- * @private
- */
- onEditCommitted_: function(e) {
- var newPattern = this.input_.value;
- var newSetting = this.select_.value;
-
- this.finishEdit(newPattern, newSetting);
- },
-
- /**
- * Called when cancelling an edit; resets the control states.
- * @param {!Event} e The cancel event.
- * @private
- */
- onEditCancelled_: function() {
- this.updateEditables();
- },
-
- /**
- * Editing is complete; update the model.
- * @param {string} newPattern The pattern that the user entered.
- * @param {string} newSetting The setting the user chose.
- */
- finishEdit: function(newPattern, newSetting) {
- this.patternLabel_.textContent = newPattern;
- this.settingLabel_.textContent = this.settingForDisplay();
- var oldPattern = this.pattern;
- this.pattern = newPattern;
- this.setting = newSetting;
-
- this.list_.settings.update(oldPattern, newPattern, newSetting,
- this.list_.settingsChangedCallback());
- }
- };
-
- /**
- * Create a new list item to add a rule.
- * @param {!RuleList} list The rule list containing this item.
- * @constructor
- * @extends {AddRuleListItem}
- */
- function AddRuleListItem(list) {
- var el = cr.doc.createElement('div');
- el.dataItem_ = {};
- el.list_ = list;
- el.__proto__ = AddRuleListItem.prototype;
- el.decorate();
-
- return el;
- }
-
- AddRuleListItem.prototype = {
- __proto__: RuleListItem.prototype,
-
- /**
- * Initializes the element.
- */
- decorate: function() {
- RuleListItem.prototype.decorate.call(this);
-
- this.setting = 'allow';
- },
-
- /**
- * Clear the <input> and let the placeholder text show again.
- */
- resetInput: function() {
- this.input_.value = '';
- },
-
- /** @inheritDoc */
- get hasBeenEdited() {
- return this.input_.value != '';
- },
-
- /**
- * Editing is complete; update the model. As long as the pattern isn't
- * empty, we'll just add it.
- * @param {string} newPattern The pattern that the user entered.
- * @param {string} newSetting The setting the user chose.
- */
- finishEdit: function(newPattern, newSetting) {
- this.resetInput();
- this.list_.settings.set(newPattern, newSetting,
- this.list_.settingsChangedCallback());
- },
- };
-
- /**
- * A list of content setting rules.
- * @constructor
- * @extends {cr.ui.List}
- */
- var RuleList = cr.ui.define('list');
-
- RuleList.prototype = {
- __proto__: InlineEditableItemList.prototype,
-
- /**
- * The content settings model for this list.
- * @type {?Settings}
- */
- settings: null,
-
- /**
- * Called when an element is decorated as a list.
- */
- decorate: function() {
- InlineEditableItemList.prototype.decorate.call(this);
-
- this.classList.add(CSSClass.RULE_LIST);
-
- this.autoExpands = true;
- this.reset();
- },
-
- /**
- * Creates an item to go in the list.
- * @param {?Object} entry The element from the data model for this row.
- */
- createItem: function(entry) {
- if (entry) {
- return new RuleListItem(this, entry);
- } else {
- var addRuleItem = new AddRuleListItem(this);
- addRuleItem.deletable = false;
- return addRuleItem;
- }
- },
-
- /**
- * Sets the rules in the js model.
- * @param {!Array} entries A list of dictionaries of values, each dictionary
- * represents a rule.
- */
- setRules_: function(entries) {
- var deleteCount = this.dataModel.length - 1;
-
- var args = [0, deleteCount];
- args.push.apply(args, entries);
- this.dataModel.splice.apply(this.dataModel, args);
- },
-
- /**
- * Called when the list of content setting rules has been changed.
- * @param {?string} error The error message, if an error occurred.
- * Otherwise, this is null.
- * @private
- */
- settingsChanged_: function(error) {
- if (error) {
- $('error').textContent = 'Error: ' + error;
- } else {
- $('error').textContent = '';
- }
- this.setRules_(this.settings.getAll());
- },
-
- /**
- * @return {function()} A bound callback to update the UI after the
- * settings have been changed.
- */
- settingsChangedCallback: function() {
- return this.settingsChanged_.bind(this);
- },
-
- /**
- * Binds this list to the content settings model.
- * @param {!Settings} settings The content settings model.
- */
- setPluginSettings: function(settings) {
- this.settings = settings;
- this.settingsChanged_();
- },
-
- /**
- * Removes all rules from the js model.
- */
- reset: function() {
- // The null creates the Add New Rule row.
- this.dataModel = new ArrayDataModel([null]);
- },
-
- /** @inheritDoc */
- deleteItemAtIndex: function(index) {
- var listItem = this.getListItemByIndex(index);
- if (listItem.undeletable) {
- return;
- }
-
- this.settings.clear(listItem.pattern, this.settingsChangedCallback());
- },
- };
-
- return {
- RuleListItem: RuleListItem,
- AddRuleListItem: AddRuleListItem,
- RuleList: RuleList,
- }
-});
diff --git a/chrome/common/extensions/docs/examples/extensions/plugin_settings/js/rule_list_test.html b/chrome/common/extensions/docs/examples/extensions/plugin_settings/js/rule_list_test.html
deleted file mode 100644
index fee89f5..0000000
--- a/chrome/common/extensions/docs/examples/extensions/plugin_settings/js/rule_list_test.html
+++ /dev/null
@@ -1,64 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<link rel="stylesheet" href="../domui/css/button.css">
-<link rel="stylesheet" href="../domui/css/chrome_shared.css">
-<link rel="stylesheet" href="../domui/css/list.css">
-<link rel="stylesheet" href="../domui/css/select.css">
-
-<link rel="stylesheet" href="../options/css/list.css">
-
-<link rel="stylesheet" href="../css/rule_list.css">
-
-<script src="http://closure-library.googlecode.com/svn/trunk/closure/goog/base.js"></script>
-<script src="../domui/js/cr.js"></script>
-<script src="../domui/js/cr/event_target.js"></script>
-<script src="../domui/js/cr/ui.js"></script>
-<script src="../domui/js/cr/ui/array_data_model.js"></script>
-<script src="../domui/js/cr/ui/list_item.js"></script>
-<script src="../domui/js/cr/ui/list_selection_controller.js"></script>
-<script src="../domui/js/cr/ui/list_selection_model.js"></script>
-<script src="../domui/js/cr/ui/list_single_selection_model.js"></script>
-<script src="../domui/js/cr/ui/list.js"></script>
-<script src="../domui/js/util.js"></script>
-
-<script src="../options/js/deletable_item_list.js"></script>
-<script src="../options/js/inline_editable_list.js"></script>
-
-<script src="plugin_settings.js" type="text/javascript"></script>
-<script src="rule_list.js" type="text/javascript"></script>
-
-<script>
-goog.require('goog.testing.jsunit');
-</script>
-<script src="chrome_stubs.js" type="text/javascript"></script>
-</head>
-<body>
-<list id="rule-list"></list>
-<div id="error"></div>
-<script>
-function testConstruction() {
- var rulesEl = document.createElement('list');
- document.body.appendChild(rulesEl);
- pluginSettings.ui.RuleList.decorate(rulesEl);
- var rules = {
- 'http://example.com/*': 'block',
- 'http://moose.org/*': 'allow',
- };
- rulesEl.setPluginSettings(createSettings(rules));
- var ruleElements = rulesEl.querySelectorAll('[role=listitem]');
- assertEquals(3, ruleElements.length);
- assertEquals('http://example.com/*',
- ruleElements[0].querySelector('.rule-pattern').textContent);
- assertEquals('http://moose.org/*',
- ruleElements[1].querySelector('.rule-pattern').textContent);
- assertEquals('', ruleElements[2].querySelector('.rule-pattern').textContent);
- assertEquals('Block',
- ruleElements[0].querySelector('.rule-behavior').textContent);
- assertEquals('Allow',
- ruleElements[1].querySelector('.rule-behavior').textContent);
- assertEquals('allow', ruleElements[2].querySelector('.rule-behavior').value);
-}
-</script>
-</body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/extensions/plugin_settings/manifest.json b/chrome/common/extensions/docs/examples/extensions/plugin_settings/manifest.json
deleted file mode 100644
index a6181e2..0000000
--- a/chrome/common/extensions/docs/examples/extensions/plugin_settings/manifest.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
- "name" : "__MSG_extName__",
- "version" : "0.6",
- "description" : "__MSG_extDescription__",
- "options_page": "options.html",
- "permissions": [
- "contentSettings"
- ],
- "icons": {
- "128": "bunny128.png",
- "48": "bunny48.png"
- },
- "minimum_chrome_version": "16.0.912",
- "default_locale": "en",
- "manifest_version": 2
-}
diff --git a/chrome/common/extensions/docs/examples/extensions/plugin_settings/options.html b/chrome/common/extensions/docs/examples/extensions/plugin_settings/options.html
deleted file mode 100644
index abfdd7e..0000000
--- a/chrome/common/extensions/docs/examples/extensions/plugin_settings/options.html
+++ /dev/null
@@ -1,38 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-<link rel="stylesheet" href="domui/css/button.css">
-<link rel="stylesheet" href="domui/css/chrome_shared.css">
-<link rel="stylesheet" href="domui/css/list.css">
-<link rel="stylesheet" href="domui/css/select.css">
-
-<link rel="stylesheet" href="options/css/list.css">
-
-<link rel="stylesheet" href="css/plugin_list.css">
-<link rel="stylesheet" href="css/rule_list.css">
-
-<script src="domui/js/cr.js"></script>
-<script src="domui/js/cr/event_target.js"></script>
-<script src="domui/js/cr/ui.js"></script>
-<script src="domui/js/cr/ui/array_data_model.js"></script>
-<script src="domui/js/cr/ui/list_item.js"></script>
-<script src="domui/js/cr/ui/list_selection_controller.js"></script>
-<script src="domui/js/cr/ui/list_selection_model.js"></script>
-<script src="domui/js/cr/ui/list_single_selection_model.js"></script>
-<script src="domui/js/cr/ui/list.js"></script>
-<script src="domui/js/util.js"></script>
-
-<script src="options/js/deletable_item_list.js"></script>
-<script src="options/js/inline_editable_list.js"></script>
-
-<script src="js/plugin_list.js" type="text/javascript"></script>
-<script src="js/plugin_settings.js" type="text/javascript"></script>
-<script src="js/rule_list.js" type="text/javascript"></script>
-
-<script src="js/main.js" type="text/javascript"></script>
-</head>
-<body>
-<list id="plugin-list"></list>
-<div id="error"></div>
-</body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/extensions/plugin_settings/options/css/list.css b/chrome/common/extensions/docs/examples/extensions/plugin_settings/options/css/list.css
deleted file mode 100644
index 4ff7b90b..0000000
--- a/chrome/common/extensions/docs/examples/extensions/plugin_settings/options/css/list.css
+++ /dev/null
@@ -1,116 +0,0 @@
-/* Copyright 2011 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. */
-
-.raw-button,
-.raw-button:hover,
-.raw-button:active {
- -webkit-box-shadow: none;
- background-color: transparent;
- background-repeat: no-repeat;
- border: none;
- min-width: 0;
- padding: 1px 6px;
-}
-
-list > * {
- -webkit-box-align: center;
- box-sizing: border-box;
- border-radius: 0;
- display: -webkit-box;
- height: 32px;
- border: none;
- margin: 0;
- transition: .15s background-color;
-}
-
-list:not([disabled]) > :hover {
- background-color: #e4ecf7;
-}
-
-list:not([hasElementFocus]) > [selected],
-list:not([hasElementFocus]) > [lead][selected] {
- background-color: #d0d0d0;
- background-image: none;
-}
-
-list[hasElementFocus] > [selected],
-list[hasElementFocus] > [lead][selected],
-list:not([hasElementFocus]) > [selected]:hover,
-list:not([hasElementFocus]) > [selected][lead]:hover {
- background-color: #bbcee9;
- background-image: none;
-}
-
-list[disabled] {
- opacity: 0.6;
-}
-
-list > .heading {
- color: #666666;
-}
-
-list > .heading:hover {
- background-color: transparent;
- border-color: transparent;
-}
-
-list .deletable-item {
- -webkit-box-align: center;
-}
-
-list .deletable-item > :first-child {
- -webkit-box-align: center;
- -webkit-box-flex: 1;
- display: -webkit-box;
- padding-inline-end: 5px;
-}
-
-list .close-button {
- background-color: transparent;
- background-image: url("../images/close_bar.png");
- border: none;
- display: block;
- height: 16px;
- opacity: 1;
- transition: .15s opacity;
- width: 16px;
-}
-
-list > *:not(:hover):not([lead]) .close-button,
-list > *:not(:hover):not([selected]) .close-button,
-list:not([hasElementFocus]) > *:not(:hover) .close-button,
-list[disabled] .close-button,
-list .close-button[disabled] {
- opacity: 0;
- pointer-events: none;
-}
-
-list .close-button:hover {
- background-image: url("../images/close_bar_h.png");
-}
-
-list .close-button:active {
- background-image: url("../images/close_bar_p.png");
-}
-
-list .static-text {
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
-}
-
-list[inlineeditable] input {
- box-sizing: border-box;
- margin: 0;
- width: 100%;
-}
-
-list[inlineeditable] > :not([editing]) [displaymode="edit"],
-list[inlineeditable] > [editing] [displaymode="static"] {
- display: none;
-}
-
-list > [editing] input:invalid {
- background-color: pink;
-}
diff --git a/chrome/common/extensions/docs/examples/extensions/plugin_settings/options/images/close_bar.png b/chrome/common/extensions/docs/examples/extensions/plugin_settings/options/images/close_bar.png
deleted file mode 100644
index 912df05d..0000000
--- a/chrome/common/extensions/docs/examples/extensions/plugin_settings/options/images/close_bar.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/plugin_settings/options/images/close_bar_h.png b/chrome/common/extensions/docs/examples/extensions/plugin_settings/options/images/close_bar_h.png
deleted file mode 100644
index 66f1d89..0000000
--- a/chrome/common/extensions/docs/examples/extensions/plugin_settings/options/images/close_bar_h.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/plugin_settings/options/images/close_bar_p.png b/chrome/common/extensions/docs/examples/extensions/plugin_settings/options/images/close_bar_p.png
deleted file mode 100644
index f9761b0..0000000
--- a/chrome/common/extensions/docs/examples/extensions/plugin_settings/options/images/close_bar_p.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/plugin_settings/options/js/deletable_item_list.js b/chrome/common/extensions/docs/examples/extensions/plugin_settings/options/js/deletable_item_list.js
deleted file mode 100644
index 4d2e68e..0000000
--- a/chrome/common/extensions/docs/examples/extensions/plugin_settings/options/js/deletable_item_list.js
+++ /dev/null
@@ -1,185 +0,0 @@
-// Copyright (c) 2011 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.
-
-cr.define('options', function() {
- const List = cr.ui.List;
- const ListItem = cr.ui.ListItem;
-
- /**
- * Creates a deletable list item, which has a button that will trigger a call
- * to deleteItemAtIndex(index) in the list.
- */
- var DeletableItem = cr.ui.define('li');
-
- DeletableItem.prototype = {
- __proto__: ListItem.prototype,
-
- /**
- * The element subclasses should populate with content.
- * @type {HTMLElement}
- * @private
- */
- contentElement_: null,
-
- /**
- * The close button element.
- * @type {HTMLElement}
- * @private
- */
- closeButtonElement_: null,
-
- /**
- * Whether or not this item can be deleted.
- * @type {boolean}
- * @private
- */
- deletable_: true,
-
- /** @inheritDoc */
- decorate: function() {
- ListItem.prototype.decorate.call(this);
-
- this.classList.add('deletable-item');
-
- this.contentElement_ = this.ownerDocument.createElement('div');
- this.appendChild(this.contentElement_);
-
- this.closeButtonElement_ = this.ownerDocument.createElement('button');
- this.closeButtonElement_.classList.add('raw-button');
- this.closeButtonElement_.classList.add('close-button');
- this.closeButtonElement_.addEventListener('mousedown',
- this.handleMouseDownUpOnClose_);
- this.closeButtonElement_.addEventListener('mouseup',
- this.handleMouseDownUpOnClose_);
- this.closeButtonElement_.addEventListener('focus',
- this.handleFocus_.bind(this));
- this.appendChild(this.closeButtonElement_);
- },
-
- /**
- * Returns the element subclasses should add content to.
- * @return {HTMLElement} The element subclasses should popuplate.
- */
- get contentElement() {
- return this.contentElement_;
- },
-
- /* Gets/sets the deletable property. An item that is not deletable doesn't
- * show the delete button (although space is still reserved for it).
- */
- get deletable() {
- return this.deletable_;
- },
- set deletable(value) {
- this.deletable_ = value;
- this.closeButtonElement_.disabled = !value;
- },
-
- /**
- * Called when a focusable child element receives focus. Selects this item
- * in the list selection model.
- * @private
- */
- handleFocus_: function() {
- var list = this.parentNode;
- var index = list.getIndexOfListItem(this);
- list.selectionModel.selectedIndex = index;
- list.selectionModel.anchorIndex = index;
- },
-
- /**
- * Don't let the list have a crack at the event. We don't want clicking the
- * close button to change the selection of the list.
- * @param {Event} e The mouse down/up event object.
- * @private
- */
- handleMouseDownUpOnClose_: function(e) {
- if (!e.target.disabled)
- e.stopPropagation();
- },
- };
-
- var DeletableItemList = cr.ui.define('list');
-
- DeletableItemList.prototype = {
- __proto__: List.prototype,
-
- /** @inheritDoc */
- decorate: function() {
- List.prototype.decorate.call(this);
- this.addEventListener('click', this.handleClick_);
- this.addEventListener('keydown', this.handleKeyDown_);
- },
-
- /**
- * Callback for onclick events.
- * @param {Event} e The click event object.
- * @private
- */
- handleClick_: function(e) {
- if (this.disabled)
- return;
-
- var target = e.target;
- if (target.classList.contains('close-button')) {
- var listItem = this.getListItemAncestor(target);
- var selected = this.selectionModel.selectedIndexes;
-
- // Check if the list item that contains the close button being clicked
- // is not in the list of selected items. Only delete this item in that
- // case.
- var idx = this.getIndexOfListItem(listItem);
- if (selected.indexOf(idx) == -1) {
- this.deleteItemAtIndex(idx);
- } else {
- this.deleteSelectedItems_();
- }
- }
- },
-
- /**
- * Callback for keydown events.
- * @param {Event} e The keydown event object.
- * @private
- */
- handleKeyDown_: function(e) {
- // Map delete (and backspace on Mac) to item deletion (unless focus is
- // in an input field, where it's intended for text editing).
- if ((e.keyCode == 46 || (e.keyCode == 8 && cr.isMac)) &&
- e.target.tagName != 'INPUT') {
- this.deleteSelectedItems_();
- // Prevent the browser from going back.
- e.preventDefault();
- }
- },
-
- /**
- * Deletes all the currently selected items that are deletable.
- * @private
- */
- deleteSelectedItems_: function() {
- var selected = this.selectionModel.selectedIndexes;
- // Reverse through the list of selected indexes to maintain the
- // correct index values after deletion.
- for (var j = selected.length - 1; j >= 0; j--) {
- var index = selected[j];
- if (this.getListItemByIndex(index).deletable)
- this.deleteItemAtIndex(index);
- }
- },
-
- /**
- * Called when an item should be deleted; subclasses are responsible for
- * implementing.
- * @param {number} index The index of the item that is being deleted.
- */
- deleteItemAtIndex: function(index) {
- },
- };
-
- return {
- DeletableItemList: DeletableItemList,
- DeletableItem: DeletableItem,
- };
-});
diff --git a/chrome/common/extensions/docs/examples/extensions/plugin_settings/options/js/inline_editable_list.js b/chrome/common/extensions/docs/examples/extensions/plugin_settings/options/js/inline_editable_list.js
deleted file mode 100644
index c09d920..0000000
--- a/chrome/common/extensions/docs/examples/extensions/plugin_settings/options/js/inline_editable_list.js
+++ /dev/null
@@ -1,414 +0,0 @@
-// Copyright (c) 2011 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.
-
-cr.define('options', function() {
- const DeletableItem = options.DeletableItem;
- const DeletableItemList = options.DeletableItemList;
-
- /**
- * Creates a new list item with support for inline editing.
- * @constructor
- * @extends {options.DeletableListItem}
- */
- function InlineEditableItem() {
- var el = cr.doc.createElement('div');
- InlineEditableItem.decorate(el);
- return el;
- }
-
- /**
- * Decorates an element as a inline-editable list item. Note that this is
- * a subclass of DeletableItem.
- * @param {!HTMLElement} el The element to decorate.
- */
- InlineEditableItem.decorate = function(el) {
- el.__proto__ = InlineEditableItem.prototype;
- el.decorate();
- };
-
- InlineEditableItem.prototype = {
- __proto__: DeletableItem.prototype,
-
- /**
- * Whether or not this item can be edited.
- * @type {boolean}
- * @private
- */
- editable_: true,
-
- /**
- * Whether or not this is a placeholder for adding a new item.
- * @type {boolean}
- * @private
- */
- isPlaceholder_: false,
-
- /**
- * Fields associated with edit mode.
- * @type {array}
- * @private
- */
- editFields_: null,
-
- /**
- * Whether or not the current edit should be considered cancelled, rather
- * than committed, when editing ends.
- * @type {boolean}
- * @private
- */
- editCancelled_: true,
-
- /**
- * The editable item corresponding to the last click, if any. Used to decide
- * initial focus when entering edit mode.
- * @type {HTMLElement}
- * @private
- */
- editClickTarget_: null,
-
- /** @inheritDoc */
- decorate: function() {
- DeletableItem.prototype.decorate.call(this);
-
- this.editFields_ = [];
- this.addEventListener('mousedown', this.handleMouseDown_);
- this.addEventListener('keydown', this.handleKeyDown_);
- this.addEventListener('leadChange', this.handleLeadChange_);
- },
-
- /** @inheritDoc */
- selectionChanged: function() {
- this.updateEditState();
- },
-
- /**
- * Called when this element gains or loses 'lead' status. Updates editing
- * mode accordingly.
- * @private
- */
- handleLeadChange_: function() {
- this.updateEditState();
- },
-
- /**
- * Updates the edit state based on the current selected and lead states.
- */
- updateEditState: function() {
- if (this.editable)
- this.editing = this.selected && this.lead;
- },
-
- /**
- * Whether the user is currently editing the list item.
- * @type {boolean}
- */
- get editing() {
- return this.hasAttribute('editing');
- },
- set editing(editing) {
- if (this.editing == editing)
- return;
-
- if (editing)
- this.setAttribute('editing', '');
- else
- this.removeAttribute('editing');
-
- if (editing) {
- this.editCancelled_ = false;
-
- cr.dispatchSimpleEvent(this, 'edit', true);
-
- var focusElement = this.editClickTarget_ || this.initialFocusElement;
- this.editClickTarget_ = null;
-
- // When this is called in response to the selectedChange event,
- // the list grabs focus immediately afterwards. Thus we must delay
- // our focus grab.
- var self = this;
- if (focusElement) {
- window.setTimeout(function() {
- // Make sure we are still in edit mode by the time we execute.
- if (self.editing) {
- focusElement.focus();
- focusElement.select();
- }
- }, 50);
- }
- } else {
- if (!this.editCancelled_ && this.hasBeenEdited &&
- this.currentInputIsValid) {
- if (this.isPlaceholder)
- this.parentNode.focusPlaceholder = true;
-
- this.updateStaticValues_();
- cr.dispatchSimpleEvent(this, 'commitedit', true);
- } else {
- this.resetEditableValues_();
- cr.dispatchSimpleEvent(this, 'canceledit', true);
- }
- }
- },
-
- /**
- * Whether the item is editable.
- * @type {boolean}
- */
- get editable() {
- return this.editable_;
- },
- set editable(editable) {
- this.editable_ = editable;
- if (!editable)
- this.editing = false;
- },
-
- /**
- * Whether the item is a new item placeholder.
- * @type {boolean}
- */
- get isPlaceholder() {
- return this.isPlaceholder_;
- },
- set isPlaceholder(isPlaceholder) {
- this.isPlaceholder_ = isPlaceholder;
- if (isPlaceholder)
- this.deletable = false;
- },
-
- /**
- * The HTML element that should have focus initially when editing starts,
- * if a specific element wasn't clicked.
- * Defaults to the first <input> element; can be overriden by subclasses if
- * a different element should be focused.
- * @type {HTMLElement}
- */
- get initialFocusElement() {
- return this.contentElement.querySelector('input');
- },
-
- /**
- * Whether the input in currently valid to submit. If this returns false
- * when editing would be submitted, either editing will not be ended,
- * or it will be cancelled, depending on the context.
- * Can be overrided by subclasses to perform input validation.
- * @type {boolean}
- */
- get currentInputIsValid() {
- return true;
- },
-
- /**
- * Returns true if the item has been changed by an edit.
- * Can be overrided by subclasses to return false when nothing has changed
- * to avoid unnecessary commits.
- * @type {boolean}
- */
- get hasBeenEdited() {
- return true;
- },
-
- /**
- * Returns a div containing an <input>, as well as static text if
- * isPlaceholder is not true.
- * @param {string} text The text of the cell.
- * @return {HTMLElement} The HTML element for the cell.
- * @private
- */
- createEditableTextCell: function(text) {
- var container = this.ownerDocument.createElement('div');
-
- if (!this.isPlaceholder) {
- var textEl = this.ownerDocument.createElement('div');
- textEl.className = 'static-text';
- textEl.textContent = text;
- textEl.setAttribute('displaymode', 'static');
- container.appendChild(textEl);
- }
-
- var inputEl = this.ownerDocument.createElement('input');
- inputEl.type = 'text';
- inputEl.value = text;
- if (!this.isPlaceholder) {
- inputEl.setAttribute('displaymode', 'edit');
- inputEl.staticVersion = textEl;
- } else {
- // At this point |this| is not attached to the parent list yet, so give
- // a short timeout in order for the attachment to occur.
- var self = this;
- window.setTimeout(function() {
- var list = self.parentNode;
- if (list && list.focusPlaceholder) {
- list.focusPlaceholder = false;
- if (list.shouldFocusPlaceholder())
- inputEl.focus();
- }
- }, 50);
- }
-
- inputEl.addEventListener('focus', this.handleFocus_.bind(this));
- container.appendChild(inputEl);
- this.editFields_.push(inputEl);
-
- return container;
- },
-
- /**
- * Resets the editable version of any controls created by createEditable*
- * to match the static text.
- * @private
- */
- resetEditableValues_: function() {
- var editFields = this.editFields_;
- for (var i = 0; i < editFields.length; i++) {
- var staticLabel = editFields[i].staticVersion;
- if (!staticLabel && !this.isPlaceholder)
- continue;
-
- if (editFields[i].tagName == 'INPUT') {
- editFields[i].value =
- this.isPlaceholder ? '' : staticLabel.textContent;
- }
- // Add more tag types here as new createEditable* methods are added.
-
- editFields[i].setCustomValidity('');
- }
- },
-
- /**
- * Sets the static version of any controls created by createEditable*
- * to match the current value of the editable version. Called on commit so
- * that there's no flicker of the old value before the model updates.
- * @private
- */
- updateStaticValues_: function() {
- var editFields = this.editFields_;
- for (var i = 0; i < editFields.length; i++) {
- var staticLabel = editFields[i].staticVersion;
- if (!staticLabel)
- continue;
-
- if (editFields[i].tagName == 'INPUT')
- staticLabel.textContent = editFields[i].value;
- // Add more tag types here as new createEditable* methods are added.
- }
- },
-
- /**
- * Called a key is pressed. Handles committing and cancelling edits.
- * @param {Event} e The key down event.
- * @private
- */
- handleKeyDown_: function(e) {
- if (!this.editing)
- return;
-
- var endEdit = false;
- switch (e.key) {
- case 'Escape':
- this.editCancelled_ = true;
- endEdit = true;
- break;
- case 'Enter':
- if (this.currentInputIsValid)
- endEdit = true;
- break;
- }
-
- if (endEdit) {
- // Blurring will trigger the edit to end; see InlineEditableItemList.
- this.ownerDocument.activeElement.blur();
- // Make sure that handled keys aren't passed on and double-handled.
- // (e.g., esc shouldn't both cancel an edit and close a subpage)
- e.stopPropagation();
- }
- },
-
- /**
- * Called when the list item is clicked. If the click target corresponds to
- * an editable item, stores that item to focus when edit mode is started.
- * @param {Event} e The mouse down event.
- * @private
- */
- handleMouseDown_: function(e) {
- if (!this.editable || this.editing)
- return;
-
- var clickTarget = e.target;
- var editFields = this.editFields_;
- for (var i = 0; i < editFields.length; i++) {
- if (editFields[i] == clickTarget ||
- editFields[i].staticVersion == clickTarget) {
- this.editClickTarget_ = editFields[i];
- return;
- }
- }
- },
- };
-
- /**
- * Takes care of committing changes to inline editable list items when the
- * window loses focus.
- */
- function handleWindowBlurs() {
- window.addEventListener('blur', function(e) {
- var itemAncestor = findAncestor(document.activeElement, function(node) {
- return node instanceof InlineEditableItem;
- });
- if (itemAncestor);
- document.activeElement.blur();
- });
- }
- handleWindowBlurs();
-
- var InlineEditableItemList = cr.ui.define('list');
-
- InlineEditableItemList.prototype = {
- __proto__: DeletableItemList.prototype,
-
- /**
- * Focuses the input element of the placeholder if true.
- * @type {boolean}
- */
- focusPlaceholder: false,
-
- /** @inheritDoc */
- decorate: function() {
- DeletableItemList.prototype.decorate.call(this);
- this.setAttribute('inlineeditable', '');
- this.addEventListener('hasElementFocusChange',
- this.handleListFocusChange_);
- },
-
- /**
- * Called when the list hierarchy as a whole loses or gains focus; starts
- * or ends editing for the lead item if necessary.
- * @param {Event} e The change event.
- * @private
- */
- handleListFocusChange_: function(e) {
- var leadItem = this.getListItemByIndex(this.selectionModel.leadIndex);
- if (leadItem) {
- if (e.newValue)
- leadItem.updateEditState();
- else
- leadItem.editing = false;
- }
- },
-
- /**
- * May be overridden by subclasses to disable focusing the placeholder.
- * @return true if the placeholder element should be focused on edit commit.
- */
- shouldFocusPlaceholder: function() {
- return true;
- },
- };
-
- // Export
- return {
- InlineEditableItem: InlineEditableItem,
- InlineEditableItemList: InlineEditableItemList,
- };
-});
diff --git a/chrome/common/extensions/docs/examples/extensions/proxy_configuration/_locales/en/messages.json b/chrome/common/extensions/docs/examples/extensions/proxy_configuration/_locales/en/messages.json
deleted file mode 100644
index 74bc6f3..0000000
--- a/chrome/common/extensions/docs/examples/extensions/proxy_configuration/_locales/en/messages.json
+++ /dev/null
@@ -1,54 +0,0 @@
-{
- "extName": {
- "message": "Proxy Extension API Sample",
- "description": "The extension name."
- },
- "extDescription": {
- "message": "Set Chrome-specific proxies; a demonstration of Chrome's Proxy API",
- "description": "The extension description."
- },
- "headerDirectConnection": {
- "message": "Direct Connection",
- "description": "Header for 'Direct Connection' configuration `fieldset`."
- },
- "errorNoExtensionAccess": {
- "message": "Sorry. This browser's proxy settings cannot be controlled via extensions.",
- "description": "Error message displayed when `levelOfControl` is 'not_controllable'."
- },
- "errorOtherExtensionControls": {
- "message": "Sorry. This browser's proxy settings are being controlled by another extension. Please visit chrome://extensions for details.",
- "description": "Error message displayed when `levelOfControl` is 'controlled_by_other_extensions'."
- },
- "errorSettingRegularProxy": {
- "message": "Setting regular proxy settings failed. Sorry!",
- "description": "Error message, displayed when failing to set regular proxy settings."
- },
- "errorSettingIncognitoProxy": {
- "message": "Setting incognito proxy settings failed. Sorry!",
- "description": "Error message, displayed when failing to set incognito proxy settings."
- },
- "successfullySetProxy": {
- "message": "Your proxy settings have been saved successfully; this window will close automagically. Have a nice day!",
- "description": "Success message, displayed after proxy settings have been written."
- },
- "errorPopupTitle": {
- "message": "Error: $1",
- "description": "Error message used as popup title."
- },
- "errorProxyError": {
- "message": "ProxyError: $1.",
- "description": "Error message displayed in popup when an error occurs."
- },
- "errorProxyDetailedError": {
- "message": "ProxyError: $1. $2.",
- "description": "Error message displayed in popup when an error occurs."
- },
- "errorIdNotFound": {
- "message": "Element with ID `$1` doesn't exist in the document",
- "description": "Error message thrown when the given `id` doesn't exist"
- },
- "errorIdNotForm": {
- "message": "Element with ID `$1` isn't a form element.",
- "description": "Error message thrown when the given `id` isn't a form element."
- }
-}
diff --git a/chrome/common/extensions/docs/examples/extensions/proxy_configuration/background.js b/chrome/common/extensions/docs/examples/extensions/proxy_configuration/background.js
deleted file mode 100644
index 8640d419..0000000
--- a/chrome/common/extensions/docs/examples/extensions/proxy_configuration/background.js
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright (c) 2011 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.
-
-/**
- * @fileoverview This file initializes the background page by loading a
- * ProxyErrorHandler, and resetting proxy settings if required.
- *
- * @author Mike West <mkwst@google.com>
- */
-
-document.addEventListener("DOMContentLoaded", function () {
- var errorHandler = new ProxyErrorHandler();
-
- // If this extension has already set the proxy settings, then reset it
- // once as the background page initializes. This is essential, as
- // incognito settings are wiped on restart.
- var persistedSettings = ProxyFormController.getPersistedSettings();
- if (persistedSettings !== null) {
- chrome.proxy.settings.set(
- {'value': persistedSettings.regular});
- }
-});
diff --git a/chrome/common/extensions/docs/examples/extensions/proxy_configuration/icon128.png b/chrome/common/extensions/docs/examples/extensions/proxy_configuration/icon128.png
deleted file mode 100644
index 1b1f7dd37..0000000
--- a/chrome/common/extensions/docs/examples/extensions/proxy_configuration/icon128.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/proxy_configuration/icon16.png b/chrome/common/extensions/docs/examples/extensions/proxy_configuration/icon16.png
deleted file mode 100644
index ef87b6e..0000000
--- a/chrome/common/extensions/docs/examples/extensions/proxy_configuration/icon16.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/proxy_configuration/icon32.png b/chrome/common/extensions/docs/examples/extensions/proxy_configuration/icon32.png
deleted file mode 100644
index ce44a553a..0000000
--- a/chrome/common/extensions/docs/examples/extensions/proxy_configuration/icon32.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/proxy_configuration/icon48.png b/chrome/common/extensions/docs/examples/extensions/proxy_configuration/icon48.png
deleted file mode 100644
index ff7d8ad1..0000000
--- a/chrome/common/extensions/docs/examples/extensions/proxy_configuration/icon48.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/proxy_configuration/manifest.json b/chrome/common/extensions/docs/examples/extensions/proxy_configuration/manifest.json
deleted file mode 100644
index 41e4e86..0000000
--- a/chrome/common/extensions/docs/examples/extensions/proxy_configuration/manifest.json
+++ /dev/null
@@ -1,27 +0,0 @@
-{
- "name": "__MSG_extName__",
- "version": "0.4",
- "description": "__MSG_extDescription__",
- "default_locale": "en",
- "browser_action": {
- "default_icon": "icon16.png",
- "default_popup": "popup.html"
- },
- "icons": {
- "16": "icon16.png",
- "32": "icon32.png",
- "48": "icon48.png",
- "128": "icon128.png"
- },
- "background": {
- "scripts": [
- "proxy_form_controller.js",
- "proxy_error_handler.js",
- "background.js"
- ]
- },
- "permissions": [
- "proxy"
- ],
- "manifest_version": 2
-}
diff --git a/chrome/common/extensions/docs/examples/extensions/proxy_configuration/popup.css b/chrome/common/extensions/docs/examples/extensions/proxy_configuration/popup.css
deleted file mode 100644
index e375e2f..0000000
--- a/chrome/common/extensions/docs/examples/extensions/proxy_configuration/popup.css
+++ /dev/null
@@ -1,198 +0,0 @@
-body {
- margin: 5px 10px 10px;
-}
-
-h1 {
- color: #53637D;
- font: 26px/1.2 Helvetica, sans-serif;
- font-size: 200%;
- margin: 0;
- padding-bottom: 4px;
- text-shadow: white 0 1px 2px;
-}
-
-div[role='main'] {
- border-radius: 5px;
- background: #EAEEF3;
- font: 14px/1 Arial,Sans Serif;
- padding: 10px;
- width: 563px;
- box-shadow: inset 0px 2px 5px rgba(0,0,0,0.5);
- overflow: hidden;
- transition: background-color 0.5s ease-out;
-}
-
-div[role='main'].incognito {
- background: #496281 url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACUAAAAhCAYAAABeD2IVAAAFz0lEQVRYw8VYC0xcRRQtUEprERQ1VkohSGNpwaCYYNBUjS2K+KEVTUkDiqY0hWD5xxhDINgQqIZviRAkSiiWNDRxWypNpaatEQk/CwvlWyks3+XPAssu7I7nbmabx+suPzfrTU7yljfz5sy95947w5YtpjcLwBLYBuzgsAGs+DuzGZGwBh4BHIDdwHPA8xxuwBOcnIWpPUAL7wQeB54CngYcAWdO4kXgDeBoWFhYSk5OTtmFCxeuxsbGpuBv3sCTwFZTkrLmXtgH+AJ+QAAQCBzz8/P7MiUl5aebN29Kh4eHFVNTU2xoaIgNDAywe/fusYyMjO858R2mJEUe2ldZWfljd3f3P+3t7bK2trZBuVyuYCJbXFxkXV1drLOzU4e7d++yzMzMasz3AexMSYq89CoRYuuwvr6+B6Q6OjpYUVFRG+Yf4iE0iZYoc5woVK2trUPrIUXh05Mir9XW1qow/33gmf8idj0ZypjHuIgj5ubm1OshpdFoVoTwzp07zMbGJsTb23s/16fFZlKcyDjY29u7+fr6HoJFV1dXt7EN2MjIyANSUqmUubq6Jtna2r7OvWW7kUy04IR2+fj4HDx+/HhUYmJiIQQuhZ5mN0JKqVSuEHtWVlbd6dOns+3s7N7h9YtKynbuhFWNQuYQGBh4ODs7u2B0dHRauNDMzIx2eXmZabXadRG7f/++jhSylV25ckXOk2D4yJEjSVjnNV7ntq9Fily6Jzg4+CTEOqf/OJFoampSFRQUjDc3Ny+QF9RqtU47hozGE3mUDIbxOtTX1ytQt5T6MQipFGu9zDPbYq0i+ey5c+dyxAvBSxrsXHXixIlmVOsOaGykp6dnYXZ2lt49BHhIWVdXN1VaWipLS0trCQ8P/xseUwrD6+HhEUJO4BFa3VMREREx4+PjCkNhunjx4iAWuI0x16KjowlVYkA7uncYczUyMpJ+3z579mzXwsLCA9fimcXHx6djvb3cGatmHrnTBxr4jSZShaYwCQnC89PQXFNUVNSvMTExv6C/XYqLi6sg0DMISRISEq7h+QY81dHY2DgpDq9CoWCYm8Fbl8FmLaxLROoA8OGpU6dKL1++LCMdGdIPEkF569atIYlE0oNNdGFsNz03NDTI0QOVhrRG31GpVCR4JcrEV1jnFWOZaMVrBx07vIDDQBiQil3XQENDMplseWlpiW3WBOLXovWoy8vLBxA+CTT6NdZ5gR9vtooFvis1NfWTioqKn6uqqv6ihius4NCYZn5+Xuf2zRAi4OSgQQIsT05OrnA71qrmR6BtQlL0wwVpL1nPIqQzCgFpzlB50HuFxlF2TkxMUKiXxBKgb4Dooqen5zHeX63FWUfl/22k/aix+qM3IkEeS05Obs7Pz6+vqakZgAcUY2Njur8T2cHBwSXobbSwsPCPgICAAny7QJgstAaVjry8vEquKwexpiz5WccrJCTkDO1yLWIILcP474DPgQ8oMahpA9+C0FxJSUk7nr/h2vwMSAfhJWFJQAKN8Xku4tCJveWP3d8gb6zWToh0aGjoJYz/FHgToGYbTMmBUM0RnJyccvE7GkiEVlv1cylhpqenGbI7l4v8UWNVfRsn5efs7Jxx/vz5fr0+VvGWuqysrMbNzS0R88KDgoLyEMo+/XvyDI4tcmHC6GsUSkgL5rxFCWbsxGDFY/oSdn+mt7d3gj5w/fp15VrENmokbvRANTbyBdbbz8/tBgsn1agD/v7+cUh7lfAj2KmGmdAoI9PT0//kOnQ01vesedF8t7+/X27oQ0hbrSmJoXBKucD3GAsd3VS8cDIoY2YykgM6RS4/Zj8kckt+sfTDeaeHmdFwHxzj98Y94qKpOz+5u7ufZGY28haOyOX89rzCW9SZ3YuLi39g/4Mhy4ex/kHejFeQ2tvS0vI79ShqE+YEmjxLSkoK5aQsheGjW6snv8EeBT42Az4C3uP/l3DhyWYhvuPZ84PWbt6tzQFH7pCdvCzoSP0LtBi6oflBr2wAAAAASUVORK5CYII=') no-repeat 533px bottom;
-}
-
-form {
- transition: transform 0.25s ease;
- width: 563px;
-}
-
-form.offscreen {
- transform: translateX(-600px);
-}
-
-fieldset {
- border: 0;
- margin: 0;
- padding: 0;
- position: relative;
-}
-
-legend {
- position: absolute;
- left: -999em;
-}
-
-form > fieldset {
- border-radius: 5px;
- border: 1px solid transparent;
- padding: 10px 10px 10px 30px;
- margin: 5px 0;
- transition: all 0.5s ease;
-}
-
-form > fieldset:hover {
- background: rgba(255,255,255,0.1);
- border-color: rgba(0,0,0,0.1);
-}
-
-form > fieldset.active {
- background: rgba(255,255,255,0.25);
- border-color: rgba(0,0,0,0.25);
-}
-
-form > fieldset > input {
- margin-left: -20px;
-}
-
-section {
- margin: 5px 0 0;
-}
-
-section fieldset:not(:first-child):not(:last-child) {
- max-height: 1.6em;
- overflow: hidden;
- transition: all 0.5s ease;
-}
-
-section.single fieldset:not(:first-child):not(:last-child) {
- max-height: 0px;
-}
-
-section fieldset:last-child {
- margin-top: 5px;
-}
-
-section fieldset:last-child label {
- display: block;
-}
-
-section fieldset:last-child textarea {
- width: 412px;
-}
-
-section > fieldset {
- position: relative;
- padding-left: 60px;
-}
-
-section > fieldset > legend {
- left: 0;
- top: 4px;
- width: 53px;
- text-align: right;
-}
-
-input[type='url']:invalid:not(:active):not(:focus) {
- border-color: rgba(255,0,0,0.5);
- background: rgba(255,0,0,0.25);
-}
-
-input:invalid:not(:active):not(:focus):after {
- content: "This isn't a valid URL!";
- display:block;
-}
-
-input[type="checkbox"] {
- margin: 5px 0 5px 35px;
-}
-
-input[type="text"] {
- width: 200px;
- margin: 0 10px 0 0;
-}
-
-input.port {
- width: 50px;
- margin: 2px 10px 0 5px;
-}
-
-section label,
-section legend {
- color: #999;
- transition: color 0.5s ease;
-}
-
-.incognito section label,
-.incognito section legend {
- color: #BBB;
-}
-
-.active section label,
-.active section legend,
-form > fieldset > label {
- color: #000;
- transition: color 0.5s ease;
-}
-
-.incognito .active section label,
-.incognito .active section legend,
-.incognito form > fieldset > label {
- color: #FFF;
-}
-
-input[type="submit"],
-button {
- border-radius: 2px;
- box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.1);
- -webkit-user-select: none;
- background: -webkit-linear-gradient(#FAFAFA, #F4F4F4 40%, #E5E5E5);
- border: 1px solid #AAA;
- color: #444;
- margin-bottom: 0;
- min-width: 4em;
- padding: 3px 12px;
- margin-top: 0;
- font-size: 1.1em;
-}
-
-.overlay {
- display: block;
- text-align: center;
- position: absolute;
- left: 50%;
- top: 50%;
- width: 500px;
- padding: 20px;
- margin: -80px 0 0 -270px;
- opacity: 0;
- background: rgba(0, 0, 0, 0.75);
- border-radius: 5px;
- color: #FFF;
- font: 1.5em/1.2 Helvetica Neue, sans-serif;
- transform: scale(0);
- transition: all 1.0s ease;
-}
-
-.overlay a {
- color: #FFF;
-}
-
-.overlay.visible {
- opacity: 1;
- transform: scale(1);
-}
diff --git a/chrome/common/extensions/docs/examples/extensions/proxy_configuration/popup.html b/chrome/common/extensions/docs/examples/extensions/proxy_configuration/popup.html
deleted file mode 100644
index 595283cf..0000000
--- a/chrome/common/extensions/docs/examples/extensions/proxy_configuration/popup.html
+++ /dev/null
@@ -1,109 +0,0 @@
-<!doctype html>
-<html>
-<head>
- <title>Popup for Proxy API Test</title>
- <link href="./popup.css" type="text/css" rel="stylesheet">
-</head>
-<body>
- <h1>Proxy Configuration</h1>
- <div role="main">
- <form id="proxyForm">
- <fieldset id="system">
- <legend>System Settings</legend>
- <input type="radio" name="proxyType" id="proxyTypeSystem" value="system">
- <label for="proxyTypeSystem">Use the <em>system's proxy settings</em>.</label>
- </fieldset>
- <fieldset id="direct">
- <legend>Direct Connection</legend>
- <input type="radio" name="proxyType" id="proxyTypeDirect" value="direct">
- <label for="proxyTypeDirect">Your computer is <em>directly connected</em> to the internet; no need for a proxy.</label>
- </fieldset>
- <fieldset id="pac_script">
- <legend>Automatic Configuration</legend>
- <input type="radio" name="proxyType" id="proxyTypeAutoconfig" value="autoconfig">
- <label for="proxyTypeAutoconfig">Your proxy supports <em>automatic configuration</em>.</label>
-
- <section>
- <label for="autoconfigURL">Autoconfiguration URL (PAC file)</label>
- <input type="url" name="autoconfigURL" id="autoconfigURL">
- <input type="hidden" name="autoconfigData" id="autoconfigData">
- </section>
- </fieldset>
- <fieldset id="fixed_servers">
- <legend>Manual Proxy</legend>
- <input type="radio" name="proxyType" id="proxyTypeManual" value="manual">
- <label for="proxyTypeManual">Configure your proxy settings <em>manually</em>.</label>
- <section>
- <fieldset>
- <legend>HTTP</legend>
- <label for="proxyHostHttp">Host</label>
- <select id="proxySchemeHttp" name="proxySchemeHttp">
- <option selected value="http">http://</option>
- <option value="https">https://</option>
- <option value="socks4">socks4://</option>
- <option value="socks5">socks5://</option>
- </select>
- <input type="text" name="proxyHostHttp" id="proxyHostHttp">
-
- <label for="proxyPortHttp">Port</label>
- <input type="text" name="proxyPortHttp" id="proxyPortHttp" class="port">
-
- <input type="checkbox" name="singleProxyForEverything" id="singleProxyForEverything">
- <label for="singleProxyForEverything">Use the same proxy server for all protocols</label>
- </fieldset>
- <fieldset>
- <legend>HTTPS</legend>
- <label for="proxyHostHttps">Host</label>
- <select id="proxySchemeHttps" name="proxySchemeHttps">
- <option selected value="http">http://</option>
- <option value="https">https://</option>
- <option value="socks4">socks4://</option>
- <option value="socks5">socks5://</option>
- </select>
- <input type="text" name="proxyHostHttps" id="proxyHostHttps">
-
- <label for="proxyPortHttps">Port</label>
- <input type="text" name="proxyPortHttps" id="proxyPortHttps" class="port">
- </fieldset>
- <fieldset>
- <legend>FTP</legend>
- <label for="proxyHostFtp">Host</label>
- <select id="proxySchemeFtp" name="proxySchemeFtp">
- <option selected value="http">http://</option>
- <option value="https">https://</option>
- <option value="socks4">socks4://</option>
- <option value="socks5">socks5://</option>
- </select>
- <input type="text" name="proxyHostFtp" id="proxyHostFtp">
-
- <label for="proxyPortFtp">Port</label>
- <input type="text" name="proxyPortFtp" id="proxyPortFtp" class="port">
- </fieldset>
- <fieldset>
- <legend>Fallback</legend>
- <label for="proxyHostFallback">Host</label>
- <select id="proxySchemeFallback" name="proxySchemeFallback">
- <option selected value="http">http://</option>
- <option value="https">https://</option>
- <option value="socks4">socks4://</option>
- <option value="socks5">socks5://</option>
- </select>
- <input type="text" name="proxyHostFallback" id="proxyHostFallback">
-
- <label for="proxyPortFallback">Port</label>
- <input type="text" name="proxyPortFallback" id="proxyPortFallback" class="port">
- </fieldset>
- <fieldset>
- <label for="bypassList">Bypass proxy for these hosts:</label>
- <textarea id="bypassList" name="bypassList" placeholder="<local>,192.168.1.1/16, .example.com"></textarea>
- </fieldset>
- </section>
- </fieldset>
- <input type="submit" value="Save proxy settings">
- <button value="incognito">Configure incognito window settings.</button>
- </form>
- </div>
- <script src="./proxy_form_controller.js"></script>
- <script src="./popup.js"></script>
-</body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/extensions/proxy_configuration/popup.js b/chrome/common/extensions/docs/examples/extensions/proxy_configuration/popup.js
deleted file mode 100644
index 1c1f36d..0000000
--- a/chrome/common/extensions/docs/examples/extensions/proxy_configuration/popup.js
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright (c) 2011 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.
-
-/**
- * @fileoverview This file initializes the extension's popup by creating a
- * ProxyFormController object.
- *
- * @author Mike West <mkwst@google.com>
- */
-
-document.addEventListener('DOMContentLoaded', function () {
- var c = new ProxyFormController( 'proxyForm' );
-});
diff --git a/chrome/common/extensions/docs/examples/extensions/proxy_configuration/proxy_error_handler.js b/chrome/common/extensions/docs/examples/extensions/proxy_configuration/proxy_error_handler.js
deleted file mode 100644
index 7d2cd223..0000000
--- a/chrome/common/extensions/docs/examples/extensions/proxy_configuration/proxy_error_handler.js
+++ /dev/null
@@ -1,104 +0,0 @@
-// Copyright (c) 2011 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.
-
-/**
- * @fileoverview This file implements the ProxyErrorHandler class, which will
- * flag proxy errors in a visual way for the extension's user.
- *
- * @author Mike West <mkwst@google.com>
- */
-
-
-/**
- * The proxy error handling object. Binds to the 'onProxyError' event, and
- * changes the extensions badge to reflect the error state (yellow for
- * non-fatal errors, red for fatal).
- *
- * @constructor
- */
-function ProxyErrorHandler() {
- // Handle proxy error events.
- chrome.proxy.onProxyError.addListener(this.handleError_.bind(this));
-
- // Handle message events from popup.
- chrome.extension.onRequest.addListener(this.handleOnRequest_.bind(this));
-};
-
-///////////////////////////////////////////////////////////////////////////////
-
-/**
- * @typedef {{fatal: boolean, error: string, details: string}}
- */
-ProxyErrorHandler.ErrorDetails;
-
-///////////////////////////////////////////////////////////////////////////////
-
-ProxyErrorHandler.prototype = {
- /**
- * Details of the most recent error.
- * @type {?ProxyErrorHandler.ErrorDetails}
- * @private
- */
- lastError_: null,
-
- /**
- * Handle request messages from the popup.
- *
- * @param {!{type:string}} request The external request to answer.
- * @param {!MessageSender} sender Info about the script context that sent
- * the request.
- * @param {!function} sendResponse Function to call to send a response.
- * @private
- */
- handleOnRequest_: function(request, sender, sendResponse) {
- if (request.type === 'getError') {
- sendResponse({result: this.getErrorDetails()});
- } else if (request.type === 'clearError') {
- this.clearErrorDetails();
- sendResponse({result: true});
- }
- },
-
- /**
- * Handles the error event, storing the error details for later use, and
- * badges the browser action icon.
- *
- * @param {!ProxyErrorHandler.ErrorDetails} details The error details.
- * @private
- */
- handleError_: function(details) {
- var RED = [255, 0, 0, 255];
- var YELLOW = [255, 205, 0, 255];
-
- // Badge the popup icon.
- var color = details.fatal ? RED : YELLOW;
- chrome.browserAction.setBadgeBackgroundColor({color: color});
- chrome.browserAction.setBadgeText({text: 'X'});
- chrome.browserAction.setTitle({
- title: chrome.i18n.getMessage('errorPopupTitle', details.error)
- });
-
- // Store the error for display in the popup.
- this.lastError_ = JSON.stringify(details);
- },
-
-
- /**
- * Returns details of the last error handled.
- *
- * @return {?ProxyErrorHandler.ErrorDetails}
- */
- getErrorDetails: function() {
- return this.lastError_;
- },
-
-
- /**
- * Clears last handled error.
- */
- clearErrorDetails: function() {
- chrome.browserAction.setBadgeText({text: ''});
- this.lastError_ = null;
- }
-}
diff --git a/chrome/common/extensions/docs/examples/extensions/proxy_configuration/proxy_form_controller.js b/chrome/common/extensions/docs/examples/extensions/proxy_configuration/proxy_form_controller.js
deleted file mode 100644
index 0157bbea..0000000
--- a/chrome/common/extensions/docs/examples/extensions/proxy_configuration/proxy_form_controller.js
+++ /dev/null
@@ -1,793 +0,0 @@
-// Copyright (c) 2011 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.
-
-/**
- * @fileoverview This file implements the ProxyFormController class, which
- * wraps a form element with logic that enables implementation of proxy
- * settings.
- *
- * @author mkwst@google.com (Mike West)
- */
-
-/**
- * Wraps the proxy configuration form, binding proper handlers to its various
- * `change`, `click`, etc. events in order to take appropriate action in
- * response to user events.
- *
- * @param {string} id The form's DOM ID.
- * @constructor
- */
-var ProxyFormController = function(id) {
- /**
- * The wrapped form element
- * @type {Node}
- * @private
- */
- this.form_ = document.getElementById(id);
-
- // Throw an error if the element either doesn't exist, or isn't a form.
- if (!this.form_)
- throw chrome.i18n.getMessage('errorIdNotFound', id);
- else if (this.form_.nodeName !== 'FORM')
- throw chrome.i18n.getMessage('errorIdNotForm', id);
-
- /**
- * Cached references to the `fieldset` groups that define the configuration
- * options presented to the user.
- *
- * @type {NodeList}
- * @private
- */
- this.configGroups_ = document.querySelectorAll('#' + id + ' > fieldset');
-
- this.bindEventHandlers_();
- this.readCurrentState_();
-
- // Handle errors
- this.handleProxyErrors_();
-};
-
-///////////////////////////////////////////////////////////////////////////////
-
-/**
- * The proxy types we're capable of handling.
- * @enum {string}
- */
-ProxyFormController.ProxyTypes = {
- AUTO: 'auto_detect',
- PAC: 'pac_script',
- DIRECT: 'direct',
- FIXED: 'fixed_servers',
- SYSTEM: 'system'
-};
-
-/**
- * The window types we're capable of handling.
- * @enum {int}
- */
-ProxyFormController.WindowTypes = {
- REGULAR: 1,
- INCOGNITO: 2
-};
-
-/**
- * The extension's level of control of Chrome's roxy setting
- * @enum {string}
- */
-ProxyFormController.LevelOfControl = {
- NOT_CONTROLLABLE: 'not_controllable',
- OTHER_EXTENSION: 'controlled_by_other_extension',
- AVAILABLE: 'controllable_by_this_extension',
- CONTROLLING: 'controlled_by_this_extension'
-};
-
-/**
- * The response type from 'proxy.settings.get'
- *
- * @typedef {{value: ProxyConfig,
- * levelOfControl: ProxyFormController.LevelOfControl}}
- */
-ProxyFormController.WrappedProxyConfig;
-
-///////////////////////////////////////////////////////////////////////////////
-
-/**
- * Retrieves proxy settings that have been persisted across restarts.
- *
- * @return {?ProxyConfig} The persisted proxy configuration, or null if no
- * value has been persisted.
- * @static
- */
-ProxyFormController.getPersistedSettings = function() {
- var result = null;
- if (window.localStorage['proxyConfig'] !== undefined)
- result = JSON.parse(window.localStorage['proxyConfig']);
- return result ? result : null;
-};
-
-
-/**
- * Persists proxy settings across restarts.
- *
- * @param {!ProxyConfig} config The proxy config to persist.
- * @static
- */
-ProxyFormController.setPersistedSettings = function(config) {
- window.localStorage['proxyConfig'] = JSON.stringify(config);
-};
-
-///////////////////////////////////////////////////////////////////////////////
-
-ProxyFormController.prototype = {
- /**
- * The form's current state.
- * @type {regular: ?ProxyConfig, incognito: ?ProxyConfig}
- * @private
- */
- config_: {regular: null, incognito: null},
-
- /**
- * Do we have access to incognito mode?
- * @type {boolean}
- * @private
- */
- isAllowedIncognitoAccess_: false,
-
- /**
- * @return {string} The PAC file URL (or an empty string).
- */
- get pacURL() {
- return document.getElementById('autoconfigURL').value;
- },
-
-
- /**
- * @param {!string} value The PAC file URL.
- */
- set pacURL(value) {
- document.getElementById('autoconfigURL').value = value;
- },
-
-
- /**
- * @return {string} The PAC file data (or an empty string).
- */
- get manualPac() {
- return document.getElementById('autoconfigData').value;
- },
-
-
- /**
- * @param {!string} value The PAC file data.
- */
- set manualPac(value) {
- document.getElementById('autoconfigData').value = value;
- },
-
-
- /**
- * @return {Array<string>} A list of hostnames that should bypass the proxy.
- */
- get bypassList() {
- return document.getElementById('bypassList').value.split(/\s*(?:,|^)\s*/m);
- },
-
-
- /**
- * @param {?Array<string>} data A list of hostnames that should bypass
- * the proxy. If empty, the bypass list is emptied.
- */
- set bypassList(data) {
- if (!data)
- data = [];
- document.getElementById('bypassList').value = data.join(', ');
- },
-
-
- /**
- * @see http://code.google.com/chrome/extensions/trunk/proxy.html
- * @return {?ProxyServer} An object containing the proxy server host, port,
- * and scheme. If null, there is no single proxy.
- */
- get singleProxy() {
- var checkbox = document.getElementById('singleProxyForEverything');
- return checkbox.checked ? this.httpProxy : null;
- },
-
-
- /**
- * @see http://code.google.com/chrome/extensions/trunk/proxy.html
- * @param {?ProxyServer} data An object containing the proxy server host,
- * port, and scheme. If null, the single proxy checkbox will be unchecked.
- */
- set singleProxy(data) {
- var checkbox = document.getElementById('singleProxyForEverything');
- checkbox.checked = !!data;
-
- if (data)
- this.httpProxy = data;
-
- if (checkbox.checked)
- checkbox.parentNode.parentNode.classList.add('single');
- else
- checkbox.parentNode.parentNode.classList.remove('single');
- },
-
- /**
- * @return {?ProxyServer} An object containing the proxy server host, port
- * and scheme.
- */
- get httpProxy() {
- return this.getProxyImpl_('Http');
- },
-
-
- /**
- * @param {?ProxyServer} data An object containing the proxy server host,
- * port, and scheme. If empty, empties the proxy setting.
- */
- set httpProxy(data) {
- this.setProxyImpl_('Http', data);
- },
-
-
- /**
- * @return {?ProxyServer} An object containing the proxy server host, port
- * and scheme.
- */
- get httpsProxy() {
- return this.getProxyImpl_('Https');
- },
-
-
- /**
- * @param {?ProxyServer} data An object containing the proxy server host,
- * port, and scheme. If empty, empties the proxy setting.
- */
- set httpsProxy(data) {
- this.setProxyImpl_('Https', data);
- },
-
-
- /**
- * @return {?ProxyServer} An object containing the proxy server host, port
- * and scheme.
- */
- get ftpProxy() {
- return this.getProxyImpl_('Ftp');
- },
-
-
- /**
- * @param {?ProxyServer} data An object containing the proxy server host,
- * port, and scheme. If empty, empties the proxy setting.
- */
- set ftpProxy(data) {
- this.setProxyImpl_('Ftp', data);
- },
-
-
- /**
- * @return {?ProxyServer} An object containing the proxy server host, port
- * and scheme.
- */
- get fallbackProxy() {
- return this.getProxyImpl_('Fallback');
- },
-
-
- /**
- * @param {?ProxyServer} data An object containing the proxy server host,
- * port, and scheme. If empty, empties the proxy setting.
- */
- set fallbackProxy(data) {
- this.setProxyImpl_('Fallback', data);
- },
-
-
- /**
- * @param {string} type The type of proxy that's being set ("Http",
- * "Https", etc.).
- * @return {?ProxyServer} An object containing the proxy server host,
- * port, and scheme.
- * @private
- */
- getProxyImpl_: function(type) {
- var result = {
- scheme: document.getElementById('proxyScheme' + type).value,
- host: document.getElementById('proxyHost' + type).value,
- port: parseInt(document.getElementById('proxyPort' + type).value, 10)
- };
- return (result.scheme && result.host && result.port) ? result : undefined;
- },
-
-
- /**
- * A generic mechanism for setting proxy data.
- *
- * @see http://code.google.com/chrome/extensions/trunk/proxy.html
- * @param {string} type The type of proxy that's being set ("Http",
- * "Https", etc.).
- * @param {?ProxyServer} data An object containing the proxy server host,
- * port, and scheme. If empty, empties the proxy setting.
- * @private
- */
- setProxyImpl_: function(type, data) {
- if (!data)
- data = {scheme: 'http', host: '', port: ''};
-
- document.getElementById('proxyScheme' + type).value = data.scheme;
- document.getElementById('proxyHost' + type).value = data.host;
- document.getElementById('proxyPort' + type).value = data.port;
- },
-
-///////////////////////////////////////////////////////////////////////////////
-
- /**
- * Calls the proxy API to read the current settings, and populates the form
- * accordingly.
- *
- * @private
- */
- readCurrentState_: function() {
- chrome.extension.isAllowedIncognitoAccess(
- this.handleIncognitoAccessResponse_.bind(this));
- },
-
- /**
- * Handles the respnse from `chrome.extension.isAllowedIncognitoAccess`
- * We can't render the form until we know what our access level is, so
- * we wait until we have confirmed incognito access levels before
- * asking for the proxy state.
- *
- * @param {boolean} state The state of incognito access.
- * @private
- */
- handleIncognitoAccessResponse_: function(state) {
- this.isAllowedIncognitoAccess_ = state;
- chrome.proxy.settings.get({incognito: false},
- this.handleRegularState_.bind(this));
- if (this.isAllowedIncognitoAccess_) {
- chrome.proxy.settings.get({incognito: true},
- this.handleIncognitoState_.bind(this));
- }
- },
-
- /**
- * Handles the response from 'proxy.settings.get' for regular
- * settings.
- *
- * @param {ProxyFormController.WrappedProxyConfig} c The proxy data and
- * extension's level of control thereof.
- * @private
- */
- handleRegularState_: function(c) {
- if (c.levelOfControl === ProxyFormController.LevelOfControl.AVAILABLE ||
- c.levelOfControl === ProxyFormController.LevelOfControl.CONTROLLING) {
- this.recalcFormValues_(c.value);
- this.config_.regular = c.value;
- } else {
- this.handleLackOfControl_(c.levelOfControl);
- }
- },
-
- /**
- * Handles the response from 'proxy.settings.get' for incognito
- * settings.
- *
- * @param {ProxyFormController.WrappedProxyConfig} c The proxy data and
- * extension's level of control thereof.
- * @private
- */
- handleIncognitoState_: function(c) {
- if (c.levelOfControl === ProxyFormController.LevelOfControl.AVAILABLE ||
- c.levelOfControl === ProxyFormController.LevelOfControl.CONTROLLING) {
- if (this.isIncognitoMode_())
- this.recalcFormValues_(c.value);
-
- this.config_.incognito = c.value;
- } else {
- this.handleLackOfControl_(c.levelOfControl);
- }
- },
-
- /**
- * Binds event handlers for the various bits and pieces of the form that
- * are interesting to the controller.
- *
- * @private
- */
- bindEventHandlers_: function() {
- this.form_.addEventListener('click', this.dispatchFormClick_.bind(this));
- },
-
-
- /**
- * When a `click` event is triggered on the form, this function handles it by
- * analyzing the context, and dispatching the click to the correct handler.
- *
- * @param {Event} e The event to be handled.
- * @private
- * @return {boolean} True if the event should bubble, false otherwise.
- */
- dispatchFormClick_: function(e) {
- var t = e.target;
-
- // Case 1: "Apply"
- if (t.nodeName === 'INPUT' && t.getAttribute('type') === 'submit') {
- return this.applyChanges_(e);
-
- // Case 2: "Use the same proxy for all protocols" in an active section
- } else if (t.nodeName === 'INPUT' &&
- t.getAttribute('type') === 'checkbox' &&
- t.parentNode.parentNode.parentNode.classList.contains('active')
- ) {
- return this.toggleSingleProxyConfig_(e);
-
- // Case 3: "Flip to incognito mode."
- } else if (t.nodeName === 'BUTTON') {
- return this.toggleIncognitoMode_(e);
-
- // Case 4: Click on something random: maybe changing active config group?
- } else {
- // Walk up the tree until we hit `form > fieldset` or fall off the top
- while (t && (t.nodeName !== 'FIELDSET' ||
- t.parentNode.nodeName !== 'FORM')) {
- t = t.parentNode;
- }
- if (t) {
- this.changeActive_(t);
- return false;
- }
- }
- return true;
- },
-
-
- /**
- * Sets the form's active config group.
- *
- * @param {DOMElement} fieldset The configuration group to activate.
- * @private
- */
- changeActive_: function(fieldset) {
- for (var i = 0; i < this.configGroups_.length; i++) {
- var el = this.configGroups_[i];
- var radio = el.querySelector("input[type='radio']");
- if (el === fieldset) {
- el.classList.add('active');
- radio.checked = true;
- } else {
- el.classList.remove('active');
- }
- }
- this.recalcDisabledInputs_();
- },
-
-
- /**
- * Recalculates the `disabled` state of the form's input elements, based
- * on the currently active group, and that group's contents.
- *
- * @private
- */
- recalcDisabledInputs_: function() {
- var i, j;
- for (i = 0; i < this.configGroups_.length; i++) {
- var el = this.configGroups_[i];
- var inputs = el.querySelectorAll(
- "input:not([type='radio']), select, textarea");
- if (el.classList.contains('active')) {
- for (j = 0; j < inputs.length; j++) {
- inputs[j].removeAttribute('disabled');
- }
- } else {
- for (j = 0; j < inputs.length; j++) {
- inputs[j].setAttribute('disabled', 'disabled');
- }
- }
- }
- },
-
-
- /**
- * Handler called in response to click on form's submission button. Generates
- * the proxy configuration and passes it to `useCustomProxySettings`, or
- * handles errors in user input.
- *
- * Proxy errors (and the browser action's badge) are cleared upon setting new
- * values.
- *
- * @param {Event} e DOM event generated by the user's click.
- * @private
- */
- applyChanges_: function(e) {
- e.preventDefault();
- e.stopPropagation();
-
- if (this.isIncognitoMode_())
- this.config_.incognito = this.generateProxyConfig_();
- else
- this.config_.regular = this.generateProxyConfig_();
-
- chrome.proxy.settings.set(
- {value: this.config_.regular, scope: 'regular'},
- this.callbackForRegularSettings_.bind(this));
- chrome.extension.sendRequest({type: 'clearError'});
- },
-
- /**
- * Called in response to setting a regular window's proxy settings: checks
- * for `lastError`, and then sets incognito settings (if they exist).
- *
- * @private
- */
- callbackForRegularSettings_: function() {
- if (chrome.runtime.lastError) {
- this.generateAlert_(chrome.i18n.getMessage('errorSettingRegularProxy'));
- return;
- }
- if (this.config_.incognito) {
- chrome.proxy.settings.set(
- {value: this.config_.incognito, scope: 'incognito_persistent'},
- this.callbackForIncognitoSettings_.bind(this));
- } else {
- ProxyFormController.setPersistedSettings(this.config_);
- this.generateAlert_(chrome.i18n.getMessage('successfullySetProxy'));
- }
- },
-
- /**
- * Called in response to setting an incognito window's proxy settings: checks
- * for `lastError` and sets a success message.
- *
- * @private
- */
- callbackForIncognitoSettings_: function() {
- if (chrome.runtime.lastError) {
- this.generateAlert_(chrome.i18n.getMessage('errorSettingIncognitoProxy'));
- return;
- }
- ProxyFormController.setPersistedSettings(this.config_);
- this.generateAlert_(
- chrome.i18n.getMessage('successfullySetProxy'));
- },
-
- /**
- * Generates an alert overlay inside the proxy's popup, then closes the popup
- * after a short delay.
- *
- * @param {string} msg The message to be displayed in the overlay.
- * @param {?boolean} close Should the window be closed? Defaults to true.
- * @private
- */
- generateAlert_: function(msg, close) {
- var success = document.createElement('div');
- success.classList.add('overlay');
- success.setAttribute('role', 'alert');
- success.textContent = msg;
- document.body.appendChild(success);
-
- setTimeout(function() { success.classList.add('visible'); }, 10);
- setTimeout(function() {
- if (close === false)
- success.classList.remove('visible');
- else
- window.close();
- }, 4000);
- },
-
-
- /**
- * Parses the proxy configuration form, and generates a ProxyConfig object
- * that can be passed to `useCustomProxyConfig`.
- *
- * @see http://code.google.com/chrome/extensions/trunk/proxy.html
- * @return {ProxyConfig} The proxy configuration represented by the form.
- * @private
- */
- generateProxyConfig_: function() {
- var active = document.getElementsByClassName('active')[0];
- switch (active.id) {
- case ProxyFormController.ProxyTypes.SYSTEM:
- return {mode: 'system'};
- case ProxyFormController.ProxyTypes.DIRECT:
- return {mode: 'direct'};
- case ProxyFormController.ProxyTypes.PAC:
- var pacScriptURL = this.pacURL;
- var pacManual = this.manualPac;
- if (pacScriptURL)
- return {mode: 'pac_script',
- pacScript: {url: pacScriptURL, mandatory: true}};
- else if (pacManual)
- return {mode: 'pac_script',
- pacScript: {data: pacManual, mandatory: true}};
- else
- return {mode: 'auto_detect'};
- case ProxyFormController.ProxyTypes.FIXED:
- var config = {mode: 'fixed_servers'};
- if (this.singleProxy) {
- config.rules = {
- singleProxy: this.singleProxy,
- bypassList: this.bypassList
- };
- } else {
- config.rules = {
- proxyForHttp: this.httpProxy,
- proxyForHttps: this.httpsProxy,
- proxyForFtp: this.ftpProxy,
- fallbackProxy: this.fallbackProxy,
- bypassList: this.bypassList
- };
- }
- return config;
- }
- },
-
-
- /**
- * Sets the proper display classes based on the "Use the same proxy server
- * for all protocols" checkbox. Expects to be called as an event handler
- * when that field is clicked.
- *
- * @param {Event} e The `click` event to respond to.
- * @private
- */
- toggleSingleProxyConfig_: function(e) {
- var checkbox = e.target;
- if (checkbox.nodeName === 'INPUT' &&
- checkbox.getAttribute('type') === 'checkbox') {
- if (checkbox.checked)
- checkbox.parentNode.parentNode.classList.add('single');
- else
- checkbox.parentNode.parentNode.classList.remove('single');
- }
- },
-
-
- /**
- * Returns the form's current incognito status.
- *
- * @return {boolean} True if the form is in incognito mode, false otherwise.
- * @private
- */
- isIncognitoMode_: function(e) {
- return this.form_.parentNode.classList.contains('incognito');
- },
-
-
- /**
- * Toggles the form's incognito mode. Saves the current state to an object
- * property for later use, clears the form, and toggles the appropriate state.
- *
- * @param {Event} e The `click` event to respond to.
- * @private
- */
- toggleIncognitoMode_: function(e) {
- var div = this.form_.parentNode;
- var button = document.getElementsByTagName('button')[0];
-
- // Cancel the button click.
- e.preventDefault();
- e.stopPropagation();
-
- // If we can't access Incognito settings, throw a message and return.
- if (!this.isAllowedIncognitoAccess_) {
- var msg = "I'm sorry, Dave, I'm afraid I can't do that. Give me access " +
- "to Incognito settings by checking the checkbox labeled " +
- "'Allow in Incognito mode', which is visible at " +
- "chrome://extensions.";
- this.generateAlert_(msg, false);
- return;
- }
-
- if (this.isIncognitoMode_()) {
- // In incognito mode, switching to cognito.
- this.config_.incognito = this.generateProxyConfig_();
- div.classList.remove('incognito');
- this.recalcFormValues_(this.config_.regular);
- button.innerText = 'Configure incognito window settings.';
- } else {
- // In cognito mode, switching to incognito.
- this.config_.regular = this.generateProxyConfig_();
- div.classList.add('incognito');
- this.recalcFormValues_(this.config_.incognito);
- button.innerText = 'Configure regular window settings.';
- }
- },
-
-
- /**
- * Sets the form's values based on a ProxyConfig.
- *
- * @param {!ProxyConfig} c The ProxyConfig object.
- * @private
- */
- recalcFormValues_: function(c) {
- // Normalize `auto_detect`
- if (c.mode === 'auto_detect')
- c.mode = 'pac_script';
- // Activate one of the groups, based on `mode`.
- this.changeActive_(document.getElementById(c.mode));
- // Populate the PAC script
- if (c.pacScript) {
- if (c.pacScript.url)
- this.pacURL = c.pacScript.url;
- } else {
- this.pacURL = '';
- }
- // Evaluate the `rules`
- if (c.rules) {
- var rules = c.rules;
- if (rules.singleProxy) {
- this.singleProxy = rules.singleProxy;
- } else {
- this.singleProxy = null;
- this.httpProxy = rules.proxyForHttp;
- this.httpsProxy = rules.proxyForHttps;
- this.ftpProxy = rules.proxyForFtp;
- this.fallbackProxy = rules.fallbackProxy;
- }
- this.bypassList = rules.bypassList;
- } else {
- this.singleProxy = null;
- this.httpProxy = null;
- this.httpsProxy = null;
- this.ftpProxy = null;
- this.fallbackProxy = null;
- this.bypassList = '';
- }
- },
-
-
- /**
- * Handles the case in which this extension doesn't have the ability to
- * control the Proxy settings, either because of an overriding policy
- * or an extension with higher priority.
- *
- * @param {ProxyFormController.LevelOfControl} l The level of control this
- * extension has over the proxy settings.
- * @private
- */
- handleLackOfControl_: function(l) {
- var msg;
- if (l === ProxyFormController.LevelOfControl.NO_ACCESS)
- msg = chrome.i18n.getMessage('errorNoExtensionAccess');
- else if (l === ProxyFormController.LevelOfControl.OTHER_EXTENSION)
- msg = chrome.i18n.getMessage('errorOtherExtensionControls');
- this.generateAlert_(msg);
- },
-
-
- /**
- * Handle the case in which errors have been generated outside the context
- * of this popup.
- *
- * @private
- */
- handleProxyErrors_: function() {
- chrome.extension.sendRequest(
- {type: 'getError'},
- this.handleProxyErrorHandlerResponse_.bind(this));
- },
-
- /**
- * Handles response from ProxyErrorHandler
- *
- * @param {{result: !string}} response The message sent in response to this
- * popup's request.
- */
- handleProxyErrorHandlerResponse_: function(response) {
- if (response.result !== null) {
- var error = JSON.parse(response.result);
- console.error(error);
- // TODO(mkwst): Do something more interesting
- this.generateAlert_(
- chrome.i18n.getMessage(
- error.details ? 'errorProxyDetailedError' : 'errorProxyError',
- [error.error, error.details]),
- false);
- }
- }
-};
diff --git a/chrome/common/extensions/docs/examples/extensions/proxy_configuration/test/jsunittest.js b/chrome/common/extensions/docs/examples/extensions/proxy_configuration/test/jsunittest.js
deleted file mode 100644
index 8e1eab03..0000000
--- a/chrome/common/extensions/docs/examples/extensions/proxy_configuration/test/jsunittest.js
+++ /dev/null
@@ -1,964 +0,0 @@
-/* Jsunittest, version 0.6.0
- * (c) 2008 Dr Nic Williams
- *
- * Jsunittest is freely distributable under
- * the terms of an MIT-style license.
- * For details, see the web site: http://jsunittest.rubyforge.org
- *
- *--------------------------------------------------------------------------*/
-
-var JsUnitTest = {
- Version: '0.6.0',
-};
-
-var DrNicTest = {
- Unit: {},
- inspect: function(object) {
- try {
- if (typeof object == "undefined") return 'undefined';
- if (object === null) return 'null';
- if (typeof object == "string") {
- var useDoubleQuotes = arguments[1];
- var escapedString = this.gsub(object, /[\x00-\x1f\\]/, function(match) {
- var character = String.specialChar[match[0]];
- return character ? character : '\\u00' + match[0].charCodeAt().toPaddedString(2, 16);
- });
- if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"';
- return "'" + escapedString.replace(/'/g, '\\\'') + "'";
- };
- return String(object);
- } catch (e) {
- if (e instanceof RangeError) return '...';
- throw e;
- }
- },
- $: function(element) {
- if (arguments.length > 1) {
- for (var i = 0, elements = [], length = arguments.length; i < length; i++)
- elements.push(this.$(arguments[i]));
- return elements;
- }
- if (typeof element == "string")
- element = document.getElementById(element);
- return element;
- },
- gsub: function(source, pattern, replacement) {
- var result = '', match;
- replacement = arguments.callee.prepareReplacement(replacement);
-
- while (source.length > 0) {
- if (match = source.match(pattern)) {
- result += source.slice(0, match.index);
- result += DrNicTest.String.interpret(replacement(match));
- source = source.slice(match.index + match[0].length);
- } else {
- result += source, source = '';
- }
- }
- return result;
- },
- scan: function(source, pattern, iterator) {
- this.gsub(source, pattern, iterator);
- return String(source);
- },
- escapeHTML: function(data) {
- return data.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>');
- },
- arrayfromargs: function(args) {
- var myarray = new Array();
- var i;
-
- for (i=0;i<args.length;i++)
- myarray[i] = args[i];
-
- return myarray;
- },
- hashToSortedArray: function(hash) {
- var results = [];
- for (key in hash) {
- results.push([key, hash[key]]);
- }
- return results.sort();
- },
- flattenArray: function(array) {
- var results = arguments[1] || [];
- for (var i=0; i < array.length; i++) {
- var object = array[i];
- if (object != null && typeof object == "object" &&
- 'splice' in object && 'join' in object) {
- this.flattenArray(object, results);
- } else {
- results.push(object);
- }
- };
- return results;
- },
- selectorMatch: function(expression, element) {
- var tokens = [];
- var patterns = {
- // combinators must be listed first
- // (and descendant needs to be last combinator)
- laterSibling: /^\s*~\s*/,
- child: /^\s*>\s*/,
- adjacent: /^\s*\+\s*/,
- descendant: /^\s/,
-
- // selectors follow
- tagName: /^\s*(\*|[\w\-]+)(\b|$)?/,
- id: /^#([\w\-\*]+)(\b|$)/,
- className: /^\.([\w\-\*]+)(\b|$)/,
- pseudo:
- /^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|(?=\s|[:+~>]))/,
- attrPresence: /^\[((?:[\w]+:)?[\w]+)\]/,
- attr: /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\4]*?)\4|([^'"][^\]]*?)))?\]/
- };
-
- var assertions = {
- tagName: function(element, matches) {
- return matches[1].toUpperCase() == element.tagName.toUpperCase();
- },
-
- className: function(element, matches) {
- return Element.hasClassName(element, matches[1]);
- },
-
- id: function(element, matches) {
- return element.id === matches[1];
- },
-
- attrPresence: function(element, matches) {
- return Element.hasAttribute(element, matches[1]);
- },
-
- attr: function(element, matches) {
- var nodeValue = Element.readAttribute(element, matches[1]);
- return nodeValue && operators[matches[2]](nodeValue, matches[5] || matches[6]);
- }
- };
- var e = this.expression, ps = patterns, as = assertions;
- var le, p, m;
-
- while (e && le !== e && (/\S/).test(e)) {
- le = e;
- for (var i in ps) {
- p = ps[i];
- if (m = e.match(p)) {
- // use the Selector.assertions methods unless the selector
- // is too complex.
- if (as[i]) {
- tokens.push([i, Object.clone(m)]);
- e = e.replace(m[0], '');
- }
- }
- }
- }
-
- var match = true, name, matches;
- for (var i = 0, token; token = tokens[i]; i++) {
- name = token[0], matches = token[1];
- if (!assertions[name](element, matches)) {
- match = false; break;
- }
- }
-
- return match;
- },
- toQueryParams: function(query, separator) {
- var query = query || window.location.search;
- var match = query.replace(/^\s+/, '').replace(/\s+$/, '').match(/([^?#]*)(#.*)?$/);
- if (!match) return { };
-
- var hash = {};
- var parts = match[1].split(separator || '&');
- for (var i=0; i < parts.length; i++) {
- var pair = parts[i].split('=');
- if (pair[0]) {
- var key = decodeURIComponent(pair.shift());
- var value = pair.length > 1 ? pair.join('=') : pair[0];
- if (value != undefined) value = decodeURIComponent(value);
-
- if (key in hash) {
- var object = hash[key];
- var isArray = object != null && typeof object == "object" &&
- 'splice' in object && 'join' in object
- if (!isArray) hash[key] = [hash[key]];
- hash[key].push(value);
- }
- else hash[key] = value;
- }
- };
- return hash;
- },
-
- String: {
- interpret: function(value) {
- return value == null ? '' : String(value);
- }
- }
-};
-
-DrNicTest.gsub.prepareReplacement = function(replacement) {
- if (typeof replacement == "function") return replacement;
- var template = new Template(replacement);
- return function(match) { return template.evaluate(match) };
-};
-
-DrNicTest.Template = function(template, pattern) {
- this.template = template; //template.toString();
- this.pattern = pattern || DrNicTest.Template.Pattern;
-};
-
-DrNicTest.Template.prototype.evaluate = function(object) {
- if (typeof object.toTemplateReplacements == "function")
- object = object.toTemplateReplacements();
-
- return DrNicTest.gsub(this.template, this.pattern, function(match) {
- if (object == null) return '';
-
- var before = match[1] || '';
- if (before == '\\') return match[2];
-
- var ctx = object, expr = match[3];
- var pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/;
- match = pattern.exec(expr);
- if (match == null) return before;
-
- while (match != null) {
- var comp = (match[1].indexOf('[]') === 0) ? match[2].gsub('\\\\]', ']') : match[1];
- ctx = ctx[comp];
- if (null == ctx || '' == match[3]) break;
- expr = expr.substring('[' == match[3] ? match[1].length : match[0].length);
- match = pattern.exec(expr);
- }
-
- return before + DrNicTest.String.interpret(ctx);
- });
-}
-
-DrNicTest.Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/;
-DrNicTest.Event = {};
-// written by Dean Edwards, 2005
-// with input from Tino Zijdel, Matthias Miller, Diego Perini
-// namespaced by Dr Nic Williams 2008
-
-// http://dean.edwards.name/weblog/2005/10/add-event/
-// http://dean.edwards.name/weblog/2005/10/add-event2/
-DrNicTest.Event.addEvent = function(element, type, handler) {
- if (element.addEventListener) {
- element.addEventListener(type, handler, false);
- } else {
- // assign each event handler a unique ID
- if (!handler.$$guid) handler.$$guid = addEvent.guid++;
- // create a hash table of event types for the element
- if (!element.events) element.events = {};
- // create a hash table of event handlers for each element/event pair
- var handlers = element.events[type];
- if (!handlers) {
- handlers = element.events[type] = {};
- // store the existing event handler (if there is one)
- if (element["on" + type]) {
- handlers[0] = element["on" + type];
- }
- }
- // store the event handler in the hash table
- handlers[handler.$$guid] = handler;
- // assign a global event handler to do all the work
- element["on" + type] = handleEvent;
- }
-};
-// a counter used to create unique IDs
-DrNicTest.Event.addEvent.guid = 1;
-
-DrNicTest.Event.removeEvent = function(element, type, handler) {
- if (element.removeEventListener) {
- element.removeEventListener(type, handler, false);
- } else {
- // delete the event handler from the hash table
- if (element.events && element.events[type]) {
- delete element.events[type][handler.$$guid];
- }
- }
-};
-
-DrNicTest.Event.handleEvent = function(event) {
- var returnValue = true;
- // grab the event object (IE uses a global event object)
- event = event || fixEvent(((this.ownerDocument || this.document || this).parentWindow || window).event);
- // get a reference to the hash table of event handlers
- var handlers = this.events[event.type];
- // execute each event handler
- for (var i in handlers) {
- this.$$handleEvent = handlers[i];
- if (this.$$handleEvent(event) === false) {
- returnValue = false;
- }
- }
- return returnValue;
-};
-
-DrNicTest.Event.fixEvent = function(event) {
- // add W3C standard event methods
- event.preventDefault = fixEvent.preventDefault;
- event.stopPropagation = fixEvent.stopPropagation;
- return event;
-};
-DrNicTest.Event.fixEvent.preventDefault = function() {
- this.returnValue = false;
-};
-DrNicTest.Event.fixEvent.stopPropagation = function() {
- this.cancelBubble = true;
-};
-
-DrNicTest.Unit.Logger = function(element) {
- this.element = DrNicTest.$(element);
- if (this.element) this._createLogTable();
-};
-
-DrNicTest.Unit.Logger.prototype.start = function(testName) {
- if (!this.element) return;
- var tbody = this.element.getElementsByTagName('tbody')[0];
- tbody.innerHTML = tbody.innerHTML + '<tr><td>' + testName + '</td><td></td><td></td></tr>';
-};
-
-DrNicTest.Unit.Logger.prototype.setStatus = function(status) {
- var logline = this.getLastLogLine();
- logline.className = status;
- var statusCell = logline.getElementsByTagName('td')[1];
- statusCell.innerHTML = status;
-};
-
-DrNicTest.Unit.Logger.prototype.finish = function(status, summary) {
- if (!this.element) return;
- this.setStatus(status);
- this.message(summary);
-};
-
-DrNicTest.Unit.Logger.prototype.message = function(message) {
- if (!this.element) return;
- var cell = this.getMessageCell();
- cell.innerHTML = this._toHTML(message);
-};
-
-DrNicTest.Unit.Logger.prototype.summary = function(summary) {
- if (!this.element) return;
- var div = this.element.getElementsByTagName('div')[0];
- div.innerHTML = this._toHTML(summary);
-};
-
-DrNicTest.Unit.Logger.prototype.getLastLogLine = function() {
- var tbody = this.element.getElementsByTagName('tbody')[0];
- var loglines = tbody.getElementsByTagName('tr');
- return loglines[loglines.length - 1];
-};
-
-DrNicTest.Unit.Logger.prototype.getMessageCell = function() {
- var logline = this.getLastLogLine();
- return logline.getElementsByTagName('td')[2];
-};
-
-DrNicTest.Unit.Logger.prototype._createLogTable = function() {
- var html = '<div class="logsummary">running...</div>' +
- '<table class="logtable">' +
- '<thead><tr><th>Status</th><th>Test</th><th>Message</th></tr></thead>' +
- '<tbody class="loglines"></tbody>' +
- '</table>';
- this.element.innerHTML = html;
-};
-
-DrNicTest.Unit.Logger.prototype.appendActionButtons = function(actions) {
- // actions = $H(actions);
- // if (!actions.any()) return;
- // var div = new Element("div", {className: 'action_buttons'});
- // actions.inject(div, function(container, action) {
- // var button = new Element("input").setValue(action.key).observe("click", action.value);
- // button.type = "button";
- // return container.insert(button);
- // });
- // this.getMessageCell().insert(div);
-};
-
-DrNicTest.Unit.Logger.prototype._toHTML = function(txt) {
- return DrNicTest.escapeHTML(txt).replace(/\n/g,"<br/>");
-};
-DrNicTest.Unit.MessageTemplate = function(string) {
- var parts = [];
- var str = DrNicTest.scan((string || ''), /(?=[^\\])\?|(?:\\\?|[^\?])+/, function(part) {
- parts.push(part[0]);
- });
- this.parts = parts;
-};
-
-DrNicTest.Unit.MessageTemplate.prototype.evaluate = function(params) {
- var results = [];
- for (var i=0; i < this.parts.length; i++) {
- var part = this.parts[i];
- var result = (part == '?') ? DrNicTest.inspect(params.shift()) : part.replace(/\\\?/, '?');
- results.push(result);
- };
- return results.join('');
-};
-// A generic function for performming AJAX requests
-// It takes one argument, which is an object that contains a set of options
-// All of which are outline in the comments, below
-// From John Resig's book Pro JavaScript Techniques
-// published by Apress, 2006-8
-DrNicTest.ajax = function( options ) {
-
- // Load the options object with defaults, if no
- // values were provided by the user
- options = {
- // The type of HTTP Request
- type: options.type || "POST",
-
- // The URL the request will be made to
- url: options.url || "",
-
- // How long to wait before considering the request to be a timeout
- timeout: options.timeout || 5000,
-
- // Functions to call when the request fails, succeeds,
- // or completes (either fail or succeed)
- onComplete: options.onComplete || function(){},
- onError: options.onError || function(){},
- onSuccess: options.onSuccess || function(){},
-
- // The data type that'll be returned from the server
- // the default is simply to determine what data was returned from the
- // and act accordingly.
- data: options.data || ""
- };
-
- // Create the request object
- var xml = new XMLHttpRequest();
-
- // Open the asynchronous POST request
- xml.open(options.type, options.url, true);
-
- // We're going to wait for a request for 5 seconds, before giving up
- var timeoutLength = 5000;
-
- // Keep track of when the request has been succesfully completed
- var requestDone = false;
-
- // Initalize a callback which will fire 5 seconds from now, cancelling
- // the request (if it has not already occurred).
- setTimeout(function(){
- requestDone = true;
- }, timeoutLength);
-
- // Watch for when the state of the document gets updated
- xml.onreadystatechange = function(){
- // Wait until the data is fully loaded,
- // and make sure that the request hasn't already timed out
- if ( xml.readyState == 4 && !requestDone ) {
-
- // Check to see if the request was successful
- if ( httpSuccess( xml ) ) {
-
- // Execute the success callback with the data returned from the server
- options.onSuccess( httpData( xml, options.type ) );
-
- // Otherwise, an error occurred, so execute the error callback
- } else {
- options.onError();
- }
-
- // Call the completion callback
- options.onComplete();
-
- // Clean up after ourselves, to avoid memory leaks
- xml = null;
- }
- };
-
- // Establish the connection to the server
- xml.send();
-
- // Determine the success of the HTTP response
- function httpSuccess(r) {
- try {
- // If no server status is provided, and we're actually
- // requesting a local file, then it was successful
- return !r.status && location.protocol == "file:" ||
-
- // Any status in the 200 range is good
- ( r.status >= 200 && r.status < 300 ) ||
-
- // Successful if the document has not been modified
- r.status == 304 ||
-
- // Safari returns an empty status if the file has not been modified
- navigator.userAgent.indexOf("Safari") >= 0 && typeof r.status == "undefined";
- } catch(e){}
-
- // If checking the status failed, then assume that the request failed too
- return false;
- }
-
- // Extract the correct data from the HTTP response
- function httpData(r,type) {
- // Get the content-type header
- var ct = r.getResponseHeader("content-type");
-
- // If no default type was provided, determine if some
- // form of XML was returned from the server
- var data = !type && ct && ct.indexOf("xml") >= 0;
-
- // Get the XML Document object if XML was returned from
- // the server, otherwise return the text contents returned by the server
- data = type == "xml" || data ? r.responseXML : r.responseText;
-
- // If the specified type is "script", execute the returned text
- // response as if it was JavaScript
- if ( type == "script" )
- eval.call( window, data );
-
- // Return the response data (either an XML Document or a text string)
- return data;
- }
-
-}
-DrNicTest.Unit.Assertions = {
- buildMessage: function(message, template) {
- var args = DrNicTest.arrayfromargs(arguments).slice(2);
- return (message ? message + '\n' : '') +
- new DrNicTest.Unit.MessageTemplate(template).evaluate(args);
- },
-
- flunk: function(message) {
- this.assertBlock(message || 'Flunked', function() { return false });
- },
-
- assertBlock: function(message, block) {
- try {
- block.call(this) ? this.pass() : this.fail(message);
- } catch(e) { this.error(e) }
- },
-
- assert: function(expression, message) {
- message = this.buildMessage(message || 'assert', 'got <?>', expression);
- this.assertBlock(message, function() { return expression });
- },
-
- assertEqual: function(expected, actual, message) {
- message = this.buildMessage(message || 'assertEqual', 'expected <?>, actual: <?>', expected, actual);
- this.assertBlock(message, function() { return expected == actual });
- },
-
- assertNotEqual: function(expected, actual, message) {
- message = this.buildMessage(message || 'assertNotEqual', 'expected <?>, actual: <?>', expected, actual);
- this.assertBlock(message, function() { return expected != actual });
- },
-
- assertEnumEqual: function(expected, actual, message) {
- message = this.buildMessage(message || 'assertEnumEqual', 'expected <?>, actual: <?>', expected, actual);
- var expected_array = DrNicTest.flattenArray(expected);
- var actual_array = DrNicTest.flattenArray(actual);
- this.assertBlock(message, function() {
- if (expected_array.length == actual_array.length) {
- for (var i=0; i < expected_array.length; i++) {
- if (expected_array[i] != actual_array[i]) return false;
- };
- return true;
- }
- return false;
- });
- },
-
- assertEnumNotEqual: function(expected, actual, message) {
- message = this.buildMessage(message || 'assertEnumNotEqual', '<?> was the same as <?>', expected, actual);
- var expected_array = DrNicTest.flattenArray(expected);
- var actual_array = DrNicTest.flattenArray(actual);
- this.assertBlock(message, function() {
- if (expected_array.length == actual_array.length) {
- for (var i=0; i < expected_array.length; i++) {
- if (expected_array[i] != actual_array[i]) return true;
- };
- return false;
- }
- return true;
- });
- },
-
- assertHashEqual: function(expected, actual, message) {
- message = this.buildMessage(message || 'assertHashEqual', 'expected <?>, actual: <?>', expected, actual);
- var expected_array = DrNicTest.flattenArray(DrNicTest.hashToSortedArray(expected));
- var actual_array = DrNicTest.flattenArray(DrNicTest.hashToSortedArray(actual));
- var block = function() {
- if (expected_array.length == actual_array.length) {
- for (var i=0; i < expected_array.length; i++) {
- if (expected_array[i] != actual_array[i]) return false;
- };
- return true;
- }
- return false;
- };
- this.assertBlock(message, block);
- },
-
- assertHashNotEqual: function(expected, actual, message) {
- message = this.buildMessage(message || 'assertHashNotEqual', '<?> was the same as <?>', expected, actual);
- var expected_array = DrNicTest.flattenArray(DrNicTest.hashToSortedArray(expected));
- var actual_array = DrNicTest.flattenArray(DrNicTest.hashToSortedArray(actual));
- // from now we recursively zip & compare nested arrays
- var block = function() {
- if (expected_array.length == actual_array.length) {
- for (var i=0; i < expected_array.length; i++) {
- if (expected_array[i] != actual_array[i]) return true;
- };
- return false;
- }
- return true;
- };
- this.assertBlock(message, block);
- },
-
- assertIdentical: function(expected, actual, message) {
- message = this.buildMessage(message || 'assertIdentical', 'expected <?>, actual: <?>', expected, actual);
- this.assertBlock(message, function() { return expected === actual });
- },
-
- assertNotIdentical: function(expected, actual, message) {
- message = this.buildMessage(message || 'assertNotIdentical', 'expected <?>, actual: <?>', expected, actual);
- this.assertBlock(message, function() { return expected !== actual });
- },
-
- assertNull: function(obj, message) {
- message = this.buildMessage(message || 'assertNull', 'got <?>', obj);
- this.assertBlock(message, function() { return obj === null });
- },
-
- assertNotNull: function(obj, message) {
- message = this.buildMessage(message || 'assertNotNull', 'got <?>', obj);
- this.assertBlock(message, function() { return obj !== null });
- },
-
- assertUndefined: function(obj, message) {
- message = this.buildMessage(message || 'assertUndefined', 'got <?>', obj);
- this.assertBlock(message, function() { return typeof obj == "undefined" });
- },
-
- assertNotUndefined: function(obj, message) {
- message = this.buildMessage(message || 'assertNotUndefined', 'got <?>', obj);
- this.assertBlock(message, function() { return typeof obj != "undefined" });
- },
-
- assertNullOrUndefined: function(obj, message) {
- message = this.buildMessage(message || 'assertNullOrUndefined', 'got <?>', obj);
- this.assertBlock(message, function() { return obj == null });
- },
-
- assertNotNullOrUndefined: function(obj, message) {
- message = this.buildMessage(message || 'assertNotNullOrUndefined', 'got <?>', obj);
- this.assertBlock(message, function() { return obj != null });
- },
-
- assertMatch: function(expected, actual, message) {
- message = this.buildMessage(message || 'assertMatch', 'regex <?> did not match <?>', expected, actual);
- this.assertBlock(message, function() { return new RegExp(expected).exec(actual) });
- },
-
- assertNoMatch: function(expected, actual, message) {
- message = this.buildMessage(message || 'assertNoMatch', 'regex <?> matched <?>', expected, actual);
- this.assertBlock(message, function() { return !(new RegExp(expected).exec(actual)) });
- },
-
- assertHidden: function(element, message) {
- message = this.buildMessage(message || 'assertHidden', '? isn\'t hidden.', element);
- this.assertBlock(message, function() { return element.style.display == 'none' });
- },
-
- assertInstanceOf: function(expected, actual, message) {
- message = this.buildMessage(message || 'assertInstanceOf', '<?> was not an instance of the expected type', actual);
- this.assertBlock(message, function() { return actual instanceof expected });
- },
-
- assertNotInstanceOf: function(expected, actual, message) {
- message = this.buildMessage(message || 'assertNotInstanceOf', '<?> was an instance of the expected type', actual);
- this.assertBlock(message, function() { return !(actual instanceof expected) });
- },
-
- assertRespondsTo: function(method, obj, message) {
- message = this.buildMessage(message || 'assertRespondsTo', 'object doesn\'t respond to <?>', method);
- this.assertBlock(message, function() { return (method in obj && typeof obj[method] == 'function') });
- },
-
- assertRaise: function(exceptionName, method, message) {
- message = this.buildMessage(message || 'assertRaise', '<?> exception expected but none was raised', exceptionName);
- var block = function() {
- try {
- method();
- return false;
- } catch(e) {
- if (e.name == exceptionName) return true;
- else throw e;
- }
- };
- this.assertBlock(message, block);
- },
-
- assertNothingRaised: function(method, message) {
- try {
- method();
- this.assert(true, "Expected nothing to be thrown");
- } catch(e) {
- message = this.buildMessage(message || 'assertNothingRaised', '<?> was thrown when nothing was expected.', e);
- this.flunk(message);
- }
- },
-
- _isVisible: function(element) {
- element = DrNicTest.$(element);
- if(!element.parentNode) return true;
- this.assertNotNull(element);
- if(element.style && element.style.display == 'none')
- return false;
-
- return arguments.callee.call(this, element.parentNode);
- },
-
- assertVisible: function(element, message) {
- message = this.buildMessage(message, '? was not visible.', element);
- this.assertBlock(message, function() { return this._isVisible(element) });
- },
-
- assertNotVisible: function(element, message) {
- message = this.buildMessage(message, '? was not hidden and didn\'t have a hidden parent either.', element);
- this.assertBlock(message, function() { return !this._isVisible(element) });
- },
-
- assertElementsMatch: function() {
- var pass = true, expressions = DrNicTest.arrayfromargs(arguments);
- var elements = expressions.shift();
- if (elements.length != expressions.length) {
- message = this.buildMessage('assertElementsMatch', 'size mismatch: ? elements, ? expressions (?).', elements.length, expressions.length, expressions);
- this.flunk(message);
- pass = false;
- }
- for (var i=0; i < expressions.length; i++) {
- var expression = expressions[i];
- var element = DrNicTest.$(elements[i]);
- if (DrNicTest.selectorMatch(expression, element)) {
- pass = true;
- break;
- }
- message = this.buildMessage('assertElementsMatch', 'In index <?>: expected <?> but got ?', index, expression, element);
- this.flunk(message);
- pass = false;
- };
- this.assert(pass, "Expected all elements to match.");
- },
-
- assertElementMatches: function(element, expression, message) {
- this.assertElementsMatch([element], expression);
- }
-};
-DrNicTest.Unit.Runner = function(testcases) {
- var argumentOptions = arguments[1] || {};
- var options = this.options = {};
- options.testLog = ('testLog' in argumentOptions) ? argumentOptions.testLog : 'testlog';
- options.resultsURL = this.queryParams.resultsURL;
- options.testLog = DrNicTest.$(options.testLog);
-
- this.tests = this.getTests(testcases);
- this.currentTest = 0;
- this.logger = new DrNicTest.Unit.Logger(options.testLog);
-
- var self = this;
- DrNicTest.Event.addEvent(window, "load", function() {
- setTimeout(function() {
- self.runTests();
- }, 0.1);
- });
-};
-
-DrNicTest.Unit.Runner.prototype.queryParams = DrNicTest.toQueryParams();
-
-DrNicTest.Unit.Runner.prototype.portNumber = function() {
- if (window.location.search.length > 0) {
- var matches = window.location.search.match(/\:(\d{3,5})\//);
- if (matches) {
- return parseInt(matches[1]);
- }
- }
- return null;
-};
-
-DrNicTest.Unit.Runner.prototype.getTests = function(testcases) {
- var tests = [], options = this.options;
- if (this.queryParams.tests) tests = this.queryParams.tests.split(',');
- else if (options.tests) tests = options.tests;
- else if (options.test) tests = [option.test];
- else {
- for (testname in testcases) {
- if (testname.match(/^test/)) tests.push(testname);
- }
- }
- var results = [];
- for (var i=0; i < tests.length; i++) {
- var test = tests[i];
- if (testcases[test])
- results.push(
- new DrNicTest.Unit.Testcase(test, testcases[test], testcases.setup, testcases.teardown)
- );
- };
- return results;
-};
-
-DrNicTest.Unit.Runner.prototype.getResult = function() {
- var results = {
- tests: this.tests.length,
- assertions: 0,
- failures: 0,
- errors: 0
- };
-
- for (var i=0; i < this.tests.length; i++) {
- var test = this.tests[i];
- results.assertions += test.assertions;
- results.failures += test.failures;
- results.errors += test.errors;
- };
- return results;
-};
-
-DrNicTest.Unit.Runner.prototype.postResults = function() {
- if (this.options.resultsURL) {
- // new Ajax.Request(this.options.resultsURL,
- // { method: 'get', parameters: this.getResult(), asynchronous: false });
- var results = this.getResult();
- var url = this.options.resultsURL + "?";
- url += "assertions="+ results.assertions + "&";
- url += "failures=" + results.failures + "&";
- url += "errors=" + results.errors;
- DrNicTest.ajax({
- url: url,
- type: 'GET'
- })
- }
-};
-
-DrNicTest.Unit.Runner.prototype.runTests = function() {
- var test = this.tests[this.currentTest], actions;
-
- if (!test) return this.finish();
- if (!test.isWaiting) this.logger.start(test.name);
- test.run();
- var self = this;
- if(test.isWaiting) {
- this.logger.message("Waiting for " + test.timeToWait + "ms");
- // setTimeout(this.runTests.bind(this), test.timeToWait || 1000);
- setTimeout(function() {
- self.runTests();
- }, test.timeToWait || 1000);
- return;
- }
-
- this.logger.finish(test.status(), test.summary());
- if (actions = test.actions) this.logger.appendActionButtons(actions);
- this.currentTest++;
- // tail recursive, hopefully the browser will skip the stackframe
- this.runTests();
-};
-
-DrNicTest.Unit.Runner.prototype.finish = function() {
- this.postResults();
- this.logger.summary(this.summary());
-};
-
-DrNicTest.Unit.Runner.prototype.summary = function() {
- return new DrNicTest.Template('#{tests} tests, #{assertions} assertions, #{failures} failures, #{errors} errors').evaluate(this.getResult());
-};
-DrNicTest.Unit.Testcase = function(name, test, setup, teardown) {
- this.name = name;
- this.test = test || function() {};
- this.setup = setup || function() {};
- this.teardown = teardown || function() {};
- this.messages = [];
- this.actions = {};
-};
-// import DrNicTest.Unit.Assertions
-
-for (method in DrNicTest.Unit.Assertions) {
- DrNicTest.Unit.Testcase.prototype[method] = DrNicTest.Unit.Assertions[method];
-}
-
-DrNicTest.Unit.Testcase.prototype.isWaiting = false;
-DrNicTest.Unit.Testcase.prototype.timeToWait = 1000;
-DrNicTest.Unit.Testcase.prototype.assertions = 0;
-DrNicTest.Unit.Testcase.prototype.failures = 0;
-DrNicTest.Unit.Testcase.prototype.errors = 0;
-// DrNicTest.Unit.Testcase.prototype.isRunningFromRake = window.location.port == 4711;
-DrNicTest.Unit.Testcase.prototype.isRunningFromRake = window.location.port;
-
-DrNicTest.Unit.Testcase.prototype.wait = function(time, nextPart) {
- this.isWaiting = true;
- this.test = nextPart;
- this.timeToWait = time;
-};
-
-DrNicTest.Unit.Testcase.prototype.run = function(rethrow) {
- try {
- try {
- if (!this.isWaiting) this.setup();
- this.isWaiting = false;
- this.test();
- } finally {
- if(!this.isWaiting) {
- this.teardown();
- }
- }
- }
- catch(e) {
- if (rethrow) throw e;
- this.error(e, this);
- }
-};
-
-DrNicTest.Unit.Testcase.prototype.summary = function() {
- var msg = '#{assertions} assertions, #{failures} failures, #{errors} errors\n';
- return new DrNicTest.Template(msg).evaluate(this) +
- this.messages.join("\n");
-};
-
-DrNicTest.Unit.Testcase.prototype.pass = function() {
- this.assertions++;
-};
-
-DrNicTest.Unit.Testcase.prototype.fail = function(message) {
- this.failures++;
- var line = "";
- try {
- throw new Error("stack");
- } catch(e){
- line = (/\.html:(\d+)/.exec(e.stack || '') || ['',''])[1];
- }
- this.messages.push("Failure: " + message + (line ? " Line #" + line : ""));
-};
-
-DrNicTest.Unit.Testcase.prototype.info = function(message) {
- this.messages.push("Info: " + message);
-};
-
-DrNicTest.Unit.Testcase.prototype.error = function(error, test) {
- this.errors++;
- this.actions['retry with throw'] = function() { test.run(true) };
- this.messages.push(error.name + ": "+ error.message + "(" + DrNicTest.inspect(error) + ")");
-};
-
-DrNicTest.Unit.Testcase.prototype.status = function() {
- if (this.failures > 0) return 'failed';
- if (this.errors > 0) return 'error';
- return 'passed';
-};
-
-DrNicTest.Unit.Testcase.prototype.benchmark = function(operation, iterations) {
- var startAt = new Date();
- (iterations || 1).times(operation);
- var timeTaken = ((new Date())-startAt);
- this.info((arguments[2] || 'Operation') + ' finished ' +
- iterations + ' iterations in ' + (timeTaken/1000)+'s' );
- return timeTaken;
-};
-
-Test = DrNicTest
diff --git a/chrome/common/extensions/docs/examples/extensions/proxy_configuration/test/proxy_form_controller_test.html b/chrome/common/extensions/docs/examples/extensions/proxy_configuration/test/proxy_form_controller_test.html
deleted file mode 100644
index 096e709..0000000
--- a/chrome/common/extensions/docs/examples/extensions/proxy_configuration/test/proxy_form_controller_test.html
+++ /dev/null
@@ -1,113 +0,0 @@
-<!doctype html>
-<html>
-<head>
- <title>Popup for Proxy API Test</title>
- <link rel="stylesheet" type="text/css" href="./unittest.css">
- <script src="./jsunittest.js"></script>
- <script src="../proxy_form_controller.js"></script>
-</head>
-<body>
- <h1>Proxy Configuration Unit Tests</h1>
-
- <h2>ProxyFormController</h2>
- <div id="proxyformcontrollerlog"></div>
-
- <div id="fixture">
- <form id="proxyForm">
- <fieldset id="system">
- <legend>System Settings</legend>
- <input type="radio" name="proxyType" id="proxyTypeSystem" value="system">
- <label for="proxyTypeSystem">Use the <em>system's proxy settings</em>.</label>
- </fieldset>
- <fieldset id="direct">
- <legend>Direct Connection</legend>
- <input type="radio" name="proxyType" id="proxyTypeDirect" value="direct">
- <label for="proxyTypeDirect">Your computer is <em>directly connected</em> to the internet; no need for a proxy.</label>
- </fieldset>
- <fieldset id="pac_script">
- <legend>Automatic Configuration</legend>
- <input type="radio" name="proxyType" id="proxyTypeAutoconfig" value="autoconfig">
- <label for="proxyTypeAutoconfig">Your proxy supports <em>automatic configuration</em>.</label>
-
- <section>
- <label for="autoconfigURL">Autoconfiguration URL (PAC file)</label>
- <input type="url" name="autoconfigURL" id="autoconfigURL">
- <input type="hidden" name="autoconfigData" id="autoconfigData">
- </section>
- </fieldset>
- <fieldset id="fixed_servers">
- <legend>Manual Proxy</legend>
- <input type="radio" name="proxyType" id="proxyTypeManual" value="manual">
- <label for="proxyTypeManual">Configure your proxy settings <em>manually</em>.</label>
- <section>
- <fieldset>
- <legend>HTTP</legend>
- <label for="proxyHostHttp">Host</label>
- <select id="proxySchemeHttp" name="proxySchemeHttp">
- <option selected value="http">http://</option>
- <option value="https">https://</option>
- <option value="socks4">socks4://</option>
- <option value="socks5">socks5://</option>
- </select>
- <input type="text" name="proxyHostHttp" id="proxyHostHttp">
-
- <label for="proxyPortHttp">Port</label>
- <input type="number" min="1" step="1" name="proxyPortHttp" id="proxyPortHttp">
-
- <input type="checkbox" name="singleProxyForEverything" id="singleProxyForEverything">
- <label for="singleProxyForEverything">Use the same proxy server for all protocols</label>
- </fieldset>
- <fieldset>
- <legend>HTTPS</legend>
- <label for="proxyHostHttps">Host</label>
- <select id="proxySchemeHttps" name="proxySchemeHttps">
- <option selected value="http">http://</option>
- <option value="https">https://</option>
- <option value="socks4">socks4://</option>
- <option value="socks5">socks5://</option>
- </select>
- <input type="text" name="proxyHostHttps" id="proxyHostHttps">
-
- <label for="proxyPortHttps">Port</label>
- <input type="number" min="1" step="1" name="proxyPortHttps" id="proxyPortHttps">
- </fieldset>
- <fieldset>
- <legend>FTP</legend>
- <label for="proxyHostFtp">Host</label>
- <select id="proxySchemeFtp" name="proxySchemeFtp">
- <option selected value="http">http://</option>
- <option value="https">https://</option>
- <option value="socks4">socks4://</option>
- <option value="socks5">socks5://</option>
- </select>
- <input type="text" name="proxyHostFtp" id="proxyHostFtp">
-
- <label for="proxyPortFtp">Port</label>
- <input type="number" min="1" step="1" name="proxyPortFtp" id="proxyPortFtp">
- </fieldset>
- <fieldset>
- <legend>Fallback</legend>
- <label for="proxyHostFallback">Host</label>
- <select id="proxySchemeFallback" name="proxySchemeFallback">
- <option selected value="http">http://</option>
- <option value="https">https://</option>
- <option value="socks4">socks4://</option>
- <option value="socks5">socks5://</option>
- </select>
- <input type="text" name="proxyHostFallback" id="proxyHostFallback">
-
- <label for="proxyPortFallback">Port</label>
- <input type="number" min="1" step="1" name="proxyPortFallback" id="proxyPortFallback">
- </fieldset>
- <fieldset>
- <label for="bypassList">Bypass proxy for these hosts:</label>
- <textarea id="bypassList" name="bypassList" placeholder="localhost,192.168.1.1/16, .example.com"></textarea>
- </fieldset>
- </section>
- </fieldset>
- <input type="submit" value="Save proxy settings">
- </form>
- </div>
- <script src="./proxy_form_controller_test.js"></script>
-</body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/extensions/proxy_configuration/test/proxy_form_controller_test.js b/chrome/common/extensions/docs/examples/extensions/proxy_configuration/test/proxy_form_controller_test.js
deleted file mode 100644
index f778ec9..0000000
--- a/chrome/common/extensions/docs/examples/extensions/proxy_configuration/test/proxy_form_controller_test.js
+++ /dev/null
@@ -1,513 +0,0 @@
-// Copyright (c) 2011 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.
-
-// Stub out the `chrome.proxy`, `chrome.i18n`, and `chrome.extension` APIs
-chrome = chrome || {
- proxy: {
- settings: {
- get: function() {},
- clear: function() {},
- set: function() {}
- }
- },
- i18n: {
- getMessage: function(x) { return x; }
- },
- extension: {
- sendRequest: function() {},
- isAllowedIncognitoAccess: function(funk) {
- funk(true);
- }
- }
-};
-
-var fixture = document.getElementById('fixture');
-var baselineHTML = fixture.innerHTML;
-var groupIDs = [ProxyFormController.ProxyTypes.DIRECT,
- ProxyFormController.ProxyTypes.SYSTEM,
- ProxyFormController.ProxyTypes.PAC,
- ProxyFormController.ProxyTypes.FIXED];
-
-var mockFunctionFactory = function(returnValue, logging) {
- var called = [];
- returnValue = returnValue || null;
-
- var funky = function() {
- called.push(arguments);
- if (arguments[1] && typeof(arguments[1]) === 'function') {
- var funk = arguments[1];
- funk(returnValue);
- }
- return returnValue;
- };
- funky.getCallList = function() { return called; };
- funky.getValue = function() { return returnValue; };
- return funky;
-};
-
-var proxyform = new Test.Unit.Runner({
- setup: function() {
- fixture.innerHTML = baselineHTML;
- this.controller_ = new ProxyFormController('proxyForm');
- this.clickEvent_ = document.createEvent('MouseEvents');
- this.clickEvent_.initMouseEvent('click', true, true, window,
- 0, 0, 0, 0, 0, false, false, false, false, 0, null);
- // Reset mock functions.
- chrome.proxy = {
- settings: {
- get: mockFunctionFactory({
- value: {mode: 'system' },
- levelOfControl: 'controllable_by_this_extension' }),
- clear: mockFunctionFactory({
- value: {mode: 'system' },
- levelOfControl: 'controllable_by_this_extension' }),
- set: mockFunctionFactory({
- value: {mode: 'system' },
- levelOfControl: 'controllable_by_this_extension' })
- }
- };
- },
-
- teardown: function() {
- fixture.removeChild(fixture.childNodes[0]);
- delete(this.controller_);
- },
-
- // Clicking on various bits of the interface should set correct classes,
- // and select correct radio buttons.
- testActivationClicks: function() {
- var self = this;
- var i;
- groupIDs.forEach(function(id) {
- var group = document.getElementById(id);
- var all = group.querySelectorAll('*');
- for (i = 0; i < all.length; i++) {
- group.classList.remove('active');
- all[i].dispatchEvent(self.clickEvent_);
- self.assert(group.classList.contains('active'));
- }
- });
- },
-
- // Elements inside an active group should not be disabled, and vice versa
- testDisabledElements: function() {
- var self = this;
- var i, j;
- groupIDs.forEach(function(id) {
- var group = document.getElementById(id);
- var all = group.querySelectorAll('*');
- // First, check that activating a group enables its form elements
- for (i = 0; i < all.length; i++) {
- group.classList.remove('active');
- var inputs = group.querySelectorAll('input:not([type="radio"]),select');
- for (j = 0; j < inputs.length; j++) {
- inputs[j].setAttribute('disabled', 'disabled');
- }
- all[i].dispatchEvent(self.clickEvent_);
- for (j = 0; j < inputs.length; j++) {
- self.assert(!inputs[j].hasAttribute('disabled'));
- }
- }
- });
- },
-
- // Clicking the "Use single proxy" checkbox should set the correct
- // classes on the form.
- testSingleProxyToggle: function() {
- var group = document.getElementById(
- ProxyFormController.ProxyTypes.FIXED);
- var checkbox = document.getElementById('singleProxyForEverything');
- var section = checkbox.parentNode.parentNode;
- // Checkbox only works in active group, `testActivationClicks` tests
- // the inactive click behavior.
- group.classList.add('active');
-
- checkbox.checked = false;
- checkbox.dispatchEvent(this.clickEvent_);
- this.assert(section.classList.contains('single'));
- checkbox.dispatchEvent(this.clickEvent_);
- this.assert(!section.classList.contains('single'));
- },
-
- // On instantiation, ProxyFormController should read the current state
- // from `chrome.proxy.settings.get`, and react accordingly.
- // Let's see if that happens with the next four sets of assertions.
- testSetupFormSystem: function() {
- chrome.proxy.settings.get = mockFunctionFactory({
- value: {mode: 'system'},
- levelOfControl: 'controllable_by_this_extension'
- });
-
- fixture.innerHTML = baselineHTML;
- this.controller_ = new ProxyFormController('proxyForm');
- // Wait for async calls to fire
- this.wait(100, function() {
- this.assertEqual(
- 6,
- chrome.proxy.settings.get.getCallList().length);
- this.assert(
- document.getElementById(ProxyFormController.ProxyTypes.SYSTEM)
- .classList.contains('active'));
- });
- },
-
- testSetupFormDirect: function() {
- chrome.proxy.settings.get =
- mockFunctionFactory({value: {mode: 'direct'},
- levelOfControl: 'controllable_by_this_extension'}, true);
-
- fixture.innerHTML = baselineHTML;
- this.controller_ = new ProxyFormController('proxyForm');
- // Wait for async calls to fire
- this.wait(100, function() {
- this.assertEqual(
- 2,
- chrome.proxy.settings.get.getCallList().length);
- this.assert(
- document.getElementById(ProxyFormController.ProxyTypes.DIRECT)
- .classList.contains('active'));
- });
- },
-
- testSetupFormPac: function() {
- chrome.proxy.settings.get =
- mockFunctionFactory({value: {mode: 'pac_script' },
- levelOfControl: 'controllable_by_this_extension'});
-
- fixture.innerHTML = baselineHTML;
- this.controller_ = new ProxyFormController('proxyForm');
- // Wait for async calls to fire
- this.wait(100, function() {
- this.assertEqual(
- 2,
- chrome.proxy.settings.get.getCallList().length);
- this.assert(
- document.getElementById(ProxyFormController.ProxyTypes.PAC)
- .classList.contains('active'));
- });
- },
-
- testSetupFormFixed: function() {
- chrome.proxy.settings.get =
- mockFunctionFactory({value: {mode: 'fixed_servers' },
- levelOfControl: 'controllable_by_this_extension'});
-
- fixture.innerHTML = baselineHTML;
- this.controller_ = new ProxyFormController('proxyForm');
- // Wait for async calls to fire
- this.wait(100, function() {
- this.assertEqual(
- 2,
- chrome.proxy.settings.get.getCallList().length);
- this.assert(
- document.getElementById(ProxyFormController.ProxyTypes.FIXED)
- .classList.contains('active'));
- });
- },
-
- // Test that `recalcFormValues_` correctly sets DOM field values when
- // given a `ProxyConfig` structure
- testRecalcFormValuesGroups: function() {
- // Test `AUTO` normalization to `PAC`
- this.controller_.recalcFormValues_({
- mode: ProxyFormController.ProxyTypes.AUTO,
- rules: {},
- pacScript: ''
- });
- this.assert(
- document.getElementById(ProxyFormController.ProxyTypes.PAC)
- .classList.contains('active'));
-
- // DIRECT
- this.controller_.recalcFormValues_({
- mode: ProxyFormController.ProxyTypes.DIRECT,
- rules: {},
- pacScript: ''
- });
- this.assert(
- document.getElementById(ProxyFormController.ProxyTypes.DIRECT)
- .classList.contains('active'));
-
- // FIXED
- this.controller_.recalcFormValues_({
- mode: ProxyFormController.ProxyTypes.FIXED,
- rules: {},
- pacScript: ''
- });
- this.assert(
- document.getElementById(ProxyFormController.ProxyTypes.FIXED)
- .classList.contains('active'));
-
- // PAC
- this.controller_.recalcFormValues_({
- mode: ProxyFormController.ProxyTypes.PAC,
- rules: {},
- pacScript: ''
- });
- this.assert(
- document.getElementById(ProxyFormController.ProxyTypes.PAC)
- .classList.contains('active'));
-
- // SYSTEM
- this.controller_.recalcFormValues_({
- mode: ProxyFormController.ProxyTypes.SYSTEM,
- rules: {},
- pacScript: ''
- });
- this.assert(
- document.getElementById(ProxyFormController.ProxyTypes.SYSTEM)
- .classList.contains('active'));
- },
-
- testRecalcFormValuesFixedSingle: function() {
- this.controller_.recalcFormValues_({
- mode: ProxyFormController.ProxyTypes.FIXED,
- rules: {
- singleProxy: {
- scheme: 'socks5',
- host: 'singleproxy.example.com',
- port: '1234'
- }
- }
- });
- var single = this.controller_.singleProxy;
- this.assertEqual('socks5', single.scheme);
- this.assertEqual('singleproxy.example.com', single.host);
- this.assertEqual(1234, single.port);
- },
-
- testRecalcFormValuesPacScript: function() {
- this.controller_.recalcFormValues_({
- mode: ProxyFormController.ProxyTypes.PAC,
- rules: {},
- pacScript: {url: 'http://example.com/this/is/a/pac.script'}
- });
- this.assertEqual(
- 'http://example.com/this/is/a/pac.script',
- document.getElementById('autoconfigURL').value);
- },
-
- testRecalcFormValuesSingle: function() {
- this.controller_.recalcFormValues_({
- mode: ProxyFormController.ProxyTypes.FIXED,
- rules: {
- singleProxy: {
- scheme: 'https',
- host: 'example.com',
- port: 80
- }
- }
- });
- // Single!
- this.assert(
- document.querySelector('#' + ProxyFormController.ProxyTypes.FIXED +
- ' > section').classList.contains('single'));
-
- var single = this.controller_.singleProxy;
- this.assertEqual('https', single.scheme);
- this.assertEqual('example.com', single.host);
- this.assertEqual(80, single.port);
- },
-
- testRecalcFormValuesMultiple: function() {
- this.controller_.recalcFormValues_({
- mode: ProxyFormController.ProxyTypes.FIXED,
- rules: {
- proxyForHttp: {
- scheme: 'http',
- host: 'http.example.com',
- port: 1
- },
- proxyForHttps: {
- scheme: 'https',
- host: 'https.example.com',
- port: 2
- },
- proxyForFtp: {
- scheme: 'socks4',
- host: 'socks4.example.com',
- port: 3
- },
- fallbackProxy: {
- scheme: 'socks5',
- host: 'socks5.example.com',
- port: 4
- }
- }
- });
- // Not Single!
- this.assert(
- !document.querySelector('#' + ProxyFormController.ProxyTypes.FIXED
- + ' > section').classList.contains('single'));
- var server = this.controller_.singleProxy;
- this.assertNull(server);
-
- server = this.controller_.httpProxy;
- this.assertEqual('http', server.scheme);
- this.assertEqual('http.example.com', server.host);
- this.assertEqual(1, server.port);
-
- server = this.controller_.httpsProxy;
- this.assertEqual('https', server.scheme);
- this.assertEqual('https.example.com', server.host);
- this.assertEqual(2, server.port);
-
- server = this.controller_.ftpProxy;
- this.assertEqual('socks4', server.scheme);
- this.assertEqual('socks4.example.com', server.host);
- this.assertEqual(3, server.port);
-
- server = this.controller_.fallbackProxy;
- this.assertEqual('socks5', server.scheme);
- this.assertEqual('socks5.example.com', server.host);
- this.assertEqual(4, server.port);
- },
-
- testBypassList: function() {
- this.controller_.bypassList = ['1.example.com',
- '2.example.com',
- '3.example.com'];
- this.assertEnumEqual(
- document.getElementById('bypassList').value,
- '1.example.com, 2.example.com, 3.example.com');
- this.assertEnumEqual(
- this.controller_.bypassList,
- ['1.example.com', '2.example.com', '3.example.com']);
- },
-
- // Test that "system" rules are correctly generated
- testProxyRulesGenerationSystem: function() {
- this.controller_.changeActive_(
- document.getElementById(ProxyFormController.ProxyTypes.SYSTEM));
-
- this.assertHashEqual(
- {mode: 'system'},
- this.controller_.generateProxyConfig_());
- },
-
- // Test that "direct" rules are correctly generated
- testProxyRulesGenerationDirect: function() {
- this.controller_.changeActive_(
- document.getElementById(ProxyFormController.ProxyTypes.DIRECT));
-
- this.assertHashEqual(
- {mode: 'direct'},
- this.controller_.generateProxyConfig_());
- },
-
- // Test that auto detection rules are correctly generated when "automatic"
- // is selected, and no PAC file URL is given
- testProxyRulesGenerationAuto: function() {
- this.controller_.changeActive_(
- document.getElementById(ProxyFormController.ProxyTypes.PAC));
-
- this.assertHashEqual(
- {mode: 'auto_detect'},
- this.controller_.generateProxyConfig_());
- },
-
- // Test that PAC URL rules are correctly generated when "automatic"
- // is selected, and a PAC file URL is given
- testProxyRulesGenerationPacURL: function() {
- this.controller_.changeActive_(
- document.getElementById(ProxyFormController.ProxyTypes.PAC));
- this.controller_.pacURL = 'http://example.com/pac.pac';
- var result = this.controller_.generateProxyConfig_();
- this.assertEqual('pac_script', result.mode);
- this.assertEqual('http://example.com/pac.pac', result.pacScript.url);
- },
-
- // Manual PAC definitions
- testProxyRulesGenerationPacData: function() {
- var pacData = 'function FindProxyForURL(url,host) { return "DIRECT"; }';
- this.controller_.changeActive_(
- document.getElementById(ProxyFormController.ProxyTypes.PAC));
- this.controller_.manualPac = pacData;
- var result = this.controller_.generateProxyConfig_();
- this.assertEqual('pac_script', result.mode);
- this.assertEqual(pacData, result.pacScript.data);
- },
-
- // PAC URLs override manual PAC definitions
- testProxyRulesGenerationPacURLOverridesData: function() {
- this.controller_.changeActive_(
- document.getElementById(ProxyFormController.ProxyTypes.PAC));
- this.controller_.pacURL = 'http://example.com/pac.pac';
- this.controller_.manualPac =
- 'function FindProxyForURL(url,host) { return "DIRECT"; }';
- var result = this.controller_.generateProxyConfig_();
- this.assertEqual('pac_script', result.mode);
- this.assertEqual('http://example.com/pac.pac', result.pacScript.url);
- },
-
- // Test that fixed, manual servers are correctly transformed into a
- // `ProxyRules` structure.
- testProxyRulesGenerationSingle: function() {
- this.controller_.changeActive_(
- document.getElementById(ProxyFormController.ProxyTypes.FIXED));
-
- this.controller_.singleProxy = {
- scheme: 'http',
- host: 'example.com',
- port: '80'
- };
-
- var result = this.controller_.generateProxyConfig_();
- this.assertEqual('fixed_servers', result.mode);
- this.assertEqual('http', result.rules.singleProxy.scheme);
- this.assertEqual('example.com', result.rules.singleProxy.host);
- this.assertEqual(80, result.rules.singleProxy.port);
- this.assertEqual(undefined, result.rules.proxyForHttp);
- this.assertEqual(undefined, result.rules.proxyForHttps);
- this.assertEqual(undefined, result.rules.proxyForFtp);
- this.assertEqual(undefined, result.rules.fallbackProxy);
- },
-
- // Test that proxy configuration rules are correctly generated
- // for separate manually entered servers.
- testProxyRulesGenerationSeparate: function() {
- this.controller_.changeActive_(
- document.getElementById(ProxyFormController.ProxyTypes.FIXED));
-
- this.controller_.singleProxy = false;
- this.controller_.httpProxy = {
- scheme: 'http',
- host: 'http.example.com',
- port: 80
- };
- this.controller_.httpsProxy = {
- scheme: 'https',
- host: 'https.example.com',
- port: 443
- };
- this.controller_.ftpProxy = {
- scheme: 'socks4',
- host: 'ftp.example.com',
- port: 80
- };
- this.controller_.fallbackProxy = {
- scheme: 'socks5',
- host: 'fallback.example.com',
- port: 80
- };
-
- var result = this.controller_.generateProxyConfig_();
- this.assertEqual('fixed_servers', result.mode);
- this.assertEqual(undefined, result.rules.singleProxy);
- this.assertEqual('http', result.rules.proxyForHttp.scheme);
- this.assertEqual('http.example.com', result.rules.proxyForHttp.host);
- this.assertEqual('80', result.rules.proxyForHttp.port);
- this.assertEqual('https', result.rules.proxyForHttps.scheme);
- this.assertEqual('https.example.com', result.rules.proxyForHttps.host);
- this.assertEqual('443', result.rules.proxyForHttps.port);
- this.assertEqual('socks4', result.rules.proxyForFtp.scheme);
- this.assertEqual('ftp.example.com', result.rules.proxyForFtp.host);
- this.assertEqual('80', result.rules.proxyForFtp.port);
- this.assertEqual('socks5', result.rules.fallbackProxy.scheme);
- this.assertEqual('fallback.example.com', result.rules.fallbackProxy.host);
- this.assertEqual('80', result.rules.fallbackProxy.port);
- }
-}, { testLog: 'proxyformcontrollerlog' });
-
-var c = new ProxyFormController('proxyForm');
diff --git a/chrome/common/extensions/docs/examples/extensions/proxy_configuration/test/unittest.css b/chrome/common/extensions/docs/examples/extensions/proxy_configuration/test/unittest.css
deleted file mode 100644
index d62b1c5..0000000
--- a/chrome/common/extensions/docs/examples/extensions/proxy_configuration/test/unittest.css
+++ /dev/null
@@ -1,58 +0,0 @@
-body, div, p, h1, h2, h3, ul, ol, span, a, table, td, form, img, li {
- font-family: sans-serif;
-}
-
-body {
- font-size:0.8em;
-}
-
-#log {
- padding-bottom: 1em;
- border-bottom: 2px solid #000;
- margin-bottom: 2em;
-}
-
-.logsummary {
- margin-top: 1em;
- margin-bottom: 1em;
- padding: 1ex;
- border: 1px solid #000;
- font-weight: bold;
-}
-
-.logtable {
- width:100%;
- border-collapse: collapse;
- border: 1px dotted #666;
-}
-
-.logtable td, .logtable th {
- text-align: left;
- padding: 3px 8px;
- border: 1px dotted #666;
-}
-
-.logtable .passed {
- background-color: #cfc;
-}
-
-.logtable .failed, .logtable .error {
- background-color: #fcc;
-}
-
-.logtable .warning {
- background-color: #FC6;
-}
-
-.logtable td div.action_buttons {
- display: inline;
-}
-
-.logtable td div.action_buttons input {
- margin: 0 5px;
- font-size: 10px;
-}
-
-#fixture {
- display: none;
-}
diff --git a/chrome/common/extensions/docs/examples/extensions/speak_selection/SpeakSel128.png b/chrome/common/extensions/docs/examples/extensions/speak_selection/SpeakSel128.png
deleted file mode 100644
index 8ec46c1..0000000
--- a/chrome/common/extensions/docs/examples/extensions/speak_selection/SpeakSel128.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/speak_selection/SpeakSel16.png b/chrome/common/extensions/docs/examples/extensions/speak_selection/SpeakSel16.png
deleted file mode 100644
index 5dad8df3..0000000
--- a/chrome/common/extensions/docs/examples/extensions/speak_selection/SpeakSel16.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/speak_selection/SpeakSel19-active.png b/chrome/common/extensions/docs/examples/extensions/speak_selection/SpeakSel19-active.png
deleted file mode 100644
index 35e6df2..0000000
--- a/chrome/common/extensions/docs/examples/extensions/speak_selection/SpeakSel19-active.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/speak_selection/SpeakSel19.png b/chrome/common/extensions/docs/examples/extensions/speak_selection/SpeakSel19.png
deleted file mode 100644
index 201831f..0000000
--- a/chrome/common/extensions/docs/examples/extensions/speak_selection/SpeakSel19.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/speak_selection/SpeakSel256.png b/chrome/common/extensions/docs/examples/extensions/speak_selection/SpeakSel256.png
deleted file mode 100644
index 7270b1f..0000000
--- a/chrome/common/extensions/docs/examples/extensions/speak_selection/SpeakSel256.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/speak_selection/SpeakSel48.png b/chrome/common/extensions/docs/examples/extensions/speak_selection/SpeakSel48.png
deleted file mode 100644
index e35886a..0000000
--- a/chrome/common/extensions/docs/examples/extensions/speak_selection/SpeakSel48.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/speak_selection/background.js b/chrome/common/extensions/docs/examples/extensions/speak_selection/background.js
deleted file mode 100644
index a67629a..0000000
--- a/chrome/common/extensions/docs/examples/extensions/speak_selection/background.js
+++ /dev/null
@@ -1,83 +0,0 @@
-/**
- * Copyright (c) 2011 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.
- */
-
-var lastUtterance = '';
-var speaking = false;
-var globalUtteranceIndex = 0;
-
-if (localStorage['lastVersionUsed'] != '1') {
- localStorage['lastVersionUsed'] = '1';
- chrome.tabs.create({
- url: chrome.extension.getURL('options.html')
- });
-}
-
-function speak(utterance) {
- if (speaking && utterance == lastUtterance) {
- chrome.tts.stop();
- return;
- }
-
- speaking = true;
- lastUtterance = utterance;
- globalUtteranceIndex++;
- var utteranceIndex = globalUtteranceIndex;
-
- chrome.browserAction.setIcon({path: 'SpeakSel19-active.png'});
-
- var rate = localStorage['rate'] || 1.0;
- var pitch = localStorage['pitch'] || 1.0;
- var volume = localStorage['volume'] || 1.0;
- var voice = localStorage['voice'];
- chrome.tts.speak(
- utterance,
- {voiceName: voice,
- rate: parseFloat(rate),
- pitch: parseFloat(pitch),
- volume: parseFloat(volume),
- onEvent: function(evt) {
- if (evt.type == 'end' ||
- evt.type == 'interrupted' ||
- evt.type == 'cancelled' ||
- evt.type == 'error') {
- if (utteranceIndex == globalUtteranceIndex) {
- speaking = false;
- chrome.browserAction.setIcon({path: 'SpeakSel19.png'});
- }
- }
- }
- });
-}
-
-function initBackground() {
- loadContentScriptInAllTabs();
-
- var defaultKeyString = getDefaultKeyString();
- var keyString = localStorage['speakKey'];
- if (keyString == undefined) {
- keyString = defaultKeyString;
- localStorage['speakKey'] = keyString;
- }
- sendKeyToAllTabs(keyString);
-
- chrome.extension.onRequest.addListener(
- function(request, sender, sendResponse) {
- if (request['init']) {
- sendResponse({'key': localStorage['speakKey']});
- } else if (request['speak']) {
- speak(request['speak']);
- }
- });
-
- chrome.browserAction.onClicked.addListener(
- function(tab) {
- chrome.tabs.sendRequest(
- tab.id,
- {'speakSelection': true});
- });
-}
-
-initBackground();
diff --git a/chrome/common/extensions/docs/examples/extensions/speak_selection/content_script.js b/chrome/common/extensions/docs/examples/extensions/speak_selection/content_script.js
deleted file mode 100644
index 69f8879..0000000
--- a/chrome/common/extensions/docs/examples/extensions/speak_selection/content_script.js
+++ /dev/null
@@ -1,56 +0,0 @@
-/**
- * Copyright (c) 2011 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.
- */
-
-var speakKeyStr;
-
-function speakSelection() {
- var focused = document.activeElement;
- var selectedText;
- if (focused) {
- try {
- selectedText = focused.value.substring(
- focused.selectionStart, focused.selectionEnd);
- } catch (err) {
- }
- }
- if (selectedText == undefined) {
- var sel = window.getSelection();
- var selectedText = sel.toString();
- }
- chrome.extension.sendRequest({'speak': selectedText});
-}
-
-function onExtensionMessage(request) {
- if (request['speakSelection'] != undefined) {
- if (!document.hasFocus()) {
- return;
- }
- speakSelection();
- } else if (request['key'] != undefined) {
- speakKeyStr = request['key'];
- }
-}
-
-function initContentScript() {
- chrome.extension.onRequest.addListener(onExtensionMessage);
- chrome.extension.sendRequest({'init': true}, onExtensionMessage);
-
- document.addEventListener('keydown', function(evt) {
- if (!document.hasFocus()) {
- return true;
- }
- var keyStr = keyEventToString(evt);
- if (keyStr == speakKeyStr && speakKeyStr.length > 0) {
- speakSelection();
- evt.stopPropagation();
- evt.preventDefault();
- return false;
- }
- return true;
- }, false);
-}
-
-initContentScript();
diff --git a/chrome/common/extensions/docs/examples/extensions/speak_selection/keycodes.js b/chrome/common/extensions/docs/examples/extensions/speak_selection/keycodes.js
deleted file mode 100644
index edea93e..0000000
--- a/chrome/common/extensions/docs/examples/extensions/speak_selection/keycodes.js
+++ /dev/null
@@ -1,94 +0,0 @@
-/**
- * Copyright (c) 2011 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.
- */
-
-var KEY_MAP = {
- 12: 'Clear',
- 14: 'Enter',
- 33: 'PgUp',
- 34: 'PgDown',
- 35: 'End',
- 36: 'Home',
- 37: 'Left',
- 38: 'Up',
- 39: 'Right',
- 40: 'Down',
- 45: 'Insert',
- 46: 'Delete',
- 96: 'Numpad0',
- 97: 'Numpad1',
- 98: 'Numpad2',
- 99: 'Numpad3',
- 100: 'Numpad4',
- 101: 'Numpad5',
- 102: 'Numpad6',
- 103: 'Numpad7',
- 104: 'Numpad8',
- 105: 'Numpad9',
- 106: '*',
- 107: 'Plus',
- 108: '_',
- 109: '-',
- 111: '/',
- 112: 'F1',
- 113: 'F2',
- 114: 'F3',
- 115: 'F4',
- 116: 'F5',
- 117: 'F6',
- 118: 'F7',
- 119: 'F8',
- 120: 'F9',
- 121: 'F10',
- 122: 'F11',
- 123: 'F12',
- 124: 'F13',
- 125: 'F14',
- 126: 'F15',
- 186: ';',
- 187: '=',
- 188: ',',
- 189: '-',
- 190: '.',
- 191: '/',
- 192: '`',
- 219: '[',
- 221: ']'
-};
-
-var isMac = (navigator.appVersion.indexOf("Mac") != -1);
-
-function keyEventToString(evt) {
- var tokens = [];
- if (evt.ctrlKey) {
- tokens.push('Control');
- }
- if (evt.altKey) {
- tokens.push(isMac ? 'Option' : 'Alt');
- }
- if (evt.metaKey) {
- tokens.push(isMac ? 'Command' : 'Meta');
- }
- if (evt.shiftKey) {
- tokens.push('Shift');
- }
- if (evt.keyCode >= 48 && evt.keyCode <= 90) {
- tokens.push(String.fromCharCode(evt.keyCode));
- } else if (KEY_MAP[evt.keyCode]) {
- tokens.push(KEY_MAP[evt.keyCode]);
- } else {
- return '';
- }
- return tokens.join('+');
-}
-
-function getDefaultKeyString() {
- return keyEventToString({
- keyCode: 83, // 's'
- shiftKey: true,
- altKey: true,
- ctrlKey: true,
- metaKey: false});
-}
diff --git a/chrome/common/extensions/docs/examples/extensions/speak_selection/manifest.json b/chrome/common/extensions/docs/examples/extensions/speak_selection/manifest.json
deleted file mode 100644
index fed3608..0000000
--- a/chrome/common/extensions/docs/examples/extensions/speak_selection/manifest.json
+++ /dev/null
@@ -1,49 +0,0 @@
-{
- "name": "Speak Selection",
- "version": "1.1",
- "description": "Speaks the current selection out loud.",
- "permissions": [
- "<all_urls>",
- "tts",
- "tabs"
- ],
-
- "background": {
- "scripts": [
- "keycodes.js",
- "tabs.js",
- "background.js"
- ]
- },
-
- "browser_action": {
- "default_icon": "SpeakSel19.png",
- "default_title": "Speak Selection"
- },
-
- "options_page": "options.html",
-
- "minimum_chrome_version": "14",
-
- "content_scripts": [
- {
- "matches": [
- "<all_urls>"
- ],
- "all_frames": true,
- "js": [
- "keycodes.js",
- "content_script.js"
- ]
- }
- ],
-
- "icons": {
- "16": "SpeakSel16.png",
- "48": "SpeakSel48.png",
- "128": "SpeakSel128.png",
- "256": "SpeakSel256.png"
- },
-
- "manifest_version": 2
-}
diff --git a/chrome/common/extensions/docs/examples/extensions/speak_selection/options.html b/chrome/common/extensions/docs/examples/extensions/speak_selection/options.html
deleted file mode 100644
index f52ce7e..0000000
--- a/chrome/common/extensions/docs/examples/extensions/speak_selection/options.html
+++ /dev/null
@@ -1,152 +0,0 @@
-<html>
-<head>
- <title>Speak Selection Options</title>
- <style>
- body {
- font-family: arial, helvetica, sans-serif;
- }
- .banner {
- width: 100%;
- float: left;
- }
- .banner_left {
- padding: 8px;
- float: left;
- }
- .banner_right {
- padding: 8px;
- }
- .body_wrapper {
- width: 100%;
- float: left;
- }
- .body_left {
- border: 0;
- padding: 0;
- margin: 0;
- width: 50%;
- float: left;
- }
- .body_right {
- border: 0;
- padding: 0;
- margin: 0;
- width: 46%;
- float: left;
- }
- .body_inner {
- padding: 0 32px;
- }
- .browser_action {
- vertical-align: middle;
- margin: 0 2px 3px 2px;
- }
- .ctrl_label {
- width: 100px;
- float: left;
- }
- .ctrl_wrap {
- margin: 18px 8px;
- }
- .ctrl {
- width: 200px;
- }
- #hotkey {
- font-size: 16px;
- width: 15em;
- margin-left: 12px;
- }
- #test {
- }
- #defaults {
- margin-left: 24px;
- }
- </style>
- <script src="keycodes.js"></script>
- <script src="tabs.js"></script>
- <script src="options.js"></script>
- <script src="content_script.js"></script>
-</head>
-<body>
-
-<div class="banner">
- <div class="banner_left">
- <img src="SpeakSel128.png" class="logo" alt="">
- </div>
- <div class="banner_right">
- <h1>Speak Selection</h1>
- <p>
- This extension lets you use Chrome's text-to-speech (TTS) capabilities
- to speak any text you find on the web.
- </p>
- </div>
-</div>
-
-<div class="body_wrapper">
- <div class="body_left">
- <div class="body_inner">
- <h2>Speech Settings</h2>
-
- <div class="ctrl_label">
- <label for="voice">Voice:</label>
- </div>
- <div class="ctrl_wrap">
- <select id="voice" class="ctrl"></select>
- </div>
-
- <div class="ctrl_label">
- <label for="rate">Rate:</label>
- </div>
- <div class="ctrl_wrap">
- <input id="rate" type="range" class="ctrl"
- min=0.5 max=2.0 step=0.1 value=1.0></input>
- </div>
-
- <div class="ctrl_label">
- <label for="pitch">Pitch:</label>
- </div>
- <div class="ctrl_wrap">
- <input id="pitch" type="range" class="ctrl"
- min=0.5 max=1.5 step=0.1 value=1.0></input>
- </div>
-
- <div class="ctrl_label">
- <label for="volume">Volume:</label>
- </div>
- <div class="ctrl_wrap">
- <input id="volume" type="range" class="ctrl"
- min=0.0 max=1.0 step=0.1 value=1.0></input>
- </div>
-
- <div class="ctrl_label">
-
- </div>
- <div class="ctrl_wrap">
- <button id="test">Test Speech</button>
- <button id="defaults">Defaults</button>
- </div>
-
- </div>
- </div>
- <div class="body_right">
- <div class="body_inner">
- <h2>When to speak</h2>
- <p>
- <span id="selected">Select some text</span>
- anywhere on a webpage, then either:
- </p>
-
- <p>1. Click on the
- <img class="browser_action" src="SpeakSel19.png" alt="Speak Selection">
- button in the toolbar ↗, or
- </p>
-
- <p>2. Use this hot key: <input type="text" id="hotkey"></input>
- </p>
- <p>Click the button or press the key again to stop speech.</p>
- </div>
- </div>
-</div>
-
-</body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/extensions/speak_selection/options.js b/chrome/common/extensions/docs/examples/extensions/speak_selection/options.js
deleted file mode 100644
index f77e739..0000000
--- a/chrome/common/extensions/docs/examples/extensions/speak_selection/options.js
+++ /dev/null
@@ -1,130 +0,0 @@
-// Copyright (c) 2012 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.
-
-function load() {
- var selectedElement = document.getElementById('selected');
- var sel = window.getSelection();
- sel.removeAllRanges();
- var range = document.createRange();
- range.selectNode(selectedElement);
- sel.addRange(range);
-
- var rateElement = document.getElementById('rate');
- var pitchElement = document.getElementById('pitch');
- var volumeElement = document.getElementById('volume');
- var rate = localStorage['rate'] || 1.0;
- var pitch = localStorage['pitch'] || 1.0;
- var volume = localStorage['volume'] || 1.0;
- rateElement.value = rate;
- pitchElement.value = pitch;
- volumeElement.value = volume;
- function listener(evt) {
- rate = rateElement.value;
- localStorage['rate'] = rate;
- pitch = pitchElement.value;
- localStorage['pitch'] = pitch;
- volume = volumeElement.value;
- localStorage['volume'] = volume;
- }
- rateElement.addEventListener('keyup', listener, false);
- pitchElement.addEventListener('keyup', listener, false);
- volumeElement.addEventListener('keyup', listener, false);
- rateElement.addEventListener('mouseup', listener, false);
- pitchElement.addEventListener('mouseup', listener, false);
- volumeElement.addEventListener('mouseup', listener, false);
-
- var defaultsButton = document.getElementById('defaults');
- defaultsButton.addEventListener('click', function(evt) {
- rate = 1.0;
- pitch = 1.0;
- volume = 1.0;
- localStorage['rate'] = rate;
- localStorage['pitch'] = pitch;
- localStorage['volume'] = volume;
- rateElement.value = rate;
- pitchElement.value = pitch;
- volumeElement.value = volume;
- }, false);
-
- var voice = document.getElementById('voice');
- var voiceArray = [];
- chrome.tts.getVoices(function(va) {
- voiceArray = va;
- for (var i = 0; i < voiceArray.length; i++) {
- var opt = document.createElement('option');
- var name = voiceArray[i].voiceName;
- if (name == localStorage['voice']) {
- opt.setAttribute('selected', '');
- }
- opt.setAttribute('value', name);
- opt.innerText = voiceArray[i].voiceName;
- voice.appendChild(opt);
- }
- });
- voice.addEventListener('change', function() {
- var i = voice.selectedIndex;
- localStorage['voice'] = voiceArray[i].voiceName;
- }, false);
-
- var defaultKeyString = getDefaultKeyString();
-
- var keyString = localStorage['speakKey'];
- if (keyString == undefined) {
- keyString = defaultKeyString;
- }
-
- var testButton = document.getElementById('test');
- testButton.addEventListener('click', function(evt) {
- chrome.tts.speak(
- 'Testing speech synthesis',
- {voiceName: localStorage['voice'],
- rate: parseFloat(rate),
- pitch: parseFloat(pitch),
- volume: parseFloat(volume)});
- });
-
- var hotKeyElement = document.getElementById('hotkey');
- hotKeyElement.value = keyString;
- hotKeyElement.addEventListener('keydown', function(evt) {
- switch (evt.keyCode) {
- case 27: // Escape
- evt.stopPropagation();
- evt.preventDefault();
- hotKeyElement.blur();
- return false;
- case 8: // Backspace
- case 46: // Delete
- evt.stopPropagation();
- evt.preventDefault();
- hotKeyElement.value = '';
- localStorage['speakKey'] = '';
- sendKeyToAllTabs('');
- window.speakKeyStr = '';
- return false;
- case 9: // Tab
- return false;
- case 16: // Shift
- case 17: // Control
- case 18: // Alt/Option
- case 91: // Meta/Command
- evt.stopPropagation();
- evt.preventDefault();
- return false;
- }
- var keyStr = keyEventToString(evt);
- if (keyStr) {
- hotKeyElement.value = keyStr;
- localStorage['speakKey'] = keyStr;
- sendKeyToAllTabs(keyStr);
-
- // Set the key used by the content script running in the options page.
- window.speakKeyStr = keyStr;
- }
- evt.stopPropagation();
- evt.preventDefault();
- return false;
- }, true);
-}
-
-document.addEventListener('DOMContentLoaded', load);
diff --git a/chrome/common/extensions/docs/examples/extensions/speak_selection/tabs.js b/chrome/common/extensions/docs/examples/extensions/speak_selection/tabs.js
deleted file mode 100644
index 4edac9cf..0000000
--- a/chrome/common/extensions/docs/examples/extensions/speak_selection/tabs.js
+++ /dev/null
@@ -1,34 +0,0 @@
-/**
- * Copyright (c) 2011 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.
- */
-
-function sendKeyToAllTabs(keyStr) {
- chrome.windows.getAll({'populate': true}, function(windows) {
- for (var i = 0; i < windows.length; i++) {
- var tabs = windows[i].tabs;
- for (var j = 0; j < tabs.length; j++) {
- chrome.tabs.sendRequest(
- tabs[j].id,
- {'key': keyStr});
- }
- }
- });
-}
-
-function loadContentScriptInAllTabs() {
- chrome.windows.getAll({'populate': true}, function(windows) {
- for (var i = 0; i < windows.length; i++) {
- var tabs = windows[i].tabs;
- for (var j = 0; j < tabs.length; j++) {
- chrome.tabs.executeScript(
- tabs[j].id,
- {file: 'keycodes.js', allFrames: true});
- chrome.tabs.executeScript(
- tabs[j].id,
- {file: 'content_script.js', allFrames: true});
- }
- }
- });
-}
diff --git a/chrome/common/extensions/docs/examples/extensions/talking_alarm_clock/audio/cuckoo.ogg b/chrome/common/extensions/docs/examples/extensions/talking_alarm_clock/audio/cuckoo.ogg
deleted file mode 100644
index 7a5cd56..0000000
--- a/chrome/common/extensions/docs/examples/extensions/talking_alarm_clock/audio/cuckoo.ogg
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/talking_alarm_clock/audio/digital.ogg b/chrome/common/extensions/docs/examples/extensions/talking_alarm_clock/audio/digital.ogg
deleted file mode 100644
index 0c9cf42f..0000000
--- a/chrome/common/extensions/docs/examples/extensions/talking_alarm_clock/audio/digital.ogg
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/talking_alarm_clock/audio/metal.ogg b/chrome/common/extensions/docs/examples/extensions/talking_alarm_clock/audio/metal.ogg
deleted file mode 100644
index 22fbceb..0000000
--- a/chrome/common/extensions/docs/examples/extensions/talking_alarm_clock/audio/metal.ogg
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/talking_alarm_clock/audio/ringing.ogg b/chrome/common/extensions/docs/examples/extensions/talking_alarm_clock/audio/ringing.ogg
deleted file mode 100644
index 04ee778..0000000
--- a/chrome/common/extensions/docs/examples/extensions/talking_alarm_clock/audio/ringing.ogg
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/talking_alarm_clock/audio/rooster.ogg b/chrome/common/extensions/docs/examples/extensions/talking_alarm_clock/audio/rooster.ogg
deleted file mode 100644
index 5ef6a0bd..0000000
--- a/chrome/common/extensions/docs/examples/extensions/talking_alarm_clock/audio/rooster.ogg
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/talking_alarm_clock/background.js b/chrome/common/extensions/docs/examples/extensions/talking_alarm_clock/background.js
deleted file mode 100644
index 38c5917..0000000
--- a/chrome/common/extensions/docs/examples/extensions/talking_alarm_clock/background.js
+++ /dev/null
@@ -1,126 +0,0 @@
-/**
- * Copyright (c) 2011 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.
- */
-
-var a1Timer = null;
-var a2Timer = null;
-var port = null;
-var iconFlashTimer = null;
-
-var HOUR_MS = 1000 * 60 * 60;
-
-// Override from common.js
-window.stopFlashingIcon = function() {
- window.clearTimeout(iconFlashTimer);
- chrome.browserAction.setIcon({'path': 'clock-19.png'});
-};
-
-// Override from common.js
-window.flashIcon = function() {
- var flashes = 10;
- function flash() {
- if (flashes == 0) {
- stopFlashingIcon();
- return;
- }
-
- if (flashes % 2 == 0) {
- chrome.browserAction.setIcon({'path': 'clock-highlighted-19.png'});
- } else {
- chrome.browserAction.setIcon({'path': 'clock-19.png'});
- }
- flashes--;
- iconFlashTimer = window.setTimeout(flash, 500);
- }
- flash();
-};
-
-function setTimer(alarmHours, alarmMinutes) {
- var alarmTime = (alarmHours * 60 + alarmMinutes) * 60 * 1000;
- var d = new Date();
- var now = d.getHours() * HOUR_MS +
- d.getMinutes() * 60 * 1000 +
- d.getSeconds() * 1000;
- var delta = (alarmTime - now);
-
- if (delta >= -5000 && delta < 1000) {
- ringAlarm(alarmHours, alarmMinutes);
- if (port) {
- port.postMessage({'cmd': 'anim'});
- }
- return null;
- }
-
- if (delta < 0) {
- delta += HOUR_MS * 24;
- }
- if (delta >= 1000) {
- if (delta > HOUR_MS) {
- delta = HOUR_MS;
- }
- console.log('Timer set for ' + delta + ' ms');
- return window.setTimeout(resetTimers, delta);
- }
-
- return null;
-};
-
-function resetTimers() {
- if (a1Timer) {
- window.clearTimeout(a1Timer);
- }
-
- try {
- var a1_on = (localStorage['a1_on'] == 'true');
- var a1_tt = localStorage['a1_tt'] || DEFAULT_A1_TT;
- var a1_ampm = localStorage['a1_ampm'] || DEFAULT_A1_AMPM;
- if (a1_on) {
- var alarmHoursMinutes = parseTime(a1_tt, a1_ampm);
- var alarmHours = alarmHoursMinutes[0];
- var alarmMinutes = alarmHoursMinutes[1];
- a1Timer = setTimer(alarmHours, alarmMinutes);
- }
- } catch (e) {
- console.log(e);
- }
-
- try {
- var a2_on = (localStorage['a2_on'] == 'true');
- var a2_tt = localStorage['a2_tt'] || DEFAULT_A2_TT;
- var a2_ampm = localStorage['a2_ampm'] || DEFAULT_A2_AMPM;
- if (a2_on) {
- var alarmHoursMinutes = parseTime(a2_tt, a2_ampm);
- var alarmHours = alarmHoursMinutes[0];
- var alarmMinutes = alarmHoursMinutes[1];
- a2Timer = setTimer(alarmHours, alarmMinutes);
- }
- } catch (e) {
- console.log(e);
- }
-
- if (a1_on || a2_on) {
- chrome.browserAction.setIcon({'path': 'clock-19.png'});
- } else {
- chrome.browserAction.setIcon({'path': 'clock-disabled-19.png'});
- }
-}
-
-function onLocalStorageChange() {
- resetTimers();
-}
-
-function initBackground() {
- window.addEventListener('storage', onLocalStorageChange, false);
-
- chrome.runtime.onConnect.addListener(function(popupPort) {
- port = popupPort;
- port.onDisconnect.addListener(function() {
- port = null;
- });
- });
-}
-
-initBackground();
-resetTimers();
diff --git a/chrome/common/extensions/docs/examples/extensions/talking_alarm_clock/blank-clock-150.png b/chrome/common/extensions/docs/examples/extensions/talking_alarm_clock/blank-clock-150.png
deleted file mode 100644
index af850fc7..0000000
--- a/chrome/common/extensions/docs/examples/extensions/talking_alarm_clock/blank-clock-150.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/talking_alarm_clock/blank-clock-ring1-150.png b/chrome/common/extensions/docs/examples/extensions/talking_alarm_clock/blank-clock-ring1-150.png
deleted file mode 100644
index b0631b40..0000000
--- a/chrome/common/extensions/docs/examples/extensions/talking_alarm_clock/blank-clock-ring1-150.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/talking_alarm_clock/blank-clock-ring2-150.png b/chrome/common/extensions/docs/examples/extensions/talking_alarm_clock/blank-clock-ring2-150.png
deleted file mode 100644
index b02437a1..0000000
--- a/chrome/common/extensions/docs/examples/extensions/talking_alarm_clock/blank-clock-ring2-150.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/talking_alarm_clock/clock-128.png b/chrome/common/extensions/docs/examples/extensions/talking_alarm_clock/clock-128.png
deleted file mode 100644
index 290e3f25f..0000000
--- a/chrome/common/extensions/docs/examples/extensions/talking_alarm_clock/clock-128.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/talking_alarm_clock/clock-16.png b/chrome/common/extensions/docs/examples/extensions/talking_alarm_clock/clock-16.png
deleted file mode 100644
index 32e570f..0000000
--- a/chrome/common/extensions/docs/examples/extensions/talking_alarm_clock/clock-16.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/talking_alarm_clock/clock-19.png b/chrome/common/extensions/docs/examples/extensions/talking_alarm_clock/clock-19.png
deleted file mode 100644
index 59685e9..0000000
--- a/chrome/common/extensions/docs/examples/extensions/talking_alarm_clock/clock-19.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/talking_alarm_clock/clock-256.png b/chrome/common/extensions/docs/examples/extensions/talking_alarm_clock/clock-256.png
deleted file mode 100644
index d576bea..0000000
--- a/chrome/common/extensions/docs/examples/extensions/talking_alarm_clock/clock-256.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/talking_alarm_clock/clock-48.png b/chrome/common/extensions/docs/examples/extensions/talking_alarm_clock/clock-48.png
deleted file mode 100644
index 1dbb771..0000000
--- a/chrome/common/extensions/docs/examples/extensions/talking_alarm_clock/clock-48.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/talking_alarm_clock/clock-disabled-19.png b/chrome/common/extensions/docs/examples/extensions/talking_alarm_clock/clock-disabled-19.png
deleted file mode 100644
index 69cf5a66..0000000
--- a/chrome/common/extensions/docs/examples/extensions/talking_alarm_clock/clock-disabled-19.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/talking_alarm_clock/clock-highlighted-19.png b/chrome/common/extensions/docs/examples/extensions/talking_alarm_clock/clock-highlighted-19.png
deleted file mode 100644
index 5729f292..0000000
--- a/chrome/common/extensions/docs/examples/extensions/talking_alarm_clock/clock-highlighted-19.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/talking_alarm_clock/common.js b/chrome/common/extensions/docs/examples/extensions/talking_alarm_clock/common.js
deleted file mode 100644
index 037aa39e..0000000
--- a/chrome/common/extensions/docs/examples/extensions/talking_alarm_clock/common.js
+++ /dev/null
@@ -1,179 +0,0 @@
-/**
- * Copyright (c) 2011 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.
- */
-
-var DEFAULT_A1_TT = '09:30';
-var DEFAULT_A1_AMPM = 0;
-var DEFAULT_A2_TT = '03:30';
-var DEFAULT_A2_AMPM = 1;
-var DEFAULT_RATE = 1.0;
-var DEFAULT_VOLUME = 1.0;
-var DEFAULT_PHRASE = 'It\'s $TIME, so get up!';
-var DEFAULT_SOUND = 'ringing';
-
-var audio = null;
-
-var isPlaying = false;
-var isSpeaking = false;
-var isAnimating = false;
-
-// Overridden in popup.js but not in background.js.
-window.displayAlarmAnimation = function() {
-};
-
-// Overridden in popup.js but not in background.js.
-window.stopAlarmAnimation = function() {
-};
-
-// Overridden in background.js but not in popup.js.
-window.flashIcon = function() {
-};
-
-// Overridden in background.js but not in popup.js.
-window.stopFlashingIcon = function() {
-};
-
-function $(id) {
- return document.getElementById(id);
-}
-
-function parseTime(timeString, ampm) {
- var time = timeString.match(/^(\d\d):(\d\d)$/);
- if (!time) {
- throw 'Cannot parse: ' + timeString;
- }
-
- var hours = parseInt(time[1], 10);
- if (hours == 12 && ampm == 0) {
- hours = 0;
- } else {
- hours += (hours < 12 && ampm == 1)? 12 : 0;
- }
- var minutes = parseInt(time[2], 10) || 0;
-
- return [hours, minutes];
-}
-
-function stopAll() {
- if (audio) {
- audio.pause();
- isPlaying = false;
- }
- try {
- chrome.tts.stop();
- isSpeaking = false;
- } catch (e) {
- }
- window.stopAlarmAnimation();
- window.stopFlashingIcon();
-}
-
-function playSound(duckAudio) {
- if (audio) {
- audio.pause();
- document.body.removeChild(audio);
- audio = null;
- }
-
- var currentSound = localStorage['sound'] || DEFAULT_SOUND;
- if (currentSound == 'none') {
- return;
- }
-
- audio = document.createElement('audio');
- audio.addEventListener('ended', function(evt) {
- isPlaying = false;
- });
- document.body.appendChild(audio);
- audio.autoplay = true;
-
- var src = 'audio/' + currentSound + '.ogg';
- var volume = parseFloat(localStorage['volume']) || DEFAULT_VOLUME;
- audio.volume = volume;
- audio.src = src;
- isPlaying = true;
-
- if (duckAudio) {
- for (var i = 0; i < 10; i++) {
- (function(i) {
- window.setTimeout(function() {
- var duckedVolume = volume * (1.0 - 0.07 * (i + 1));
- audio.volume = duckedVolume;
- }, 1800 + 50 * i);
- })(i);
- }
- }
-}
-
-function getTimeString(hh, mm) {
- var ampm = hh >= 12 ? 'P M' : 'A M';
- hh = (hh % 12);
- if (hh == 0)
- hh = 12;
- if (mm == 0)
- mm = 'o\'clock';
- else if (mm < 10)
- mm = 'O ' + mm;
-
- return hh + ' ' + mm + ' ' + ampm;
-}
-
-function speak(text) {
- var rate = parseFloat(localStorage['rate']) || DEFAULT_RATE;
- var pitch = 1.0;
- var volume = parseFloat(localStorage['volume']) || DEFAULT_VOLUME;
- var voice = localStorage['voice'];
- chrome.tts.speak(
- text,
- {voiceName: voice,
- rate: rate,
- pitch: pitch,
- volume: volume,
- onEvent: function(evt) {
- if (evt.type == 'end') {
- isSpeaking = false;
- }
- }
- });
-}
-
-function speakPhraseWithTimeString(timeString) {
- var phraseTemplate = localStorage['phrase'] || DEFAULT_PHRASE;
- var utterance = phraseTemplate.replace(/\$TIME/g, timeString);
- speak(utterance);
-}
-
-function speakPhraseWithCurrentTime() {
- var d = new Date();
- speakPhraseWithTimeString(getTimeString(d.getHours(), d.getMinutes()));
-}
-
-function ringAlarm(alarmHours, alarmMinutes) {
- window.displayAlarmAnimation();
- window.flashIcon();
-
- var phraseTemplate = localStorage['phrase'] || DEFAULT_PHRASE;
- var currentSound = localStorage['sound'] || DEFAULT_SOUND;
-
- if (phraseTemplate == '') {
- playSound(false);
- } else if (currentSound == 'none') {
- speakPhraseWithTimeString(getTimeString(alarmHours, alarmMinutes));
- } else {
- chrome.tts.stop();
- playSound(true);
- isSpeaking = true;
- window.setTimeout(function() {
- if (isSpeaking) {
- speakPhraseWithTimeString(getTimeString(alarmHours, alarmMinutes));
- }
- }, 2000);
- }
-}
-
-function ringAlarmWithCurrentTime() {
- var d = new Date();
- ringAlarm(d.getHours(), d.getMinutes());
-}
diff --git a/chrome/common/extensions/docs/examples/extensions/talking_alarm_clock/credits.html b/chrome/common/extensions/docs/examples/extensions/talking_alarm_clock/credits.html
deleted file mode 100644
index 303b916..0000000
--- a/chrome/common/extensions/docs/examples/extensions/talking_alarm_clock/credits.html
+++ /dev/null
@@ -1,39 +0,0 @@
-<html>
-<head>
- <title>Talking Alarm Clock</title>
- <style>
- body {
- font-family: arial, helvetica, sans-serif;
- font-size: 13;
- }
- </style>
-</head>
-<body>
-
-<img src="clock-128.png" style="float: left; margin: 0 20px 200px 0;">
-
-<p>
-<b>Talking Alarm Clock for Google Chrome</b>
-</p>
-
-<p>
-by Dominic Mazzoni
-</p>
-
-<p>
-Talking Alarm Clock uses the following sound files from Freesound
-(<a href="http://www.freesound.org">http://www.freesound.org</a>):
-</p>
-
-<ul style="margin-left: 150px;">
-<li>alarmclockbeeps from tedthetrumpet
-<li>alarm_clock_ringing from joedeshon
-<li>CuckooClock6DP from acclivity
-<li>ClockStrikes12 from acclivity
-<li>Maxines from TexasMusicForge
-<li>fat_beat_1 from -zin-
-<li>20070812.rooster from dobroide
-</ul>
-
-</body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/extensions/talking_alarm_clock/manifest.json b/chrome/common/extensions/docs/examples/extensions/talking_alarm_clock/manifest.json
deleted file mode 100644
index 79f5b50..0000000
--- a/chrome/common/extensions/docs/examples/extensions/talking_alarm_clock/manifest.json
+++ /dev/null
@@ -1,23 +0,0 @@
-{
- "name": "Talking Alarm Clock",
- "version": "1.3",
- "description": "A clock with two configurable alarms that will play a sound and speak a phrase of your choice.",
- "permissions": [ "background", "tts" ],
-
- "background": { "scripts": ["common.js", "background.js"] },
-
- "browser_action": {
- "default_icon": "clock-19.png",
- "default_title": "Talking Alarm Clock",
- "default_popup": "popup.html"
- },
-
- "icons": {
- "16": "clock-16.png",
- "48": "clock-48.png",
- "128": "clock-128.png",
- "256": "clock-256.png"
- },
-
- "manifest_version": 2
-}
diff --git a/chrome/common/extensions/docs/examples/extensions/talking_alarm_clock/play.png b/chrome/common/extensions/docs/examples/extensions/talking_alarm_clock/play.png
deleted file mode 100644
index 08e8b3e..0000000
--- a/chrome/common/extensions/docs/examples/extensions/talking_alarm_clock/play.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/talking_alarm_clock/popup.html b/chrome/common/extensions/docs/examples/extensions/talking_alarm_clock/popup.html
deleted file mode 100644
index cb82ed3..0000000
--- a/chrome/common/extensions/docs/examples/extensions/talking_alarm_clock/popup.html
+++ /dev/null
@@ -1,205 +0,0 @@
-<html>
-<head>
- <title>Talking Alarm Clock</title>
- <link href='http://fonts.googleapis.com/css?family=Nova%20Mono' rel='stylesheet' type='text/css'>
- <style>
- body {
- overflow: hidden;
- margin-top: 0px;
- }
- #main {
- width: 200px;
- font-family: arial, helvetica, sans-serif;
- font-size: 13;
- }
- #clock {
- cursor: pointer;
- }
- .alarm_wrap {
- margin-top: 6px;
- padding: 6px;
- background-color: #dfd;
- border: 1px solid #aaa;
- border-radius: 4px;
- }
- .alarm_wrap.disabled {
- background-color: #eee;
- }
- .alarm_wrap[aria-invalid] {
- background-color: #f99;
- }
- .alarm_wrap[aria-invalid] input {
- color: #900;
- }
- .alarm_wrap input {
- font-size: 20;
- }
- .alarm_wrap input[type=time] {
- font-size: 20;
- width: 85px;
- }
- .alarm_wrap.disabled input {
- color: #999;
- }
- .ctrl_label {
- float: left;
- width: 100%;
- margin-top: 6px;
- }
- .ctrl_wrap {
- width: 200px;
- float: left;
- }
- .ctrl_wrap input[type=range] {
- width: 180px;
- height: 16px;
- }
- .buttons {
- margin-top: 10px;
- }
- .voice_options {
- }
- #sound {
- float: left;
- width: 160px;
- margin: 8px 0px;
- }
- #playsound {
- padding: 5px;
- margin: 5px;
- }
- #phrase {
- float: left;
- width: 160px;
- }
- #playspeech {
- padding: 5px;
- margin: 5px;
- }
- #a1_tt {
- font-family: Nova Mono;
- height: 34px;
- }
- #a2_tt {
- font-family: Nova Mono;
- height: 34px;
- }
- #a1_ampm {
- font-family: Nova Mono;
- }
- #a2_ampm {
- font-family: Nova Mono;
- }
- #current_time {
- font-family: Nova Mono;
- font-size: 24;
- height: 32px;
- }
- body.nooutline * {
- outline: none;
- }
- .footer {
- clear:left;
- }
- </style>
- <script src="common.js"></script>
- <script src="popup.js"></script>
-</head>
-<body>
-
-<div id="main">
-
- <center>
- <canvas id="clock" width="150" height="150"
- role="button" tabindex="0"></canvas>
- <div id="current_time">00:00:00</div>
- </center>
-
- <div id="a1_wrap" class="alarm_wrap">
- <label for="a1_on">Alarm 1</label>
- <br>
- <input id="a1_on" type="checkbox">
- <input id="a1_tt" type="time" step="300" size="5">
- <select id="a1_ampm">
- <option>AM</option>
- <option selected>PM</option>
- </select>
- </div>
- <div id="a2_wrap" class="alarm_wrap">
- <label for="a2_on">Alarm 2</label>
- <br>
- <input id="a2_on" type="checkbox">
- <input id="a2_tt" type="time" step="300" size="5">
- <select id="a2_ampm">
- <option>AM</option>
- <option selected>PM</option>
- </select>
- </div>
-
- <div class="voice_options">
- <div>
- <div class="ctrl_label">
- <label for="sound">Sound:</label>
- </div>
- <div class="ctrl_wrap">
- <select id="sound" class="ctrl">
- <option value="none">None</option>
- <option selected value="cuckoo">Cuckoo Clock</option>
- <option value="digital">Digital Alarm Clock</option>
- <option value="metal">Metal</option>
- <option value="ringing">Ringing Alarm Clock</option>
- <option value="rooster">Rooster</option>
- </select>
-
- <button id="playsound" title="Play Sound">
- <img src="play.png">
- </button>
- </div>
-
- <div class="ctrl_label">
- <label for="sound">Phrase (use $TIME to say time):</label>
- </div>
- <div class="ctrl_wrap">
- <textarea id="phrase"></textarea>
-
- <button id="playspeech" title="Play Speech">
- <img src="play.png">
- </button>
- </div>
-
- <div class="ctrl_label">
- <label for="voice">Voice:</label>
- </div>
- <div class="ctrl_wrap">
- <select id="voice" class="ctrl"></select>
- </div>
-
- <div class="ctrl_label">
- <label for="rate">Speech rate:</label>
- </div>
- <div class="ctrl_wrap">
- <input id="rate" type="range" class="ctrl"
- min=0.5 max=1.5 step=0.1 value=1.0></input>
- </div>
-
- <div class="ctrl_label">
- <label for="volume">Speech and sound volume:</label>
- </div>
- <div class="ctrl_wrap">
- <input id="volume" type="range" class="ctrl"
- min=0.0 max=1.0 step=0.1 value=1.0></input>
- </div>
- </div>
- </div>
-
- <div class="footer">
- <a href="credits.html" target="_blank">Credits</a>
- |
- <a href="https://chrome.google.com/webstore/search?q=tts"
- target="_blank">Get more voices</a>
- </div>
-
-</div>
-
-</body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/extensions/talking_alarm_clock/popup.js b/chrome/common/extensions/docs/examples/extensions/talking_alarm_clock/popup.js
deleted file mode 100644
index 30b80853..0000000
--- a/chrome/common/extensions/docs/examples/extensions/talking_alarm_clock/popup.js
+++ /dev/null
@@ -1,403 +0,0 @@
-// Copyright (c) 2012 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.
-
-var blankClockImage;
-var blankClockAnim1Image;
-var blankClockAnim2Image;
-var animationTimer;
-var currentClockImage;
-var port;
-
-function updateEnabledStatus(alarm) {
- var enabled = $('a' + alarm + '_on').checked;
- $('a' + alarm + '_tt').disabled = !enabled;
- $('a' + alarm + '_ampm').disabled = !enabled;
- var valid = true;
- try {
- var tt = $('a' + alarm + '_tt').value;
- var ampm = $('a' + alarm + '_ampm').selectedIndex;
- parseTime(tt, ampm);
- } catch (x) {
- valid = false;
- }
- if (valid) {
- $('a' + alarm + '_wrap').removeAttribute('aria-invalid');
- } else {
- $('a' + alarm + '_wrap').setAttribute('aria-invalid', 'true');
- }
- if (enabled) {
- $('a' + alarm + '_wrap').classList.remove('disabled');
- } else {
- $('a' + alarm + '_wrap').classList.add('disabled');
- }
-}
-
-function loadAllImages() {
- var loadCount = 0;
- var img = new Image();
- img.onload = function() {
- blankClockImage = img;
- currentClockImage = blankClockImage;
- drawClock();
- };
- img.src = 'blank-clock-150.png';
-
- // These will finish loading before they're needed, no need
- // for an onload handler.
- blankClockAnim1Image = new Image();
- blankClockAnim1Image.src = 'blank-clock-ring1-150.png';
- blankClockAnim2Image = new Image();
- blankClockAnim2Image.src = 'blank-clock-ring2-150.png';
-}
-
-function drawClock(hh, mm, ss) {
- if (hh == undefined || mm == undefined) {
- var d = new Date();
- hh = d.getHours();
- mm = d.getMinutes();
- ss = d.getSeconds() + 0.001 * d.getMilliseconds();
- }
-
- if (!currentClockImage) {
- loadAllImages();
- return;
- }
-
- var ctx = $('clock').getContext('2d');
- ctx.drawImage(currentClockImage, 0, 0);
-
- // Move the hour by the fraction of the minute
- hh = (hh % 12) + (mm / 60);
-
- // Move the minute by the fraction of the second
- mm += (ss / 60);
-
- var hourAngle = Math.PI * hh / 6;
- var hourX = Math.sin(hourAngle);
- var hourY = -Math.cos(hourAngle);
- var minAngle = Math.PI * mm / 30;
- var minX = Math.sin(minAngle);
- var minY = -Math.cos(minAngle);
- var secAngle = Math.PI * ss / 30;
- var secX = Math.sin(secAngle);
- var secY = -Math.cos(secAngle);
-
- var cx = 75;
- var cy = 77;
-
- ctx.lineWidth = 5;
- ctx.strokeStyle = '#ffffff';
- ctx.globalAlpha = 0.5;
- ctx.beginPath();
- ctx.moveTo(cx - 4 * hourX, cy - 4 * hourY);
- ctx.lineTo(cx + 20 * hourX, cy + 20 * hourY);
- ctx.stroke();
- ctx.beginPath();
- ctx.moveTo(cx - 8 * minX, cy - 8 * minY);
- ctx.lineTo(cx + 35 * minX, cy + 33 * minY);
- ctx.stroke();
-
- ctx.lineWidth = 3;
- ctx.strokeStyle = '#696969';
- ctx.globalAlpha = 1.0;
- ctx.beginPath();
- ctx.moveTo(cx - 4 * hourX, cy - 4 * hourY);
- ctx.lineTo(cx + 20 * hourX, cy + 20 * hourY);
- ctx.stroke();
- ctx.beginPath();
- ctx.moveTo(cx - 8 * minX, cy - 8 * minY);
- ctx.lineTo(cx + 35 * minX, cy + 33 * minY);
- ctx.stroke();
-
- ctx.lineWidth = 1;
- ctx.strokeStyle = '#990000';
- ctx.globalAlpha = 1.0;
- ctx.beginPath();
- ctx.moveTo(cx - 4 * secX, cy - 4 * secY);
- ctx.lineTo(cx + 40 * secX, cy + 40 * secY);
- ctx.stroke();
-}
-
-function updateCurrentTime() {
- var now = new Date();
- var hh = now.getHours();
- var mm = now.getMinutes();
- var ss = now.getSeconds();
- var str = '';
- if (hh % 12 == 0) {
- str += '12';
- } else {
- str += (hh % 12);
- }
- str += ':';
- if (mm >= 10) {
- str += mm;
- } else {
- str += '0' + mm;
- }
- str += ':';
- if (ss >= 10) {
- str += ss;
- } else {
- str += '0' + ss;
- }
- if (hh >= 12) {
- str += " PM";
- } else {
- str += " AM";
- }
- $('current_time').innerText = str;
-}
-
-// Override from common.js
-window.stopAlarmAnimation = function() {
- window.clearTimeout(animationTimer);
- currentClockImage = blankClockImage;
- drawClock();
- isAnimating = false;
-};
-
-// Override from common.js
-window.displayAlarmAnimation = function() {
- isAnimating = true;
- var rings = 100;
- function ring() {
- if (rings == 0) {
- stopAlarmAnimation();
- return;
- }
- currentClockImage = (rings % 2 == 0)?
- blankClockAnim1Image:
- blankClockAnim2Image;
- drawClock();
- rings--;
- animationTimer = window.setTimeout(ring, 50);
- }
- ring();
-};
-
-function addOutlineStyleListeners() {
- document.addEventListener('click', function(evt) {
- document.body.classList.add('nooutline');
- return true;
- }, true);
- document.addEventListener('keydown', function(evt) {
- document.body.classList.remove('nooutline');
- return true;
- }, true);
-}
-
-function load() {
- try {
- port = chrome.runtime.connect();
- port.onMessage.addListener(function(msg) {
- if (msg.cmd == 'anim') {
- displayAlarmAnimation();
- }
- });
- } catch (e) {
- }
-
- addOutlineStyleListeners();
-
- stopAll();
- drawClock();
- setInterval(drawClock, 100);
-
- updateCurrentTime();
- setInterval(updateCurrentTime, 250);
-
- function updateTime(timeElement) {
- if (!parseTime(timeElement.value)) {
- return false;
- }
-
- timeElement.valueAsNumber =
- timeElement.valueAsNumber % (12 * 60 * 60 * 1000);
- if (timeElement.valueAsNumber < (1 * 60 * 60 * 1000))
- timeElement.valueAsNumber += (12 * 60 * 60 * 1000);
- return true;
- }
-
- $('clock').addEventListener('click', function(evt) {
- if (isPlaying || isSpeaking || isAnimating) {
- stopAll();
- } else {
- ringAlarmWithCurrentTime();
- }
- }, false);
- $('clock').addEventListener('keydown', function(evt) {
- if (evt.keyCode == 13 || evt.keyCode == 32) {
- if (isPlaying || isSpeaking || isAnimating) {
- stopAll();
- } else {
- ringAlarmWithCurrentTime();
- }
- }
- }, false);
-
- // Alarm 1
-
- var a1_tt = localStorage['a1_tt'] || DEFAULT_A1_TT;
- $('a1_tt').value = a1_tt;
- $('a1_tt').addEventListener('input', function(evt) {
- updateEnabledStatus(1);
- if (!updateTime($('a1_tt'))) {
- evt.stopPropagation();
- return false;
- }
- localStorage['a1_tt'] = $('a1_tt').value;
- updateEnabledStatus(1);
- return true;
- }, false);
- $('a1_tt').addEventListener('change', function(evt) {
- if ($('a1_tt').value.length == 4 &&
- parseTime('0' + $('a1_tt').value)) {
- $('a1_tt').value = '0' + $('a1_tt').value;
- }
- if (!updateTime($('a1_tt'))) {
- evt.stopPropagation();
- return false;
- }
- localStorage['a1_tt'] = $('a1_tt').value;
- updateEnabledStatus(1);
- return true;
- }, false);
-
- var a1_on = (localStorage['a1_on'] == 'true');
- $('a1_on').checked = a1_on;
- $('a1_on').addEventListener('change', function(evt) {
- window.setTimeout(function() {
- localStorage['a1_on'] = $('a1_on').checked;
- updateEnabledStatus(1);
- }, 0);
- }, false);
-
- var a1_ampm = localStorage['a1_ampm'] || DEFAULT_A1_AMPM;
- $('a1_ampm').selectedIndex = a1_ampm;
- $('a1_ampm').addEventListener('change', function(evt) {
- localStorage['a1_ampm'] = $('a1_ampm').selectedIndex;
- }, false);
-
- updateEnabledStatus(1);
-
- // Alarm 2
-
- var a2_tt = localStorage['a2_tt'] || DEFAULT_A2_TT;
- $('a2_tt').value = a2_tt;
- $('a2_tt').addEventListener('input', function(evt) {
- updateEnabledStatus(2);
- if (!updateTime($('a2_tt'))) {
- evt.stopPropagation();
- return false;
- }
- localStorage['a2_tt'] = $('a2_tt').value;
- updateEnabledStatus(2);
- return true;
- }, false);
- $('a2_tt').addEventListener('change', function(evt) {
- if ($('a2_tt').value.length == 4 &&
- parseTime('0' + $('a2_tt').value)) {
- $('a2_tt').value = '0' + $('a2_tt').value;
- }
- if (!updateTime($('a2_tt'))) {
- evt.stopPropagation();
- return false;
- }
- localStorage['a2_tt'] = $('a2_tt').value;
- updateEnabledStatus(2);
- return true;
- }, false);
-
- var a2_on = (localStorage['a2_on'] == 'true');
- $('a2_on').checked = a2_on;
- $('a2_on').addEventListener('change', function(evt) {
- window.setTimeout(function() {
- localStorage['a2_on'] = $('a2_on').checked;
- updateEnabledStatus(2);
- }, 0);
- }, false);
-
- var a2_ampm = localStorage['a2_ampm'] || DEFAULT_A2_AMPM;
- $('a2_ampm').selectedIndex = a2_ampm;
- $('a2_ampm').addEventListener('change', function(evt) {
- localStorage['a2_ampm'] = $('a2_ampm').selectedIndex;
- }, false);
-
- updateEnabledStatus(2);
-
- // Phrase
-
- var phrase = localStorage['phrase'] || DEFAULT_PHRASE;
- $('phrase').value = phrase;
- $('phrase').addEventListener('change', function(evt) {
- localStorage['phrase'] = $('phrase').value;
- }, false);
-
- // Speech parameters
-
- var rateElement = $('rate');
- var volumeElement = $('volume');
- var rate = localStorage['rate'] || DEFAULT_RATE;
- var volume = localStorage['volume'] || DEFAULT_VOLUME;
- rateElement.value = rate;
- volumeElement.value = volume;
- function listener(evt) {
- rate = rateElement.value;
- localStorage['rate'] = rate;
- volume = volumeElement.value;
- localStorage['volume'] = volume;
- }
- rateElement.addEventListener('keyup', listener, false);
- volumeElement.addEventListener('keyup', listener, false);
- rateElement.addEventListener('mouseup', listener, false);
- volumeElement.addEventListener('mouseup', listener, false);
-
- var sound = $('sound');
- var currentSound = localStorage['sound'] || DEFAULT_SOUND;
- for (var i = 0; i < sound.options.length; i++) {
- if (sound.options[i].value == currentSound) {
- sound.selectedIndex = i;
- break;
- }
- }
- localStorage['sound'] = sound.options[sound.selectedIndex].value;
- sound.addEventListener('change', function() {
- localStorage['sound'] = sound.options[sound.selectedIndex].value;
- }, false);
-
- var playSoundButton = $('playsound');
- playSoundButton.addEventListener('click', function(evt) {
- playSound(false);
- });
-
- var playSpeechButton = $('playspeech');
- playSpeechButton.addEventListener('click', function(evt) {
- speakPhraseWithCurrentTime();
- });
-
- var voice = $('voice');
- var voiceArray = [];
- if (chrome && chrome.tts) {
- chrome.tts.getVoices(function(va) {
- voiceArray = va;
- for (var i = 0; i < voiceArray.length; i++) {
- var opt = document.createElement('option');
- var name = voiceArray[i].voiceName;
- if (name == localStorage['voice']) {
- opt.setAttribute('selected', '');
- }
- opt.setAttribute('value', name);
- opt.innerText = voiceArray[i].voiceName;
- voice.appendChild(opt);
- }
- });
- }
- voice.addEventListener('change', function() {
- var i = voice.selectedIndex;
- localStorage['voice'] = voiceArray[i].voiceName;
- }, false);
-}
-
-document.addEventListener('DOMContentLoaded', load);
diff --git a/chrome/common/extensions/docs/examples/extensions/ttsdebug/128.png b/chrome/common/extensions/docs/examples/extensions/ttsdebug/128.png
deleted file mode 100644
index 6411dc9..0000000
--- a/chrome/common/extensions/docs/examples/extensions/ttsdebug/128.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/ttsdebug/16.png b/chrome/common/extensions/docs/examples/extensions/ttsdebug/16.png
deleted file mode 100644
index 9e55a982..0000000
--- a/chrome/common/extensions/docs/examples/extensions/ttsdebug/16.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/ttsdebug/256.png b/chrome/common/extensions/docs/examples/extensions/ttsdebug/256.png
deleted file mode 100644
index 986d3ae8..0000000
--- a/chrome/common/extensions/docs/examples/extensions/ttsdebug/256.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/ttsdebug/manifest.json b/chrome/common/extensions/docs/examples/extensions/ttsdebug/manifest.json
deleted file mode 100644
index 0a856f9..0000000
--- a/chrome/common/extensions/docs/examples/extensions/ttsdebug/manifest.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
- "app": {
- "launch": {
- "local_path": "ttsdebug.html"
- }
- },
- "description": "Tool for developers of Chrome TTS engine extensions to help them test their engines are implementing the API correctly.",
- "icons": {
- "16": "16.png",
- "128": "128.png",
- "256": "256.png"
- },
- "minimum_chrome_version": "14",
- "name": "TTS Debug",
- "permissions": [ "tts" ],
- "version": "1.0",
- "manifest_version": 2
-}
diff --git a/chrome/common/extensions/docs/examples/extensions/ttsdebug/pacman.gif b/chrome/common/extensions/docs/examples/extensions/ttsdebug/pacman.gif
deleted file mode 100644
index d43fcb5..0000000
--- a/chrome/common/extensions/docs/examples/extensions/ttsdebug/pacman.gif
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/ttsdebug/ttsdebug.css b/chrome/common/extensions/docs/examples/extensions/ttsdebug/ttsdebug.css
deleted file mode 100644
index 86f603e..0000000
--- a/chrome/common/extensions/docs/examples/extensions/ttsdebug/ttsdebug.css
+++ /dev/null
@@ -1,64 +0,0 @@
-/**
- * Copyright (c) 2011 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.
- */
-
-#main {
- font-family: arial,helvetica;
- font-size: 10pt;
- text-align: center;
- margin-left: auto;
- margin-right: auto;
- padding: 10px 30px 20px 30px;
- width: 800px;
- border-left: solid 1px #ccc;
- border-right: solid 1px #ccc;
-}
-#stop {
- margin-left: 100px;
-}
-#container {
- text-align: left;
-}
-#instructions {
- text-align: left;
-}
-.outer {
- margin: 12px 6px 6px 6px;
- padding: 6px;
- border: 1px solid #000;
-}
-.outer.disabled {
- border: 1px solid #696969;
-}
-.runTestButton {
- margin: 12px;
-}
-.description {
- margin: 6px 12px;
-}
-.results {
- margin: 12px;
-}
-.messages {
- margin: 12px;
-}
-.error {
- color: #900;
-}
-.result {
- margin: 6px;
- padding: 6px;
-}
-.success {
- font-weight: bold;
- color: #090;
-}
-.failure {
- font-weight: bold;
- color: #900;
-}
-.disabled {
- color: #696969 !important;
-}
diff --git a/chrome/common/extensions/docs/examples/extensions/ttsdebug/ttsdebug.html b/chrome/common/extensions/docs/examples/extensions/ttsdebug/ttsdebug.html
deleted file mode 100644
index 745fb2f..0000000
--- a/chrome/common/extensions/docs/examples/extensions/ttsdebug/ttsdebug.html
+++ /dev/null
@@ -1,35 +0,0 @@
-<!DOCTYPE html>
-<html>
- <head>
- <title>Chrome TTS Debug</title>
- <link href="ttsdebug.css" rel="stylesheet" type="text/css">
- <script src="ttsdebug.js"></script>
- </head>
- <body>
- <div id="main">
- <h2>Chrome Text-to-Speech Debug</h2>
-
- <div id="instructions">
- <p>
- This app is for developers of Chrome TTS engines, to help validate that
- an engine is properly implementing the API. Click on a button to run a
- test. A lot of errors can be detected automatically, but some tests
- require manually listening to the speech, and it's important to listen to
- all tests running to identify other potential glitches.</p>
- <p>For more diagnostic information, open the JavaScript console.</p>
- </div>
-
- <div>
- <label for="voices">Voice:</label>
-
- <select id="voices">
- <option value="">Unspecified</option>
- </select>
-
- <button id="stop">Emergency Stop!</button>
- </div>
-
- <div id="container"></div>
- </div>
- </body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/extensions/ttsdebug/ttsdebug.js b/chrome/common/extensions/docs/examples/extensions/ttsdebug/ttsdebug.js
deleted file mode 100644
index 61b71c9..0000000
--- a/chrome/common/extensions/docs/examples/extensions/ttsdebug/ttsdebug.js
+++ /dev/null
@@ -1,694 +0,0 @@
-/**
- * Copyright (c) 2011 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.
- */
-
-var voiceArray;
-var trials = 3;
-var resultMap = {};
-var updateDependencyFunctions = [];
-var testRunIndex = 0;
-var emergencyStop = false;
-
-function $(id) {
- return document.getElementById(id);
-}
-
-function isErrorEvent(evt) {
- return (evt.type == 'error' ||
- evt.type == 'interrupted' ||
- evt.type == 'cancelled');
-}
-
-function logEvent(callTime, testRunName, evt) {
- var elapsed = ((new Date() - callTime) / 1000).toFixed(3);
- while (elapsed.length < 7) {
- elapsed = ' ' + elapsed;
- }
- console.log(elapsed + ' ' + testRunName + ': ' + JSON.stringify(evt));
-}
-
-function logSpeakCall(utterance, options, callback) {
- var optionsCopy = {};
- for (var key in options) {
- if (key != 'onEvent') {
- optionsCopy[key] = options[key];
- }
- }
- console.log('Calling chrome.tts.speak(\'' +
- utterance + '\', ' +
- JSON.stringify(optionsCopy) + ')');
- if (callback)
- chrome.tts.speak(utterance, options, callback);
- else
- chrome.tts.speak(utterance, options);
-}
-
-var tests = [
- {
- name: 'Baseline',
- description: 'Ensures that the speech engine sends both start and ' +
- 'end events, and establishes a baseline time to speak a ' +
- 'key phrase, to compare other tests against.',
- dependencies: [],
- trials: 3,
- run: function(testRunName, voiceName, callback) {
- var callTime = new Date();
- var startTime;
- var warnings = [];
- var errors = [];
- logSpeakCall('Alpha Bravo Charlie Delta Echo', {
- voiceName: voiceName,
- onEvent: function(evt) {
- logEvent(callTime, testRunName, evt);
- if (isErrorEvent(evt)) {
- callback(false, null, []);
- } else if (evt.type == 'start') {
- startTime = new Date();
- if (evt.charIndex != 0) {
- errors.push('Error: start event should have a charIndex of 0.');
- }
- } else if (evt.type == 'end') {
- if (startTime == undefined) {
- errors.push('Error: no "start" event received!');
- startTime = callTime;
- }
- if (evt.charIndex != 30) {
- errors.push('Error: end event should have a charIndex of 30.');
- }
- var endTime = new Date();
- if (startTime - callTime > 1000) {
- var delta = ((startTime - callTime) / 1000).toFixed(3);
- warnings.push('Note: Delay of ' + delta +
- ' before speech started. ' +
- 'Less than 1.0 s latency is recommended.');
- }
- var delta = (endTime - startTime) / 1000;
- if (delta < 1.0) {
- warnings.push('Warning: Default speech rate seems too fast.');
- } else if (delta > 3.0) {
- warnings.push('Warning: Default speech rate seems too slow.');
- }
- callback(errors.length == 0, delta, warnings.concat(errors));
- }
- }
- });
- }
- },
- {
- name: 'Fast',
- description: 'Speaks twice as fast and compares the time to the baseline.',
- dependencies: ['Baseline'],
- trials: 3,
- run: function(testRunName, voiceName, callback) {
- var callTime = new Date();
- var startTime;
- var errors = [];
- logSpeakCall('Alpha Bravo Charlie Delta Echo', {
- voiceName: voiceName,
- rate: 2.0,
- onEvent: function(evt) {
- logEvent(callTime, testRunName, evt);
- if (isErrorEvent(evt)) {
- callback(false, null, []);
- } else if (evt.type == 'start') {
- startTime = new Date();
- } else if (evt.type == 'end') {
- if (startTime == undefined)
- startTime = callTime;
- var endTime = new Date();
- var delta = (endTime - startTime) / 1000;
- var relative = delta / resultMap['Baseline'];
- if (relative < 0.35) {
- errors.push('2x speech rate seems too fast.');
- } else if (relative > 0.65) {
- errors.push('2x speech rate seems too slow.');
- }
- callback(errors.length == 0, delta, errors);
- }
- }
- });
- }
- },
- {
- name: 'Slow',
- description: 'Speaks twice as slow and compares the time to the baseline.',
- dependencies: ['Baseline'],
- trials: 3,
- run: function(testRunName, voiceName, callback) {
- var callTime = new Date();
- var startTime;
- var errors = [];
- logSpeakCall('Alpha Bravo Charlie Delta Echo', {
- voiceName: voiceName,
- rate: 0.5,
- onEvent: function(evt) {
- logEvent(callTime, testRunName, evt);
- if (isErrorEvent(evt)) {
- callback(false, null, []);
- } else if (evt.type == 'start') {
- startTime = new Date();
- } else if (evt.type == 'end') {
- if (startTime == undefined)
- startTime = callTime;
- var endTime = new Date();
- var delta = (endTime - startTime) / 1000;
- var relative = delta / resultMap['Baseline'];
- if (relative < 1.6) {
- errors.push('Half-speed speech rate seems too fast.');
- } else if (relative > 2.4) {
- errors.push('Half-speed speech rate seems too slow.');
- }
- callback(errors.length == 0, delta, errors);
- }
- }
- });
- }
- },
- {
- name: 'Interrupt and restart',
- description: 'Interrupts partway through a long sentence and then ' +
- 'the baseline utterance, to make sure that speech after ' +
- 'an interruption works correctly.',
- dependencies: ['Baseline'],
- trials: 1,
- run: function(testRunName, voiceName, callback) {
- var callTime = new Date();
- var startTime;
- var errors = [];
- logSpeakCall('When in the course of human events it becomes ' +
- 'necessary for one people to dissolve the political ' +
- 'bands which have connected them ', {
- voiceName: voiceName,
- onEvent: function(evt) {
- logEvent(callTime, testRunName, evt);
- }
- });
- window.setTimeout(function() {
- logSpeakCall('Alpha Bravo Charlie Delta Echo', {
- voiceName: voiceName,
- onEvent: function(evt) {
- logEvent(callTime, testRunName, evt);
- if (isErrorEvent(evt)) {
- callback(false, null, []);
- } else if (evt.type == 'start') {
- startTime = new Date();
- } else if (evt.type == 'end') {
- if (startTime == undefined)
- startTime = callTime;
- var endTime = new Date();
- var delta = (endTime - startTime) / 1000;
- var relative = delta / resultMap['Baseline'];
- if (relative < 0.9) {
- errors.push('Interrupting speech seems too short.');
- } else if (relative > 1.1) {
- errors.push('Interrupting speech seems too long.');
- }
- callback(errors.length == 0, delta, errors);
- }
- }
- });
- }, 4000);
- }
- },
- {
- name: 'Low volume',
- description: '<b>Manual</b> test - verify that the volume is lower.',
- dependencies: [],
- trials: 1,
- run: function(testRunName, voiceName, callback) {
- var callTime = new Date();
- logSpeakCall('Alpha Bravo Charlie Delta Echo', {
- voiceName: voiceName,
- volume: 0.5,
- onEvent: function(evt) {
- logEvent(callTime, testRunName, evt);
- if (isErrorEvent(evt)) {
- callback(false, null, []);
- } else if (evt.type == 'end') {
- callback(true, null, []);
- }
- }
- });
- }
- },
- {
- name: 'High pitch',
- description: '<b>Manual</b> test - verify that the pitch is ' +
- 'moderately higher, but quite understandable.',
- dependencies: [],
- trials: 1,
- run: function(testRunName, voiceName, callback) {
- var callTime = new Date();
- logSpeakCall('Alpha Bravo Charlie Delta Echo', {
- voiceName: voiceName,
- pitch: 1.2,
- onEvent: function(evt) {
- logEvent(callTime, testRunName, evt);
- if (isErrorEvent(evt)) {
- callback(false, null, []);
- } else if (evt.type == 'end') {
- callback(true, null, []);
- }
- }
- });
- }
- },
- {
- name: 'Low pitch',
- description: '<b>Manual</b> test - verify that the pitch is ' +
- 'moderately lower, but quite understandable.',
- dependencies: [],
- trials: 1,
- run: function(testRunName, voiceName, callback) {
- var callTime = new Date();
- logSpeakCall('Alpha Bravo Charlie Delta Echo', {
- voiceName: voiceName,
- pitch: 0.8,
- onEvent: function(evt) {
- logEvent(callTime, testRunName, evt);
- if (isErrorEvent(evt)) {
- callback(false, null, []);
- } else if (evt.type == 'end') {
- callback(true, null, []);
- }
- }
- });
- }
- },
- {
- name: 'Word and sentence callbacks',
- description: 'Checks to see if proper word and sentence callbacks ' +
- 'are received.',
- dependencies: ['Baseline'],
- trials: 1,
- run: function(testRunName, voiceName, callback) {
- var callTime = new Date();
- var startTime;
- var errors = [];
- var wordExpected = [{min: 5, max: 6},
- {min: 11, max: 12},
- {min: 19, max: 20},
- {min: 25, max: 26},
- {min: 30, max: 32},
- {min: 37, max: 38},
- {min: 43, max: 44},
- {min: 51, max: 52},
- {min: 57, max: 58}];
- var sentenceExpected = [{min: 30, max: 32}]
- var wordCount = 0;
- var sentenceCount = 0;
- var lastWordTime = callTime;
- var lastSentenceTime = callTime;
- var avgWordTime = resultMap['Baseline'] / 5;
- logSpeakCall('Alpha Bravo Charlie Delta Echo. ' +
- 'Alpha Bravo Charlie Delta Echo.', {
- voiceName: voiceName,
- onEvent: function(evt) {
- logEvent(callTime, testRunName, evt);
- if (isErrorEvent(evt)) {
- callback(false, null, []);
- } else if (evt.type == 'start') {
- startTime = new Date();
- lastWordTime = startTime;
- lastSentenceTime = startTime;
- } else if (evt.type == 'word') {
- if (evt.charIndex > 0 && evt.charIndex < 62) {
- var min = wordExpected[wordCount].min;
- var max = wordExpected[wordCount].max;
- if (evt.charIndex < min || evt.charIndex > max) {
- errors.push('Got word at charIndex ' + evt.charIndex + ', ' +
- 'was expecting next word callback charIndex ' +
- 'in the range ' + min + ':' + max + '.');
- }
- if (wordCount != 4) {
- var delta = (new Date() - lastWordTime) / 1000;
- if (delta < 0.6 * avgWordTime) {
- errors.push('Word at charIndex ' + evt.charIndex +
- ' came after only ' + delta.toFixed(3) +
- ' s, which seems too short.');
- } else if (delta > 1.3 * avgWordTime) {
- errors.push('Word at charIndex ' + evt.charIndex +
- ' came after ' + delta.toFixed(3) +
- ' s, which seems too long.');
- }
- }
- wordCount++;
- }
- lastWordTime = new Date();
- } else if (evt.type == 'sentence') {
- if (evt.charIndex > 0 && evt.charIndex < 62) {
- var min = sentenceExpected[sentenceCount].min;
- var max = sentenceExpected[sentenceCount].max;
- if (evt.charIndex < min || evt.charIndex > max) {
- errors.push('Got sentence at charIndex ' + evt.charIndex +
- ', was expecting next callback charIndex ' +
- 'in the range ' + min + ':' + max + '.');
- }
- var delta = (new Date() - lastSentenceTime) / 1000;
- if (delta < 0.75 * resultMap['Baseline']) {
- errors.push('Sentence at charIndex ' + evt.charIndex +
- ' came after only ' + delta.toFixed(3) +
- ' s, which seems too short.');
- } else if (delta > 1.25 * resultMap['Baseline']) {
- errors.push('Sentence at charIndex ' + evt.charIndex +
- ' came after ' + delta.toFixed(3) +
- ' s, which seems too long.');
- }
- sentenceCount++;
- }
- lastSentenceTime = new Date();
- } else if (evt.type == 'end') {
- if (wordCount == 0) {
- errors.push('Didn\'t get any word callbacks.');
- } else if (wordCount < wordExpected.length) {
- errors.push('Not enough word callbacks.');
- } else if (wordCount > wordExpected.length) {
- errors.push('Too many word callbacks.');
- }
- if (sentenceCount == 0) {
- errors.push('Didn\'t get any sentence callbacks.');
- } else if (sentenceCount < sentenceExpected.length) {
- errors.push('Not enough sentence callbacks.');
- } else if (sentenceCount > sentenceExpected.length) {
- errors.push('Too many sentence callbacks.');
- }
- if (startTime == undefined) {
- errors.push('Error: no "start" event received!');
- startTime = callTime;
- }
- var endTime = new Date();
- var delta = (endTime - startTime) / 1000;
- if (delta < 2.5) {
- errors.push('Default speech rate seems too fast.');
- } else if (delta > 7.0) {
- errors.push('Default speech rate seems too slow.');
- }
- callback(errors.length == 0, delta, errors);
- }
- }
- });
- }
- },
- {
- name: 'Baseline Queueing Test',
- description: 'Establishes a baseline time to speak a ' +
- 'sequence of three enqueued phrases, to compare ' +
- 'other tests against.',
- dependencies: [],
- trials: 3,
- run: function(testRunName, voiceName, callback) {
- var callTime = new Date();
- var startTime;
- var errors = [];
- logSpeakCall('Alpha Alpha', {
- voiceName: voiceName,
- onEvent: function(evt) {
- logEvent(callTime, testRunName, evt);
- if (isErrorEvent(evt)) {
- callback(false, null, []);
- } else if (evt.type == 'start') {
- startTime = new Date();
- }
- }
- });
- logSpeakCall('Bravo bravo.', {
- voiceName: voiceName,
- enqueue: true,
- onEvent: function(evt) {
- logEvent(callTime, testRunName, evt);
- if (isErrorEvent(evt)) {
- callback(false, null, []);
- }
- }
- });
- logSpeakCall('Charlie charlie', {
- voiceName: voiceName,
- enqueue: true,
- onEvent: function(evt) {
- logEvent(callTime, testRunName, evt);
- if (isErrorEvent(evt)) {
- callback(false, null, []);
- } else if (evt.type == 'end') {
- if (startTime == undefined) {
- errors.push('Error: no "start" event received!');
- startTime = callTime;
- }
- var endTime = new Date();
- var delta = (endTime - startTime) / 1000;
- callback(errors.length == 0, delta, errors);
- }
- }
- });
- }
- },
- {
- name: 'Interruption with Queueing',
- description: 'Queue a sequence of three utterances, then before they ' +
- 'are finished, interrupt and queue a sequence of three ' +
- 'more utterances. Make sure that interrupting and ' +
- 'cancelling the previous utterances doesn\'t interfere ' +
- 'with the interrupting utterances.',
- dependencies: ['Baseline Queueing Test'],
- trials: 1,
- run: function(testRunName, voiceName, callback) {
- var callTime = new Date();
- var startTime;
- var errors = [];
-
- logSpeakCall('Just when I\'m about to say something interesting,', {
- voiceName: voiceName
- });
- logSpeakCall('it seems that I always get interrupted.', {
- voiceName: voiceName,
- enqueue: true,
- });
- logSpeakCall('How rude! Will you ever let me finish?', {
- voiceName: voiceName,
- enqueue: true,
- });
-
- window.setTimeout(function() {
- logSpeakCall('Alpha Alpha', {
- voiceName: voiceName,
- onEvent: function(evt) {
- logEvent(callTime, testRunName, evt);
- if (isErrorEvent(evt)) {
- callback(false, null, []);
- } else if (evt.type == 'start') {
- startTime = new Date();
- }
- }
- });
- logSpeakCall('Bravo bravo.', {
- voiceName: voiceName,
- enqueue: true,
- onEvent: function(evt) {
- logEvent(callTime, testRunName, evt);
- if (isErrorEvent(evt)) {
- callback(false, null, []);
- }
- }
- });
- logSpeakCall('Charlie charlie', {
- voiceName: voiceName,
- enqueue: true,
- onEvent: function(evt) {
- logEvent(callTime, testRunName, evt);
- if (isErrorEvent(evt)) {
- callback(false, null, []);
- } else if (evt.type == 'end') {
- if (startTime == undefined) {
- errors.push('Error: no "start" event received!');
- startTime = callTime;
- }
- var endTime = new Date();
- var delta = (endTime - startTime) / 1000;
- var relative = delta / resultMap['Baseline Queueing Test'];
- if (relative < 0.9) {
- errors.push('Interrupting speech seems too short.');
- } else if (relative > 1.1) {
- errors.push('Interrupting speech seems too long.');
- }
- callback(errors.length == 0, delta, errors);
- }
- }
- });
- }, 4000);
- }
- }
-];
-
-function updateDependencies() {
- for (var i = 0; i < updateDependencyFunctions.length; i++) {
- updateDependencyFunctions[i]();
- }
-}
-
-function registerTest(test) {
- var outer = document.createElement('div');
- outer.className = 'outer';
- $('container').appendChild(outer);
-
- var buttonWrap = document.createElement('div');
- buttonWrap.className = 'buttonWrap';
- outer.appendChild(buttonWrap);
-
- var button = document.createElement('button');
- button.className = 'runTestButton';
- button.innerText = test.name;
- buttonWrap.appendChild(button);
-
- var busy = document.createElement('img');
- busy.src = 'pacman.gif';
- busy.alt = 'Busy indicator';
- buttonWrap.appendChild(busy);
- busy.style.visibility = 'hidden';
-
- var description = document.createElement('div');
- description.className = 'description';
- description.innerHTML = test.description;
- outer.appendChild(description);
-
- var resultsWrap = document.createElement('div');
- resultsWrap.className = 'results';
- outer.appendChild(resultsWrap);
- var results = [];
- for (var j = 0; j < test.trials; j++) {
- var result = document.createElement('span');
- resultsWrap.appendChild(result);
- results.push(result);
- }
- var avg = document.createElement('span');
- resultsWrap.appendChild(avg);
-
- var messagesWrap = document.createElement('div');
- messagesWrap.className = 'messages';
- outer.appendChild(messagesWrap);
-
- var totalTime;
- var successCount;
-
- function finishTrials() {
- busy.style.visibility = 'hidden';
- if (successCount == test.trials) {
- console.log('Test succeeded.');
- var success = document.createElement('div');
- success.className = 'success';
- success.innerText = 'Test succeeded.';
- messagesWrap.appendChild(success);
- if (totalTime > 0.0) {
- var avgTime = totalTime / test.trials;
- avg.className = 'result';
- avg.innerText = 'Avg: ' + avgTime.toFixed(3) + ' s';
- resultMap[test.name] = avgTime;
- updateDependencies();
- }
- } else {
- console.log('Test failed.');
- var failure = document.createElement('div');
- failure.className = 'failure';
- failure.innerText = 'Test failed.';
- messagesWrap.appendChild(failure);
- }
- }
-
- function runTest(index, voiceName) {
- if (emergencyStop) {
- busy.style.visibility = 'hidden';
- emergencyStop = false;
- return;
- }
- var testRunName = 'Test run ' + testRunIndex + ', ' +
- test.name + ', trial ' + (index+1) + ' of ' +
- test.trials;
- console.log('*** Beginning ' + testRunName +
- ' with voice ' + voiceName);
- test.run(testRunName, voiceName, function(success, resultTime, errors) {
- if (success) {
- successCount++;
- }
- for (var i = 0; i < errors.length; i++) {
- console.log(errors[i]);
- var error = document.createElement('div');
- error.className = 'error';
- error.innerText = errors[i];
- messagesWrap.appendChild(error);
- }
- if (resultTime != null) {
- results[index].className = 'result';
- results[index].innerText = resultTime.toFixed(3) + ' s';
- totalTime += resultTime;
- }
- index++;
- if (index < test.trials) {
- runTest(index, voiceName);
- } else {
- finishTrials();
- }
- });
- }
-
- button.addEventListener('click', function() {
- var voiceIndex = $('voices').selectedIndex - 1;
- if (voiceIndex < 0) {
- alert('Please select a voice first!');
- return;
- }
- testRunIndex++;
- busy.style.visibility = 'visible';
- totalTime = 0.0;
- successCount = 0;
- messagesWrap.innerHTML = '';
- var voiceName = voiceArray[voiceIndex].voiceName;
- runTest(0, voiceName);
- }, false);
-
- updateDependencyFunctions.push(function() {
- for (var i = 0; i < test.dependencies.length; i++) {
- if (resultMap[test.dependencies[i]] != undefined) {
- button.disabled = false;
- outer.className = 'outer';
- } else {
- button.disabled = true;
- outer.className = 'outer disabled';
- }
- }
- });
-}
-
-function load() {
- var voice = localStorage['voice'];
- chrome.tts.getVoices(function(va) {
- voiceArray = va;
- for (var i = 0; i < voiceArray.length; i++) {
- var opt = document.createElement('option');
- var name = voiceArray[i].voiceName;
- if (name == localStorage['voice']) {
- opt.setAttribute('selected', '');
- }
- opt.setAttribute('value', name);
- opt.innerText = voiceArray[i].voiceName;
- $('voices').appendChild(opt);
- }
- });
- $('voices').addEventListener('change', function() {
- var i = $('voices').selectedIndex;
- localStorage['voice'] = $('voices').item(i).value;
- }, false);
- $('stop').addEventListener('click', stop);
-
- for (var i = 0; i < tests.length; i++) {
- registerTest(tests[i]);
- }
- updateDependencies();
-}
-
-function stop() {
- console.log('*** Emergency stop!');
- emergencyStop = true;
- chrome.tts.stop();
-}
-
-document.addEventListener('DOMContentLoaded', load);
diff --git a/chrome/common/extensions/docs/examples/extensions/ttsdemo/128.png b/chrome/common/extensions/docs/examples/extensions/ttsdemo/128.png
deleted file mode 100644
index b9ba0f38..0000000
--- a/chrome/common/extensions/docs/examples/extensions/ttsdemo/128.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/ttsdemo/16.png b/chrome/common/extensions/docs/examples/extensions/ttsdemo/16.png
deleted file mode 100644
index d206ec1..0000000
--- a/chrome/common/extensions/docs/examples/extensions/ttsdemo/16.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/ttsdemo/256.png b/chrome/common/extensions/docs/examples/extensions/ttsdemo/256.png
deleted file mode 100644
index 2990023..0000000
--- a/chrome/common/extensions/docs/examples/extensions/ttsdemo/256.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/ttsdemo/manifest.json b/chrome/common/extensions/docs/examples/extensions/ttsdemo/manifest.json
deleted file mode 100644
index ade1281d..0000000
--- a/chrome/common/extensions/docs/examples/extensions/ttsdemo/manifest.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- "app": {
- "launch": {
- "local_path": "ttsdemo.html"
- }
- },
- "description": "Demo Chrome's synthesized text-to-speech capabilities.",
- "icons": {
- "16": "16.png",
- "128": "128.png",
- "256": "256.png"
- },
- "minimum_chrome_version": "14",
- "name": "TTS Demo",
- "permissions": [ "tts" ],
- "version": "2.1",
-
- "manifest_version": 2
-}
diff --git a/chrome/common/extensions/docs/examples/extensions/ttsdemo/ttsdemo.html b/chrome/common/extensions/docs/examples/extensions/ttsdemo/ttsdemo.html
deleted file mode 100644
index 6f916364..0000000
--- a/chrome/common/extensions/docs/examples/extensions/ttsdemo/ttsdemo.html
+++ /dev/null
@@ -1,172 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
- <title>Chrome TTS Demo</title>
- <style>
- body {
- font-family: arial, helvetica, sans-serif;
- }
- .banner {
- width: 100%;
- float: left;
- }
- .banner_left {
- padding: 8px;
- float: left;
- }
- .banner_right {
- padding: 8px;
- }
- .body_wrapper {
- width: 100%;
- float: left;
- }
- .body_left {
- border: 0;
- padding: 0;
- margin: 0;
- width: 50%;
- float: left;
- }
- .body_right {
- border: 0;
- padding: 0;
- margin: 0;
- width: 46%;
- float: left;
- }
- .body_inner {
- padding: 0 32px;
- }
- #srctext {
- width: 100%;
- font-size: 133%;
- }
- .large_button {
- font-size: 166%;
- padding: 6pt 12pt 6pt 12pt;
- }
- .box {
- margin: 10px;
- padding: 10px;
- border: 1px solid #999;
- }
- .tabbable {
- padding: 10px;
- border: 1px solid #00C;
- }
- table {
- margin-left: auto;
- margin-right: auto;
- }
- #help {
- text-align: left;
- }
- #voiceInfo {
- text-align: left;
- padding: 4px;
- border: 1px solid #aaa;
- width: 100%;
- min-height: 100px;
- overflow: auto;
- }
- </style>
- <script src="ttsdemo.js"></script>
-</head>
-
-<body>
-
-<div class="banner">
- <div class="banner_left">
- <img src="128.png" class="logo" alt="">
- </div>
- <div class="banner_right">
- <h1>Chrome Text-to-Speech Demo</h1>
- <p>
- Use this application to try out all of the text-to-speech voices in Chrome, or
- <a href="https://chrome.google.com/webstore/search?q=tts">Search the Chrome Web Store</a>
- for more TTS voices.
- </p>
- </div>
-</div>
-
-<div class="body_wrapper">
- <div class="body_left">
- <div class="body_inner">
-
- Enter text here:
- <textarea id="srctext" rows="6" cols="40">This is a demo of text-to-speech in Chrome.</textarea>
-
- <p>
- <button class="large_button" id="speakUserTextButton">Speak</button>
- <button class="large_button" id="stopButton">Stop</button>
- </p>
-
- <div class="box" id="ttsStatusBox">
- TTS status: <b><span id="ttsStatus"></span></b>
- </div>
-
- <p>
-
- Click on or tab to these boxes:
-
- <p>
-
- <span tabindex="0" class="tabbable" id="speakAlpha">Alpha</span>
- <span tabindex="0" class="tabbable" id="speakBravo">Bravo</span>
- <span tabindex="0" class="tabbable" id="speakCharlie">Charlie</span>
- <span tabindex="0" class="tabbable" id="speakDelta">Delta</span>
- <span tabindex="0" class="tabbable" id="speakEcho">Echo</span>
- <span tabindex="0" class="tabbable" id="speakFoxtrot">Foxtrot</span>
-
- </div>
- </div>
- <div class="body_right">
- <div class="body_inner">
-
- <table class="simple">
- <tr>
- <td>Voice:</td>
- <td><select id="voices">
- <option value="">Unspecified</option>
- </select></td>
- </td>
- </tr>
- <tr>
- <td>Lang:</td>
- <td><select id="lang">
- <option value="">Unspecified</option>
- <option value="de">de (German)</option>
- <option value="en-GB">en-GB (British English)</option>
- <option value="en-US" selected>en-US (American English)</option>
- <option value="es">es (Spanish)</option>
- <option value="fr">fr (French)</option>
- <option value="it">it (Italian)</option>
- </select></td></tr>
- <tr>
- <td>Queuing mode:</td>
- <td><select id="enqueue">
- <option value="">Interrupt</option>
- <option value="true">Enqueue</option>
- </select></td></tr>
- <tr>
- <td>Rate:</td>
- <td><input id="rate" type="range" min="0.5" max="4.0" value="1.0" step="0.1">
- </td></tr>
- <tr>
- <td>Pitch:</td>
- <td><input id="pitch" type="range" min="0.0" max="2.0" value="1.0" step="0.2">
- </td></tr>
- <tr>
- <td>Volume:</td>
- <td><input id="volume" type="range" min="0.0" max="1.0" value="1.0" step="0.1">
- </td></tr>
- </table>
-
- <pre id="voiceInfo"></pre>
- </div>
- </div>
-</div>
-
-</body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/extensions/ttsdemo/ttsdemo.js b/chrome/common/extensions/docs/examples/extensions/ttsdemo/ttsdemo.js
deleted file mode 100644
index 518dbce..0000000
--- a/chrome/common/extensions/docs/examples/extensions/ttsdemo/ttsdemo.js
+++ /dev/null
@@ -1,128 +0,0 @@
-/**
- * Copyright (c) 2012 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.
- */
-
-var text;
-var ttsStatus;
-var ttsStatusBox;
-var lang;
-var enqueue;
-var voices;
-var voiceInfo;
-var voiceArray;
-var utteranceIndex = 0;
-
-function load() {
- text = document.getElementById('srctext');
- ttsStatus = document.getElementById('ttsStatus');
- ttsStatusBox = document.getElementById('ttsStatusBox');
- lang = document.getElementById('lang');
- enqueue = document.getElementById('enqueue');
- voices = document.getElementById('voices');
- voiceInfo = document.getElementById('voiceInfo');
-
- document.getElementById('speakUserTextButton')
- .addEventListener('click', speakUserText);
- document.getElementById('stopButton')
- .addEventListener('click', stop);
-
- const speechOptions = [
- { id: 'speakAlpha', text: 'Alpha' },
- { id: 'speakBravo', text: 'Bravo' },
- { id: 'speakCharlie', text: 'Charlie' },
- { id: 'speakDelta', text: 'Delta' },
- { id: 'speakEcho', text: 'Echo' },
- { id: 'speakFoxtrot', text: 'Foxtrot' },
- ];
-
- for (const option of speechOptions) {
- document.getElementById(option.id)
- .addEventListener('focus', function(){ speak(option.text); });
- }
-
- chrome.tts.getVoices(function(va) {
- voiceArray = va;
- for (var i = 0; i < voiceArray.length; i++) {
- var opt = document.createElement('option');
- opt.setAttribute('value', voiceArray[i].voiceName);
- opt.innerText = voiceArray[i].voiceName;
- voices.appendChild(opt);
- }
- });
- voices.addEventListener('change', function() {
- var i = voices.selectedIndex - 1;
- if (i >= 0) {
- voiceInfo.innerText = JSON.stringify(voiceArray[i], null, 2);
- } else {
- voiceInfo.innerText = '';
- }
- }, false);
-}
-
-function speak(str, options, highlightText) {
- if (!options) {
- options = {};
- }
- if (enqueue.value) {
- options.enqueue = Boolean(enqueue.value);
- }
- var voiceIndex = voices.selectedIndex - 1;
- if (voiceIndex >= 0) {
- options.voiceName = voiceArray[voiceIndex].voiceName;
- }
- var rateValue = Number(rate.value);
- if (rateValue >= 0.1 && rateValue <= 10.0) {
- options.rate = rateValue;
- }
- var pitchValue = Number(pitch.value);
- if (pitchValue >= 0.0 && pitchValue <= 2.0) {
- options.pitch = pitchValue;
- }
- var volumeValue = Number(volume.value);
- if (volumeValue >= 0.0 && volumeValue <= 1.0) {
- options.volume = volumeValue;
- }
- utteranceIndex++;
- console.log(utteranceIndex + ': ' + JSON.stringify(options));
- options.onEvent = function(event) {
- console.log(utteranceIndex + ': ' + JSON.stringify(event));
- if (highlightText) {
- text.setSelectionRange(0, event.charIndex);
- }
- if (event.type == 'end' ||
- event.type == 'interrupted' ||
- event.type == 'cancelled' ||
- event.type == 'error') {
- chrome.tts.isSpeaking(function(isSpeaking) {
- if (!isSpeaking) {
- ttsStatus.innerHTML = 'Idle';
- ttsStatusBox.style.background = '#fff';
- }
- });
- }
- };
- chrome.tts.speak(
- str, options, function() {
- if (chrome.runtime.lastError) {
- console.log('TTS Error: ' + chrome.runtime.lastError.message);
- }
- });
- ttsStatus.innerHTML = 'Busy';
- ttsStatusBox.style.background = '#ffc';
-}
-
-function stop() {
- chrome.tts.stop();
-}
-
-function speakUserText() {
- var options = {};
- if (lang.value) {
- options.lang = lang.value;
- }
- speak(text.value, options, true);
-}
-
-document.addEventListener('DOMContentLoaded', load);
diff --git a/chrome/common/extensions/docs/examples/howto/sandbox/LICENSE.handlebars b/chrome/common/extensions/docs/examples/howto/sandbox/LICENSE.handlebars
deleted file mode 100644
index 237cd0346..0000000
--- a/chrome/common/extensions/docs/examples/howto/sandbox/LICENSE.handlebars
+++ /dev/null
@@ -1,20 +0,0 @@
-Copyright (C) 2011 by Yehuda Katz
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-
diff --git a/chrome/common/extensions/docs/examples/howto/sandbox/eventpage.html b/chrome/common/extensions/docs/examples/howto/sandbox/eventpage.html
deleted file mode 100644
index 8a29dbb..0000000
--- a/chrome/common/extensions/docs/examples/howto/sandbox/eventpage.html
+++ /dev/null
@@ -1,14 +0,0 @@
-<!--
- - Copyright (c) 2012 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.
- -->
-<!doctype html>
-<html>
- <head>
- <script src="eventpage.js"></script>
- </head>
- <body>
- <iframe id="theFrame" src="sandbox.html"></iframe>
- </body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/howto/sandbox/eventpage.js b/chrome/common/extensions/docs/examples/howto/sandbox/eventpage.js
deleted file mode 100644
index feb07385..0000000
--- a/chrome/common/extensions/docs/examples/howto/sandbox/eventpage.js
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright (c) 2012 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.
-
-chrome.browserAction.onClicked.addListener(function() {
- var iframe = document.getElementById('theFrame');
- var message = {
- command: 'render',
- context: {thing: 'world'}
- };
- iframe.contentWindow.postMessage(message, '*');
-});
-
-
-window.addEventListener('message', function(event) {
- if (event.data.html) {
- new Notification('Templated!', {
- icon: 'icon.png',
- body: 'HTML Received for "' + event.data.name + '": `' +
- event.data.html + '`'
- });
- }
-});
diff --git a/chrome/common/extensions/docs/examples/howto/sandbox/handlebars-1.0.0.beta.6.js b/chrome/common/extensions/docs/examples/howto/sandbox/handlebars-1.0.0.beta.6.js
deleted file mode 100644
index 4f9e2c5..0000000
--- a/chrome/common/extensions/docs/examples/howto/sandbox/handlebars-1.0.0.beta.6.js
+++ /dev/null
@@ -1,1553 +0,0 @@
-// Copyright (C) 2011 by Yehuda Katz
-// Licensing details in LICENSE.handlebars
-
-// lib/handlebars/base.js
-var Handlebars = {};
-
-Handlebars.VERSION = "1.0.beta.6";
-
-Handlebars.helpers = {};
-Handlebars.partials = {};
-
-Handlebars.registerHelper = function(name, fn, inverse) {
- if(inverse) { fn.not = inverse; }
- this.helpers[name] = fn;
-};
-
-Handlebars.registerPartial = function(name, str) {
- this.partials[name] = str;
-};
-
-Handlebars.registerHelper('helperMissing', function(arg) {
- if(arguments.length === 2) {
- return undefined;
- } else {
- throw new Error("Could not find property '" + arg + "'");
- }
-});
-
-var toString = Object.prototype.toString, functionType = "[object Function]";
-
-Handlebars.registerHelper('blockHelperMissing', function(context, options) {
- var inverse = options.inverse || function() {}, fn = options.fn;
-
-
- var ret = "";
- var type = toString.call(context);
-
- if(type === functionType) { context = context.call(this); }
-
- if(context === true) {
- return fn(this);
- } else if(context === false || context == null) {
- return inverse(this);
- } else if(type === "[object Array]") {
- if(context.length > 0) {
- for(var i=0, j=context.length; i<j; i++) {
- ret = ret + fn(context[i]);
- }
- } else {
- ret = inverse(this);
- }
- return ret;
- } else {
- return fn(context);
- }
-});
-
-Handlebars.registerHelper('each', function(context, options) {
- var fn = options.fn, inverse = options.inverse;
- var ret = "";
-
- if(context && context.length > 0) {
- for(var i=0, j=context.length; i<j; i++) {
- ret = ret + fn(context[i]);
- }
- } else {
- ret = inverse(this);
- }
- return ret;
-});
-
-Handlebars.registerHelper('if', function(context, options) {
- var type = toString.call(context);
- if(type === functionType) { context = context.call(this); }
-
- if(!context || Handlebars.Utils.isEmpty(context)) {
- return options.inverse(this);
- } else {
- return options.fn(this);
- }
-});
-
-Handlebars.registerHelper('unless', function(context, options) {
- var fn = options.fn, inverse = options.inverse;
- options.fn = inverse;
- options.inverse = fn;
-
- return Handlebars.helpers['if'].call(this, context, options);
-});
-
-Handlebars.registerHelper('with', function(context, options) {
- return options.fn(context);
-});
-
-Handlebars.registerHelper('log', function(context) {
- Handlebars.log(context);
-});
-;
-// lib/handlebars/compiler/parser.js
-/* Jison generated parser */
-var handlebars = (function(){
-
-var parser = {trace: function trace() { },
-yy: {},
-symbols_: {"error":2,"root":3,"program":4,"EOF":5,"statements":6,"simpleInverse":7,"statement":8,"openInverse":9,"closeBlock":10,"openBlock":11,"mustache":12,"partial":13,"CONTENT":14,"COMMENT":15,"OPEN_BLOCK":16,"inMustache":17,"CLOSE":18,"OPEN_INVERSE":19,"OPEN_ENDBLOCK":20,"path":21,"OPEN":22,"OPEN_UNESCAPED":23,"OPEN_PARTIAL":24,"params":25,"hash":26,"param":27,"STRING":28,"INTEGER":29,"BOOLEAN":30,"hashSegments":31,"hashSegment":32,"ID":33,"EQUALS":34,"pathSegments":35,"SEP":36,"$accept":0,"$end":1},
-terminals_: {2:"error",5:"EOF",14:"CONTENT",15:"COMMENT",16:"OPEN_BLOCK",18:"CLOSE",19:"OPEN_INVERSE",20:"OPEN_ENDBLOCK",22:"OPEN",23:"OPEN_UNESCAPED",24:"OPEN_PARTIAL",28:"STRING",29:"INTEGER",30:"BOOLEAN",33:"ID",34:"EQUALS",36:"SEP"},
-productions_: [0,[3,2],[4,3],[4,1],[4,0],[6,1],[6,2],[8,3],[8,3],[8,1],[8,1],[8,1],[8,1],[11,3],[9,3],[10,3],[12,3],[12,3],[13,3],[13,4],[7,2],[17,3],[17,2],[17,2],[17,1],[25,2],[25,1],[27,1],[27,1],[27,1],[27,1],[26,1],[31,2],[31,1],[32,3],[32,3],[32,3],[32,3],[21,1],[35,3],[35,1]],
-performAction: function anonymous(yytext,yyleng,yylineno,yy,yystate,$$,_$) {
-
-var $0 = $$.length - 1;
-switch (yystate) {
-case 1: return $$[$0-1]
-break;
-case 2: this.$ = new yy.ProgramNode($$[$0-2], $$[$0])
-break;
-case 3: this.$ = new yy.ProgramNode($$[$0])
-break;
-case 4: this.$ = new yy.ProgramNode([])
-break;
-case 5: this.$ = [$$[$0]]
-break;
-case 6: $$[$0-1].push($$[$0]); this.$ = $$[$0-1]
-break;
-case 7: this.$ = new yy.InverseNode($$[$0-2], $$[$0-1], $$[$0])
-break;
-case 8: this.$ = new yy.BlockNode($$[$0-2], $$[$0-1], $$[$0])
-break;
-case 9: this.$ = $$[$0]
-break;
-case 10: this.$ = $$[$0]
-break;
-case 11: this.$ = new yy.ContentNode($$[$0])
-break;
-case 12: this.$ = new yy.CommentNode($$[$0])
-break;
-case 13: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1])
-break;
-case 14: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1])
-break;
-case 15: this.$ = $$[$0-1]
-break;
-case 16: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1])
-break;
-case 17: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1], true)
-break;
-case 18: this.$ = new yy.PartialNode($$[$0-1])
-break;
-case 19: this.$ = new yy.PartialNode($$[$0-2], $$[$0-1])
-break;
-case 20:
-break;
-case 21: this.$ = [[$$[$0-2]].concat($$[$0-1]), $$[$0]]
-break;
-case 22: this.$ = [[$$[$0-1]].concat($$[$0]), null]
-break;
-case 23: this.$ = [[$$[$0-1]], $$[$0]]
-break;
-case 24: this.$ = [[$$[$0]], null]
-break;
-case 25: $$[$0-1].push($$[$0]); this.$ = $$[$0-1];
-break;
-case 26: this.$ = [$$[$0]]
-break;
-case 27: this.$ = $$[$0]
-break;
-case 28: this.$ = new yy.StringNode($$[$0])
-break;
-case 29: this.$ = new yy.IntegerNode($$[$0])
-break;
-case 30: this.$ = new yy.BooleanNode($$[$0])
-break;
-case 31: this.$ = new yy.HashNode($$[$0])
-break;
-case 32: $$[$0-1].push($$[$0]); this.$ = $$[$0-1]
-break;
-case 33: this.$ = [$$[$0]]
-break;
-case 34: this.$ = [$$[$0-2], $$[$0]]
-break;
-case 35: this.$ = [$$[$0-2], new yy.StringNode($$[$0])]
-break;
-case 36: this.$ = [$$[$0-2], new yy.IntegerNode($$[$0])]
-break;
-case 37: this.$ = [$$[$0-2], new yy.BooleanNode($$[$0])]
-break;
-case 38: this.$ = new yy.IdNode($$[$0])
-break;
-case 39: $$[$0-2].push($$[$0]); this.$ = $$[$0-2];
-break;
-case 40: this.$ = [$$[$0]]
-break;
-}
-},
-table: [{3:1,4:2,5:[2,4],6:3,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],22:[1,13],23:[1,14],24:[1,15]},{1:[3]},{5:[1,16]},{5:[2,3],7:17,8:18,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,19],20:[2,3],22:[1,13],23:[1,14],24:[1,15]},{5:[2,5],14:[2,5],15:[2,5],16:[2,5],19:[2,5],20:[2,5],22:[2,5],23:[2,5],24:[2,5]},{4:20,6:3,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,4],22:[1,13],23:[1,14],24:[1,15]},{4:21,6:3,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,4],22:[1,13],23:[1,14],24:[1,15]},{5:[2,9],14:[2,9],15:[2,9],16:[2,9],19:[2,9],20:[2,9],22:[2,9],23:[2,9],24:[2,9]},{5:[2,10],14:[2,10],15:[2,10],16:[2,10],19:[2,10],20:[2,10],22:[2,10],23:[2,10],24:[2,10]},{5:[2,11],14:[2,11],15:[2,11],16:[2,11],19:[2,11],20:[2,11],22:[2,11],23:[2,11],24:[2,11]},{5:[2,12],14:[2,12],15:[2,12],16:[2,12],19:[2,12],20:[2,12],22:[2,12],23:[2,12],24:[2,12]},{17:22,21:23,33:[1,25],35:24},{17:26,21:23,33:[1,25],35:24},{17:27,21:23,33:[1,25],35:24},{17:28,21:23,33:[1,25],35:24},{21:29,33:[1,25],35:24},{1:[2,1]},{6:30,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],22:[1,13],23:[1,14],24:[1,15]},{5:[2,6],14:[2,6],15:[2,6],16:[2,6],19:[2,6],20:[2,6],22:[2,6],23:[2,6],24:[2,6]},{17:22,18:[1,31],21:23,33:[1,25],35:24},{10:32,20:[1,33]},{10:34,20:[1,33]},{18:[1,35]},{18:[2,24],21:40,25:36,26:37,27:38,28:[1,41],29:[1,42],30:[1,43],31:39,32:44,33:[1,45],35:24},{18:[2,38],28:[2,38],29:[2,38],30:[2,38],33:[2,38],36:[1,46]},{18:[2,40],28:[2,40],29:[2,40],30:[2,40],33:[2,40],36:[2,40]},{18:[1,47]},{18:[1,48]},{18:[1,49]},{18:[1,50],21:51,33:[1,25],35:24},{5:[2,2],8:18,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,2],22:[1,13],23:[1,14],24:[1,15]},{14:[2,20],15:[2,20],16:[2,20],19:[2,20],22:[2,20],23:[2,20],24:[2,20]},{5:[2,7],14:[2,7],15:[2,7],16:[2,7],19:[2,7],20:[2,7],22:[2,7],23:[2,7],24:[2,7]},{21:52,33:[1,25],35:24},{5:[2,8],14:[2,8],15:[2,8],16:[2,8],19:[2,8],20:[2,8],22:[2,8],23:[2,8],24:[2,8]},{14:[2,14],15:[2,14],16:[2,14],19:[2,14],20:[2,14],22:[2,14],23:[2,14],24:[2,14]},{18:[2,22],21:40,26:53,27:54,28:[1,41],29:[1,42],30:[1,43],31:39,32:44,33:[1,45],35:24},{18:[2,23]},{18:[2,26],28:[2,26],29:[2,26],30:[2,26],33:[2,26]},{18:[2,31],32:55,33:[1,56]},{18:[2,27],28:[2,27],29:[2,27],30:[2,27],33:[2,27]},{18:[2,28],28:[2,28],29:[2,28],30:[2,28],33:[2,28]},{18:[2,29],28:[2,29],29:[2,29],30:[2,29],33:[2,29]},{18:[2,30],28:[2,30],29:[2,30],30:[2,30],33:[2,30]},{18:[2,33],33:[2,33]},{18:[2,40],28:[2,40],29:[2,40],30:[2,40],33:[2,40],34:[1,57],36:[2,40]},{33:[1,58]},{14:[2,13],15:[2,13],16:[2,13],19:[2,13],20:[2,13],22:[2,13],23:[2,13],24:[2,13]},{5:[2,16],14:[2,16],15:[2,16],16:[2,16],19:[2,16],20:[2,16],22:[2,16],23:[2,16],24:[2,16]},{5:[2,17],14:[2,17],15:[2,17],16:[2,17],19:[2,17],20:[2,17],22:[2,17],23:[2,17],24:[2,17]},{5:[2,18],14:[2,18],15:[2,18],16:[2,18],19:[2,18],20:[2,18],22:[2,18],23:[2,18],24:[2,18]},{18:[1,59]},{18:[1,60]},{18:[2,21]},{18:[2,25],28:[2,25],29:[2,25],30:[2,25],33:[2,25]},{18:[2,32],33:[2,32]},{34:[1,57]},{21:61,28:[1,62],29:[1,63],30:[1,64],33:[1,25],35:24},{18:[2,39],28:[2,39],29:[2,39],30:[2,39],33:[2,39],36:[2,39]},{5:[2,19],14:[2,19],15:[2,19],16:[2,19],19:[2,19],20:[2,19],22:[2,19],23:[2,19],24:[2,19]},{5:[2,15],14:[2,15],15:[2,15],16:[2,15],19:[2,15],20:[2,15],22:[2,15],23:[2,15],24:[2,15]},{18:[2,34],33:[2,34]},{18:[2,35],33:[2,35]},{18:[2,36],33:[2,36]},{18:[2,37],33:[2,37]}],
-defaultActions: {16:[2,1],37:[2,23],53:[2,21]},
-parseError: function parseError(str, hash) {
- throw new Error(str);
-},
-parse: function parse(input) {
- var self = this, stack = [0], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1;
- this.lexer.setInput(input);
- this.lexer.yy = this.yy;
- this.yy.lexer = this.lexer;
- if (typeof this.lexer.yylloc == "undefined")
- this.lexer.yylloc = {};
- var yyloc = this.lexer.yylloc;
- lstack.push(yyloc);
- if (typeof this.yy.parseError === "function")
- this.parseError = this.yy.parseError;
- function popStack(n) {
- stack.length = stack.length - 2 * n;
- vstack.length = vstack.length - n;
- lstack.length = lstack.length - n;
- }
- function lex() {
- var token;
- token = self.lexer.lex() || 1;
- if (typeof token !== "number") {
- token = self.symbols_[token] || token;
- }
- return token;
- }
- var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected;
- while (true) {
- state = stack[stack.length - 1];
- if (this.defaultActions[state]) {
- action = this.defaultActions[state];
- } else {
- if (symbol == null)
- symbol = lex();
- action = table[state] && table[state][symbol];
- }
- if (typeof action === "undefined" || !action.length || !action[0]) {
- if (!recovering) {
- expected = [];
- for (p in table[state])
- if (this.terminals_[p] && p > 2) {
- expected.push("'" + this.terminals_[p] + "'");
- }
- var errStr = "";
- if (this.lexer.showPosition) {
- errStr = "Parse error on line " + (yylineno + 1) + ":\n" + this.lexer.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + this.terminals_[symbol] + "'";
- } else {
- errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == 1?"end of input":"'" + (this.terminals_[symbol] || symbol) + "'");
- }
- this.parseError(errStr, {text: this.lexer.match, token: this.terminals_[symbol] || symbol, line: this.lexer.yylineno, loc: yyloc, expected: expected});
- }
- }
- if (action[0] instanceof Array && action.length > 1) {
- throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol);
- }
- switch (action[0]) {
- case 1:
- stack.push(symbol);
- vstack.push(this.lexer.yytext);
- lstack.push(this.lexer.yylloc);
- stack.push(action[1]);
- symbol = null;
- if (!preErrorSymbol) {
- yyleng = this.lexer.yyleng;
- yytext = this.lexer.yytext;
- yylineno = this.lexer.yylineno;
- yyloc = this.lexer.yylloc;
- if (recovering > 0)
- recovering--;
- } else {
- symbol = preErrorSymbol;
- preErrorSymbol = null;
- }
- break;
- case 2:
- len = this.productions_[action[1]][1];
- yyval.$ = vstack[vstack.length - len];
- yyval._$ = {first_line: lstack[lstack.length - (len || 1)].first_line, last_line: lstack[lstack.length - 1].last_line, first_column: lstack[lstack.length - (len || 1)].first_column, last_column: lstack[lstack.length - 1].last_column};
- r = this.performAction.call(yyval, yytext, yyleng, yylineno, this.yy, action[1], vstack, lstack);
- if (typeof r !== "undefined") {
- return r;
- }
- if (len) {
- stack = stack.slice(0, -1 * len * 2);
- vstack = vstack.slice(0, -1 * len);
- lstack = lstack.slice(0, -1 * len);
- }
- stack.push(this.productions_[action[1]][0]);
- vstack.push(yyval.$);
- lstack.push(yyval._$);
- newState = table[stack[stack.length - 2]][stack[stack.length - 1]];
- stack.push(newState);
- break;
- case 3:
- return true;
- }
- }
- return true;
-}
-};/* Jison generated lexer */
-var lexer = (function(){
-
-var lexer = ({EOF:1,
-parseError:function parseError(str, hash) {
- if (this.yy.parseError) {
- this.yy.parseError(str, hash);
- } else {
- throw new Error(str);
- }
- },
-setInput:function (input) {
- this._input = input;
- this._more = this._less = this.done = false;
- this.yylineno = this.yyleng = 0;
- this.yytext = this.matched = this.match = '';
- this.conditionStack = ['INITIAL'];
- this.yylloc = {first_line:1,first_column:0,last_line:1,last_column:0};
- return this;
- },
-input:function () {
- var ch = this._input[0];
- this.yytext+=ch;
- this.yyleng++;
- this.match+=ch;
- this.matched+=ch;
- var lines = ch.match(/\n/);
- if (lines) this.yylineno++;
- this._input = this._input.slice(1);
- return ch;
- },
-unput:function (ch) {
- this._input = ch + this._input;
- return this;
- },
-more:function () {
- this._more = true;
- return this;
- },
-pastInput:function () {
- var past = this.matched.substr(0, this.matched.length - this.match.length);
- return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\n/g, "");
- },
-upcomingInput:function () {
- var next = this.match;
- if (next.length < 20) {
- next += this._input.substr(0, 20-next.length);
- }
- return (next.substr(0,20)+(next.length > 20 ? '...':'')).replace(/\n/g, "");
- },
-showPosition:function () {
- var pre = this.pastInput();
- var c = new Array(pre.length + 1).join("-");
- return pre + this.upcomingInput() + "\n" + c+"^";
- },
-next:function () {
- if (this.done) {
- return this.EOF;
- }
- if (!this._input) this.done = true;
-
- var token,
- match,
- col,
- lines;
- if (!this._more) {
- this.yytext = '';
- this.match = '';
- }
- var rules = this._currentRules();
- for (var i=0;i < rules.length; i++) {
- match = this._input.match(this.rules[rules[i]]);
- if (match) {
- lines = match[0].match(/\n.*/g);
- if (lines) this.yylineno += lines.length;
- this.yylloc = {first_line: this.yylloc.last_line,
- last_line: this.yylineno+1,
- first_column: this.yylloc.last_column,
- last_column: lines ? lines[lines.length-1].length-1 : this.yylloc.last_column + match[0].length}
- this.yytext += match[0];
- this.match += match[0];
- this.matches = match;
- this.yyleng = this.yytext.length;
- this._more = false;
- this._input = this._input.slice(match[0].length);
- this.matched += match[0];
- token = this.performAction.call(this, this.yy, this, rules[i],this.conditionStack[this.conditionStack.length-1]);
- if (token) return token;
- else return;
- }
- }
- if (this._input === "") {
- return this.EOF;
- } else {
- this.parseError('Lexical error on line '+(this.yylineno+1)+'. Unrecognized text.\n'+this.showPosition(),
- {text: "", token: null, line: this.yylineno});
- }
- },
-lex:function lex() {
- var r = this.next();
- if (typeof r !== 'undefined') {
- return r;
- } else {
- return this.lex();
- }
- },
-begin:function begin(condition) {
- this.conditionStack.push(condition);
- },
-popState:function popState() {
- return this.conditionStack.pop();
- },
-_currentRules:function _currentRules() {
- return this.conditions[this.conditionStack[this.conditionStack.length-1]].rules;
- },
-topState:function () {
- return this.conditionStack[this.conditionStack.length-2];
- },
-pushState:function begin(condition) {
- this.begin(condition);
- }});
-lexer.performAction = function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) {
-
-var YYSTATE=YY_START
-switch($avoiding_name_collisions) {
-case 0:
- if(yy_.yytext.slice(-1) !== "\\") this.begin("mu");
- if(yy_.yytext.slice(-1) === "\\") yy_.yytext = yy_.yytext.substr(0,yy_.yyleng-1), this.begin("emu");
- if(yy_.yytext) return 14;
-
-break;
-case 1: return 14;
-break;
-case 2: this.popState(); return 14;
-break;
-case 3: return 24;
-break;
-case 4: return 16;
-break;
-case 5: return 20;
-break;
-case 6: return 19;
-break;
-case 7: return 19;
-break;
-case 8: return 23;
-break;
-case 9: return 23;
-break;
-case 10: yy_.yytext = yy_.yytext.substr(3,yy_.yyleng-5); this.popState(); return 15;
-break;
-case 11: return 22;
-break;
-case 12: return 34;
-break;
-case 13: return 33;
-break;
-case 14: return 33;
-break;
-case 15: return 36;
-break;
-case 16: /*ignore whitespace*/
-break;
-case 17: this.popState(); return 18;
-break;
-case 18: this.popState(); return 18;
-break;
-case 19: yy_.yytext = yy_.yytext.substr(1,yy_.yyleng-2).replace(/\\"/g,'"'); return 28;
-break;
-case 20: return 30;
-break;
-case 21: return 30;
-break;
-case 22: return 29;
-break;
-case 23: return 33;
-break;
-case 24: yy_.yytext = yy_.yytext.substr(1, yy_.yyleng-2); return 33;
-break;
-case 25: return 'INVALID';
-break;
-case 26: return 5;
-break;
-}
-};
-lexer.rules = [/^[^\x00]*?(?=(\{\{))/,/^[^\x00]+/,/^[^\x00]{2,}?(?=(\{\{))/,/^\{\{>/,/^\{\{#/,/^\{\{\//,/^\{\{\^/,/^\{\{\s*else\b/,/^\{\{\{/,/^\{\{&/,/^\{\{![\s\S]*?\}\}/,/^\{\{/,/^=/,/^\.(?=[} ])/,/^\.\./,/^[\/.]/,/^\s+/,/^\}\}\}/,/^\}\}/,/^"(\\["]|[^"])*"/,/^true(?=[}\s])/,/^false(?=[}\s])/,/^[0-9]+(?=[}\s])/,/^[a-zA-Z0-9_$-]+(?=[=}\s\/.])/,/^\[[^\]]*\]/,/^./,/^$/];
-lexer.conditions = {"mu":{"rules":[3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26],"inclusive":false},"emu":{"rules":[2],"inclusive":false},"INITIAL":{"rules":[0,1,26],"inclusive":true}};return lexer;})()
-parser.lexer = lexer;
-return parser;
-})();
-if (typeof require !== 'undefined' && typeof exports !== 'undefined') {
-exports.parser = handlebars;
-exports.parse = function () { return handlebars.parse.apply(handlebars, arguments); }
-exports.main = function commonjsMain(args) {
- if (!args[1])
- throw new Error('Usage: '+args[0]+' FILE');
- if (typeof process !== 'undefined') {
- var source = require('fs').readFileSync(require('path').join(process.cwd(), args[1]), "utf8");
- } else {
- var cwd = require("file").path(require("file").cwd());
- var source = cwd.join(args[1]).read({charset: "utf-8"});
- }
- return exports.parser.parse(source);
-}
-if (typeof module !== 'undefined' && require.main === module) {
- exports.main(typeof process !== 'undefined' ? process.argv.slice(1) : require("system").args);
-}
-};
-;
-// lib/handlebars/compiler/base.js
-Handlebars.Parser = handlebars;
-
-Handlebars.parse = function(string) {
- Handlebars.Parser.yy = Handlebars.AST;
- return Handlebars.Parser.parse(string);
-};
-
-Handlebars.print = function(ast) {
- return new Handlebars.PrintVisitor().accept(ast);
-};
-
-Handlebars.logger = {
- DEBUG: 0, INFO: 1, WARN: 2, ERROR: 3, level: 3,
-
- // override in the host environment
- log: function(level, str) {}
-};
-
-Handlebars.log = function(level, str) { Handlebars.logger.log(level, str); };
-;
-// lib/handlebars/compiler/ast.js
-(function() {
-
- Handlebars.AST = {};
-
- Handlebars.AST.ProgramNode = function(statements, inverse) {
- this.type = "program";
- this.statements = statements;
- if(inverse) { this.inverse = new Handlebars.AST.ProgramNode(inverse); }
- };
-
- Handlebars.AST.MustacheNode = function(params, hash, unescaped) {
- this.type = "mustache";
- this.id = params[0];
- this.params = params.slice(1);
- this.hash = hash;
- this.escaped = !unescaped;
- };
-
- Handlebars.AST.PartialNode = function(id, context) {
- this.type = "partial";
-
- // TODO: disallow complex IDs
-
- this.id = id;
- this.context = context;
- };
-
- var verifyMatch = function(open, close) {
- if(open.original !== close.original) {
- throw new Handlebars.Exception(open.original + " doesn't match " + close.original);
- }
- };
-
- Handlebars.AST.BlockNode = function(mustache, program, close) {
- verifyMatch(mustache.id, close);
- this.type = "block";
- this.mustache = mustache;
- this.program = program;
- };
-
- Handlebars.AST.InverseNode = function(mustache, program, close) {
- verifyMatch(mustache.id, close);
- this.type = "inverse";
- this.mustache = mustache;
- this.program = program;
- };
-
- Handlebars.AST.ContentNode = function(string) {
- this.type = "content";
- this.string = string;
- };
-
- Handlebars.AST.HashNode = function(pairs) {
- this.type = "hash";
- this.pairs = pairs;
- };
-
- Handlebars.AST.IdNode = function(parts) {
- this.type = "ID";
- this.original = parts.join(".");
-
- var dig = [], depth = 0;
-
- for(var i=0,l=parts.length; i<l; i++) {
- var part = parts[i];
-
- if(part === "..") { depth++; }
- else if(part === "." || part === "this") { this.isScoped = true; }
- else { dig.push(part); }
- }
-
- this.parts = dig;
- this.string = dig.join('.');
- this.depth = depth;
- this.isSimple = (dig.length === 1) && (depth === 0);
- };
-
- Handlebars.AST.StringNode = function(string) {
- this.type = "STRING";
- this.string = string;
- };
-
- Handlebars.AST.IntegerNode = function(integer) {
- this.type = "INTEGER";
- this.integer = integer;
- };
-
- Handlebars.AST.BooleanNode = function(bool) {
- this.type = "BOOLEAN";
- this.bool = bool;
- };
-
- Handlebars.AST.CommentNode = function(comment) {
- this.type = "comment";
- this.comment = comment;
- };
-
-})();;
-// lib/handlebars/utils.js
-Handlebars.Exception = function(message) {
- var tmp = Error.prototype.constructor.apply(this, arguments);
-
- for (var p in tmp) {
- if (tmp.hasOwnProperty(p)) { this[p] = tmp[p]; }
- }
-
- this.message = tmp.message;
-};
-Handlebars.Exception.prototype = new Error;
-
-// Build out our basic SafeString type
-Handlebars.SafeString = function(string) {
- this.string = string;
-};
-Handlebars.SafeString.prototype.toString = function() {
- return this.string.toString();
-};
-
-(function() {
- var escape = {
- "<": "<",
- ">": ">",
- '"': """,
- "'": "'",
- "`": "`"
- };
-
- var badChars = /&(?!\w+;)|[<>"'`]/g;
- var possible = /[&<>"'`]/;
-
- var escapeChar = function(chr) {
- return escape[chr] || "&";
- };
-
- Handlebars.Utils = {
- escapeExpression: function(string) {
- // don't escape SafeStrings, since they're already safe
- if (string instanceof Handlebars.SafeString) {
- return string.toString();
- } else if (string == null || string === false) {
- return "";
- }
-
- if(!possible.test(string)) { return string; }
- return string.replace(badChars, escapeChar);
- },
-
- isEmpty: function(value) {
- if (typeof value === "undefined") {
- return true;
- } else if (value === null) {
- return true;
- } else if (value === false) {
- return true;
- } else if(Object.prototype.toString.call(value) === "[object Array]" && value.length === 0) {
- return true;
- } else {
- return false;
- }
- }
- };
-})();;
-// lib/handlebars/compiler/compiler.js
-Handlebars.Compiler = function() {};
-Handlebars.JavaScriptCompiler = function() {};
-
-(function(Compiler, JavaScriptCompiler) {
- Compiler.OPCODE_MAP = {
- appendContent: 1,
- getContext: 2,
- lookupWithHelpers: 3,
- lookup: 4,
- append: 5,
- invokeMustache: 6,
- appendEscaped: 7,
- pushString: 8,
- truthyOrFallback: 9,
- functionOrFallback: 10,
- invokeProgram: 11,
- invokePartial: 12,
- push: 13,
- assignToHash: 15,
- pushStringParam: 16
- };
-
- Compiler.MULTI_PARAM_OPCODES = {
- appendContent: 1,
- getContext: 1,
- lookupWithHelpers: 2,
- lookup: 1,
- invokeMustache: 3,
- pushString: 1,
- truthyOrFallback: 1,
- functionOrFallback: 1,
- invokeProgram: 3,
- invokePartial: 1,
- push: 1,
- assignToHash: 1,
- pushStringParam: 1
- };
-
- Compiler.DISASSEMBLE_MAP = {};
-
- for(var prop in Compiler.OPCODE_MAP) {
- var value = Compiler.OPCODE_MAP[prop];
- Compiler.DISASSEMBLE_MAP[value] = prop;
- }
-
- Compiler.multiParamSize = function(code) {
- return Compiler.MULTI_PARAM_OPCODES[Compiler.DISASSEMBLE_MAP[code]];
- };
-
- Compiler.prototype = {
- compiler: Compiler,
-
- disassemble: function() {
- var opcodes = this.opcodes, opcode, nextCode;
- var out = [], str, name, value;
-
- for(var i=0, l=opcodes.length; i<l; i++) {
- opcode = opcodes[i];
-
- if(opcode === 'DECLARE') {
- name = opcodes[++i];
- value = opcodes[++i];
- out.push("DECLARE " + name + " = " + value);
- } else {
- str = Compiler.DISASSEMBLE_MAP[opcode];
-
- var extraParams = Compiler.multiParamSize(opcode);
- var codes = [];
-
- for(var j=0; j<extraParams; j++) {
- nextCode = opcodes[++i];
-
- if(typeof nextCode === "string") {
- nextCode = "\"" + nextCode.replace("\n", "\\n") + "\"";
- }
-
- codes.push(nextCode);
- }
-
- str = str + " " + codes.join(" ");
-
- out.push(str);
- }
- }
-
- return out.join("\n");
- },
-
- guid: 0,
-
- compile: function(program, options) {
- this.children = [];
- this.depths = {list: []};
- this.options = options;
-
- // These changes will propagate to the other compiler components
- var knownHelpers = this.options.knownHelpers;
- this.options.knownHelpers = {
- 'helperMissing': true,
- 'blockHelperMissing': true,
- 'each': true,
- 'if': true,
- 'unless': true,
- 'with': true,
- 'log': true
- };
- if (knownHelpers) {
- for (var name in knownHelpers) {
- this.options.knownHelpers[name] = knownHelpers[name];
- }
- }
-
- return this.program(program);
- },
-
- accept: function(node) {
- return this[node.type](node);
- },
-
- program: function(program) {
- var statements = program.statements, statement;
- this.opcodes = [];
-
- for(var i=0, l=statements.length; i<l; i++) {
- statement = statements[i];
- this[statement.type](statement);
- }
- this.isSimple = l === 1;
-
- this.depths.list = this.depths.list.sort(function(a, b) {
- return a - b;
- });
-
- return this;
- },
-
- compileProgram: function(program) {
- var result = new this.compiler().compile(program, this.options);
- var guid = this.guid++;
-
- this.usePartial = this.usePartial || result.usePartial;
-
- this.children[guid] = result;
-
- for(var i=0, l=result.depths.list.length; i<l; i++) {
- depth = result.depths.list[i];
-
- if(depth < 2) { continue; }
- else { this.addDepth(depth - 1); }
- }
-
- return guid;
- },
-
- block: function(block) {
- var mustache = block.mustache;
- var depth, child, inverse, inverseGuid;
-
- var params = this.setupStackForMustache(mustache);
-
- var programGuid = this.compileProgram(block.program);
-
- if(block.program.inverse) {
- inverseGuid = this.compileProgram(block.program.inverse);
- this.declare('inverse', inverseGuid);
- }
-
- this.opcode('invokeProgram', programGuid, params.length, !!mustache.hash);
- this.declare('inverse', null);
- this.opcode('append');
- },
-
- inverse: function(block) {
- var params = this.setupStackForMustache(block.mustache);
-
- var programGuid = this.compileProgram(block.program);
-
- this.declare('inverse', programGuid);
-
- this.opcode('invokeProgram', null, params.length, !!block.mustache.hash);
- this.declare('inverse', null);
- this.opcode('append');
- },
-
- hash: function(hash) {
- var pairs = hash.pairs, pair, val;
-
- this.opcode('push', '{}');
-
- for(var i=0, l=pairs.length; i<l; i++) {
- pair = pairs[i];
- val = pair[1];
-
- this.accept(val);
- this.opcode('assignToHash', pair[0]);
- }
- },
-
- partial: function(partial) {
- var id = partial.id;
- this.usePartial = true;
-
- if(partial.context) {
- this.ID(partial.context);
- } else {
- this.opcode('push', 'depth0');
- }
-
- this.opcode('invokePartial', id.original);
- this.opcode('append');
- },
-
- content: function(content) {
- this.opcode('appendContent', content.string);
- },
-
- mustache: function(mustache) {
- var params = this.setupStackForMustache(mustache);
-
- this.opcode('invokeMustache', params.length, mustache.id.original, !!mustache.hash);
-
- if(mustache.escaped && !this.options.noEscape) {
- this.opcode('appendEscaped');
- } else {
- this.opcode('append');
- }
- },
-
- ID: function(id) {
- this.addDepth(id.depth);
-
- this.opcode('getContext', id.depth);
-
- this.opcode('lookupWithHelpers', id.parts[0] || null, id.isScoped || false);
-
- for(var i=1, l=id.parts.length; i<l; i++) {
- this.opcode('lookup', id.parts[i]);
- }
- },
-
- STRING: function(string) {
- this.opcode('pushString', string.string);
- },
-
- INTEGER: function(integer) {
- this.opcode('push', integer.integer);
- },
-
- BOOLEAN: function(bool) {
- this.opcode('push', bool.bool);
- },
-
- comment: function() {},
-
- // HELPERS
- pushParams: function(params) {
- var i = params.length, param;
-
- while(i--) {
- param = params[i];
-
- if(this.options.stringParams) {
- if(param.depth) {
- this.addDepth(param.depth);
- }
-
- this.opcode('getContext', param.depth || 0);
- this.opcode('pushStringParam', param.string);
- } else {
- this[param.type](param);
- }
- }
- },
-
- opcode: function(name, val1, val2, val3) {
- this.opcodes.push(Compiler.OPCODE_MAP[name]);
- if(val1 !== undefined) { this.opcodes.push(val1); }
- if(val2 !== undefined) { this.opcodes.push(val2); }
- if(val3 !== undefined) { this.opcodes.push(val3); }
- },
-
- declare: function(name, value) {
- this.opcodes.push('DECLARE');
- this.opcodes.push(name);
- this.opcodes.push(value);
- },
-
- addDepth: function(depth) {
- if(depth === 0) { return; }
-
- if(!this.depths[depth]) {
- this.depths[depth] = true;
- this.depths.list.push(depth);
- }
- },
-
- setupStackForMustache: function(mustache) {
- var params = mustache.params;
-
- this.pushParams(params);
-
- if(mustache.hash) {
- this.hash(mustache.hash);
- }
-
- this.ID(mustache.id);
-
- return params;
- }
- };
-
- JavaScriptCompiler.prototype = {
- // PUBLIC API: You can override these methods in a subclass to provide
- // alternative compiled forms for name lookup and buffering semantics
- nameLookup: function(parent, name, type) {
- if (/^[0-9]+$/.test(name)) {
- return parent + "[" + name + "]";
- } else if (JavaScriptCompiler.isValidJavaScriptVariableName(name)) {
- return parent + "." + name;
- }
- else {
- return parent + "['" + name + "']";
- }
- },
-
- appendToBuffer: function(string) {
- if (this.environment.isSimple) {
- return "return " + string + ";";
- } else {
- return "buffer += " + string + ";";
- }
- },
-
- initializeBuffer: function() {
- return this.quotedString("");
- },
-
- namespace: "Handlebars",
- // END PUBLIC API
-
- compile: function(environment, options, context, asObject) {
- this.environment = environment;
- this.options = options || {};
-
- this.name = this.environment.name;
- this.isChild = !!context;
- this.context = context || {
- programs: [],
- aliases: { self: 'this' },
- registers: {list: []}
- };
-
- this.preamble();
-
- this.stackSlot = 0;
- this.stackVars = [];
-
- this.compileChildren(environment, options);
-
- var opcodes = environment.opcodes, opcode;
-
- this.i = 0;
-
- for(l=opcodes.length; this.i<l; this.i++) {
- opcode = this.nextOpcode(0);
-
- if(opcode[0] === 'DECLARE') {
- this.i = this.i + 2;
- this[opcode[1]] = opcode[2];
- } else {
- this.i = this.i + opcode[1].length;
- this[opcode[0]].apply(this, opcode[1]);
- }
- }
-
- return this.createFunctionContext(asObject);
- },
-
- nextOpcode: function(n) {
- var opcodes = this.environment.opcodes, opcode = opcodes[this.i + n], name, val;
- var extraParams, codes;
-
- if(opcode === 'DECLARE') {
- name = opcodes[this.i + 1];
- val = opcodes[this.i + 2];
- return ['DECLARE', name, val];
- } else {
- name = Compiler.DISASSEMBLE_MAP[opcode];
-
- extraParams = Compiler.multiParamSize(opcode);
- codes = [];
-
- for(var j=0; j<extraParams; j++) {
- codes.push(opcodes[this.i + j + 1 + n]);
- }
-
- return [name, codes];
- }
- },
-
- eat: function(opcode) {
- this.i = this.i + opcode.length;
- },
-
- preamble: function() {
- var out = [];
-
- // this register will disambiguate helper lookup from finding a function in
- // a context. This is necessary for mustache compatibility, which requires
- // that context functions in blocks are evaluated by blockHelperMissing, and
- // then proceed as if the resulting value was provided to blockHelperMissing.
- this.useRegister('foundHelper');
-
- if (!this.isChild) {
- var namespace = this.namespace;
- var copies = "helpers = helpers || " + namespace + ".helpers;";
- if(this.environment.usePartial) { copies = copies + " partials = partials || " + namespace + ".partials;"; }
- out.push(copies);
- } else {
- out.push('');
- }
-
- if (!this.environment.isSimple) {
- out.push(", buffer = " + this.initializeBuffer());
- } else {
- out.push("");
- }
-
- // track the last context pushed into place to allow skipping the
- // getContext opcode when it would be a noop
- this.lastContext = 0;
- this.source = out;
- },
-
- createFunctionContext: function(asObject) {
- var locals = this.stackVars;
- if (!this.isChild) {
- locals = locals.concat(this.context.registers.list);
- }
-
- if(locals.length > 0) {
- this.source[1] = this.source[1] + ", " + locals.join(", ");
- }
-
- // Generate minimizer alias mappings
- if (!this.isChild) {
- var aliases = []
- for (var alias in this.context.aliases) {
- this.source[1] = this.source[1] + ', ' + alias + '=' + this.context.aliases[alias];
- }
- }
-
- if (this.source[1]) {
- this.source[1] = "var " + this.source[1].substring(2) + ";";
- }
-
- // Merge children
- if (!this.isChild) {
- this.source[1] += '\n' + this.context.programs.join('\n') + '\n';
- }
-
- if (!this.environment.isSimple) {
- this.source.push("return buffer;");
- }
-
- var params = this.isChild ? ["depth0", "data"] : ["Handlebars", "depth0", "helpers", "partials", "data"];
-
- for(var i=0, l=this.environment.depths.list.length; i<l; i++) {
- params.push("depth" + this.environment.depths.list[i]);
- }
-
- if (asObject) {
- params.push(this.source.join("\n "));
-
- return Function.apply(this, params);
- } else {
- var functionSource = 'function ' + (this.name || '') + '(' + params.join(',') + ') {\n ' + this.source.join("\n ") + '}';
- Handlebars.log(Handlebars.logger.DEBUG, functionSource + "\n\n");
- return functionSource;
- }
- },
-
- appendContent: function(content) {
- this.source.push(this.appendToBuffer(this.quotedString(content)));
- },
-
- append: function() {
- var local = this.popStack();
- this.source.push("if(" + local + " || " + local + " === 0) { " + this.appendToBuffer(local) + " }");
- if (this.environment.isSimple) {
- this.source.push("else { " + this.appendToBuffer("''") + " }");
- }
- },
-
- appendEscaped: function() {
- var opcode = this.nextOpcode(1), extra = "";
- this.context.aliases.escapeExpression = 'this.escapeExpression';
-
- if(opcode[0] === 'appendContent') {
- extra = " + " + this.quotedString(opcode[1][0]);
- this.eat(opcode);
- }
-
- this.source.push(this.appendToBuffer("escapeExpression(" + this.popStack() + ")" + extra));
- },
-
- getContext: function(depth) {
- if(this.lastContext !== depth) {
- this.lastContext = depth;
- }
- },
-
- lookupWithHelpers: function(name, isScoped) {
- if(name) {
- var topStack = this.nextStack();
-
- this.usingKnownHelper = false;
-
- var toPush;
- if (!isScoped && this.options.knownHelpers[name]) {
- toPush = topStack + " = " + this.nameLookup('helpers', name, 'helper');
- this.usingKnownHelper = true;
- } else if (isScoped || this.options.knownHelpersOnly) {
- toPush = topStack + " = " + this.nameLookup('depth' + this.lastContext, name, 'context');
- } else {
- this.register('foundHelper', this.nameLookup('helpers', name, 'helper'));
- toPush = topStack + " = foundHelper || " + this.nameLookup('depth' + this.lastContext, name, 'context');
- }
-
- toPush += ';';
- this.source.push(toPush);
- } else {
- this.pushStack('depth' + this.lastContext);
- }
- },
-
- lookup: function(name) {
- var topStack = this.topStack();
- this.source.push(topStack + " = (" + topStack + " === null || " + topStack + " === undefined || " + topStack + " === false ? " +
- topStack + " : " + this.nameLookup(topStack, name, 'context') + ");");
- },
-
- pushStringParam: function(string) {
- this.pushStack('depth' + this.lastContext);
- this.pushString(string);
- },
-
- pushString: function(string) {
- this.pushStack(this.quotedString(string));
- },
-
- push: function(name) {
- this.pushStack(name);
- },
-
- invokeMustache: function(paramSize, original, hasHash) {
- this.populateParams(paramSize, this.quotedString(original), "{}", null, hasHash, function(nextStack, helperMissingString, id) {
- if (!this.usingKnownHelper) {
- this.context.aliases.helperMissing = 'helpers.helperMissing';
- this.context.aliases.undef = 'void 0';
- this.source.push("else if(" + id + "=== undef) { " + nextStack + " = helperMissing.call(" + helperMissingString + "); }");
- if (nextStack !== id) {
- this.source.push("else { " + nextStack + " = " + id + "; }");
- }
- }
- });
- },
-
- invokeProgram: function(guid, paramSize, hasHash) {
- var inverse = this.programExpression(this.inverse);
- var mainProgram = this.programExpression(guid);
-
- this.populateParams(paramSize, null, mainProgram, inverse, hasHash, function(nextStack, helperMissingString, id) {
- if (!this.usingKnownHelper) {
- this.context.aliases.blockHelperMissing = 'helpers.blockHelperMissing';
- this.source.push("else { " + nextStack + " = blockHelperMissing.call(" + helperMissingString + "); }");
- }
- });
- },
-
- populateParams: function(paramSize, helperId, program, inverse, hasHash, fn) {
- var needsRegister = hasHash || this.options.stringParams || inverse || this.options.data;
- var id = this.popStack(), nextStack;
- var params = [], param, stringParam, stringOptions;
-
- if (needsRegister) {
- this.register('tmp1', program);
- stringOptions = 'tmp1';
- } else {
- stringOptions = '{ hash: {} }';
- }
-
- if (needsRegister) {
- var hash = (hasHash ? this.popStack() : '{}');
- this.source.push('tmp1.hash = ' + hash + ';');
- }
-
- if(this.options.stringParams) {
- this.source.push('tmp1.contexts = [];');
- }
-
- for(var i=0; i<paramSize; i++) {
- param = this.popStack();
- params.push(param);
-
- if(this.options.stringParams) {
- this.source.push('tmp1.contexts.push(' + this.popStack() + ');');
- }
- }
-
- if(inverse) {
- this.source.push('tmp1.fn = tmp1;');
- this.source.push('tmp1.inverse = ' + inverse + ';');
- }
-
- if(this.options.data) {
- this.source.push('tmp1.data = data;');
- }
-
- params.push(stringOptions);
-
- this.populateCall(params, id, helperId || id, fn, program !== '{}');
- },
-
- populateCall: function(params, id, helperId, fn, program) {
- var paramString = ["depth0"].concat(params).join(", ");
- var helperMissingString = ["depth0"].concat(helperId).concat(params).join(", ");
-
- var nextStack = this.nextStack();
-
- if (this.usingKnownHelper) {
- this.source.push(nextStack + " = " + id + ".call(" + paramString + ");");
- } else {
- this.context.aliases.functionType = '"function"';
- var condition = program ? "foundHelper && " : ""
- this.source.push("if(" + condition + "typeof " + id + " === functionType) { " + nextStack + " = " + id + ".call(" + paramString + "); }");
- }
- fn.call(this, nextStack, helperMissingString, id);
- this.usingKnownHelper = false;
- },
-
- invokePartial: function(context) {
- params = [this.nameLookup('partials', context, 'partial'), "'" + context + "'", this.popStack(), "helpers", "partials"];
-
- if (this.options.data) {
- params.push("data");
- }
-
- this.pushStack("self.invokePartial(" + params.join(", ") + ");");
- },
-
- assignToHash: function(key) {
- var value = this.popStack();
- var hash = this.topStack();
-
- this.source.push(hash + "['" + key + "'] = " + value + ";");
- },
-
- // HELPERS
-
- compiler: JavaScriptCompiler,
-
- compileChildren: function(environment, options) {
- var children = environment.children, child, compiler;
-
- for(var i=0, l=children.length; i<l; i++) {
- child = children[i];
- compiler = new this.compiler();
-
- this.context.programs.push(''); // Placeholder to prevent name conflicts for nested children
- var index = this.context.programs.length;
- child.index = index;
- child.name = 'program' + index;
- this.context.programs[index] = compiler.compile(child, options, this.context);
- }
- },
-
- programExpression: function(guid) {
- if(guid == null) { return "self.noop"; }
-
- var child = this.environment.children[guid],
- depths = child.depths.list;
- var programParams = [child.index, child.name, "data"];
-
- for(var i=0, l = depths.length; i<l; i++) {
- depth = depths[i];
-
- if(depth === 1) { programParams.push("depth0"); }
- else { programParams.push("depth" + (depth - 1)); }
- }
-
- if(depths.length === 0) {
- return "self.program(" + programParams.join(", ") + ")";
- } else {
- programParams.shift();
- return "self.programWithDepth(" + programParams.join(", ") + ")";
- }
- },
-
- register: function(name, val) {
- this.useRegister(name);
- this.source.push(name + " = " + val + ";");
- },
-
- useRegister: function(name) {
- if(!this.context.registers[name]) {
- this.context.registers[name] = true;
- this.context.registers.list.push(name);
- }
- },
-
- pushStack: function(item) {
- this.source.push(this.nextStack() + " = " + item + ";");
- return "stack" + this.stackSlot;
- },
-
- nextStack: function() {
- this.stackSlot++;
- if(this.stackSlot > this.stackVars.length) { this.stackVars.push("stack" + this.stackSlot); }
- return "stack" + this.stackSlot;
- },
-
- popStack: function() {
- return "stack" + this.stackSlot--;
- },
-
- topStack: function() {
- return "stack" + this.stackSlot;
- },
-
- quotedString: function(str) {
- return '"' + str
- .replace(/\\/g, '\\\\')
- .replace(/"/g, '\\"')
- .replace(/\n/g, '\\n')
- .replace(/\r/g, '\\r') + '"';
- }
- };
-
- var reservedWords = (
- "break else new var" +
- " case finally return void" +
- " catch for switch while" +
- " continue function this with" +
- " default if throw" +
- " delete in try" +
- " do instanceof typeof" +
- " abstract enum int short" +
- " boolean export interface static" +
- " byte extends long super" +
- " char final native synchronized" +
- " class float package throws" +
- " const goto private transient" +
- " debugger implements protected volatile" +
- " double import public let yield"
- ).split(" ");
-
- var compilerWords = JavaScriptCompiler.RESERVED_WORDS = {};
-
- for(var i=0, l=reservedWords.length; i<l; i++) {
- compilerWords[reservedWords[i]] = true;
- }
-
- JavaScriptCompiler.isValidJavaScriptVariableName = function(name) {
- if(!JavaScriptCompiler.RESERVED_WORDS[name] && /^[a-zA-Z_$][0-9a-zA-Z_$]+$/.test(name)) {
- return true;
- }
- return false;
- }
-
-})(Handlebars.Compiler, Handlebars.JavaScriptCompiler);
-
-Handlebars.precompile = function(string, options) {
- options = options || {};
-
- var ast = Handlebars.parse(string);
- var environment = new Handlebars.Compiler().compile(ast, options);
- return new Handlebars.JavaScriptCompiler().compile(environment, options);
-};
-
-Handlebars.compile = function(string, options) {
- options = options || {};
-
- var compiled;
- function compile() {
- var ast = Handlebars.parse(string);
- var environment = new Handlebars.Compiler().compile(ast, options);
- var templateSpec = new Handlebars.JavaScriptCompiler().compile(environment, options, undefined, true);
- return Handlebars.template(templateSpec);
- }
-
- // Template is only compiled on first use and cached after that point.
- return function(context, options) {
- if (!compiled) {
- compiled = compile();
- }
- return compiled.call(this, context, options);
- };
-};
-;
-// lib/handlebars/runtime.js
-Handlebars.VM = {
- template: function(templateSpec) {
- // Just add water
- var container = {
- escapeExpression: Handlebars.Utils.escapeExpression,
- invokePartial: Handlebars.VM.invokePartial,
- programs: [],
- program: function(i, fn, data) {
- var programWrapper = this.programs[i];
- if(data) {
- return Handlebars.VM.program(fn, data);
- } else if(programWrapper) {
- return programWrapper;
- } else {
- programWrapper = this.programs[i] = Handlebars.VM.program(fn);
- return programWrapper;
- }
- },
- programWithDepth: Handlebars.VM.programWithDepth,
- noop: Handlebars.VM.noop
- };
-
- return function(context, options) {
- options = options || {};
- return templateSpec.call(container, Handlebars, context, options.helpers, options.partials, options.data);
- };
- },
-
- programWithDepth: function(fn, data, $depth) {
- var args = Array.prototype.slice.call(arguments, 2);
-
- return function(context, options) {
- options = options || {};
-
- return fn.apply(this, [context, options.data || data].concat(args));
- };
- },
- program: function(fn, data) {
- return function(context, options) {
- options = options || {};
-
- return fn(context, options.data || data);
- };
- },
- noop: function() { return ""; },
- invokePartial: function(partial, name, context, helpers, partials, data) {
- options = { helpers: helpers, partials: partials, data: data };
-
- if(partial === undefined) {
- throw new Handlebars.Exception("The partial " + name + " could not be found");
- } else if(partial instanceof Function) {
- return partial(context, options);
- } else if (!Handlebars.compile) {
- throw new Handlebars.Exception("The partial " + name + " could not be compiled when running in runtime-only mode");
- } else {
- partials[name] = Handlebars.compile(partial);
- return partials[name](context, options);
- }
- }
-};
-
-Handlebars.template = Handlebars.VM.template;
-;
diff --git a/chrome/common/extensions/docs/examples/howto/sandbox/icon.png b/chrome/common/extensions/docs/examples/howto/sandbox/icon.png
deleted file mode 100644
index 3620d4f..0000000
--- a/chrome/common/extensions/docs/examples/howto/sandbox/icon.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/howto/sandbox/manifest.json b/chrome/common/extensions/docs/examples/howto/sandbox/manifest.json
deleted file mode 100644
index 0fd7c52..0000000
--- a/chrome/common/extensions/docs/examples/howto/sandbox/manifest.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- "name": "Sandboxed Frame",
- "description": "Demonstrate use of handlebars inside a sandboxed frame",
- "version": "1.0",
- "manifest_version": 2,
- "permissions": ["notifications"],
- "background": {
- "page": "eventpage.html",
- "persistent": false
- },
- "browser_action": {
- "default_icon" : "icon.png",
- "default_title": "Start Event Page"
- },
- "sandbox": {
- "pages": ["sandbox.html"]
- },
- "web_accessible_resources": ["icon.png"]
-}
diff --git a/chrome/common/extensions/docs/examples/howto/sandbox/sandbox.html b/chrome/common/extensions/docs/examples/howto/sandbox/sandbox.html
deleted file mode 100644
index d66fa223..0000000
--- a/chrome/common/extensions/docs/examples/howto/sandbox/sandbox.html
+++ /dev/null
@@ -1,44 +0,0 @@
-<!--
- - Copyright (c) 2012 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.
- -->
-<!doctype html>
-<html>
- <head>
- <script src="handlebars-1.0.0.beta.6.js"></script>
- </head>
- <body>
- <script id="hello-world-template" type="text/x-handlebars-template">
- <div class="entry">
- <h1>Hello, {{thing}}!</h1>
- </div>
- </script>
- <script>
- var templates = [];
- var source = document.getElementById('hello-world-template').innerHTML;
- templates['hello'] = Handlebars.compile(source);
-
- // Set up message event handler:
- window.addEventListener('message', function(event) {
- var command = event.data.command;
- var name = event.data.name || 'hello';
- switch(command) {
- case 'render':
- event.source.postMessage({
- name: name,
- html: templates[name](event.data.context)
- }, event.origin);
- break;
-
- // You could imagine additional functionality. For instance:
- //
- // case 'new':
- // templates[event.data.name] = Handlebars.compile(event.data.source);
- // event.source.postMessage({name: name, success: true}, event.origin);
- // break;
- }
- });
- </script>
- </body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/howto/tab_shortcuts/manifest.json b/chrome/common/extensions/docs/examples/howto/tab_shortcuts/manifest.json
deleted file mode 100644
index 198ac7a..0000000
--- a/chrome/common/extensions/docs/examples/howto/tab_shortcuts/manifest.json
+++ /dev/null
@@ -1,26 +0,0 @@
-{
- "name": "Tab Shortcuts",
- "version": "1.0",
- "description": "Allows pinning and duplication of tabs via keyboard shortcuts.",
- "manifest_version": 2,
- "background": {
- "scripts": ["tab_shortcuts.js"],
- "persistent": false
- },
- "commands": {
- "toggle-pin-tab": {
- "suggested_key": {
- "default": "Ctrl+Shift+X",
- "mac": "Command+Shift+X"
- },
- "description": "Toggles whether the current tab is pinned."
- },
- "duplicate-tab": {
- "suggested_key": {
- "default": "Ctrl+Shift+Z",
- "mac": "Command+Shift+Z"
- },
- "description": "Duplicates the current tab."
- }
- }
-}
diff --git a/chrome/common/extensions/docs/examples/howto/tab_shortcuts/tab_shortcuts.js b/chrome/common/extensions/docs/examples/howto/tab_shortcuts/tab_shortcuts.js
deleted file mode 100644
index 4ff711f..0000000
--- a/chrome/common/extensions/docs/examples/howto/tab_shortcuts/tab_shortcuts.js
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright (c) 2013 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.
-
-/**
- * Register a callback function with the commands api, which will be called when
- * one of our registered commands is detected.
- */
-chrome.commands.onCommand.addListener(function(command) {
- // Call 'update' with an empty properties object to get access to the current
- // tab (given to us in the callback function).
- chrome.tabs.update({}, function(tab) {
- if (command == 'toggle-pin-tab')
- chrome.tabs.update({pinned: !tab.pinned});
- else if (command == 'duplicate-tab')
- chrome.tabs.duplicate(tab.id);
- });
-});
diff --git a/chrome/common/extensions/docs/examples/tutorials/analytics/analytics-extension-icon-128.png b/chrome/common/extensions/docs/examples/tutorials/analytics/analytics-extension-icon-128.png
deleted file mode 100644
index 9013abf..0000000
--- a/chrome/common/extensions/docs/examples/tutorials/analytics/analytics-extension-icon-128.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/tutorials/analytics/analytics-extension-icon-19.png b/chrome/common/extensions/docs/examples/tutorials/analytics/analytics-extension-icon-19.png
deleted file mode 100644
index af80e35e..0000000
--- a/chrome/common/extensions/docs/examples/tutorials/analytics/analytics-extension-icon-19.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/tutorials/analytics/analytics-extension-icon-48.png b/chrome/common/extensions/docs/examples/tutorials/analytics/analytics-extension-icon-48.png
deleted file mode 100644
index 4548ea3..0000000
--- a/chrome/common/extensions/docs/examples/tutorials/analytics/analytics-extension-icon-48.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/tutorials/analytics/manifest.json b/chrome/common/extensions/docs/examples/tutorials/analytics/manifest.json
deleted file mode 100644
index 11f90a0..0000000
--- a/chrome/common/extensions/docs/examples/tutorials/analytics/manifest.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- "name": "Event Tracking with Google Analytics",
- "version": "2.0.0",
- "description": "A sample extension which uses Google Analytics to track usage.",
- "browser_action": {
- "default_title": "Open the popup",
- "default_icon": "analytics-extension-icon-19.png",
- "default_popup" : "popup.html"
- },
- "icons": {
- "48": "analytics-extension-icon-48.png",
- "128": "analytics-extension-icon-128.png"
- },
-
- "manifest_version": 2,
- "content_security_policy": "script-src 'self' https://ssl.google-analytics.com; object-src 'self'"
-}
diff --git a/chrome/common/extensions/docs/examples/tutorials/analytics/popup.html b/chrome/common/extensions/docs/examples/tutorials/analytics/popup.html
deleted file mode 100644
index 9a76c267..0000000
--- a/chrome/common/extensions/docs/examples/tutorials/analytics/popup.html
+++ /dev/null
@@ -1,32 +0,0 @@
-<!DOCTYPE html>
-<!--
- * Copyright (c) 2012 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>
- <style>
- body {
- width: 300px;
- color: #000;
- font-family: Arial;
- }
- #output {
- color: #d00;
- text-align: center;
- }
- </style>
- <script src="popup.js"></script>
- </head>
- <body>
- <h1>Popup</h1>
- <p>Track the following actions:</p>
- <button id='button1'>Button 1</button>
- <button id='button2'>Button 2</button>
- <button id='button3'>Button 3</button>
- <button id='button4'>Button 4</button>
- <button id='button5'>Button 5</button>
- <button id='button6'>Button 6</button>
- </body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/tutorials/analytics/popup.js b/chrome/common/extensions/docs/examples/tutorials/analytics/popup.js
deleted file mode 100644
index 160fe15..0000000
--- a/chrome/common/extensions/docs/examples/tutorials/analytics/popup.js
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright (c) 2012 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.
-
-/**
- * Add your Analytics tracking ID here.
- */
-var _AnalyticsCode = 'UA-XXXXXX-X';
-
-/**
- * Below is a modified version of the Google Analytics asynchronous tracking
- * code snippet. It has been modified to pull the HTTPS version of ga.js
- * instead of the default HTTP version. It is recommended that you use this
- * snippet instead of the standard tracking snippet provided when setting up
- * a Google Analytics account.
- */
-var _gaq = _gaq || [];
-_gaq.push(['_setAccount', _AnalyticsCode]);
-_gaq.push(['_trackPageview']);
-
-(function() {
- var ga = document.createElement('script');
- ga.type = 'text/javascript';
- ga.async = true;
- ga.src = 'https://ssl.google-analytics.com/ga.js';
- var s = document.getElementsByTagName('script')[0];
- s.parentNode.insertBefore(ga, s);
-})();
-
-/**
- * Track a click on a button using the asynchronous tracking API.
- *
- * See http://code.google.com/apis/analytics/docs/tracking/asyncTracking.html
- * for information on how to use the asynchronous tracking API.
- */
-function trackButtonClick(e) {
- _gaq.push(['_trackEvent', e.target.id, 'clicked']);
-}
-
-/**
- * Now set up your event handlers for the popup's `button` elements once the
- * popup's DOM has loaded.
- */
-document.addEventListener('DOMContentLoaded', function () {
- var buttons = document.querySelectorAll('button');
- for (var i = 0; i < buttons.length; i++) {
- buttons[i].addEventListener('click', trackButtonClick);
- }
-});
diff --git a/chrome/common/extensions/docs/examples/tutorials/broken_background_color.zip b/chrome/common/extensions/docs/examples/tutorials/broken_background_color.zip
deleted file mode 100644
index 3b9b80f0..0000000
--- a/chrome/common/extensions/docs/examples/tutorials/broken_background_color.zip
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/tutorials/broken_background_color/background.js b/chrome/common/extensions/docs/examples/tutorials/broken_background_color/background.js
deleted file mode 100644
index 9465c72..0000000
--- a/chrome/common/extensions/docs/examples/tutorials/broken_background_color/background.js
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2018 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.
-
-'use strict';
-
-// There's a typo in the line below; oninstalled should be onInstalled.
-chrome.runtime.oninstalled.addListener(function() {
- chrome.storage.sync.set({color: '#3aa757'}, function() {
- console.log('The color is green.');
- });
- chrome.declarativeContent.onPageChanged.removeRules(undefined, function() {
- chrome.declarativeContent.onPageChanged.addRules([{
- conditions: [new chrome.declarativeContent.PageStateMatcher({
- pageUrl: {hostEquals: 'developer.chrome.com'},
- })],
- actions: [new chrome.declarativeContent.ShowPageAction()]
- }]);
- });
-});
diff --git a/chrome/common/extensions/docs/examples/tutorials/broken_background_color/images/get_started128.png b/chrome/common/extensions/docs/examples/tutorials/broken_background_color/images/get_started128.png
deleted file mode 100644
index 4c1cf87..0000000
--- a/chrome/common/extensions/docs/examples/tutorials/broken_background_color/images/get_started128.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/tutorials/broken_background_color/images/get_started16.png b/chrome/common/extensions/docs/examples/tutorials/broken_background_color/images/get_started16.png
deleted file mode 100644
index fb8531c..0000000
--- a/chrome/common/extensions/docs/examples/tutorials/broken_background_color/images/get_started16.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/tutorials/broken_background_color/images/get_started32.png b/chrome/common/extensions/docs/examples/tutorials/broken_background_color/images/get_started32.png
deleted file mode 100644
index 7715223..0000000
--- a/chrome/common/extensions/docs/examples/tutorials/broken_background_color/images/get_started32.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/tutorials/broken_background_color/images/get_started48.png b/chrome/common/extensions/docs/examples/tutorials/broken_background_color/images/get_started48.png
deleted file mode 100644
index 94ddde9b..0000000
--- a/chrome/common/extensions/docs/examples/tutorials/broken_background_color/images/get_started48.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/tutorials/broken_background_color/manifest.json b/chrome/common/extensions/docs/examples/tutorials/broken_background_color/manifest.json
deleted file mode 100644
index 8e84613..0000000
--- a/chrome/common/extensions/docs/examples/tutorials/broken_background_color/manifest.json
+++ /dev/null
@@ -1,27 +0,0 @@
-{
- "name": "Broken Background Color",
- "version": "1.0",
- "description": "Fix an Extension!",
- "permissions": ["activeTab", "declarativeContent", "storage"],
- "options_page": "options.html",
- "background": {
- "scripts": ["background.js"],
- "persistent": false
- },
- "page_action": {
- "default_popup": "popup.html",
- "default_icon": {
- "16": "images/get_started16.png",
- "32": "images/get_started32.png",
- "48": "images/get_started48.png",
- "128": "images/get_started128.png"
- }
- },
- "icons": {
- "16": "images/get_started16.png",
- "32": "images/get_started32.png",
- "48": "images/get_started48.png",
- "128": "images/get_started128.png"
- },
- "manifest_version": 2
-}
diff --git a/chrome/common/extensions/docs/examples/tutorials/broken_background_color/options.html b/chrome/common/extensions/docs/examples/tutorials/broken_background_color/options.html
deleted file mode 100644
index b46772d..0000000
--- a/chrome/common/extensions/docs/examples/tutorials/broken_background_color/options.html
+++ /dev/null
@@ -1,21 +0,0 @@
-<!DOCTYPE html>
-<html>
- <head>
- <style>
- button {
- height: 30px;
- width: 30px;
- outline: none;
- margin: 10px;
- }
- </style>
- </head>
- <body>
- <div id="buttonDiv">
- </div>
- <div>
- <p>Choose a different background color!</p>
- </div>
- </body>
- <script src="options.js"></script>
-</html>
diff --git a/chrome/common/extensions/docs/examples/tutorials/broken_background_color/options.js b/chrome/common/extensions/docs/examples/tutorials/broken_background_color/options.js
deleted file mode 100644
index 94f8e545b..0000000
--- a/chrome/common/extensions/docs/examples/tutorials/broken_background_color/options.js
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2018 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.
-
-'use strict';
-
-let page = document.getElementById('buttonDiv');
-const kButtonColors = ['#3aa757', '#e8453c', '#f9bb2d', '#4688f1'];
-function constructOptions(kButtonColors) {
- for (let item of kButtonColors) {
- let button = document.createElement('button');
- button.style.backgroundColor = item;
- button.addEventListener('click', function() {
- chrome.storage.sync.set({color: item}, function() {
- console.log('color is ' + item);
- })
- });
- page.appendChild(button);
- }
-}
-constructOptions(kButtonColors);
diff --git a/chrome/common/extensions/docs/examples/tutorials/broken_background_color/popup.html b/chrome/common/extensions/docs/examples/tutorials/broken_background_color/popup.html
deleted file mode 100644
index 77247ec2..0000000
--- a/chrome/common/extensions/docs/examples/tutorials/broken_background_color/popup.html
+++ /dev/null
@@ -1,17 +0,0 @@
-<!DOCTYPE html>
-<html>
- <head>
- <style>
- button {
- height: 30px;
- width: 30px;
- outline: none;
- background-color: #3aa757;
- }
- </style>
- </head>
- <body>
- <button id="changeColor"></button>
- <script src="popup.js"></script>
- </body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/tutorials/broken_background_color/popup.js b/chrome/common/extensions/docs/examples/tutorials/broken_background_color/popup.js
deleted file mode 100644
index baec3802..0000000
--- a/chrome/common/extensions/docs/examples/tutorials/broken_background_color/popup.js
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2018 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.
-
-'use strict';
-
-let changeColor = document.getElementById('changeColor');
-
-chrome.storage.sync.get('color', function(data) {
- changeColor.style.backgroundColor = data.color;
- changeColor.setAttribute('value', data.color);
-});
-
-changeColor.onclick = function(element) {
- let color = element.target.value;
- // The extension must query the active tab
- // before it can injected a content script
- chrome.tabs.executeScript(
- tabs[0].id,
- // Scripts injected with tabs.executeScript() will not have access to
- // variables from this context, leaving |color| undefined.
- {code: 'document.body.style.backgroundColor = color;'});
-};
diff --git a/chrome/common/extensions/docs/examples/tutorials/get_started/background.js b/chrome/common/extensions/docs/examples/tutorials/get_started/background.js
deleted file mode 100644
index 0dc66a6..0000000
--- a/chrome/common/extensions/docs/examples/tutorials/get_started/background.js
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2018 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.
-
-'use strict';
-
-chrome.runtime.onInstalled.addListener(function() {
- chrome.storage.sync.set({color: '#3aa757'}, function() {
- console.log("The color is green.");
- });
-});
diff --git a/chrome/common/extensions/docs/examples/tutorials/get_started/images.zip b/chrome/common/extensions/docs/examples/tutorials/get_started/images.zip
deleted file mode 100644
index 3a18b55..0000000
--- a/chrome/common/extensions/docs/examples/tutorials/get_started/images.zip
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/tutorials/get_started/images/get_started128.png b/chrome/common/extensions/docs/examples/tutorials/get_started/images/get_started128.png
deleted file mode 100644
index 4c1cf87..0000000
--- a/chrome/common/extensions/docs/examples/tutorials/get_started/images/get_started128.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/tutorials/get_started/images/get_started16.png b/chrome/common/extensions/docs/examples/tutorials/get_started/images/get_started16.png
deleted file mode 100644
index fb8531c..0000000
--- a/chrome/common/extensions/docs/examples/tutorials/get_started/images/get_started16.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/tutorials/get_started/images/get_started32.png b/chrome/common/extensions/docs/examples/tutorials/get_started/images/get_started32.png
deleted file mode 100644
index 7715223..0000000
--- a/chrome/common/extensions/docs/examples/tutorials/get_started/images/get_started32.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/tutorials/get_started/images/get_started48.png b/chrome/common/extensions/docs/examples/tutorials/get_started/images/get_started48.png
deleted file mode 100644
index 94ddde9b..0000000
--- a/chrome/common/extensions/docs/examples/tutorials/get_started/images/get_started48.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/tutorials/get_started/manifest.json b/chrome/common/extensions/docs/examples/tutorials/get_started/manifest.json
deleted file mode 100644
index b9ff56c22..0000000
--- a/chrome/common/extensions/docs/examples/tutorials/get_started/manifest.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "name": "Getting Started Example",
- "version": "1.0",
- "description": "Build an Extension!",
- "manifest_version": 2
-}
diff --git a/chrome/common/extensions/docs/examples/tutorials/get_started/options.html b/chrome/common/extensions/docs/examples/tutorials/get_started/options.html
deleted file mode 100644
index 1b28273..0000000
--- a/chrome/common/extensions/docs/examples/tutorials/get_started/options.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE html>
-<html>
- <head>
- <style>
- button {
- height: 30px;
- width: 30px;
- outline: none;
- margin: 10px;
- }
- </style>
- </head>
- <body>
- <div id="buttonDiv">
- </div>
- </body>
- <script src="options.js"></script>
-</html>
diff --git a/chrome/common/extensions/docs/examples/tutorials/get_started/options.js b/chrome/common/extensions/docs/examples/tutorials/get_started/options.js
deleted file mode 100644
index 94f8e545b..0000000
--- a/chrome/common/extensions/docs/examples/tutorials/get_started/options.js
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2018 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.
-
-'use strict';
-
-let page = document.getElementById('buttonDiv');
-const kButtonColors = ['#3aa757', '#e8453c', '#f9bb2d', '#4688f1'];
-function constructOptions(kButtonColors) {
- for (let item of kButtonColors) {
- let button = document.createElement('button');
- button.style.backgroundColor = item;
- button.addEventListener('click', function() {
- chrome.storage.sync.set({color: item}, function() {
- console.log('color is ' + item);
- })
- });
- page.appendChild(button);
- }
-}
-constructOptions(kButtonColors);
diff --git a/chrome/common/extensions/docs/examples/tutorials/get_started/popup.html b/chrome/common/extensions/docs/examples/tutorials/get_started/popup.html
deleted file mode 100644
index f857131..0000000
--- a/chrome/common/extensions/docs/examples/tutorials/get_started/popup.html
+++ /dev/null
@@ -1,16 +0,0 @@
-<!DOCTYPE html>
-<html>
- <head>
- <style>
- button {
- height: 30px;
- width: 30px;
- outline: none;
- }
- </style>
- </head>
- <body>
- <button id="changeColor"></button>
- <script src="popup.js"></script>
- </body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/tutorials/get_started/popup.js b/chrome/common/extensions/docs/examples/tutorials/get_started/popup.js
deleted file mode 100644
index abe2aad1..0000000
--- a/chrome/common/extensions/docs/examples/tutorials/get_started/popup.js
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2018 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.
-
-'use strict';
-
-let changeColor = document.getElementById('changeColor');
-chrome.storage.sync.get('color', function(data) {
- changeColor.style.backgroundColor = data.color;
- changeColor.setAttribute('value', data.color);
-});
diff --git a/chrome/common/extensions/docs/examples/tutorials/get_started_complete.zip b/chrome/common/extensions/docs/examples/tutorials/get_started_complete.zip
deleted file mode 100644
index f075650..0000000
--- a/chrome/common/extensions/docs/examples/tutorials/get_started_complete.zip
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/tutorials/get_started_complete/background.js b/chrome/common/extensions/docs/examples/tutorials/get_started_complete/background.js
deleted file mode 100644
index ddc4cfd8..0000000
--- a/chrome/common/extensions/docs/examples/tutorials/get_started_complete/background.js
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2018 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.
-
-'use strict';
-
-chrome.runtime.onInstalled.addListener(function() {
- chrome.storage.sync.set({color: '#3aa757'}, function() {
- console.log('The color is green.');
- });
- chrome.declarativeContent.onPageChanged.removeRules(undefined, function() {
- chrome.declarativeContent.onPageChanged.addRules([{
- conditions: [new chrome.declarativeContent.PageStateMatcher({
- pageUrl: {hostEquals: 'developer.chrome.com'},
- })],
- actions: [new chrome.declarativeContent.ShowPageAction()]
- }]);
- });
-});
diff --git a/chrome/common/extensions/docs/examples/tutorials/get_started_complete/images/get_started128.png b/chrome/common/extensions/docs/examples/tutorials/get_started_complete/images/get_started128.png
deleted file mode 100644
index 4c1cf87..0000000
--- a/chrome/common/extensions/docs/examples/tutorials/get_started_complete/images/get_started128.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/tutorials/get_started_complete/images/get_started16.png b/chrome/common/extensions/docs/examples/tutorials/get_started_complete/images/get_started16.png
deleted file mode 100644
index fb8531c..0000000
--- a/chrome/common/extensions/docs/examples/tutorials/get_started_complete/images/get_started16.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/tutorials/get_started_complete/images/get_started32.png b/chrome/common/extensions/docs/examples/tutorials/get_started_complete/images/get_started32.png
deleted file mode 100644
index 7715223..0000000
--- a/chrome/common/extensions/docs/examples/tutorials/get_started_complete/images/get_started32.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/tutorials/get_started_complete/images/get_started48.png b/chrome/common/extensions/docs/examples/tutorials/get_started_complete/images/get_started48.png
deleted file mode 100644
index 94ddde9b..0000000
--- a/chrome/common/extensions/docs/examples/tutorials/get_started_complete/images/get_started48.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/tutorials/get_started_complete/manifest.json b/chrome/common/extensions/docs/examples/tutorials/get_started_complete/manifest.json
deleted file mode 100644
index 71290e77..0000000
--- a/chrome/common/extensions/docs/examples/tutorials/get_started_complete/manifest.json
+++ /dev/null
@@ -1,27 +0,0 @@
-{
- "name": "Getting Started Example",
- "version": "1.0",
- "description": "Build an Extension!",
- "permissions": ["activeTab", "declarativeContent", "storage"],
- "options_page": "options.html",
- "background": {
- "scripts": ["background.js"],
- "persistent": false
- },
- "page_action": {
- "default_popup": "popup.html",
- "default_icon": {
- "16": "images/get_started16.png",
- "32": "images/get_started32.png",
- "48": "images/get_started48.png",
- "128": "images/get_started128.png"
- }
- },
- "icons": {
- "16": "images/get_started16.png",
- "32": "images/get_started32.png",
- "48": "images/get_started48.png",
- "128": "images/get_started128.png"
- },
- "manifest_version": 2
-}
diff --git a/chrome/common/extensions/docs/examples/tutorials/get_started_complete/options.html b/chrome/common/extensions/docs/examples/tutorials/get_started_complete/options.html
deleted file mode 100644
index b46772d..0000000
--- a/chrome/common/extensions/docs/examples/tutorials/get_started_complete/options.html
+++ /dev/null
@@ -1,21 +0,0 @@
-<!DOCTYPE html>
-<html>
- <head>
- <style>
- button {
- height: 30px;
- width: 30px;
- outline: none;
- margin: 10px;
- }
- </style>
- </head>
- <body>
- <div id="buttonDiv">
- </div>
- <div>
- <p>Choose a different background color!</p>
- </div>
- </body>
- <script src="options.js"></script>
-</html>
diff --git a/chrome/common/extensions/docs/examples/tutorials/get_started_complete/options.js b/chrome/common/extensions/docs/examples/tutorials/get_started_complete/options.js
deleted file mode 100644
index 94f8e545b..0000000
--- a/chrome/common/extensions/docs/examples/tutorials/get_started_complete/options.js
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2018 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.
-
-'use strict';
-
-let page = document.getElementById('buttonDiv');
-const kButtonColors = ['#3aa757', '#e8453c', '#f9bb2d', '#4688f1'];
-function constructOptions(kButtonColors) {
- for (let item of kButtonColors) {
- let button = document.createElement('button');
- button.style.backgroundColor = item;
- button.addEventListener('click', function() {
- chrome.storage.sync.set({color: item}, function() {
- console.log('color is ' + item);
- })
- });
- page.appendChild(button);
- }
-}
-constructOptions(kButtonColors);
diff --git a/chrome/common/extensions/docs/examples/tutorials/get_started_complete/popup.html b/chrome/common/extensions/docs/examples/tutorials/get_started_complete/popup.html
deleted file mode 100644
index f857131..0000000
--- a/chrome/common/extensions/docs/examples/tutorials/get_started_complete/popup.html
+++ /dev/null
@@ -1,16 +0,0 @@
-<!DOCTYPE html>
-<html>
- <head>
- <style>
- button {
- height: 30px;
- width: 30px;
- outline: none;
- }
- </style>
- </head>
- <body>
- <button id="changeColor"></button>
- <script src="popup.js"></script>
- </body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/tutorials/get_started_complete/popup.js b/chrome/common/extensions/docs/examples/tutorials/get_started_complete/popup.js
deleted file mode 100644
index ea9b26f..0000000
--- a/chrome/common/extensions/docs/examples/tutorials/get_started_complete/popup.js
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2018 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.
-
-'use strict';
-
-let changeColor = document.getElementById('changeColor');
-
-chrome.storage.sync.get('color', function(data) {
- changeColor.style.backgroundColor = data.color;
- changeColor.setAttribute('value', data.color);
-});
-
-changeColor.onclick = function(element) {
- let color = element.target.value;
- chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
- chrome.tabs.executeScript(
- tabs[0].id,
- {code: 'document.body.style.backgroundColor = "' + color + '";'});
- });
-};
diff --git a/chrome/common/extensions/docs/examples/tutorials/getstarted/icon.png b/chrome/common/extensions/docs/examples/tutorials/getstarted/icon.png
deleted file mode 100644
index d86677db..0000000
--- a/chrome/common/extensions/docs/examples/tutorials/getstarted/icon.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/tutorials/getstarted/manifest.json b/chrome/common/extensions/docs/examples/tutorials/getstarted/manifest.json
deleted file mode 100644
index 28a1fda3..0000000
--- a/chrome/common/extensions/docs/examples/tutorials/getstarted/manifest.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
- "manifest_version": 2,
-
- "name": "Getting started example",
- "description": "This extension allows the user to change the background color of the current page.",
- "version": "1.0",
-
- "browser_action": {
- "default_icon": "icon.png",
- "default_popup": "popup.html"
- },
- "permissions": [
- "activeTab",
- "storage"
- ]
-}
diff --git a/chrome/common/extensions/docs/examples/tutorials/getstarted/popup.html b/chrome/common/extensions/docs/examples/tutorials/getstarted/popup.html
deleted file mode 100644
index 1a96b226..0000000
--- a/chrome/common/extensions/docs/examples/tutorials/getstarted/popup.html
+++ /dev/null
@@ -1,49 +0,0 @@
-<!doctype html>
-<!--
- This page is shown when the extension button is clicked, because the
- "browser_action" field in manifest.json contains the "default_popup" key with
- value "popup.html".
- -->
-<html>
- <head>
- <title>Getting Started Extension's Popup</title>
- <style type="text/css">
- body {
- margin: 10px;
- white-space: nowrap;
- }
-
- h1 {
- font-size: 15px;
- }
-
- #container {
- align-items: center;
- display: flex;
- justify-content: space-between;
- }
- </style>
-
- <!--
- - JavaScript and HTML must be in separate files: see our Content Security
- - Policy documentation[1] for details and explanation.
- -
- - [1]: https://developer.chrome.com/extensions/contentSecurityPolicy
- -->
- <script src="popup.js"></script>
- </head>
-
- <body>
- <h1>Background Color Changer</h1>
- <div id="container">
- <span>Choose a color</span>
- <select id="dropdown">
- <option selected disabled hidden value=''></option>
- <option value="white">White</option>
- <option value="pink">Pink</option>
- <option value="green">Green</option>
- <option value="yellow">Yellow</option>
- </select>
- </div>
- </body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/tutorials/getstarted/popup.js b/chrome/common/extensions/docs/examples/tutorials/getstarted/popup.js
deleted file mode 100644
index 30ea3f55..0000000
--- a/chrome/common/extensions/docs/examples/tutorials/getstarted/popup.js
+++ /dev/null
@@ -1,126 +0,0 @@
-// Copyright (c) 2014 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.
-
-/**
- * Get the current URL.
- *
- * @param {function(string)} callback called when the URL of the current tab
- * is found.
- */
-function getCurrentTabUrl(callback) {
- // Query filter to be passed to chrome.tabs.query - see
- // https://developer.chrome.com/extensions/tabs#method-query
- var queryInfo = {
- active: true,
- currentWindow: true
- };
-
- chrome.tabs.query(queryInfo, (tabs) => {
- // chrome.tabs.query invokes the callback with a list of tabs that match the
- // query. When the popup is opened, there is certainly a window and at least
- // one tab, so we can safely assume that |tabs| is a non-empty array.
- // A window can only have one active tab at a time, so the array consists of
- // exactly one tab.
- var tab = tabs[0];
-
- // A tab is a plain object that provides information about the tab.
- // See https://developer.chrome.com/extensions/tabs#type-Tab
- var url = tab.url;
-
- // tab.url is only available if the "activeTab" permission is declared.
- // If you want to see the URL of other tabs (e.g. after removing active:true
- // from |queryInfo|), then the "tabs" permission is required to see their
- // "url" properties.
- console.assert(typeof url == 'string', 'tab.url should be a string');
-
- callback(url);
- });
-
- // Most methods of the Chrome extension APIs are asynchronous. This means that
- // you CANNOT do something like this:
- //
- // var url;
- // chrome.tabs.query(queryInfo, (tabs) => {
- // url = tabs[0].url;
- // });
- // alert(url); // Shows "undefined", because chrome.tabs.query is async.
-}
-
-/**
- * Change the background color of the current page.
- *
- * @param {string} color The new background color.
- */
-function changeBackgroundColor(color) {
- var script = 'document.body.style.backgroundColor="' + color + '";';
- // See https://developer.chrome.com/extensions/tabs#method-executeScript.
- // chrome.tabs.executeScript allows us to programmatically inject JavaScript
- // into a page. Since we omit the optional first argument "tabId", the script
- // is inserted into the active tab of the current window, which serves as the
- // default.
- chrome.tabs.executeScript({
- code: script
- });
-}
-
-/**
- * Gets the saved background color for url.
- *
- * @param {string} url URL whose background color is to be retrieved.
- * @param {function(string)} callback called with the saved background color for
- * the given url on success, or a falsy value if no color is retrieved.
- */
-function getSavedBackgroundColor(url, callback) {
- // See https://developer.chrome.com/apps/storage#type-StorageArea. We check
- // for chrome.runtime.lastError to ensure correctness even when the API call
- // fails.
- chrome.storage.sync.get(url, (items) => {
- callback(chrome.runtime.lastError ? null : items[url]);
- });
-}
-
-/**
- * Sets the given background color for url.
- *
- * @param {string} url URL for which background color is to be saved.
- * @param {string} color The background color to be saved.
- */
-function saveBackgroundColor(url, color) {
- var items = {};
- items[url] = color;
- // See https://developer.chrome.com/apps/storage#type-StorageArea. We omit the
- // optional callback since we don't need to perform any action once the
- // background color is saved.
- chrome.storage.sync.set(items);
-}
-
-// This extension loads the saved background color for the current tab if one
-// exists. The user can select a new background color from the dropdown for the
-// current page, and it will be saved as part of the extension's isolated
-// storage. The chrome.storage API is used for this purpose. This is different
-// from the window.localStorage API, which is synchronous and stores data bound
-// to a document's origin. Also, using chrome.storage.sync instead of
-// chrome.storage.local allows the extension data to be synced across multiple
-// user devices.
-document.addEventListener('DOMContentLoaded', () => {
- getCurrentTabUrl((url) => {
- var dropdown = document.getElementById('dropdown');
-
- // Load the saved background color for this page and modify the dropdown
- // value, if needed.
- getSavedBackgroundColor(url, (savedColor) => {
- if (savedColor) {
- changeBackgroundColor(savedColor);
- dropdown.value = savedColor;
- }
- });
-
- // Ensure the background color is changed and saved when the dropdown
- // selection changes.
- dropdown.addEventListener('change', () => {
- changeBackgroundColor(dropdown.value);
- saveBackgroundColor(url, dropdown.value);
- });
- });
-});
diff --git a/chrome/common/extensions/docs/examples/tutorials/hello_extensions/hello.html b/chrome/common/extensions/docs/examples/tutorials/hello_extensions/hello.html
deleted file mode 100644
index c717ab4..0000000
--- a/chrome/common/extensions/docs/examples/tutorials/hello_extensions/hello.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<!DOCTYPE html>
-<html>
- <head>
- <title> Hello Extensions </title>
- </head>
-
- <body>
- <h1>Hello Extensions</h1>
- </body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/tutorials/hello_extensions/hello_extensions.png b/chrome/common/extensions/docs/examples/tutorials/hello_extensions/hello_extensions.png
deleted file mode 100644
index 63ea0d20..0000000
--- a/chrome/common/extensions/docs/examples/tutorials/hello_extensions/hello_extensions.png
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/tutorials/hello_extensions/manifest.json b/chrome/common/extensions/docs/examples/tutorials/hello_extensions/manifest.json
deleted file mode 100644
index d21bdaa..0000000
--- a/chrome/common/extensions/docs/examples/tutorials/hello_extensions/manifest.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- "name": "Hello Extensions",
- "description" : "Base Level Extension",
- "version": "1.0",
- "browser_action": {
- "default_popup": "hello.html",
- "default_icon": "hello_extensions.png"
- },
- "manifest_version": 2,
- "commands": {
- "_execute_browser_action": {
- "suggested_key": {
- "default": "Ctrl+Shift+F",
- "mac": "MacCtrl+Shift+F"
- },
- "description": "Opens hello.html"
- }
- }
-}
diff --git a/chrome/common/extensions/docs/examples/tutorials/oauth_starter/background.js b/chrome/common/extensions/docs/examples/tutorials/oauth_starter/background.js
deleted file mode 100644
index dd2c417..0000000
--- a/chrome/common/extensions/docs/examples/tutorials/oauth_starter/background.js
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright 2018 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.
-
-'use strict';
-
-chrome.browserAction.onClicked.addListener(function() {
- chrome.tabs.create({url: 'index.html'});
-});
diff --git a/chrome/common/extensions/docs/examples/tutorials/oauth_starter/index.html b/chrome/common/extensions/docs/examples/tutorials/oauth_starter/index.html
deleted file mode 100644
index a254f12..0000000
--- a/chrome/common/extensions/docs/examples/tutorials/oauth_starter/index.html
+++ /dev/null
@@ -1,20 +0,0 @@
-<!-- Copyright 2018 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>
- <title>FriendBlock</title>
- <style>
- button {
- padding: 10px;
- background-color: #3C79F8;
- display: inline-block;
- }
- </style>
- </head>
- <body>
- <button>FriendBlock Contacts</button>
- <div id="friendDiv"></div>
- </body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/tutorials/oauth_starter/manifest.json b/chrome/common/extensions/docs/examples/tutorials/oauth_starter/manifest.json
deleted file mode 100644
index 1035894..0000000
--- a/chrome/common/extensions/docs/examples/tutorials/oauth_starter/manifest.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "name": "OAuth Tutorial FriendBlock",
- "version": "1.0",
- "description": "Uses OAuth to connect to Google's People API and display contacts photos.",
- "manifest_version": 2,
- "browser_action": {
- "default_title": "FriendBlock, friends face's in a block."
- },
- "background": {
- "scripts": [
- "background.js"
- ],
- "persistent": false
- }
- }
diff --git a/chrome/common/extensions/docs/examples/tutorials/oauth_starter/oauth.js b/chrome/common/extensions/docs/examples/tutorials/oauth_starter/oauth.js
deleted file mode 100644
index 73e23976..0000000
--- a/chrome/common/extensions/docs/examples/tutorials/oauth_starter/oauth.js
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2018 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.
-
-'use strict';
-
-window.onload = function() {
- document.querySelector('button').addEventListener('click', function() {
- chrome.identity.getAuthToken({interactive: true}, function(token) {
- console.log(token);
- });
- });
-};
diff --git a/chrome/common/extensions/docs/examples/tutorials/oauth_tutorial_complete.zip b/chrome/common/extensions/docs/examples/tutorials/oauth_tutorial_complete.zip
deleted file mode 100644
index 72a3843..0000000
--- a/chrome/common/extensions/docs/examples/tutorials/oauth_tutorial_complete.zip
+++ /dev/null
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/tutorials/oauth_tutorial_complete/background.js b/chrome/common/extensions/docs/examples/tutorials/oauth_tutorial_complete/background.js
deleted file mode 100644
index dd2c417..0000000
--- a/chrome/common/extensions/docs/examples/tutorials/oauth_tutorial_complete/background.js
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright 2018 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.
-
-'use strict';
-
-chrome.browserAction.onClicked.addListener(function() {
- chrome.tabs.create({url: 'index.html'});
-});
diff --git a/chrome/common/extensions/docs/examples/tutorials/oauth_tutorial_complete/index.html b/chrome/common/extensions/docs/examples/tutorials/oauth_tutorial_complete/index.html
deleted file mode 100644
index bf79418..0000000
--- a/chrome/common/extensions/docs/examples/tutorials/oauth_tutorial_complete/index.html
+++ /dev/null
@@ -1,17 +0,0 @@
-<html>
- <head>
- <title>FriendBlock</title>
- <style>
- button {
- padding: 10px;
- background-color: #3C79F8;
- display: inline-block;
- }
- </style>
- <script type="text/javascript" src="oauth.js"></script>
- </head>
- <body>
- <button>FriendBlock Contacts</button>
- <div id="friendDiv"></div>
- </body>
- </html>
diff --git a/chrome/common/extensions/docs/examples/tutorials/oauth_tutorial_complete/manifest.json b/chrome/common/extensions/docs/examples/tutorials/oauth_tutorial_complete/manifest.json
deleted file mode 100644
index 5afe50be..0000000
--- a/chrome/common/extensions/docs/examples/tutorials/oauth_tutorial_complete/manifest.json
+++ /dev/null
@@ -1,23 +0,0 @@
-{
- "name": "OAuth Tutorial FriendBlock",
- "version": "1.0",
- "description": "Uses OAuth to connect to Google's People API and display contacts photos.",
- "manifest_version": 2,
- "browser_action": {
- "default_title": "FriendBlock, friends face's in a block."
- },
- "permissions": [
- "identity"
- ],
- "background": {
- "scripts": [
- "background.js"
- ],
- "persistent": false
- },
- "oauth2": {
- "client_id": "ClientIDFromGoogleAPIConsole",
- "scopes":["https://www.googleapis.com/auth/contacts.readonly"]
- },
- "key": "KeyFromDeveloperDashboardHere"
-}
diff --git a/chrome/common/extensions/docs/examples/tutorials/oauth_tutorial_complete/oauth.js b/chrome/common/extensions/docs/examples/tutorials/oauth_tutorial_complete/oauth.js
deleted file mode 100644
index f59da65..0000000
--- a/chrome/common/extensions/docs/examples/tutorials/oauth_tutorial_complete/oauth.js
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2018 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.
-
-'use strict';
-
-window.onload = function() {
- document.querySelector('button').addEventListener('click', function() {
- chrome.identity.getAuthToken({interactive: true}, function(token) {
- var init = {
- method: 'GET',
- async: true,
- headers: {
- Authorization: 'Bearer ' + token,
- 'Content-Type': 'application/json'
- },
- 'contentType': 'json'
- };
- fetch(
- 'https://people.googleapis.com/v1/contactGroups/all?maxMembers=20&key=<API_Key_Here>',
- init)
- .then((response) => response.json())
- .then(function(data) {
- let photoDiv = document.querySelector('#friendDiv');
- let returnedContacts = data.memberResourceNames;
- for (var i = 0; i < returnedContacts.length; i++) {
- fetch(
- 'https://people.googleapis.com/v1/' + returnedContacts[i] +
- '?personFields=photos&key=<API_Key_Here>',
- init)
- .then((response) => response.json())
- .then(function(data) {
- let profileImg = document.createElement('img');
- profileImg.src = data.photos[0].url;
- photoDiv.appendChild(profileImg);
- });
- };
- });
- });
- });
-};
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index 2eb571f..d1e3df2 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -911,7 +911,6 @@
data = [
"data/",
"//chrome/browser/page_load_metrics/integration_tests/data/",
- "//chrome/common/extensions/docs/examples/apps/calculator/",
"//components/test/data/arc/",
"//components/test/data/autofill/",
"//components/test/data/payments/",
@@ -2016,6 +2015,7 @@
"../browser/extensions/background_page_apitest.cc",
"../browser/extensions/background_scripts_apitest.cc",
"../browser/extensions/background_xhr_browsertest.cc",
+ "../browser/extensions/calculator_app_browsertest.cc",
"../browser/extensions/chrome_app_api_browsertest.cc",
"../browser/extensions/chrome_test_extension_loader_browsertest.cc",
"../browser/extensions/chrome_theme_url_browsertest.cc",
@@ -2029,7 +2029,6 @@
"../browser/extensions/corb_and_cors_extension_browsertest.cc",
"../browser/extensions/cross_origin_xhr_apitest.cc",
"../browser/extensions/crx_installer_browsertest.cc",
- "../browser/extensions/docs/examples/apps/calculator_browsertest.cc",
"../browser/extensions/error_console/error_console_browsertest.cc",
"../browser/extensions/events_apitest.cc",
"../browser/extensions/execute_script_apitest.cc",
diff --git a/chrome/common/extensions/docs/examples/apps/calculator/app/LICENSE b/chrome/test/data/extensions/calculator_app/LICENSE
similarity index 100%
rename from chrome/common/extensions/docs/examples/apps/calculator/app/LICENSE
rename to chrome/test/data/extensions/calculator_app/LICENSE
diff --git a/chrome/common/extensions/docs/examples/apps/calculator/OWNERS b/chrome/test/data/extensions/calculator_app/OWNERS
similarity index 100%
rename from chrome/common/extensions/docs/examples/apps/calculator/OWNERS
rename to chrome/test/data/extensions/calculator_app/OWNERS
diff --git a/chrome/common/extensions/docs/examples/apps/calculator/README.md b/chrome/test/data/extensions/calculator_app/README.md
similarity index 100%
rename from chrome/common/extensions/docs/examples/apps/calculator/README.md
rename to chrome/test/data/extensions/calculator_app/README.md
diff --git a/chrome/common/extensions/docs/examples/apps/calculator/app/LICENSE b/chrome/test/data/extensions/calculator_app/app/LICENSE
similarity index 100%
copy from chrome/common/extensions/docs/examples/apps/calculator/app/LICENSE
copy to chrome/test/data/extensions/calculator_app/app/LICENSE
diff --git a/chrome/common/extensions/docs/examples/apps/calculator/app/calculator.html b/chrome/test/data/extensions/calculator_app/app/calculator.html
similarity index 100%
rename from chrome/common/extensions/docs/examples/apps/calculator/app/calculator.html
rename to chrome/test/data/extensions/calculator_app/app/calculator.html
diff --git a/chrome/common/extensions/docs/examples/apps/calculator/app/controller.js b/chrome/test/data/extensions/calculator_app/app/controller.js
similarity index 100%
rename from chrome/common/extensions/docs/examples/apps/calculator/app/controller.js
rename to chrome/test/data/extensions/calculator_app/app/controller.js
diff --git a/chrome/common/extensions/docs/examples/apps/calculator/app/images/buttons_1x.png b/chrome/test/data/extensions/calculator_app/app/images/buttons_1x.png
similarity index 100%
rename from chrome/common/extensions/docs/examples/apps/calculator/app/images/buttons_1x.png
rename to chrome/test/data/extensions/calculator_app/app/images/buttons_1x.png
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/apps/calculator/app/images/buttons_2x.png b/chrome/test/data/extensions/calculator_app/app/images/buttons_2x.png
similarity index 100%
rename from chrome/common/extensions/docs/examples/apps/calculator/app/images/buttons_2x.png
rename to chrome/test/data/extensions/calculator_app/app/images/buttons_2x.png
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/apps/calculator/app/images/icon-128x128.png b/chrome/test/data/extensions/calculator_app/app/images/icon-128x128.png
similarity index 100%
rename from chrome/common/extensions/docs/examples/apps/calculator/app/images/icon-128x128.png
rename to chrome/test/data/extensions/calculator_app/app/images/icon-128x128.png
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/apps/calculator/app/images/icon-16x16.png b/chrome/test/data/extensions/calculator_app/app/images/icon-16x16.png
similarity index 100%
rename from chrome/common/extensions/docs/examples/apps/calculator/app/images/icon-16x16.png
rename to chrome/test/data/extensions/calculator_app/app/images/icon-16x16.png
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/apps/calculator/app/manifest.json b/chrome/test/data/extensions/calculator_app/app/manifest.json
similarity index 100%
rename from chrome/common/extensions/docs/examples/apps/calculator/app/manifest.json
rename to chrome/test/data/extensions/calculator_app/app/manifest.json
diff --git a/chrome/common/extensions/docs/examples/apps/calculator/app/model.js b/chrome/test/data/extensions/calculator_app/app/model.js
similarity index 100%
rename from chrome/common/extensions/docs/examples/apps/calculator/app/model.js
rename to chrome/test/data/extensions/calculator_app/app/model.js
diff --git a/chrome/common/extensions/docs/examples/apps/calculator/app/style.css b/chrome/test/data/extensions/calculator_app/app/style.css
similarity index 100%
rename from chrome/common/extensions/docs/examples/apps/calculator/app/style.css
rename to chrome/test/data/extensions/calculator_app/app/style.css
diff --git a/chrome/common/extensions/docs/examples/apps/calculator/app/view.js b/chrome/test/data/extensions/calculator_app/app/view.js
similarity index 100%
rename from chrome/common/extensions/docs/examples/apps/calculator/app/view.js
rename to chrome/test/data/extensions/calculator_app/app/view.js
diff --git a/chrome/common/extensions/docs/examples/apps/calculator/assets/440-280-tile.png b/chrome/test/data/extensions/calculator_app/assets/440-280-tile.png
similarity index 100%
rename from chrome/common/extensions/docs/examples/apps/calculator/assets/440-280-tile.png
rename to chrome/test/data/extensions/calculator_app/assets/440-280-tile.png
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/apps/calculator/assets/promo.png b/chrome/test/data/extensions/calculator_app/assets/promo.png
similarity index 100%
rename from chrome/common/extensions/docs/examples/apps/calculator/assets/promo.png
rename to chrome/test/data/extensions/calculator_app/assets/promo.png
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/apps/calculator/tests/automatic.html b/chrome/test/data/extensions/calculator_app/tests/automatic.html
similarity index 100%
rename from chrome/common/extensions/docs/examples/apps/calculator/tests/automatic.html
rename to chrome/test/data/extensions/calculator_app/tests/automatic.html
diff --git a/chrome/common/extensions/docs/examples/apps/calculator/tests/manual.css b/chrome/test/data/extensions/calculator_app/tests/manual.css
similarity index 100%
rename from chrome/common/extensions/docs/examples/apps/calculator/tests/manual.css
rename to chrome/test/data/extensions/calculator_app/tests/manual.css
diff --git a/chrome/common/extensions/docs/examples/apps/calculator/tests/manual.html b/chrome/test/data/extensions/calculator_app/tests/manual.html
similarity index 100%
rename from chrome/common/extensions/docs/examples/apps/calculator/tests/manual.html
rename to chrome/test/data/extensions/calculator_app/tests/manual.html
diff --git a/chrome/common/extensions/docs/examples/apps/calculator/tests/manual.js b/chrome/test/data/extensions/calculator_app/tests/manual.js
similarity index 100%
rename from chrome/common/extensions/docs/examples/apps/calculator/tests/manual.js
rename to chrome/test/data/extensions/calculator_app/tests/manual.js
diff --git a/chrome/common/extensions/docs/examples/apps/calculator/tests/tests.js b/chrome/test/data/extensions/calculator_app/tests/tests.js
similarity index 100%
rename from chrome/common/extensions/docs/examples/apps/calculator/tests/tests.js
rename to chrome/test/data/extensions/calculator_app/tests/tests.js
diff --git a/chrome/common/extensions/docs/examples/apps/calculator/tests/utilities.js b/chrome/test/data/extensions/calculator_app/tests/utilities.js
similarity index 100%
rename from chrome/common/extensions/docs/examples/apps/calculator/tests/utilities.js
rename to chrome/test/data/extensions/calculator_app/tests/utilities.js
diff --git a/extensions/shell/README b/extensions/shell/README
index c080677..ceb4f042 100644
--- a/extensions/shell/README
+++ b/extensions/shell/README
@@ -14,7 +14,7 @@
# For example, you can try the calculator app:
-$ app_shell --load-apps=chrome/common/extensions/docs/examples/apps/calculator/app/
+$ app_shell --load-apps=chrome/test/data/extensions/calculator_app/app/
# To load multiple apps, specify them in a comma separated list. The first app
# will be launched: