diff --git a/.gitignore b/.gitignore index 2752eb9..541931a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ node_modules/ .DS_Store + diff --git a/README.md b/README.md index 6ae83db..2075c1d 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,31 @@ -## better-history [![NPM](https://img.shields.io/npm/v/better-history.svg)](https://www.npmjs.com/package/better-history) [![Chrome Web Store](https://img.shields.io/chrome-web-store/v/mkfgjjeggnmkbobjmelbjhdchcoadnin.svg)](https://chrome.google.com/webstore/detail/advanced-history/mkfgjjeggnmkbobjmelbjhdchcoadnin) [![Stars](https://img.shields.io/github/stars/jiacai2050/better-history.svg)](https://github.com/jiacai2050/better-history/stargazers) +## History Master [![Chrome Web Store](https://img.shields.io/chrome-web-store/v/mkfgjjeggnmkbobjmelbjhdchcoadnin.svg?style=plastic)](https://chrome.google.com/webstore/detail/gooreplacer/mkfgjjeggnmkbobjmelbjhdchcoadnin) [![Mozilla Add-on](https://img.shields.io/amo/v/history-master.svg?style=plastic)](https://addons.mozilla.org/firefox/addon/history-master/) -> 💡 Get a better sense of browsing history via Chrome/Firefox 💡 +> 💡 Visualize browsing history, Discover your unknown habits, downloads supported. -Nowadays everyone surfs the Internet a lot, but I don't think everyone have a clear sense of their browsing habits. +> 🏆 Try to be the best practical history manager ever! -`better-history` comes to the rescue. Chrome and Firefox are supported. Hope you enjoy. 💗 +Open an issue If you have any problems/suggestions. 💗 + +## Install - [Chrome Web Store](https://chrome.google.com/webstore/detail/advanced-history/mkfgjjeggnmkbobjmelbjhdchcoadnin) -- [Mozilla Add-ons](https://addons.mozilla.org/firefox/addon/advanced-history/) +- [Mozilla Add-ons](https://addons.mozilla.org/firefox/addon/history-master/) + +## Screenshots +![activity](screenshots/activity.jpg) +![Page Views](screenshots/pv.png) +![URL Schemes](screenshots/url_scheme.png) ## Development -- [master](https://github.com/jiacai2050/better-history/tree/master) branch used for Node.js +History Master is written in pure JavaScript before v2.0.0, you can check this version at [legacy-js-src](legacy-js-src). + +After v2.0.0, it gets a big rewrite in [ClojureScript](https://github.com/clojure/clojurescript) + [Reagent](https://github.com/reagent-project/reagent) + [Re-frame](https://github.com/Day8/re-frame) + [Ant.design](https://ant.design/),which locates in [cljs-src](cljs-src). + - [extensions](https://github.com/jiacai2050/better-history/tree/extensions) branch used for Firefox/Chrome extensions, thanks to [WebExtensions](https://developer.mozilla.org/Add-ons/WebExtensions) -- Write once, Run All browsers. +- [master](https://github.com/jiacai2050/better-history/tree/master) branch used for Node.js + ## License diff --git a/cljs-src/.gitignore b/cljs-src/.gitignore new file mode 100644 index 0000000..5a0d812 --- /dev/null +++ b/cljs-src/.gitignore @@ -0,0 +1,19 @@ +/classes/ +/lib/ +/node_modules/ +/target/ +resources/release/background/js/ +resources/release/option/js/ +resources/release/content/js/ +resources/dev/background/js/ +resources/dev/option/js/ +resources/dev/content/js/ +*.jar +.lein-deps-sum +.lein-repl-history +.lein-plugins/ +.nrepl-port +.figwheel*.log +pom.xml +*.DS_Store +.cljs_rhino_repl/ \ No newline at end of file diff --git a/cljs-src/externs/chrome.js b/cljs-src/externs/chrome.js new file mode 100644 index 0000000..202bc63 --- /dev/null +++ b/cljs-src/externs/chrome.js @@ -0,0 +1,537 @@ +/* + * Copyright 2013 The Closure Compiler Authors + * + * 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 Definitions for globals in Chrome. This file describes the + * externs API for the chrome.* object when running in a normal browser + * context. For APIs available in Chrome Extensions, see chrome_extensions.js + * in this directory. + * @externs + */ + + +/** + * namespace + * @const + */ +var chrome = {}; + + +/** + * @see http://developer.chrome.com/apps/runtime.html#type-Port + * @constructor + */ +function Port() {} + + +/** @type {string} */ +Port.prototype.name; + + +/** @type {!ChromeEvent} */ +Port.prototype.onDisconnect; + + +/** @type {!ChromeEvent} */ +Port.prototype.onMessage; + + +/** @type {!MessageSender|undefined} */ +Port.prototype.sender; + + +/** + * @param {*} obj Message object. + * @return {undefined} + */ +Port.prototype.postMessage = function(obj) {}; + + +/** @return {undefined} */ +Port.prototype.disconnect = function() {}; + + +/** + * Base event type from which all others inherit. + * + * LISTENER must be a function type that returns void. + * + * @see https://developer.chrome.com/extensions/events.html + * @record + * @template LISTENER + */ +function ChromeBaseEvent() {} + + +/** + * @param {LISTENER} callback + * @return {undefined} + */ +ChromeBaseEvent.prototype.addListener = function(callback) {}; + + +/** + * @param {LISTENER} callback + * @return {undefined} + */ +ChromeBaseEvent.prototype.removeListener = function(callback) {}; + + +/** + * @param {LISTENER} callback + * @return {boolean} + */ +ChromeBaseEvent.prototype.hasListener = function(callback) {}; + + +/** @return {boolean} */ +ChromeBaseEvent.prototype.hasListeners = function() {}; + + +// TODO(bradfordcsmith): Add the addRules, getRules, and removeRules methods? + + +/** + * Event whose listeners take unspecified parameters. + * + * TODO(bradfordcsmith): Definitions using this type are failing to provide + * information about the parameters that will actually be supplied to the + * listener and should be updated to use a more specific event type. + * @see https://developer.chrome.com/extensions/events.html + * @record + * @extends {ChromeBaseEvent} + */ +function ChromeEvent() {} + + +/** + * Event whose listeners take no parameters. + * + * @see https://developer.chrome.com/extensions/events.html + * @record + * @extends {ChromeBaseEvent} + */ +function ChromeVoidEvent() {} + + +/** + * Event whose listeners take a string parameter. + * @record + * @extends {ChromeBaseEvent} + */ +function ChromeStringEvent() {} + + +/** + * Event whose listeners take a boolean parameter. + * @record + * @extends {ChromeBaseEvent} + */ +function ChromeBooleanEvent() {} + + +/** + * Event whose listeners take a number parameter. + * @record + * @extends {ChromeBaseEvent} + */ +function ChromeNumberEvent() {} + + +/** + * Event whose listeners take an Object parameter. + * @record + * @extends {ChromeBaseEvent} + */ +function ChromeObjectEvent() {} + + +/** + * Event whose listeners take a string array parameter. + * @record + * @extends {ChromeBaseEvent)>} + */ +function ChromeStringArrayEvent() {} + + +/** + * Event whose listeners take two strings as parameters. + * @record + * @extends {ChromeBaseEvent} + */ +function ChromeStringStringEvent() {} + + +/** + * @see http://developer.chrome.com/extensions/runtime.html#type-MessageSender + * @constructor + */ +function MessageSender() {} + + +/** @type {!Tab|undefined} */ +MessageSender.prototype.tab; + + +/** @type {number|undefined} */ +MessageSender.prototype.frameId; + + +/** @type {string|undefined} */ +MessageSender.prototype.id; + + +/** @type {string|undefined} */ +MessageSender.prototype.url; + + +/** @type {string|undefined} */ +MessageSender.prototype.tlsChannelId; + + +/** + * @enum {string} + * @see https://developer.chrome.com/extensions/tabs#type-MutedInfoReason + */ +var MutedInfoReason = { + USER: '', + CAPTURE: '', + EXTENSION: '', +}; + + +/** + * @see https://developer.chrome.com/extensions/tabs#type-MutedInfo + * @constructor + */ +var MutedInfo = function() {}; + + +/** @type {boolean} */ +MutedInfo.prototype.muted; + + +/** @type {!MutedInfoReason|string|undefined} */ +MutedInfo.prototype.reason; + + +/** @type {string|undefined} */ +MutedInfo.prototype.extensionId; + + + + +/** + * @see https://developer.chrome.com/extensions/tabs#type-Tab + * @constructor + */ +function Tab() {} + + +// TODO: Make this field optional once dependent projects have been updated. +/** @type {number} */ +Tab.prototype.id; + + +/** @type {number} */ +Tab.prototype.index; + + +/** @type {number} */ +Tab.prototype.windowId; + + +// TODO: Make this field optional once dependent projects have been updated. +/** @type {number} */ +Tab.prototype.openerTabId; + + +/** @type {boolean} */ +Tab.prototype.highlighted; + + +/** @type {boolean} */ +Tab.prototype.active; + + +/** @type {boolean} */ +Tab.prototype.pinned; + + +/** @type {boolean|undefined} */ +Tab.prototype.audible; + + +/** @type {boolean} */ +Tab.prototype.discarded; + + +/** @type {boolean} */ +Tab.prototype.autoDiscardable; + + +/** @type {!MutedInfo|undefined} */ +Tab.prototype.mutedInfo; + + +// TODO: Make this field optional once dependent projects have been updated. +/** @type {string} */ +Tab.prototype.url; + + +// TODO: Make this field optional once dependent projects have been updated. +/** @type {string} */ +Tab.prototype.title; + + +// TODO: Make this field optional once dependent projects have been updated. +/** @type {string} */ +Tab.prototype.favIconUrl; + + +// TODO: Make this field optional once dependent projects have been updated. +/** @type {string} */ +Tab.prototype.status; + + +/** @type {boolean} */ +Tab.prototype.incognito; + + +/** @type {number|undefined} */ +Tab.prototype.width; + + +/** @type {number|undefined} */ +Tab.prototype.height; + + +/** @type {string|undefined} */ +Tab.prototype.sessionId; + + +/** @const */ +chrome.app = {}; + +/** + * @see https://developer.chrome.com/webstore/inline_installation#already-installed + * @type {boolean} + */ +chrome.app.isInstalled; + +/** + * @const + * @see https://developer.chrome.com/apps/webstore + */ +chrome.webstore = {}; + + +/** + * @param {string|function()|function(string, string=)=} + * opt_urlOrSuccessCallbackOrFailureCallback Either the URL to install or + * the succcess callback taking no arg or the failure callback taking an + * error string arg. + * @param {function()|function(string, string=)=} + * opt_successCallbackOrFailureCallback Either the succcess callback taking + * no arg or the failure callback taking an error string arg. + * @param {function(string, string=)=} opt_failureCallback The failure callback. + * @return {undefined} + */ +chrome.webstore.install = function( + opt_urlOrSuccessCallbackOrFailureCallback, + opt_successCallbackOrFailureCallback, + opt_failureCallback) {}; + + +/** @type {!ChromeStringEvent} */ +chrome.webstore.onInstallStageChanged; + + +/** @type {!ChromeNumberEvent} */ +chrome.webstore.onDownloadProgress; + + +/** + * @see https://developer.chrome.com/extensions/runtime.html + * @const + */ +chrome.runtime = {}; + + +/** @type {!Object|undefined} */ +chrome.runtime.lastError = {}; + + +/** @type {string|undefined} */ +chrome.runtime.lastError.message; + + +/** + * @param {string|!Object=} opt_extensionIdOrConnectInfo Either the + * extensionId to connect to, in which case connectInfo params can be + * passed in the next optional argument, or the connectInfo params. + * @param {!Object=} opt_connectInfo The connectInfo object, + * if arg1 was the extensionId to connect to. + * @return {!Port} New port. + */ +chrome.runtime.connect = function( + opt_extensionIdOrConnectInfo, opt_connectInfo) {}; + + +/** + * @param {string|*} extensionIdOrMessage Either the extensionId to send the + * message to, in which case the message is passed as the next arg, or the + * message itself. + * @param {(*|!Object|function(*): void)=} opt_messageOrOptsOrCallback + * One of: + * The message, if arg1 was the extensionId. + * The options for message sending, if arg1 was the message and this + * argument is not a function. + * The callback, if arg1 was the message and this argument is a function. + * @param {(!Object|function(*): void)=} opt_optsOrCallback + * Either the options for message sending, if arg2 was the message, + * or the callback. + * @param {function(*): void=} opt_callback The callback function which + * takes a JSON response object sent by the handler of the request. + * @return {undefined} + */ +chrome.runtime.sendMessage = function( + extensionIdOrMessage, opt_messageOrOptsOrCallback, opt_optsOrCallback, + opt_callback) {}; + + +/** + * Returns an object representing current load times. Note that the properties + * on the object do not change and the function must be called again to get + * up-to-date data. + * + * @return {!ChromeLoadTimes} + */ +chrome.loadTimes = function() {}; + + + +/** + * The data object given by chrome.loadTimes(). + * @constructor + */ +function ChromeLoadTimes() {} + + +/** @type {number} */ +ChromeLoadTimes.prototype.requestTime; + + +/** @type {number} */ +ChromeLoadTimes.prototype.startLoadTime; + + +/** @type {number} */ +ChromeLoadTimes.prototype.commitLoadTime; + + +/** @type {number} */ +ChromeLoadTimes.prototype.finishDocumentLoadTime; + + +/** @type {number} */ +ChromeLoadTimes.prototype.finishLoadTime; + + +/** @type {number} */ +ChromeLoadTimes.prototype.firstPaintTime; + + +/** @type {number} */ +ChromeLoadTimes.prototype.firstPaintAfterLoadTime; + + +/** @type {number} */ +ChromeLoadTimes.prototype.navigationType; + + +/** + * True iff the resource was fetched over SPDY. + * @type {boolean} + */ +ChromeLoadTimes.prototype.wasFetchedViaSpdy; + + +/** @type {boolean} */ +ChromeLoadTimes.prototype.wasNpnNegotiated; + + +/** @type {string} */ +ChromeLoadTimes.prototype.npnNegotiatedProtocol; + + +/** @type {boolean} */ +ChromeLoadTimes.prototype.wasAlternateProtocolAvailable; + + +/** @type {string} */ +ChromeLoadTimes.prototype.connectionInfo; + + +/** + * Returns an object containing timing information. + * @return {!ChromeCsiInfo} + */ +chrome.csi = function() {}; + + + +/** + * The data object given by chrome.csi(). + * @constructor + */ +function ChromeCsiInfo() {} + + +/** + * Same as chrome.loadTimes().requestTime, if defined. + * Otherwise, gives the same value as chrome.loadTimes().startLoadTime. + * In milliseconds, truncated. + * @type {number} + */ +ChromeCsiInfo.prototype.startE; + + +/** + * Same as chrome.loadTimes().finishDocumentLoadTime but in milliseconds and + * truncated. + * @type {number} + */ +ChromeCsiInfo.prototype.onloadT; + + +/** + * The time since startE in milliseconds. + * @type {number} + */ +ChromeCsiInfo.prototype.pageT; + + +/** @type {number} */ +ChromeCsiInfo.prototype.tran; + + +/** + * @param {string|!ArrayBuffer|!Object} message + * @see https://developers.google.com/native-client/devguide/tutorial + * @return {undefined} + */ +HTMLEmbedElement.prototype.postMessage = function(message) {}; diff --git a/cljs-src/externs/chrome_extensions.js b/cljs-src/externs/chrome_extensions.js new file mode 100644 index 0000000..3e645cd --- /dev/null +++ b/cljs-src/externs/chrome_extensions.js @@ -0,0 +1,10261 @@ +/* + * Copyright 2009 The Closure Compiler Authors + * + * 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 Definitions for the Chromium extensions API. + * + * This is the externs file for the Chrome Extensions API. + * See http://developer.chrome.com/extensions/ + * + * There are several problematic issues regarding Chrome extension APIs and + * this externs files, including: + * A. When to add packages to this file + * B. Optional parameters + * C. Pseudo-types + * D. Events + * E. Nullability + * F. Private APIs + * G. Enums + * + * The best practices for each are described in more detail below. It + * should be noted that, due to historical reasons, and the evolutionary + * nature of this file, much this file currently violates the best practices + * described below. As changes are made, the changes should adhere to the + * best practices. + * + * A. When to Add Packages to this File? + * Packages in chrome.experimental.* should *not* be added to this file. The + * experimental APIs change very quickly, so rather than add them here, make a + * separate externs file for your project, then move the API here when it moves + * out of experimental. + * + * Some non-experimental APIs are still evolving or are not full documented. It + * is still advantageous to include these in this file as doing so avoids a + * proliferation of project-private externs files containing duplicated info. In + * these cases, use comments to describe the situation. + * + * B. Optional Parameters + * The Chrome extension APIs make extensive use of optional parameters that + * are not at the end of the parameter list, "interior optional parameters", + * while the JS Compiler's type system requires optional parameters to be + * at the end. This creates a bit of tension: + * + * 1. If a method has N required params, then the parameter declarations + * should have N required params. + * 2. If, due to interior optional params, a parameter can be of more than + * one type, its at-param should: + * a. be named to indicate both possibilities, eg, extensionIdOrRequest, + * or getInfoOrCallback. + * b. the type should include both types, in the same order as the parts + * of the name, even when one type subsumes the other, eg, {string|*} + * or {Object|function(string)}. + * See chrome.runtime.sendMessage for a complex example as sendMessage + * takes three params with the first and third being optional. + * + * C. Pseudo-types + * The Chrome APIs define many types are that actually pseudo-types, that + * is, they can't be instantiated by name. The extension APIs also pass + * untyped objects (a bag of properties) to callbacks. + * + * The Chrome extension APIs include at least three different situations: + * + * 1. an object that must be created by an extension developer and passed + * into a Chrome extension API and for which there is no constructor. + * 2. an instance of a type that is created inside the extension libraries + * and passed out to a callback/listener or returned by an extension API + * (the constructor implicity lives within the library). + * 3. like #2, but a bag-of-properties object that is passed out to a + * callback/listener or returned by an extension API so there is no + * defined type. + * + * For #1, use a typedef so object literals and objects created via goog.object + * are acceptable, for example, the Permissions type defined at + * http://developer.chrome.com/extensions/permissions.html#type-Permissions + * should be: + * + * / ** + * * at-typedef {?{ + * * permissions: (!Array|undefined), + * * origins: (!Array|undefined) + * * }} + * * / + * chrome.permissions.Permissions; + * + * Using typedefs provides type-safety for the fields that are defined in + * the object literal and also defined in the typedef. Note that typedefs define + * a minimal interface and will not complain about extraneous (often + * misspelled) fields. + * + * Also, typedefs of record types are non-nullable by default. The "{?{" + * creates a nullable record-type typedef so ! has the same meaning in usages + * as it does for real types. + * + * For #2, use a standard constructor, even though no constructor is provided + * and extension writers will never instantiate an instance, as using a first + * class type provides the strongest type checking. For example, see the Port + * type defined at http://developer.chrome.com/apps/runtime.html#type-Port. + * Always qualify the type name to reduce top-level pollution in this file: + * + * Do: + * chrome.runtime.Port = function() {} + * Don't: + * function Port() {} + * + * Note that, unfortunately, the actual Port class definition in this file + * does not follow this recommendation. + * + * For #3, use {!Object}, that is, a bag of properites. This is a sad reality + * given that the Chrome extensions do not document a real type. It is tempting + * to define a real-type within this file and treat this situation as identical + * to #2, but that means a new type is being defined in this file and developers + * do not expect to find required new types in extension files. + * + * If a real type is declared here, then developers will need to incorporate + * that type into the signature of their callback method and there will be + * no indication from the docs that they need to do so. + * + * D. Events + * Most packages define a set of events with the standard set of methods: + * addListener, removeListener, hasListener and hasListeners. ChromeVoidEvent + * is the appropriate type when an event's listeners do not take any + * parameters, however, many events take parameters specific to that event. + * + * For those cases, create a record type for the event that extends + * ChromeBaseEvent with the correct listener function type filled in. + * See any of the Event type definitions below for an example. + * + * E. Nullability + * We treat the Chrome Extension API pages as "the truth". Not-null types + * should be used in the following situations: + * + * 1. Parameters and return values that are not explicitly declared to handle + * null. + * 2. Static event instances, for example, chrome.runtime.onConnect's type + * should be: !chrome.runtime.PortEvent. + * 3. Optional params as there is little value to passing null when the + * parameter can be omitted, of course, if null is explicitly declared + * to be meaningful, then a nullable type should be used. + * + * F. Private APIs + * Private Chrome APIs (such as those that end in "Private") should go at the + * bottom of this file. + * + * G. Enums + * An enum's type name and the name of its members must be included in an + * externs file, but the values of its members are ignored by the compiler. + * To make it clear enums are not being *defined* in this file, we set + * string enum values to the empty string (at this time, there are no + * known enums of other types). + * + * As of Mar 2016, the chrome extension docs are incomplete wrt to enums + * as they don't list the member names, only their string values. This means + * extension authors will tend to use string literals. Therefore, whereever + * an enum type should be used, we support either the enum or a string. Once + * the docs are complete, new uses of enums will no longer need the "or string" + * portion of the type. + * + * Finally, most places in this file where enums should be used are using only + * string. This is historical and is no longer the recommended practice. + * + * See enum chrome.wallpaper.WallpaperLayout and chrome.wallpaper.setWallpaper's + * param for examples. + * + * @externs + * + */ + + +/* + * Ensure projects don't execute this file. + * The throw is to catch executions of this file, however, without the guard, + * the compiler's flow analysis stops at the throw, even for an externs file. + * Therefore, the Math.random() guard fools the compiler during externs + * processing. + */ +if (Math.random() < 1) { // always true but the compiler doesn't know that + throw 'Externs file "chrome_extensions.js" should not be executed'; +} + + +/** + * @see https://developer.chrome.com/extensions/accessibilityFeatures + * @const + */ +chrome.accessibilityFeatures = {}; + + +/** @type {!ChromeSetting} */ +chrome.accessibilityFeatures.spokenFeedback; + + +/** @type {!ChromeSetting} */ +chrome.accessibilityFeatures.largeCursor; + + +/** @type {!ChromeSetting} */ +chrome.accessibilityFeatures.stickyKeys; + + +/** @type {!ChromeSetting} */ +chrome.accessibilityFeatures.highContrast; + + +/** @type {!ChromeSetting} */ +chrome.accessibilityFeatures.screenMagnifier; + + +/** @type {!ChromeSetting} */ +chrome.accessibilityFeatures.autoclick; + + +/** @type {!ChromeSetting} */ +chrome.accessibilityFeatures.virtualKeyboard; + + +/** @type {!ChromeSetting} */ +chrome.accessibilityFeatures.animationPolicy; + + +/** + * @const + * @see http://developer.chrome.com/apps/app.runtime.html + */ +chrome.app.runtime = {}; + + + +/** + * @constructor + * @see http://developer.chrome.com/apps/app_runtime.html + */ +chrome.app.runtime.LaunchItem = function() {}; + + +/** @type {!FileEntry} */ +chrome.app.runtime.LaunchItem.prototype.entry; + + +/** @type {string} */ +chrome.app.runtime.LaunchItem.prototype.type; + + +/** @type {!ChromeObjectEvent} */ +chrome.app.runtime.onEmbedRequested; + + +/** @type {!ChromeObjectEvent} */ +chrome.app.runtime.onLaunched; + + +/** + * @type {!ChromeEvent} + * @see http://developer.chrome.com/apps/app.runtime.html#event-onRestarted + */ +chrome.app.runtime.onRestarted; + + +/** + * @const + * @see http://developer.chrome.com/apps/app.window.html + */ +chrome.app.window = {}; + + +/** + * @see https://developer.chrome.com/apps/app_window#method-getAll + * @return {!Array} + */ +chrome.app.window.getAll = function() {}; + + +/** + * @see https://developer.chrome.com/apps/app_window#method-get + * @param {string} id + * @return {chrome.app.window.AppWindow} + */ +chrome.app.window.get = function(id) {}; + + + +/** + * @constructor + * @see http://developer.chrome.com/apps/app.window.html#type-AppWindow + */ +chrome.app.window.AppWindow = function() {}; + + +/** + * @see http://developer.chrome.com/apps/app.window.html#type-AppWindow + * @return {undefined} + */ +chrome.app.window.AppWindow.prototype.focus = function() {}; + + +/** + * @see http://developer.chrome.com/apps/app.window.html#type-AppWindow + * @return {undefined} + */ +chrome.app.window.AppWindow.prototype.fullscreen = function() {}; + + +/** + * @return {boolean} + * @see http://developer.chrome.com/apps/app.window.html#type-AppWindow + */ +chrome.app.window.AppWindow.prototype.isFullscreen = function() {}; + + +/** + * @see http://developer.chrome.com/apps/app.window.html#type-AppWindow + * @return {undefined} + */ +chrome.app.window.AppWindow.prototype.minimize = function() {}; + + +/** + * @return {boolean} + * @see http://developer.chrome.com/apps/app.window.html#type-AppWindow + */ +chrome.app.window.AppWindow.prototype.isMinimized = function() {}; + + +/** + * @see http://developer.chrome.com/apps/app.window.html#type-AppWindow + * @return {undefined} + */ +chrome.app.window.AppWindow.prototype.maximize = function() {}; + + +/** + * @return {boolean} + * @see http://developer.chrome.com/apps/app.window.html#type-AppWindow + */ +chrome.app.window.AppWindow.prototype.isMaximized = function() {}; + + +/** + * @see http://developer.chrome.com/apps/app.window.html#type-AppWindow + * @return {undefined} + */ +chrome.app.window.AppWindow.prototype.restore = function() {}; + + +/** + * @param {number} left The new left position, in pixels. + * @param {number} top The new top position, in pixels. + * @see http://developer.chrome.com/apps/app.window.html#type-AppWindow + * @return {undefined} + */ +chrome.app.window.AppWindow.prototype.moveTo = function(left, top) {}; + + +/** + * @param {number} width The new width, in pixels. + * @param {number} height The new height, in pixels. + * @see http://developer.chrome.com/apps/app.window.html#type-AppWindow + * @return {undefined} + */ +chrome.app.window.AppWindow.prototype.resizeTo = function(width, height) {}; + + +/** + * @see http://developer.chrome.com/apps/app.window.html#type-AppWindow + * @return {undefined} + */ +chrome.app.window.AppWindow.prototype.drawAttention = function() {}; + + +/** + * @see http://developer.chrome.com/apps/app.window.html#type-AppWindow + * @return {undefined} + */ +chrome.app.window.AppWindow.prototype.clearAttention = function() {}; + + +/** + * @see http://developer.chrome.com/apps/app.window.html#type-AppWindow + * @return {undefined} + */ +chrome.app.window.AppWindow.prototype.close = function() {}; + + +/** + * @param {boolean=} opt_focus Should the window be focused? Defaults to true. + * @see http://developer.chrome.com/apps/app.window.html#type-AppWindow + * @return {undefined} + */ +chrome.app.window.AppWindow.prototype.show = function(opt_focus) {}; + + +/** + * @see http://developer.chrome.com/apps/app.window.html#type-AppWindow + * @return {undefined} + */ +chrome.app.window.AppWindow.prototype.hide = function() {}; + + +/** + * @return {!chrome.app.window.ContentBounds} The current window bounds. + * @see http://developer.chrome.com/apps/app.window.html#type-AppWindow + */ +chrome.app.window.AppWindow.prototype.getBounds = function() {}; + + +/** + * @param {!chrome.app.window.ContentBounds} bounds The new window bounds. + * @see http://developer.chrome.com/apps/app.window.html#type-AppWindow + * @return {undefined} + */ +chrome.app.window.AppWindow.prototype.setBounds = function(bounds) {}; + + +/** + * @return {boolean} + * @see http://developer.chrome.com/apps/app.window.html#type-AppWindow + */ +chrome.app.window.AppWindow.prototype.isAlwaysOnTop = function() {}; + + +/** + * @param {boolean} alwaysOnTop Set whether the window should stay above most + * other windows. + * @see http://developer.chrome.com/apps/app.window.html#type-AppWindow + * @return {undefined} + */ +chrome.app.window.AppWindow.prototype.setAlwaysOnTop = function(alwaysOnTop) {}; + + +/** + * @param {boolean} alwaysVisible Set whether the window is visible on all + * workspaces. + * @see http://developer.chrome.com/apps/app.window.html#type-AppWindow + * @return {undefined} + */ +chrome.app.window.AppWindow.prototype.setVisibleOnAllWorkspaces = + function(alwaysVisible) {}; + + +/** + * @param {boolean} wantAllKeys Set whether the window should get all keyboard + * events including system keys that are usually not sent. + * @see http://developer.chrome.com/apps/app.window.html#type-AppWindow + * @return {undefined} + */ +chrome.app.window.AppWindow.prototype.setInterceptAllKeys = + function(wantAllKeys) {}; + + +/** @type {!ChromeEvent} */ +chrome.app.window.AppWindow.prototype.onBoundsChanged; + + +/** @type {!ChromeEvent} */ +chrome.app.window.AppWindow.prototype.onClosed; + + +/** @type {!ChromeEvent} */ +chrome.app.window.AppWindow.prototype.onFullscreened; + + +/** @type {!ChromeEvent} */ +chrome.app.window.AppWindow.prototype.onMinimized; + + +/** @type {!ChromeEvent} */ +chrome.app.window.AppWindow.prototype.onMaximized; + + +/** @type {!ChromeEvent} */ +chrome.app.window.AppWindow.prototype.onRestored; + + +/** @type {!Window} */ +chrome.app.window.AppWindow.prototype.contentWindow; + + +/** @type {string} */ +chrome.app.window.AppWindow.prototype.id; + + +/** @type {!chrome.app.window.Bounds} */ +chrome.app.window.AppWindow.prototype.innerBounds; + + +/** @type {!chrome.app.window.Bounds} */ +chrome.app.window.AppWindow.prototype.outerBounds; + + +/** + * @typedef {?{ + * left: number, + * top: number, + * width: number, + * height: number, + * minWidth: (number|undefined), + * minHeight: (number|undefined), + * maxWidth: (number|undefined), + * maxHeight: (number|undefined), + * setPosition: function(number, number), + * setSize: function(number, number), + * setMinimumSize: function(number, number), + * setMaximumSize: function(number, number) + * }} + * @see http://developer.chrome.com/apps/app.window.html#type-Bounds + */ +chrome.app.window.Bounds; + + +/** + * @typedef {?{ + * left: (number|undefined), + * top: (number|undefined), + * width: (number|undefined), + * height: (number|undefined), + * minWidth: (number|undefined), + * minHeight: (number|undefined), + * maxWidth: (number|undefined), + * maxHeight: (number|undefined) + * }} + * @see http://developer.chrome.com/apps/app_window#type-BoundsSpecification + */ +chrome.app.window.BoundsSpecification; + + +/** + * @typedef {?{ + * left: (number|undefined), + * top: (number|undefined), + * width: (number|undefined), + * height: (number|undefined) + * }} + * @see http://developer.chrome.com/apps/app_window#type-ContentBounds + */ +chrome.app.window.ContentBounds; + + +/** + * @typedef {?{ + * type: (string|undefined), + * color: (string|undefined), + * activeColor: (string|undefined), + * inactiveColor: (string|undefined) + * }} + * @see http://developer.chrome.com/apps/app_window#type-FrameOptions + */ +chrome.app.window.FrameOptions; + + +/** + * @typedef {?{ + * id: (string|undefined), + * innerBounds: (!chrome.app.window.BoundsSpecification|undefined), + * outerBounds: (!chrome.app.window.BoundsSpecification|undefined), + * minWidth: (number|undefined), + * minHeight: (number|undefined), + * maxWidth: (number|undefined), + * maxHeight: (number|undefined), + * frame: (!chrome.app.window.FrameOptions|string|undefined), + * bounds: (!chrome.app.window.ContentBounds|undefined), + * state: (string|undefined), + * hidden: (boolean|undefined), + * resizable: (boolean|undefined), + * singleton: (boolean|undefined), + * alwaysOnTop: (boolean|undefined), + * focused: (boolean|undefined), + * visibleOnAllWorkspaces: (boolean|undefined) + * }} + * @see http://developer.chrome.com/apps/app.window.html#method-create + */ +chrome.app.window.CreateWindowOptions; + + +/** + * @param {string} url URL to create. + * @param {!chrome.app.window.CreateWindowOptions=} opt_options The options for + * the new window. + * @param {function(!chrome.app.window.AppWindow)=} opt_createWindowCallback + * Callback to be run. + * @see http://developer.chrome.com/apps/app.window.html#method-create + * @return {undefined} + */ +chrome.app.window.create = function( + url, opt_options, opt_createWindowCallback) {}; + + +/** + * Returns an AppWindow object for the current script context (ie JavaScript + * 'window' object). + * @return {!chrome.app.window.AppWindow} + * @see http://developer.chrome.com/apps/app.window.html#method-current + */ +chrome.app.window.current = function() {}; + + +/** + * @type {!ChromeEvent} + * @see http://developer.chrome.com/apps/app.window.html#event-onBoundsChanged + */ +chrome.app.window.onBoundsChanged; + + +/** + * @type {!ChromeEvent} + * @see http://developer.chrome.com/apps/app.window.html#event-onClosed + */ +chrome.app.window.onClosed; + + +/** + * @type {!ChromeEvent} + * @see http://developer.chrome.com/apps/app.window.html#event-onFullscreened + */ +chrome.app.window.onFullscreened; + + +/** + * @type {!ChromeEvent} + * @see http://developer.chrome.com/apps/app.window.html#event-onMaximized + */ +chrome.app.window.onMaximized; + + +/** + * @type {!ChromeEvent} + * @see http://developer.chrome.com/apps/app.window.html#event-onMinimized + */ +chrome.app.window.onMinimized; + + +/** + * @type {!ChromeEvent} + * @see http://developer.chrome.com/apps/app.window.html#event-onRestored + */ +chrome.app.window.onRestored; + + +/** + * Private API. + * + * @const + * @see https://code.google.com/p/chromium/codesearch#chromium/src/chrome/common/extensions/api/audio_modem.idl + * @see go/chrome-modem + */ +chrome.audioModem = {}; + + +/** + * @typedef {?{ + * tokenLength: number, + * crc: (boolean|undefined), + * parity: (boolean|undefined) + * }} + */ +chrome.audioModem.TokenEncoding; + + +/** + * @typedef {?{ + * timeoutMillis: number, + * band: string, + * encoding: !chrome.audioModem.TokenEncoding + * }} + */ +chrome.audioModem.RequestParams; + + +/** @constructor */ +chrome.audioModem.ReceivedToken = function() {}; + + +/** @type {!ArrayBuffer} */ +chrome.audioModem.ReceivedToken.prototype.token; + + +/** @type {string} */ +chrome.audioModem.ReceivedToken.prototype.band; + + +/** + * @param {!chrome.audioModem.RequestParams} params + * @param {!ArrayBuffer} token + * @param {function(string)} callback + * @return {undefined} + */ +chrome.audioModem.transmit = function(params, token, callback) {}; + + +/** + * @param {string} band + * @param {function(string)} callback + * @return {undefined} + */ +chrome.audioModem.stopTransmit = function(band, callback) {}; + + +/** + * @param {!chrome.audioModem.RequestParams} params + * @param {function(string)} callback + * @return {undefined} + */ +chrome.audioModem.receive = function(params, callback) {}; + + +/** + * @param {string} band + * @param {function(string)} callback + * @return {undefined} + */ +chrome.audioModem.stopReceive = function(band, callback) {}; + + +/** + * @record + * @extends {ChromeBaseEvent)>} + */ +chrome.audioModem.ReceivedEvent = function() {}; + + +/** @type {!chrome.audioModem.ReceivedEvent} */ +chrome.audioModem.onReceived; + + +/** @type {!ChromeStringEvent} */ +chrome.audioModem.onTransmitFail; + + +/** + * @see https://developer.chrome.com/apps/bluetooth + */ +chrome.bluetooth = {}; + + + +/** + * @constructor + * @see https://developer.chrome.com/apps/bluetooth#type-AdapterState + */ +chrome.bluetooth.AdapterState = function() {}; + + +/** @type {string} */ +chrome.bluetooth.AdapterState.prototype.address; + + +/** @type {string} */ +chrome.bluetooth.AdapterState.prototype.name; + + +/** @type {boolean} */ +chrome.bluetooth.AdapterState.prototype.powered; + + +/** @type {boolean} */ +chrome.bluetooth.AdapterState.prototype.available; + + +/** @type {boolean} */ +chrome.bluetooth.AdapterState.prototype.discovering; + + + +/** + * @constructor + * @see https://developer.chrome.com/apps/bluetooth#type-Device + */ +chrome.bluetooth.Device = function() {}; + + +/** @type {string} */ +chrome.bluetooth.Device.prototype.address; + + +/** @type {string|undefined} */ +chrome.bluetooth.Device.prototype.name; + + +/** @type {number|undefined} */ +chrome.bluetooth.Device.prototype.deviceClass; + + +/** @type {string|undefined} */ +chrome.bluetooth.Device.prototype.vendorIdSource; + + +/** @type {string|undefined} */ +chrome.bluetooth.Device.prototype.vendorId; + + +/** @type {number|undefined} */ +chrome.bluetooth.Device.prototype.productId; + + +/** @type {number|undefined} */ +chrome.bluetooth.Device.prototype.deviceId; + + +/** @type {string|undefined} */ +chrome.bluetooth.Device.prototype.type; + + +/** @type {boolean|undefined} */ +chrome.bluetooth.Device.prototype.paired; + + +/** @type {boolean|undefined} */ +chrome.bluetooth.Device.prototype.connected; + + +/** @type {boolean|undefined} */ +chrome.bluetooth.Device.prototype.connecting; + + +/** @type {boolean|undefined} */ +chrome.bluetooth.Device.prototype.connectable; + + +/** @type {!Array|undefined} */ +chrome.bluetooth.Device.prototype.uuids; + + +/** @type {number|undefined} */ +chrome.bluetooth.Device.prototype.inquiryRssi; + + +/** @type {number|undefined} */ +chrome.bluetooth.Device.prototype.inquiryTxPower; + + +/** + * @param {function(!chrome.bluetooth.AdapterState)} callback + * @see https://developer.chrome.com/apps/bluetooth#method-getAdapterState + * @return {undefined} + */ +chrome.bluetooth.getAdapterState = function(callback) {}; + + +/** + * @param {string} deviceAddress + * @param {function(!chrome.bluetooth.Device)} callback + * @see https://developer.chrome.com/apps/bluetooth#method-getDevice + * @return {undefined} + */ +chrome.bluetooth.getDevice = function(deviceAddress, callback) {}; + + +/** + * @param {function(!Array)} callback + * @see https://developer.chrome.com/apps/bluetooth#method-getDevices + * @return {undefined} + */ +chrome.bluetooth.getDevices = function(callback) {}; + + +/** + * @param {function()=} opt_callback + * @see https://developer.chrome.com/apps/bluetooth#method-startDiscovery + * @return {undefined} + */ +chrome.bluetooth.startDiscovery = function(opt_callback) {}; + + +/** + * @param {function()=} opt_callback + * @see https://developer.chrome.com/apps/bluetooth#method-stopDiscovery + * @return {undefined} + */ +chrome.bluetooth.stopDiscovery = function(opt_callback) {}; + + + +/** + * Event whose listeners take an AdapaterState parameter. + * @record + * @extends {ChromeBaseEvent} + */ +chrome.bluetooth.AdapterStateEvent = function() {}; + + +/** + * @type {!chrome.bluetooth.AdapterStateEvent} + * @see https://developer.chrome.com/apps/bluetooth#event-onAdapterStateChanged + */ +chrome.bluetooth.onAdapterStateChanged; + + +/** + * Event whose listeners take an Device parameter. + * @record + * @extends {ChromeBaseEvent} + */ +chrome.bluetooth.DeviceEvent = function() {}; + + +/** + * @type {!chrome.bluetooth.DeviceEvent} + * @see https://developer.chrome.com/apps/bluetooth#event-onDeviceAdded + */ +chrome.bluetooth.onDeviceAdded; + + +/** + * @type {!chrome.bluetooth.DeviceEvent} + * @see https://developer.chrome.com/apps/bluetooth#event-onDeviceChanged + */ +chrome.bluetooth.onDeviceChanged; + + +/** + * @type {!chrome.bluetooth.DeviceEvent} + * @see https://developer.chrome.com/apps/bluetooth#event-onDeviceRemoved + */ +chrome.bluetooth.onDeviceRemoved; + + +/** + * @const + * @see https://developer.chrome.com/apps/bluetoothSocket + */ +chrome.bluetoothSocket = {}; + + +/** + * @typedef {{ + * persistent: (boolean|undefined), + * name: (string|undefined), + * bufferSize: (number|undefined) + * }} + * @see https://developer.chrome.com/apps/bluetoothSocket#type-SocketProperties + */ +chrome.bluetoothSocket.SocketProperties; + + +/** + * @typedef {{ + * channel: (number|undefined), + * psm: (number|undefined), + * backlog: (number|undefined) + * }} + * @see https://developer.chrome.com/apps/bluetoothSocket#type-ListenOptions + */ +chrome.bluetoothSocket.ListenOptions; + + + +/** + * @constructor + * @see https://developer.chrome.com/apps/bluetoothSocket#type-SocketInfo + */ +chrome.bluetoothSocket.SocketInfo = function() {}; + + +/** @type {number} */ +chrome.bluetoothSocket.SocketInfo.prototype.socketId; + + +/** @type {boolean} */ +chrome.bluetoothSocket.SocketInfo.prototype.persistent; + + +/** @type {string|undefined} */ +chrome.bluetoothSocket.SocketInfo.prototype.name; + + +/** @type {number|undefined} */ +chrome.bluetoothSocket.SocketInfo.prototype.bufferSize; + + +/** @type {boolean} */ +chrome.bluetoothSocket.SocketInfo.prototype.paused; + + +/** @type {boolean} */ +chrome.bluetoothSocket.SocketInfo.prototype.connected; + + +/** @type {string|undefined} */ +chrome.bluetoothSocket.SocketInfo.prototype.address; + + +/** @type {string|undefined} */ +chrome.bluetoothSocket.SocketInfo.prototype.uuid; + + +/** + * @param {!chrome.bluetoothSocket.SocketProperties| + * function(!{socketId: number})} propertiesOrCallback + * @param {function(!{socketId: number})=} opt_callback + * @see https://developer.chrome.com/apps/bluetoothSocket#method-create + * @return {undefined} + */ +chrome.bluetoothSocket.create = function(propertiesOrCallback, opt_callback) {}; + + +/** + * @param {number} socketId + * @param {!chrome.bluetoothSocket.SocketProperties} properties + * @param {function()=} opt_callback + * @see https://developer.chrome.com/apps/bluetoothSocket#method-update + * @return {undefined} + */ +chrome.bluetoothSocket.update = function(socketId, properties, opt_callback) {}; + + +/** + * @param {number} socketId + * @param {boolean} paused + * @param {function()=} opt_callback + * @see https://developer.chrome.com/apps/bluetoothSocket#method-setPaused + * @return {undefined} + */ +chrome.bluetoothSocket.setPaused = function(socketId, paused, opt_callback) {}; + + +/** + * @param {number} socketId + * @param {string} uuid + * @param {!chrome.bluetoothSocket.ListenOptions|function()} optionsOrCallback + * @param {function()=} opt_callback + * @see https://developer.chrome.com/apps/bluetoothSocket#method-listenUsingRfcomm + * @return {undefined} + */ +chrome.bluetoothSocket.listenUsingRfcomm = + function(socketId, uuid, optionsOrCallback, opt_callback) {}; + + +/** + * @param {number} socketId + * @param {string} uuid + * @param {!chrome.bluetoothSocket.ListenOptions|function()} optionsOrCallback + * @param {function()=} opt_callback + * @see https://developer.chrome.com/apps/bluetoothSocket#method-listenUsingL2cap + * @return {undefined} + */ +chrome.bluetoothSocket.listenUsingL2cap = + function(socketId, uuid, optionsOrCallback, opt_callback) {}; + + +/** + * @param {number} socketId + * @param {string} address + * @param {string} uuid + * @param {function()} callback + * @see https://developer.chrome.com/apps/bluetoothSocket#method-connect + * @return {undefined} + */ +chrome.bluetoothSocket.connect = function(socketId, address, uuid, callback) {}; + + +/** + * @param {number} socketId + * @param {function()=} opt_callback + * @see https://developer.chrome.com/apps/bluetoothSocket#method-disconnect + * @return {undefined} + */ +chrome.bluetoothSocket.disconnect = function(socketId, opt_callback) {}; + + +/** + * @param {number} socketId + * @param {function()=} opt_callback + * @see https://developer.chrome.com/apps/bluetoothSocket#method-close + * @return {undefined} + */ +chrome.bluetoothSocket.close = function(socketId, opt_callback) {}; + + +/** + * @param {number} socketId + * @param {!ArrayBuffer} data + * @param {function(number)=} opt_callback + * @see https://developer.chrome.com/apps/bluetoothSocket#method-send + * @return {undefined} + */ +chrome.bluetoothSocket.send = function(socketId, data, opt_callback) {}; + + +/** + * @param {number} socketId + * @param {function(!chrome.bluetoothSocket.SocketInfo)} callback + * @see https://developer.chrome.com/apps/bluetoothSocket#method-getInfo + * @return {undefined} + */ +chrome.bluetoothSocket.getInfo = function(socketId, callback) {}; + + +/** + * @param {function(!Array)} callback + * @see https://developer.chrome.com/apps/bluetoothSocket#method-getSockets + * @return {undefined} + */ +chrome.bluetoothSocket.getSockets = function(callback) {}; + + + +/** + * @constructor + * @see https://developer.chrome.com/apps/bluetoothSocket#event-onAccept + */ +chrome.bluetoothSocket.AcceptEventData = function() {}; + + +/** @type {number} */ +chrome.bluetoothSocket.AcceptEventData.prototype.socketId; + + +/** @type {number} */ +chrome.bluetoothSocket.AcceptEventData.prototype.clientSocketId; + + + +/** + * Event whose listeners take a AcceptEventData parameter. + * @record + * @extends {ChromeBaseEvent} + */ +chrome.bluetoothSocket.AcceptEvent = function() {}; + + +/** @type {!chrome.bluetoothSocket.AcceptEvent} */ +chrome.bluetoothSocket.onAccept; + + + +/** + * @constructor + * @see https://developer.chrome.com/apps/bluetoothSocket#event-onAcceptError + */ +chrome.bluetoothSocket.AcceptErrorEventData = function() {}; + + +/** @type {number} */ +chrome.bluetoothSocket.AcceptErrorEventData.prototype.socketId; + + +/** @type {string} */ +chrome.bluetoothSocket.AcceptErrorEventData.prototype.errorMessage; + + +/** @type {string} */ +chrome.bluetoothSocket.AcceptErrorEventData.prototype.error; + + + +/** + * Event whose listeners take a AcceptErrorEventData parameter. + * @record + * @extends {ChromeBaseEvent} + */ +chrome.bluetoothSocket.AcceptErrorEvent = function() {}; + + +/** @type {!chrome.bluetoothSocket.AcceptErrorEvent} */ +chrome.bluetoothSocket.onAcceptError; + + + +/** + * @constructor + * @see https://developer.chrome.com/apps/bluetoothSocket#event-onReceive + */ +chrome.bluetoothSocket.ReceiveEventData = function() {}; + + +/** @type {number} */ +chrome.bluetoothSocket.ReceiveEventData.prototype.socketId; + + +/** @type {!ArrayBuffer} */ +chrome.bluetoothSocket.ReceiveEventData.prototype.data; + + + +/** + * Event whose listeners take a ReceiveEventData parameter. + * @record + * @extends + * {ChromeBaseEvent} + */ +chrome.bluetoothSocket.ReceiveEvent = function() {}; + + +/** @type {!chrome.bluetoothSocket.ReceiveEvent} */ +chrome.bluetoothSocket.onReceive; + + + +/** + * @constructor + * @see https://developer.chrome.com/apps/bluetoothSocket#event-onReceiveError + */ +chrome.bluetoothSocket.ReceiveErrorEventData = function() {}; + + +/** @type {number} */ +chrome.bluetoothSocket.ReceiveErrorEventData.prototype.socketId; + + +/** @type {string} */ +chrome.bluetoothSocket.ReceiveErrorEventData.prototype.errorMessage; + + +/** @type {string} */ +chrome.bluetoothSocket.ReceiveErrorEventData.prototype.error; + + + +/** + * Event whose listeners take a ReceiveErrorEventData parameter. + * @record + * @extends {ChromeBaseEvent< + * function(!chrome.bluetoothSocket.ReceiveErrorEventData)>} + */ +chrome.bluetoothSocket.ReceiveErrorEvent = function() {}; + + +/** @type {!chrome.bluetoothSocket.ReceiveErrorEvent} */ +chrome.bluetoothSocket.onReceiveError; + + +/** + * @see https://developer.chrome.com/apps/bluetoothLowEnergy + * @const + */ +chrome.bluetoothLowEnergy = {}; + + +/** + * @typedef {?{ + * uuid: string, + * isPrimary: boolean, + * instanceId: (string|undefined), + * deviceAddress: (string|undefined) + * }} + * @see https://developer.chrome.com/apps/bluetoothLowEnergy#type-Service + */ +chrome.bluetoothLowEnergy.Service; + + +/** + * @constructor + * @see https://developer.chrome.com/apps/bluetoothLowEnergy#type-Request + */ +chrome.bluetoothLowEnergy.Request = function() {}; + + +/** @type {number} */ +chrome.bluetoothLowEnergy.Request.prototype.requestId; + + +/** @type {!Object} */ +chrome.bluetoothLowEnergy.Request.prototype.device; + + +/** @type {!ArrayBuffer|undefined} */ +chrome.bluetoothLowEnergy.Request.prototype.value; + + +/** + * @typedef {?{ + * uuid: string, + * service: (!chrome.bluetoothLowEnergy.Service|undefined), + * properties: !Array, + * instanceId: (string|undefined), + * value: (!ArrayBuffer|undefined) + * }} + * @see https://developer.chrome.com/apps/bluetoothLowEnergy#type-Characteristic + */ +chrome.bluetoothLowEnergy.Characteristic; + + +/** + * @typedef {?{ + * uuid: string, + * characteristic: (!chrome.bluetoothLowEnergy.Characteristic|undefined), + * permissions: !Array, + * instanceId: (string|undefined), + * value: (!ArrayBuffer|undefined) + * }} + * @see https://developer.chrome.com/apps/bluetoothLowEnergy#type-Descriptor + */ +chrome.bluetoothLowEnergy.Descriptor; + + +/** + * @typedef {?{ + * persistent: boolean + * }} + */ +chrome.bluetoothLowEnergy.ConnectionProperties; + + +/** + * @param {string} deviceAddress + * @param {!chrome.bluetoothLowEnergy.ConnectionProperties|function()} + * propertiesOrCallback + * @param {function()=} opt_callback + * @see https://developer.chrome.com/apps/bluetoothLowEnergy#method-connect + * @return {undefined} + */ +chrome.bluetoothLowEnergy.connect = + function(deviceAddress, propertiesOrCallback, opt_callback) {}; + +/** + * @param {string} deviceAddress + * @param {function()=} opt_callback + * @see https://developer.chrome.com/apps/bluetoothLowEnergy#method-disconnect + * @return {undefined} + */ +chrome.bluetoothLowEnergy.disconnect = function(deviceAddress, opt_callback) {}; + + +/** + * @param {string} serviceId + * @param {function(!chrome.bluetoothLowEnergy.Service)} callback + * @see https://developer.chrome.com/apps/bluetoothLowEnergy#method-getService + * @return {undefined} + */ +chrome.bluetoothLowEnergy.getService = function(serviceId, callback) {}; + + +/** + * @param {!chrome.bluetoothLowEnergy.Service} service + * @param {function(string)} callback + * @see https://developer.chrome.com/apps/bluetoothLowEnergy#method-createService + * @return {undefined} + */ +chrome.bluetoothLowEnergy.createService = function(service, callback) {}; + + +/** + * @param {string} deviceAddress + * @param {function(!Array)} callback + * @see https://developer.chrome.com/apps/bluetoothLowEnergy#method-getServices + * @return {undefined} + */ +chrome.bluetoothLowEnergy.getServices = function(deviceAddress, callback) {}; + + +/** + * @param {string} characteristicId + * @param {function(!chrome.bluetoothLowEnergy.Characteristic)} callback + * @see https://developer.chrome.com/apps/bluetoothLowEnergy#method-getCharacteristic + * @return {undefined} + */ +chrome.bluetoothLowEnergy.getCharacteristic = + function(characteristicId, callback) {}; + + +/** + * @param {!chrome.bluetoothLowEnergy.Characteristic} characteristic + * @param {string} serviceId + * @param {function(string)} callback + * @see https://developer.chrome.com/apps/bluetoothLowEnergy#method-createCharacteristic + * @return {undefined} + */ +chrome.bluetoothLowEnergy.createCharacteristic = function( + characteristic, serviceId, callback) {}; + + +/** + * @param {string} serviceId + * @param {function(!Array)} + * callback + * @see https://developer.chrome.com/apps/bluetoothLowEnergy#method-getCharacteristics + * @return {undefined} + */ +chrome.bluetoothLowEnergy.getCharacteristics = + function(serviceId, callback) {}; + + +/** + * @param {string} serviceId + * @param {function(!Array)} callback + * @see https://developer.chrome.com/apps/bluetoothLowEnergy#method-getIncludedServices + * @return {undefined} + */ +chrome.bluetoothLowEnergy.getIncludedServices = + function(serviceId, callback) {}; + + +/** + * @param {string} descriptorId + * @param {function(!chrome.bluetoothLowEnergy.Descriptor)} callback + * @see https://developer.chrome.com/apps/bluetoothLowEnergy#method-getDescriptor + * @return {undefined} + */ +chrome.bluetoothLowEnergy.getDescriptor = function(descriptorId, callback) {}; + + +/** + * @param {!chrome.bluetoothLowEnergy.Descriptor} descriptor + * @param {string} characteristicId + * @param {function(string)} callback + * @see https://developer.chrome.com/apps/bluetoothLowEnergy#method-createDescriptor + * @return {undefined} + */ +chrome.bluetoothLowEnergy.createDescriptor = function( + descriptor, characteristicId, callback) {}; + + +/** + * @param {string} characteristicId + * @param {function(!Array)} callback + * @see https://developer.chrome.com/apps/bluetoothLowEnergy#method-getDescriptors + * @return {undefined} + */ +chrome.bluetoothLowEnergy.getDescriptors = + function(characteristicId, callback) {}; + + +/** + * @param {string} characteristicId + * @param {function(!chrome.bluetoothLowEnergy.Characteristic)} callback + * @see https://developer.chrome.com/apps/bluetoothLowEnergy#method-readCharacteristicValue + * @return {undefined} + */ +chrome.bluetoothLowEnergy.readCharacteristicValue = + function(characteristicId, callback) {}; + + +/** + * @param {string} characteristicId + * @param {!ArrayBuffer} value + * @param {function()} callback + * @see https://developer.chrome.com/apps/bluetoothLowEnergy#method-writeCharacteristicValue + * @return {undefined} + */ +chrome.bluetoothLowEnergy.writeCharacteristicValue = + function(characteristicId, value, callback) {}; + + +/** + * @typedef {?{ + * persistent: boolean + * }} + */ +chrome.bluetoothLowEnergy.NotificationSessionProperties; + +/** + * @param {string} characteristicId + * @param {!chrome.bluetoothLowEnergy.NotificationSessionProperties|function()} + * propertiesOrCallback + * @param {function()=} opt_callback + * @see https://developer.chrome.com/apps/bluetoothLowEnergy#method-startCharacteristicNotifications + * @return {undefined} + */ +chrome.bluetoothLowEnergy.startCharacteristicNotifications = + function(characteristicId, propertiesOrCallback, opt_callback) {}; + + +/** + * @param {string} characteristicId + * @param {function()=} opt_callback + * @see https://developer.chrome.com/apps/bluetoothLowEnergy#method-stopCharacteristicNotifications + * @return {undefined} + */ +chrome.bluetoothLowEnergy.stopCharacteristicNotifications = + function(characteristicId, opt_callback) {}; + + +/** + * @typedef {?{ + * value: !ArrayBuffer, + * shouldIndicate: (boolean|undefined) + * }} + */ +chrome.bluetoothLowEnergy.NotificationIndication; + + +/** + * @param {string} characteristicId + * @param {!chrome.bluetoothLowEnergy.NotificationIndication} notification + * @param {function()} callback + * @see https://developer.chrome.com/apps/bluetoothLowEnergy#method-notifyCharacteristicValueChanged + * @return {undefined} + */ +chrome.bluetoothLowEnergy.notifyCharacteristicValueChanged = function( + characteristicId, notification, callback) {}; + + +/** + * @param {string} descriptorId + * @param {function(!chrome.bluetoothLowEnergy.Descriptor)} callback + * @see https://developer.chrome.com/apps/bluetoothLowEnergy#method-readDescriptorValue + * @return {undefined} + */ +chrome.bluetoothLowEnergy.readDescriptorValue = + function(descriptorId, callback) {}; + + +/** + * @param {string} descriptorId + * @param {!ArrayBuffer} value + * @param {function()} callback + * @see https://developer.chrome.com/apps/bluetoothLowEnergy#method-writeDescriptorValue + * @return {undefined} + */ +chrome.bluetoothLowEnergy.writeDescriptorValue = + function(descriptorId, value, callback) {}; + + +/** + * @param {string} serviceId + * @param {function()} callback + * @see https://developer.chrome.com/apps/bluetoothLowEnergy#method-registerService + * @return {undefined} + */ +chrome.bluetoothLowEnergy.registerService = function(serviceId, callback) {}; + + +/** + * @param {string} serviceId + * @param {function()} callback + * @see https://developer.chrome.com/apps/bluetoothLowEnergy#method-unregisterService + * @return {undefined} + */ +chrome.bluetoothLowEnergy.unregisterService = function(serviceId, callback) {}; + + +/** + * @param {string} serviceId + * @param {function()=} opt_callback + * @see https://developer.chrome.com/apps/bluetoothLowEnergy#method-removeService + * @return {undefined} + */ +chrome.bluetoothLowEnergy.removeService = function(serviceId, opt_callback) {}; + + +/** + * @typedef {?{ + * type: string, + * serviceUuids: (!Array|undefined), + * manufacturerData: (!Array<{id: number, data: !Array}>|undefined), + * solicitUuids: (!Array|undefined), + * serviceData: (!Array<{uuid: string, data: !Array}>|undefined) + * }} + */ +chrome.bluetoothLowEnergy.Advertisement; + + +/** + * @param {!chrome.bluetoothLowEnergy.Advertisement} advertisement + * @param {function(number)} callback + * @see https://developer.chrome.com/apps/bluetoothLowEnergy#method-registerAdvertisement + */ +chrome.bluetoothLowEnergy.registerAdvertisement = + function(advertisement, callback) {}; + + +/** + * @param {number} advertisementId + * @param {function()} callback + * @see https://developer.chrome.com/apps/bluetoothLowEnergy#method-unregisterAdvertisement + */ +chrome.bluetoothLowEnergy.unregisterAdvertisement = + function(advertisementId, callback) {}; + + +/** + * @param {function()} callback + * @see https://developer.chrome.com/apps/bluetoothLowEnergy#method-resetAdvertising + */ +chrome.bluetoothLowEnergy.resetAdvertising = function(callback) {}; + + +/** + * @param {number} minInterval + * @param {number} maxInterval + * @param {function()} callback + * @see https://developer.chrome.com/apps/bluetoothLowEnergy#method-setAdvertisingInterval + */ +chrome.bluetoothLowEnergy.setAdvertisingInterval = function( + minInterval, maxInterval, callback) {}; + + +/** + * @typedef {?{ + * requestId: number, + * isError: boolean, + * value: (!ArrayBuffer|undefined) + * }} + */ +chrome.bluetoothLowEnergy.RequestResponse; + + +/** @param {!chrome.bluetoothLowEnergy.RequestResponse} response */ +chrome.bluetoothLowEnergy.sendRequestResponse = function(response) {}; + + +/** + * Event whose listeners take a Service parameter. + * @record + * @extends {ChromeBaseEvent} + */ +chrome.bluetoothLowEnergy.ServiceEvent = function() {}; + + +/** + * @type {!chrome.bluetoothLowEnergy.ServiceEvent} + * @see https://developer.chrome.com/apps/bluetoothLowEnergy#event-onServiceAdded + */ +chrome.bluetoothLowEnergy.onServiceAdded; + + +/** + * @type {!chrome.bluetoothLowEnergy.ServiceEvent} + * @see https://developer.chrome.com/apps/bluetoothLowEnergy#event-onServiceChanged + */ +chrome.bluetoothLowEnergy.onServiceChanged; + + +/** + * @type {!chrome.bluetoothLowEnergy.ServiceEvent} + * @see https://developer.chrome.com/apps/bluetoothLowEnergy#event-onServiceRemoved + */ +chrome.bluetoothLowEnergy.onServiceRemoved; + + +/** + * Event whose listeners take a Characteristic parameter. + * @record + * @extends {ChromeBaseEvent} + */ +chrome.bluetoothLowEnergy.CharacteristicEvent = function() {}; + + +/** + * @type {!chrome.bluetoothLowEnergy.CharacteristicEvent} + * @see https://developer.chrome.com/apps/bluetoothLowEnergy#event-onCharacteristicValueChanged + */ +chrome.bluetoothLowEnergy.onCharacteristicValueChanged; + + +/** + * Event whose listeners take a Descriptor parameter. + * @record + * @extends {ChromeBaseEvent} + */ +chrome.bluetoothLowEnergy.DescriptorEvent = function() {}; + + +/** + * @type {!chrome.bluetoothLowEnergy.DescriptorEvent} + * @see https://developer.chrome.com/apps/bluetoothLowEnergy#event-onDescriptorValueChanged + */ +chrome.bluetoothLowEnergy.onDescriptorValueChanged; + + +/** + * Event whose listeners take a Request parameter. + * @record + * @extends {ChromeBaseEvent} + */ +chrome.bluetoothLowEnergy.RequestEvent = function() {}; + + +/** + * @type {!chrome.bluetoothLowEnergy.RequestEvent} + * @see https://developer.chrome.com/apps/bluetoothLowEnergy#event-onCharacteristicReadRequest + */ +chrome.bluetoothLowEnergy.onCharacteristicReadRequest; + + +/** + * @type {!chrome.bluetoothLowEnergy.RequestEvent} + * @see https://developer.chrome.com/apps/bluetoothLowEnergy#event-onCharacteristicWriteRequest + */ +chrome.bluetoothLowEnergy.onCharacteristicWriteRequest; + + +/** + * @type {!chrome.bluetoothLowEnergy.RequestEvent} + * @see https://developer.chrome.com/apps/bluetoothLowEnergy#event-onDescriptorReadRequest + */ +chrome.bluetoothLowEnergy.onDescriptorReadRequest; + + +/** + * @type {!chrome.bluetoothLowEnergy.RequestEvent} + * @see https://developer.chrome.com/apps/bluetoothLowEnergy#event-onDescriptorWriteRequest + */ +chrome.bluetoothLowEnergy.onDescriptorWriteRequest; + + +/** + * @see http://developer.chrome.com/extensions/commands.html + * @const + */ +chrome.commands = {}; + + +/** + * @param {function(Array): void} callback Callback function. + * @return {undefined} + */ +chrome.commands.getAll = function(callback) {}; + + +/** @type {!ChromeEvent} */ +chrome.commands.onCommand; + + +/** + * @see https://developer.chrome.com/apps/copresence + * @const + */ +chrome.copresence = {}; + + +/** + * @typedef {?{ + * lowPower: (boolean|undefined), + * onlyBroadcast: (boolean|undefined), + * onlyScan: (boolean|undefined), + * audible: (boolean|undefined) + * }} + * @see https://developer.chrome.com/apps/copresence#type-Strategy + */ +chrome.copresence.Strategy; + + +/** + * @typedef {?{ + * type: string, + * payload: ArrayBuffer + * }} + * @see https://developer.chrome.com/apps/copresence#type-Message + */ +chrome.copresence.Message; + + +/** + * @typedef {?{ + * onlyEarshot: (boolean|undefined) + * }} + * https://developer.chrome.com/apps/copresence#type-AccessPolicy + */ +chrome.copresence.AccessPolicy; + + +/** + * @typedef {?{ + * id: string, + * message: !chrome.copresence.Message, + * timeToLiveMillis: (number|undefined), + * policy: (!chrome.copresence.AccessPolicy|undefined), + * strategies: (!chrome.copresence.Strategy|undefined) + * }} + * @see https://developer.chrome.com/apps/copresence#type-PublishOperation + */ +chrome.copresence.PublishOperation; + + +/** @typedef {?{type: string}} */ +chrome.copresence.SubscriptionFilter; + + +/** + * @typedef {?{ + * id: string, + * filter: !chrome.copresence.SubscriptionFilter, + * timeToLiveMillis: (number|undefined), + * strategies: (!chrome.copresence.Strategy|undefined) + * }} + * @see https://developer.chrome.com/apps/copresence#type-SubscribeOperation + */ +chrome.copresence.SubscribeOperation; + + +/** + * @typedef {?{ + * unpublishId: string + * }} + * @see https://developer.chrome.com/apps/copresence#type-UnpublishOperation + */ +chrome.copresence.UnpublishOperation; + + +/** + * @typedef {?{ + * unsubscribeId: string + * }} + * @see https://developer.chrome.com/apps/copresence#type-UnsubscribeOperation + */ +chrome.copresence.UnsubscribeOperation; + + +/** + * @typedef {?{ + * publish: (!chrome.copresence.PublishOperation|undefined), + * subscribe: (!chrome.copresence.SubscribeOperation|undefined), + * unpublish: (!chrome.copresence.UnpublishOperation|undefined), + * unsubscribe: (!chrome.copresence.UnsubscribeOperation|undefined) + * }} + * @see https://developer.chrome.com/apps/copresence#type-Operation + */ +chrome.copresence.Operation; + + +/** + * @param {!Array} operations + * @param {function(string): void} callback + * @see https://developer.chrome.com/apps/copresence#method-execute + * @return {undefined} + */ +chrome.copresence.execute = function(operations, callback) {}; + + + +/** + * Event whose listeners take a subscription id and received messages as a + * parameter. + * @record + * @extends {ChromeBaseEvent)>} + * @see https://developer.chrome.com/apps/copresence#event-onMessagesReceived + */ +chrome.copresence.MessagesReceivedEvent = function() {}; + + +/** + * @type {!chrome.copresence.MessagesReceivedEvent} + * @see https://developer.chrome.com/apps/copresence#event-onMessagesReceived + */ +chrome.copresence.onMessagesReceived; + + +/** + * @type {!ChromeStringEvent} + * @see https://developer.chrome.com/apps/copresence#event-onStatusUpdated + */ +chrome.copresence.onStatusUpdated; + + +/** + * @see https://developer.chrome.com/extensions/enterprise_platformKeys + * @const + */ +chrome.enterprise = {}; + + +/** + * @constructor + * deviceAttributes allows for reading device attributes. + * @see https://developer.chrome.com/extensions/enterprise_deviceAttributes. + */ +chrome.enterprise.deviceAttributes = function() {}; + + +/** + * @param {function(string): void} callback Called with the device identifier + * of the directory API when received. + * @return {undefined} + */ +chrome.enterprise.deviceAttributes.getDirectoryDeviceId = function(callback) {}; + + +/** + * @constructor + * platformKeys allows for generating hardware-backed keys and the installation + * of certificates for these keys. + * @see https://developer.chrome.com/extensions/enterprise_platformKeys. + */ +chrome.enterprise.platformKeys = function() {}; + + +/** + * @constructor + * @see https://developer.chrome.com/extensions/enterprise_platformKeys#type-Token + */ +chrome.enterprise.Token = function() {}; + + +/** + * @type {string} Unique id for the Token, either "user" or "system." + */ +chrome.enterprise.Token.prototype.id; + + +/** + * @type {!webCrypto.SubtleCrypto} Implements the WebCrypto's + * SubtleCrypto interface. The cryptographic operations, including key + * generation, are hardware-backed. + */ +chrome.enterprise.Token.prototype.subtleCrypto; + + +/** + * @param {!ArrayBuffer} challenge A challenge as emitted by the Verified Access + * Web API. + * @param {boolean|function(!ArrayBuffer): void} registerKeyOrCallback Either a + * flag indicating whether to register the key, in which case the callback + * is passed as the next arg, or the callback. If a flag is set, the current + * Enterprise Machine Key is registered with the "system" token and + * relinquishes the Enterprise Machine Key role. The key can then be + * associated with a certificate and used like any other signing key. This + * key is 2048-bit RSA. Subsequent calls to this function will then generate + * a new Enterprise Machine Key. + * @param {function(!ArrayBuffer=): void=} callback The callback (called back + * with the challenge response), if arg2 was the registerKey flag. + * @return {undefined} + */ +chrome.enterprise.platformKeys.challengeMachineKey = + function(challenge, registerKeyOrCallback, callback) {}; + + +/** + * @param {!ArrayBuffer} challenge A challenge as emitted by the Verified Access + * Web API. + * @param {boolean} registerKey If set, the current Enterprise User Key is + * registered with the "user" token and relinquishes the Enterprise User + * Key role. The key can then be associated with a certificate and used like + * any other signing key. This key is 2048-bit RSA. Subsequent calls to this + * function will then generate a new Enterprise User Key. + * @param {function(!ArrayBuffer): void} callback Called back with the + * challenge response. + * @return {undefined} + */ +chrome.enterprise.platformKeys.challengeUserKey = + function(challenge, registerKey, callback) {}; + + +/** + * @param {function(!Array): void} callback Called + * with an array of Tokens. + * @return {undefined} + */ +chrome.enterprise.platformKeys.getTokens = function(callback) {}; + + +/** + * @param {string} tokenId Id of cetificate token either "user" or "system". + * @param {(function(!Array): void)} callback Array of DER + * encoded x.509 certificates. + * @return {undefined} + */ +chrome.enterprise.platformKeys.getCertificates = function(tokenId, callback) {}; + + +/** + * @param {string} tokenId The id of a Token returned by getTokens. + * @param {!ArrayBuffer} certificate The DER encoding of a X.509 certificate. + * @param {function(): void=} opt_callback Called back when this operation is + * finished. + * @return {undefined} + */ +chrome.enterprise.platformKeys.importCertificate = + function(tokenId, certificate, opt_callback) {}; + + +/** + * @param {string} tokenId The id of a Token returned by getTokens. + * @param {!ArrayBuffer} certificate The DER encoding of a X.509 certificate. + * @param {(function(): void)=} opt_callback Called back when this operation is + * finished. + * @return {undefined} + */ +chrome.enterprise.platformKeys.removeCertificate = + function(tokenId, certificate, opt_callback) {}; + + +/** + * @see https://developer.chrome.com/extensions/extension.html + * @const + */ +chrome.extension = {}; + + +/** + * @enum {string} + * @see https://developer.chrome.com/extensions/extension#type-ViewType + */ +chrome.extension.ViewType = { + TAB: '', + POPUP: '', +}; + + +/** @type {!Object|undefined} */ +chrome.extension.lastError = {}; + + +/** + * @type {string|undefined} + */ +chrome.extension.lastError.message; + + +/** @type {boolean|undefined} */ +chrome.extension.inIncognitoContext; + + +// TODO: change Object to !Object when it's clear nobody is passing in null +// TODO: change Port to !Port since it should never be null +/** + * @param {string|Object=} opt_extensionIdOrConnectInfo Either the + * extensionId to connect to, in which case connectInfo params can be + * passed in the next optional argument, or the connectInfo params. + * @param {Object=} opt_connectInfo The connectInfo object, + * if arg1 was the extensionId to connect to. + * @return {Port} New port. + */ +chrome.extension.connect = function( + opt_extensionIdOrConnectInfo, opt_connectInfo) {}; + + +/** + * @return {Window} The global JS object for the background page. + */ +chrome.extension.getBackgroundPage = function() {}; + + +/** + * @param {string} path A path to a resource within an extension expressed + * relative to it's install directory. + * @return {string} The fully-qualified URL to the resource. + */ +chrome.extension.getURL = function(path) {}; + + +/** + * @typedef {?{ + * type: (!chrome.extension.ViewType|string|undefined), + * windowId: (number|undefined), + * tabId: (number|undefined) + * }} + */ +chrome.extension.ViewInfo; + +/** + * @param {?chrome.extension.ViewInfo=} opt_fetchProperties + * @return {Array} The global JS objects for each content view. + */ +chrome.extension.getViews = function(opt_fetchProperties) {}; + + +/** + * @param {function(boolean): void} callback Callback function. + * @return {undefined} + */ +chrome.extension.isAllowedFileSchemeAccess = function(callback) {}; + + +/** + * @param {function(boolean): void} callback Callback function. + * @return {undefined} + */ +chrome.extension.isAllowedIncognitoAccess = function(callback) {}; + + +/** + * @param {string|*} extensionIdOrRequest Either the extensionId to send the + * request to, in which case the request is passed as the next arg, or the + * request. + * @param {*=} opt_request The request value, if arg1 was the extensionId. + * @param {function(*): void=} opt_callback The callback function which + * takes a JSON response object sent by the handler of the request. + * @return {undefined} + */ +chrome.extension.sendMessage = function( + extensionIdOrRequest, opt_request, opt_callback) {}; + + +/** + * @param {number|*=} opt_arg1 Either the extensionId to send the request to, + * in which case the request is passed as the next arg, or the request. + * @param {*=} opt_request The request value, if arg1 was the extensionId. + * @param {function(*): void=} opt_callback The callback function which + * takes a JSON response object sent by the handler of the request. + * @return {undefined} + */ +chrome.extension.sendRequest = function(opt_arg1, opt_request, opt_callback) {}; + + +/** + * @param {string} data + * @return {undefined} + */ +chrome.extension.setUpdateUrlData = function(data) {}; + + +/** @type {!ChromeEvent} */ +chrome.extension.onConnect; + + +/** @type {!ChromeEvent} */ +chrome.extension.onConnectExternal; + + +/** @type {!ChromeEvent} */ +chrome.extension.onMessage; + + +/** @type {!ChromeEvent} */ +chrome.extension.onRequest; + + +/** @type {!ChromeEvent} */ +chrome.extension.onRequestExternal; + + + +/** @type {string} */ +chrome.runtime.id; + + +/** + * @param {function(!Window=): void} callback Callback function. + * @return {undefined} + */ +chrome.runtime.getBackgroundPage = function(callback) {}; + + +/** + * @param {function(): void=} opt_callback Callback function. + * @return {undefined} + */ +chrome.runtime.openOptionsPage = function(opt_callback) {}; + + +/** + * Manifest information returned from chrome.runtime.getManifest. See + * https://developer.chrome.com/extensions/manifest.html and + * https://developer.chrome.com/apps/manifest.html + * + * Note that: + * 1) There are several other fields not included here. They should be + * added to these externs as needed. + * 2) There are some distinct fields for app vs extension manifests. The + * below manifest definition contains the union of all fields; unique + * fields should be annotated as such (see e.g. kiosk_only property + * below). + * @constructor + */ +chrome.runtime.Manifest = function() {}; + + +/** @type {string} */ +chrome.runtime.Manifest.prototype.name; + + +/** @type {string} */ +chrome.runtime.Manifest.prototype.version; + + +/** @type {number|undefined} */ +chrome.runtime.Manifest.prototype.manifest_version; + + +/** @type {string|undefined} */ +chrome.runtime.Manifest.prototype.description; + + +/** @type {!chrome.runtime.Manifest.Oauth2|undefined} */ +chrome.runtime.Manifest.prototype.oauth2; + + +/** @type {!Array<(string|!Object)>} */ +chrome.runtime.Manifest.prototype.permissions; + + +/** + * App-only manifest field. + * @see https://developer.chrome.com/apps/manifest + * @type {boolean|undefined} + */ +chrome.runtime.Manifest.prototype.kiosk_only; + +/** + * App-only manifest field. + * @see https://developer.chrome.com/apps/manifest + * @type {boolean|undefined} + */ +chrome.runtime.Manifest.prototype.kiosk_enabled; + + + +/** + * Oauth2 info in the manifest. + * See http://developer.chrome.com/apps/app_identity.html#update_manifest. + * @constructor + */ +chrome.runtime.Manifest.Oauth2 = function() {}; + + +/** @type {string} */ +chrome.runtime.Manifest.Oauth2.prototype.client_id; + + +/**@type {!Array} */ +chrome.runtime.Manifest.Oauth2.prototype.scopes; + + +/** + * https://developer.chrome.com/extensions/runtime.html#method-getManifest + * https://developer.chrome.com/apps/runtime#method-getManifest + * @return {!chrome.runtime.Manifest} The full manifest file of the app or + * extension. + */ +chrome.runtime.getManifest = function() {}; + + +/** + * @param {string} path A path to a resource within an extension expressed + * relative to it's install directory. + * @return {string} The fully-qualified URL to the resource. + */ +chrome.runtime.getURL = function(path) {}; + + +/** + * @param {string} url This may be used to clean up server-side data, do + * analytics, and implement surveys. Maximum 255 characters. + * @return {undefined} + */ +chrome.runtime.setUninstallURL = function(url) {}; + + +/** + * Reloads the app or extension. + * @return {undefined} + */ +chrome.runtime.reload = function() {}; + + +/** + * @param {function(string, !Object=): void} callback Called with "throttled", + * "no_update", or "update_available". If an update is available, the object + * contains more information about the available update. + * @return {undefined} + */ +chrome.runtime.requestUpdateCheck = function(callback) {}; + + +/** + * Restart the ChromeOS device when the app runs in kiosk mode. Otherwise, it's + * no-op. + * @return {undefined} + */ +chrome.runtime.restart = function() {}; + + +/** + * @see https://developer.chrome.com/extensions/runtime#method-restartAfterDelay + * @param {number} seconds Time to wait in seconds before rebooting the device, + * or -1 to cancel a scheduled reboot. + * @param {function():void=} opt_callback A callback to be invoked when a + * restart request was successfully rescheduled. + * @return {undefined} + */ +chrome.runtime.restartAfterDelay = function(seconds, opt_callback) {}; + + +/** + * @see http://developer.chrome.com/extensions/runtime.html#method-connectNative + * @param {string} application Name of the registered native messaging host to + * connect to, like 'com.google.your_product'. + * @return {!Port} New port. + */ +chrome.runtime.connectNative = function(application) {}; + + +/** + * @see http://developer.chrome.com/extensions/runtime.html#method-sendNativeMessage + * @param {string} application Name of the registered native messaging host to + * connect to, like 'com.google.your_product'. + * @param {Object} message The message that will be passed to the native + * messaging host. + * @param {function(*)=} opt_callback Called with the response message sent by + * the native messaging host. If an error occurs while connecting to the + * native messaging host, the callback will be called with no arguments and + * chrome.runtime.lastError will be set to the error message. + * @return {undefined} + */ +chrome.runtime.sendNativeMessage = function( + application, message, opt_callback) {}; + + +/** + * + * @param {function(!Object)} callback + * @return {undefined} + */ +chrome.runtime.getPlatformInfo = function(callback) {}; + + +/** + * @param {function(!DirectoryEntry)} callback + * @return {undefined} + */ +chrome.runtime.getPackageDirectoryEntry = function(callback) {}; + + +/** @type {!chrome.runtime.PortEvent} */ +chrome.runtime.onConnect; + + +/** @type {!chrome.runtime.PortEvent} */ +chrome.runtime.onConnectExternal; + + +/** @type {!ChromeObjectEvent} */ +chrome.runtime.onInstalled; + + +/** @type {!chrome.runtime.MessageSenderEvent} */ +chrome.runtime.onMessage; + + +/** @type {!chrome.runtime.MessageSenderEvent} */ +chrome.runtime.onMessageExternal; + + +/** @type {!ChromeEvent} */ +chrome.runtime.onStartup; + + +/** @type {!ChromeEvent} */ +chrome.runtime.onSuspend; + + +/** @type {!ChromeEvent} */ +chrome.runtime.onSuspendCanceled; + + +/** @type {!ChromeObjectEvent} */ +chrome.runtime.onUpdateAvailable; + + +/** @type {!ChromeStringEvent} */ +chrome.runtime.onRestartRequired; + + + +/** + * Event whose listeners take a Port parameter. + * @record + * @extends {ChromeBaseEvent} + */ +chrome.runtime.PortEvent = function() {}; + + +/** + * Event whose listeners take a MessageSender and additional parameters. + * @see http://developer.chrome.com/dev/apps/runtime.html#event-onMessage + * @record + * @extends {ChromeBaseEvent} + */ +chrome.runtime.MessageSenderEvent = function() {}; + + +/** + * @const + * @see https://developer.chrome.com/extensions/tabs + */ +chrome.tabs = {}; + + +/** + * @enum {string} + * @see https://developer.chrome.com/extensions/tabs#type-TabStatus + */ +chrome.tabs.TabStatus = { + COMPLETE: '', + LOADING: '', +}; + + +/** + * @typedef {?{ + * code: (string|undefined), + * file: (string|undefined), + * allFrames: (boolean|undefined), + * matchAboutBlank: (boolean|undefined), + * runAt: (string|undefined) + * }} + */ +chrome.tabs.InjectDetails; + + +/** + * @see https://developer.chrome.com/extensions/tabs#method-captureVisibleTab + * @param {number|!chrome.types.ImageDetails|function(string):void} + * windowIdOrOptionsOrCallback One of: + * The target window. + * An object defining details about the format and quality of an image, in + * which case the window defaults to the current window. + * A callback function which accepts the data URL string of a JPEG encoding + * of the visible area of the captured tab. + * @param {(!chrome.types.ImageDetails|function(string):void)=} + * opt_optionsOrCallback Either an object defining details about the + * format and quality of an image, or a callback function which accepts the + * data URL string of a JPEG encoding of the visible area of the captured + * tab. + * @param {function(string):void=} opt_callback A callback function which + * accepts the data URL string of a JPEG encoding of the visible area of the + * captured tab. + * @return {undefined} + */ +chrome.tabs.captureVisibleTab = function(windowIdOrOptionsOrCallback, + opt_optionsOrCallback, opt_callback) {}; + + +/** + * @param {number} tabId Tab Id. + * @param {{name: (string|undefined)}=} connectInfo Info Object. + * @return {Port} New port. + */ +chrome.tabs.connect = function(tabId, connectInfo) {}; + + +/** + * @typedef {?{ + * windowId: (number|undefined), + * index: (number|undefined), + * url: (string|undefined), + * active: (boolean|undefined), + * pinned: (boolean|undefined), + * openerTabId: (number|undefined) + * }} + */ +chrome.tabs.CreateProperties; + + +/** + * @param {!chrome.tabs.CreateProperties} createProperties Info object. + * @param {function(!Tab): void=} opt_callback The callback function. + * @return {undefined} + */ +chrome.tabs.create = function(createProperties, opt_callback) {}; + + +/** + * @see https://developer.chrome.com/extensions/tabs#method-detectLanguage + * @param {number|function(string): void} tabIdOrCallback The tab id, or a + * callback function that will be invoked with the language of the active + * tab in the current window. + * @param {function(string): void=} opt_callback An optional callback function + * that will be invoked with the language of the tab specified as first + * argument. + * @return {undefined} + */ +chrome.tabs.detectLanguage = function(tabIdOrCallback, opt_callback) {}; + + +/** + * @see https://developer.chrome.com/extensions/tabs#method-discard + * @param {number|function(!Tab): void} tabIdOrCallback + * @param {function(!Tab): void=} opt_callback + */ +chrome.tabs.discard; + + +/** + * @see https://developer.chrome.com/extensions/tabs#method-executeScript + * @param {number|!chrome.tabs.InjectDetails} tabIdOrDetails + * Either the id of the tab in which to run the script, or an object + * containing the details of the script to run, in which case the script + * will be executed in the active tab of the current window. + * @param {(!chrome.tabs.InjectDetails|function(!Array<*>):void)=} + * opt_detailsOrCallback Either an object containing the details of the + * script to run, if the tab id was speficied as first argument, or a + * callback that will be invoked with the result of the execution of the + * script in every injected frame. + * @param {function(!Array<*>):void=} opt_callback A callback that will be + * invoked with the result of the execution of the script in every + * injected frame. + * @return {undefined} + */ +chrome.tabs.executeScript = function(tabIdOrDetails, opt_detailsOrCallback, + opt_callback) {}; + + +/** + * @param {number} tabId Tab id. + * @param {function(!Tab): void} callback Callback. + * @return {undefined} + */ +chrome.tabs.get = function(tabId, callback) {}; + + +/** + * Note (2014-05-21): Because this function is deprecated, the types of it's + * parameters were not upgraded to make the first parameter optional and to mark + * the Array and Tab in the callback as non-null. + * + * @param {number?} windowId Window id. + * @param {function(Array): void} callback Callback. + * @deprecated Please use tabs.query {windowId: windowId}. + * @return {undefined} + */ +chrome.tabs.getAllInWindow = function(windowId, callback) {}; + + +/** + * @param {function(!Tab=): void} callback Callback. + * @return {undefined} + */ +chrome.tabs.getCurrent = function(callback) {}; + + +/** + * Note (2014-05-21): Because this function is deprecated, the types of it's + * parameters were not upgraded to make the first parameter optional and to mark + * the Array and Tab in the callback as non-null. + * + * @param {number?} windowId Window id. + * @param {function(Tab): void} callback Callback. + * @deprecated Please use tabs.query({active: true}). + * @return {undefined} + */ +chrome.tabs.getSelected = function(windowId, callback) {}; + + +/** + * @see https://developer.chrome.com/extensions/tabs#method-getZoom + * @param {number|function(number): void} tabIdOrCallback + * @param {function(number): void=} opt_callback + * @return {undefined} + */ +chrome.tabs.getZoom = function(tabIdOrCallback, opt_callback) {}; + + +/** + * @see https://developer.chrome.com/extensions/tabs#type-ZoomSettings + * @typedef {?{ + * mode: (string|undefined), + * scope: (string|undefined), + * defaultZoomFactor: (number|undefined), + * }} + */ +chrome.tabs.ZoomSettings; + + +/** + * @see https://developer.chrome.com/extensions/tabs#method-getZoomSettings + * @param {number|function(!chrome.tabs.ZoomSettings): void} tabIdOrCallback + * @param {function(!chrome.tabs.ZoomSettings): void=} opt_callback + */ +chrome.tabs.getZoomSettings = function(tabIdOrCallback, opt_callback) {}; + + +/** + * @typedef {?{ + * windowId: (number|undefined), + * tabs: (number|!Array) + * }} + */ +chrome.tabs.HighlightInfo; + + +/** + * @param {!chrome.tabs.HighlightInfo} highlightInfo + * @param {function(!Window): void} callback Callback function invoked + * with each appropriate Window. + * @return {undefined} + */ +chrome.tabs.highlight = function(highlightInfo, callback) {}; + + +/** + * @link https://developer.chrome.com/extensions/tabs#method-insertCSS + * @param {number|!chrome.tabs.InjectDetails} tabIdOrDetails + * Either the id of the tab in which to run the script, or an object + * containing the details of the CSS to insert, in which case the script + * will be executed in the active tab of the current window. + * @param {(!chrome.tabs.InjectDetails|function():void)=} + * opt_detailsOrCallback Either an object containing the details of the + * CSS to insert, if the tab id was speficied as first argument, or a + * callback that will be invoked after the CSS has been injected. + * @param {function():void=} opt_callback A callback that will be invoked after + * the CSS has been injected. + * @return {undefined} + */ +chrome.tabs.insertCSS = function(tabIdOrDetails, opt_detailsOrCallback, + opt_callback) {}; + + +/** + * @typedef {?{ + * windowId: (number|undefined), + * index: number + * }} + */ +chrome.tabs.MoveProperties; + + +/** + * @param {number|!Array} tabId Tab id or array of tab ids. + * @param {!chrome.tabs.MoveProperties} moveProperties + * @param {function((!Tab|!Array)): void=} opt_callback Callback. + * @return {undefined} + */ +chrome.tabs.move = function(tabId, moveProperties, opt_callback) {}; + + +/** + * @typedef {?{ + * active: (boolean|undefined), + * pinned: (boolean|undefined), + * audible: (boolean|undefined), + * muted: (boolean|undefined), + * highlighted: (boolean|undefined), + * discarded: (boolean|undefined), + * autoDiscardable: (boolean|undefined), + * currentWindow: (boolean|undefined), + * lastFocusedWindow: (boolean|undefined), + * status: (!chrome.tabs.TabStatus|string|undefined), + * title: (string|undefined), + * url: (!Array|string|undefined), + * windowId: (number|undefined), + * windowType: (string|undefined), + * index: (number|undefined) + * }} + */ +chrome.tabs.QueryInfo; + + +/** + * @param {!chrome.tabs.QueryInfo} queryInfo + * @param {function(!Array): void} callback Callback. + * @return {undefined} + */ +chrome.tabs.query = function(queryInfo, callback) {}; + + +/** + * @see https://developer.chrome.com/extensions/tabs#method-query + * @param {number} tabId The ID of the tab which is to be duplicated. + * @param {(function(!Tab=):void)=} opt_callback A callback to be invoked with + * details about the duplicated tab. + * @return {undefined} + */ +chrome.tabs.duplicate = function(tabId, opt_callback) {}; + + +/** + * @typedef {?{ + * bypassCache: (boolean|undefined) + * }} + */ +chrome.tabs.ReloadProperties; + + +/** + * @see https://developer.chrome.com/extensions/tabs#method-reload + * @param {(number|!chrome.tabs.ReloadProperties|function():void)=} + * opt_tabIdOrReloadPropertiesOrCallback One of: + * The ID of the tab to reload; defaults to the selected tab of the current + * window. + * An object specifying boolean flags to customize the reload operation. + * A callback to be invoked when the reload is complete. + * @param {(!chrome.tabs.ReloadProperties|function():void)=} + * opt_reloadPropertiesOrCallback Either an object specifying boolean flags + * to customize the reload operation, or a callback to be invoked when the + * reload is complete, if no object needs to be specified. + * @param {function():void=} opt_callback A callback to be invoked when the + * reload is complete. + * @return {undefined} + */ +chrome.tabs.reload = function(opt_tabIdOrReloadPropertiesOrCallback, + opt_reloadPropertiesOrCallback, opt_callback) {}; + + +/** + * @param {number|!Array} tabIds A tab ID or an array of tab IDs. + * @param {function(): void=} opt_callback Callback. + * @return {undefined} + */ +chrome.tabs.remove = function(tabIds, opt_callback) {}; + + +/** + * @typedef {?{ + * frameId: (number|undefined) + * }} + */ +chrome.tabs.SendMessageOptions; + + +/** + * @param {number} tabId Tab id. + * @param {*} request The request value of any type. + * @param {(!chrome.tabs.SendMessageOptions|function(*): void)=} + * opt_optionsOrCallback The object with an optional "frameId" or the + * callback function. + * @param {function(*): void=} opt_callback The callback function which + * takes a JSON response object sent by the handler of the request. + * @return {undefined} + */ +chrome.tabs.sendMessage = function(tabId, request, opt_optionsOrCallback, + opt_callback) {}; + + +/** + * @param {number} tabId Tab id. + * @param {*} request The request value of any type. + * @param {function(*): void=} opt_callback The callback function which + * takes a JSON response object sent by the handler of the request. + * @deprecated Please use runtime.sendMessage. + * @return {undefined} + */ +chrome.tabs.sendRequest = function(tabId, request, opt_callback) {}; + + +/** + * @see https://developer.chrome.com/extensions/tabs#method-setZoom + * @param {number} tabIdOrZoomFactor + * @param {(number|function(): void)=} opt_zoomFactorOrCallback + * @param {function(): void=} opt_callback + * @return {undefined} + */ +chrome.tabs.setZoom = function( + tabIdOrZoomFactor, opt_zoomFactorOrCallback, opt_callback) {}; + + +/** + * @see https://developer.chrome.com/extensions/tabs#method-setZoomSettings + * @param {number|!chrome.tabs.ZoomSettings} tabIdOrZoomSettings + * @param {(!chrome.tabs.ZoomSettings|function(): void)=} + * opt_zoomSettingsOrCallback + * @param {function(): void=} opt_callback + */ +chrome.tabs.setZoomSettings = function( + tabIdOrZoomSettings, opt_zoomSettingsOrCallback, opt_callback) {}; + + +/** + * @typedef {?{ + * url: (string|undefined), + * active: (boolean|undefined), + * highlighted: (boolean|undefined), + * pinned: (boolean|undefined), + * openerTabId: (number|undefined) + * }} + */ +chrome.tabs.UpdateProperties; + + +/** + * @see https://developer.chrome.com/extensions/tabs#method-update + * @param {number|!chrome.tabs.UpdateProperties} tabIdOrUpdateProperties + * Either the id of the tab to update, or an object with new property + * values, in which case the selected tab of the current window will be + * updated. + * @param {(!chrome.tabs.UpdateProperties|function(Tab):void)=} + * opt_updatePropertiesOrCallback Either an object with new property values, + * if the tabId was specified as first parameter, or an optional callback + * that will be invoked with information about the tab being updated. + * @param {function(!Tab=): void=} opt_callback An optional callback that will + * be invoked with information about the tab being updated. + * @return {undefined} + */ +chrome.tabs.update = function(tabIdOrUpdateProperties, + opt_updatePropertiesOrCallback, opt_callback) {}; + + +/** + * @type {!ChromeEvent} + * @deprecated Please use tabs.onActivated. + */ +chrome.tabs.onActiveChanged; + + +/** @type {!ChromeEvent} */ +chrome.tabs.onActivated; + + +/** @type {!ChromeEvent} */ +chrome.tabs.onAttached; + + +/** @type {!ChromeEvent} */ +chrome.tabs.onCreated; + + +/** @type {!ChromeEvent} */ +chrome.tabs.onDetached; + + +/** + * @type {!ChromeEvent} + * @deprecated Please use tabs.onHighlighted. + */ +chrome.tabs.onHighlightChanged; + + +/** + * @type {!ChromeEvent} + */ +chrome.tabs.onHighlighted; + + +/** @type {!ChromeEvent} */ +chrome.tabs.onMoved; + + +/** @type {!ChromeEvent} */ +chrome.tabs.onRemoved; + + +/** @type {!ChromeEvent} */ +chrome.tabs.onUpdated; + + +/** @type {!ChromeEvent} */ +chrome.tabs.onReplaced; + +// DEPRECATED: +// TODO(user): Remove once all usage has been confirmed to have ended. + + +/** + * @type {!ChromeEvent} + * @deprecated Please use tabs.onActivated. + */ +chrome.tabs.onSelectionChanged; + + +/** + * @see https://developer.chrome.com/extensions/tabs#event-onZoomChange + * @type {!ChromeObjectEvent} + */ +chrome.tabs.onZoomChange; + + +/** + * @see https://developer.chrome.com/extensions/topSites + * @const + */ +chrome.topSites = {}; + + + +/** + * @constructor + * @see https://developer.chrome.com/extensions/topSites#type-MostVisitedURL + */ +chrome.topSites.MostVisitedURL = function() {}; + + +/** @type {string} */ +chrome.topSites.MostVisitedURL.prototype.url; + + +/** @type {string} */ +chrome.topSites.MostVisitedURL.prototype.title; + + +/** + * Gets a list of top sites. + * @param {function(!Array)} callback Invoked + * with a list of most visited URLs. + * @see https://developer.chrome.com/extensions/topSites#method-get + * @return {undefined} + */ +chrome.topSites.get = function(callback) {}; + + +/** + * @const + * @see https://developer.chrome.com/extensions/windows.html + */ +chrome.windows = {}; + + +/** + * @param {Object=} opt_createData May have many keys to specify parameters. + * Or the callback. + * @param {function(ChromeWindow): void=} opt_callback Callback. + * @return {undefined} + */ +chrome.windows.create = function(opt_createData, opt_callback) {}; + + +/** + * @param {number} id Window id. + * @param {Object=} opt_getInfo May have 'populate' key. Or the callback. + * @param {function(!ChromeWindow): void=} opt_callback Callback when + * opt_getInfo is an object. + * @return {undefined} + */ +chrome.windows.get = function(id, opt_getInfo, opt_callback) {}; + + +/** + * @param {Object=} opt_getInfo May have 'populate' key. Or the callback. + * @param {function(!Array): void=} opt_callback Callback. + * @return {undefined} + */ +chrome.windows.getAll = function(opt_getInfo, opt_callback) {}; + + +/** + * @param {Object=} opt_getInfo May have 'populate' key. Or the callback. + * @param {function(ChromeWindow): void=} opt_callback Callback. + * @return {undefined} + */ +chrome.windows.getCurrent = function(opt_getInfo, opt_callback) { }; + + +/** + * @param {Object=} opt_getInfo May have 'populate' key. Or the callback. + * @param {function(ChromeWindow): void=} opt_callback Callback. + * @return {undefined} + */ +chrome.windows.getLastFocused = function(opt_getInfo, opt_callback) { }; + + +/** + * @param {number} tabId Tab Id. + * @param {function(): void=} opt_callback Callback. + * @return {undefined} + */ +chrome.windows.remove = function(tabId, opt_callback) {}; + + +/** + * @param {number} tabId Tab Id. + * @param {Object} updateProperties An object which may have many keys for + * various options. + * @param {function(): void=} opt_callback Callback. + * @return {undefined} + */ +chrome.windows.update = function(tabId, updateProperties, opt_callback) {}; + + +/** @type {!ChromeEvent} */ +chrome.windows.onCreated; + + +/** @type {!ChromeEvent} */ +chrome.windows.onFocusChanged; + + +/** @type {!ChromeEvent} */ +chrome.windows.onRemoved; + + +/** + * @see https://developer.chrome.com/extensions/windows.html#property-WINDOW_ID_NONE + * @type {number} + */ +chrome.windows.WINDOW_ID_NONE; + + +/** + * @see https://developer.chrome.com/extensions/windows.html#property-WINDOW_ID_CURRENT + * @type {number} + */ +chrome.windows.WINDOW_ID_CURRENT; + + +/** + * @const + * @see https://developer.chrome.com/extensions/i18n.html + */ +chrome.i18n = {}; + + +/** + * @param {function(Array): void} callback The callback function which + * accepts an array of the accept languages of the browser, such as + * 'en-US','en','zh-CN'. + * @return {undefined} + */ +chrome.i18n.getAcceptLanguages = function(callback) {}; + + +/** + * @param {string} messageName + * @param {(string|Array)=} opt_args + * @return {string} + */ +chrome.i18n.getMessage = function(messageName, opt_args) {}; + + +/** + * @return {string} + */ +chrome.i18n.getUILanguage = function() {}; + + +/** + * @param {string} text User input string to be detected. + * @param {function(!Object)} callback The callback for passing back the + * language detection result. + * @return {undefined} + */ +chrome.i18n.detectLanguage = function(text, callback) {}; + + +/** + * @const + * @see https://developer.chrome.com/extensions/pageAction.html + */ +chrome.pageAction = {}; + + +/** + * @param {number} tabId Tab Id. + * @return {undefined} + */ +chrome.pageAction.hide = function(tabId) {}; + + +/** + * @param {Object} details An object which has 'tabId' and either + * 'imageData' or 'path'. + * @return {undefined} + */ +chrome.pageAction.setIcon = function(details) {}; + + +/** + * @param {Object} details An object which may have 'popup' or 'tabId' as keys. + * @return {undefined} + */ +chrome.pageAction.setPopup = function(details) {}; + + +/** + * @param {Object} details An object which has 'tabId' and 'title'. + * @return {undefined} + */ +chrome.pageAction.setTitle = function(details) {}; + + +/** + * @param {number} tabId Tab Id. + * @return {undefined} + */ +chrome.pageAction.show = function(tabId) {}; + + +/** @type {!ChromeEvent} */ +chrome.pageAction.onClicked; + + +/** + * @const + * @see https://developer.chrome.com/apps/browser + */ +chrome.browser = {}; + + +/** + * @param {{url: string}} details An object with a single 'url' key. + * @param {(function(): void)=} opt_callback The callback function. If an error + * occurs opening the URL, chrome.runtime.lastError will be set to the error + * message. + * @return {undefined} + */ +chrome.browser.openTab = function(details, opt_callback) {}; + + +/** + * @const + * @see https://developer.chrome.com/extensions/browserAction.html + */ +chrome.browserAction = {}; + + +/** + * @typedef {?{ + * tabId: (number|undefined) + * }} + */ +chrome.browserAction.Tab; + + +/** + * @typedef {Array} + * @see https://developer.chrome.com/extensions/browserAction#type-ColorArray + */ +chrome.browserAction.ColorArray; + + +/** + * @typedef {{ + * imageData: (!ImageData|!Object|undefined), + * path: (string|!Object|undefined), + * tabId: (number|undefined) + * }} + */ +chrome.browserAction.SetIconImageData; + + +/** + * @param {{ + * title: string, + * tabId: (number|undefined) + * }} details + * @see https://developer.chrome.com/extensions/browserAction#method-setTitle + * @return {undefined} + */ +chrome.browserAction.setTitle = function(details) {}; + + +/** + * @param {!chrome.browserAction.Tab} details + * @param {function(string): void} callback + * @see https://developer.chrome.com/extensions/browserAction#method-getTitle + * @return {undefined} + */ +chrome.browserAction.getTitle = function(details, callback) {}; + + +/** + * @param {!chrome.browserAction.SetIconImageData} details + * @param {function(): void=} opt_callback + * @see https://developer.chrome.com/extensions/browserAction#method-setIcon + * @return {undefined} + */ +chrome.browserAction.setIcon = function(details, opt_callback) {}; + + +/** + * @param {{ + * tabId: (number|undefined), + * popup: string + * }} details + * @see https://developer.chrome.com/extensions/browserAction#method-setPopup + * @return {undefined} + */ +chrome.browserAction.setPopup = function(details) {}; + + +/** + * @param {!chrome.browserAction.Tab} details + * @param {function(string): void} callback + * @see https://developer.chrome.com/extensions/browserAction#method-getPopup + * @return {undefined} + */ +chrome.browserAction.getPopup = function(details, callback) {}; + + +/** + * @param {{ + * text: string, + * tabId: (number|undefined) + * }} details + * @see https://developer.chrome.com/extensions/browserAction#method-setBadgeText + * @return {undefined} + */ +chrome.browserAction.setBadgeText = function(details) {}; + + +/** + * @param {!chrome.browserAction.Tab} details + * @param {function(string): void} callback + * @see https://developer.chrome.com/extensions/browserAction#method-getBadgeText + * @return {undefined} + */ +chrome.browserAction.getBadgeText = function(details, callback) {}; + + +/** + * @param {{ + * color: (string|chrome.browserAction.ColorArray), + * tabId: (number|undefined) + * }} details + * @see https://developer.chrome.com/extensions/browserAction#method-setBadgeBackgroundColor + * @return {undefined} + */ +chrome.browserAction.setBadgeBackgroundColor = function(details) {}; + + +/** + * @param {!chrome.browserAction.Tab} details + * @param {function(chrome.browserAction.ColorArray): void} callback + * @see https://developer.chrome.com/extensions/browserAction#method-getBadgeBackgroundColor + * @return {undefined} + */ +chrome.browserAction.getBadgeBackgroundColor = function(details, callback) {}; + + +/** + * @param {number=} opt_tabId + * @see https://developer.chrome.com/extensions/browserAction#method-enable + * @return {undefined} + */ +chrome.browserAction.enable = function(opt_tabId) {}; + + +/** + * @param {number=} opt_tabId + * @see https://developer.chrome.com/extensions/browserAction#method-disable + * @return {undefined} + */ +chrome.browserAction.disable = function(opt_tabId) {}; + + +/** + * @record + * @extends {ChromeBaseEvent} + */ +chrome.browserAction.BrowserActionTabEvent = function() {}; + + +/** + * @type {!chrome.browserAction.BrowserActionTabEvent} + * @see https://developer.chrome.com/extensions/browserAction#event-onClicked + */ +chrome.browserAction.onClicked; + + +/** + * @const + * @see https://developer.chrome.com/extensions/bookmarks.html + */ +chrome.bookmarks = {}; + + +/** + * @typedef {?{ + * parentId: (string|undefined), + * index: (number|undefined), + * url: (string|undefined), + * title: (string|undefined) + * }} + * @see https://developer.chrome.com/extensions/bookmarks#method-create + */ +chrome.bookmarks.CreateDetails; + + +/** + * @typedef {?{ + * query: (string|undefined), + * url: (string|undefined), + * title: (string|undefined) + * }} + * @see https://developer.chrome.com/extensions/bookmarks#method-search + */ +chrome.bookmarks.SearchDetails; + + +/** + * @param {(string|Array)} idOrIdList + * @param {function(Array): void} callback The + * callback function which accepts an array of BookmarkTreeNode. + * @return {Array} + */ +chrome.bookmarks.get = function(idOrIdList, callback) {}; + + +/** + * @param {string} id + * @param {function(Array): void} callback The + * callback function which accepts an array of BookmarkTreeNode. + * @return {Array} + */ +chrome.bookmarks.getChildren = function(id, callback) {}; + + +/** + * @param {number} numberOfItems The number of items to return. + * @param {function(Array): void} callback The + * callback function which accepts an array of BookmarkTreeNode. + * @return {Array} + */ +chrome.bookmarks.getRecent = function(numberOfItems, callback) {}; + + +/** + * @param {function(Array): void} callback The + * callback function which accepts an array of BookmarkTreeNode. + * @return {Array} + */ +chrome.bookmarks.getTree = function(callback) {}; + + +/** + * @param {string} id The ID of the root of the subtree to retrieve. + * @param {function(Array): void} callback The + * callback function which accepts an array of BookmarkTreeNode. + * @return {Array} + */ +chrome.bookmarks.getSubTree = function(id, callback) {}; + + +/** + * @param {string|!chrome.bookmarks.SearchDetails} query + * @param {function(Array): void} callback + * @return {Array} + */ +chrome.bookmarks.search = function(query, callback) {}; + + +/** + * @param {chrome.bookmarks.CreateDetails} bookmark + * @param {function(BookmarkTreeNode): void=} opt_callback The + * callback function which accepts a BookmarkTreeNode object. + * @return {undefined} + */ +chrome.bookmarks.create = function(bookmark, opt_callback) {}; + + +/** + * @param {string} id + * @param {Object} destination An object which has optional 'parentId' and + * optional 'index'. + * @param {function(BookmarkTreeNode): void=} opt_callback + * The callback function which accepts a BookmarkTreeNode object. + * @return {undefined} + */ +chrome.bookmarks.move = function(id, destination, opt_callback) {}; + + +/** + * @param {string} id + * @param {Object} changes An object which may have 'title' as a key. + * @param {function(BookmarkTreeNode): void=} opt_callback The + * callback function which accepts a BookmarkTreeNode object. + * @return {undefined} + */ +chrome.bookmarks.update = function(id, changes, opt_callback) {}; + + +/** + * @param {string} id + * @param {function(): void=} opt_callback + * @return {undefined} + */ +chrome.bookmarks.remove = function(id, opt_callback) {}; + + +/** + * @param {string} id + * @param {function(): void=} opt_callback + * @return {undefined} + */ +chrome.bookmarks.removeTree = function(id, opt_callback) {}; + + +/** + * @param {function(): void=} opt_callback + * @return {undefined} + */ +chrome.bookmarks.import = function(opt_callback) {}; + + +/** + * @param {function(): void=} opt_callback + * @return {undefined} + */ +chrome.bookmarks.export = function(opt_callback) {}; + + +/** @type {!ChromeEvent} */ +chrome.bookmarks.onChanged; + + +/** @type {!ChromeEvent} */ +chrome.bookmarks.onChildrenReordered; + + +/** @type {!ChromeEvent} */ +chrome.bookmarks.onCreated; + + +/** @type {!ChromeEvent} */ +chrome.bookmarks.onImportBegan; + + +/** @type {!ChromeEvent} */ +chrome.bookmarks.onImportEnded; + + +/** @type {!ChromeEvent} */ +chrome.bookmarks.onMoved; + + +/** @type {!ChromeEvent} */ +chrome.bookmarks.onRemoved; + + +/** + * @typedef {?{ + * content: string, + * description: string + * }} + */ +var SuggestResult; + + +/** + * @const + * @see https://developer.chrome.com/extensions/omnibox.html + */ +chrome.omnibox = {}; + + + +/** + * @record + * @extends {ChromeBaseEvent))>} + */ +chrome.omnibox.InputChangedEvent = function() {}; + + +/** + * @record + * @extends {ChromeBaseEvent} + */ +chrome.omnibox.InputEnteredEvent = function() {}; + + +/** + * @param {{description: string}} suggestion A partial SuggestResult object. + * @return {undefined} + */ +chrome.omnibox.setDefaultSuggestion = function(suggestion) {}; + + +/** @type {!ChromeEvent} */ +chrome.omnibox.onInputCancelled; + + +/** @type {!chrome.omnibox.InputChangedEvent} */ +chrome.omnibox.onInputChanged; + + +/** @type {!chrome.omnibox.InputEnteredEvent} */ +chrome.omnibox.onInputEntered; + + +/** @type {!ChromeEvent} */ +chrome.omnibox.onInputStarted; + + +/** + * @const + * @see https://developer.chrome.com/extensions/dev/contextMenus.html + */ +chrome.contextMenus = {}; + + +/** + * @typedef {?{ + * type: (string|undefined), + * id: (string|undefined), + * title: (string|undefined), + * checked: (boolean|undefined), + * contexts: (!Array|undefined), + * onclick: (function(!Object, !Tab)|undefined), + * parentId: (number|string|undefined), + * documentUrlPatterns: (!Array|undefined), + * targetUrlPatterns: (!Array|undefined), + * enabled: (boolean|undefined) + * }} + * @see https://developer.chrome.com/extensions/contextMenus#method-create + */ +chrome.contextMenus.CreateProperties; + + +/** + * @typedef {?{ + * type: (string|undefined), + * title: (string|undefined), + * checked: (boolean|undefined), + * contexts: (!Array|undefined), + * onclick: (function(!Object, !Tab)|undefined), + * parentId: (number|string|undefined), + * documentUrlPatterns: (!Array|undefined), + * targetUrlPatterns: (!Array|undefined), + * enabled: (boolean|undefined) + * }} + * @see https://developer.chrome.com/extensions/contextMenus#method-update + */ +chrome.contextMenus.UpdateProperties; + + +/** + * @param {!chrome.contextMenus.CreateProperties} createProperties + * @param {function()=} opt_callback + * @return {(number|string)} The id of the newly created window. + * @see https://developer.chrome.com/extensions/contextMenus#method-create + */ +chrome.contextMenus.create = function(createProperties, opt_callback) {}; + + +/** + * @param {(number|string)} id + * @param {!chrome.contextMenus.UpdateProperties} updateProperties + * @param {function()=} opt_callback + * @see https://developer.chrome.com/extensions/contextMenus#method-update + * @return {undefined} + */ +chrome.contextMenus.update = function(id, updateProperties, opt_callback) {}; + + +/** + * @param {(number|string)} menuItemId + * @param {function()=} opt_callback + * @see https://developer.chrome.com/extensions/contextMenus#method-remove + * @return {undefined} + */ +chrome.contextMenus.remove = function(menuItemId, opt_callback) {}; + + +/** + * @param {function()=} opt_callback + * @see https://developer.chrome.com/extensions/contextMenus#method-removeAll + * @return {undefined} + */ +chrome.contextMenus.removeAll = function(opt_callback) {}; + + +/** + * @record + * @extends {ChromeBaseEvent} + * @see https://developer.chrome.com/extensions/contextMenus#event-onClicked + */ +chrome.contextMenus.ClickedEvent = function() {}; + + +/** + * @type {!chrome.contextMenus.ClickedEvent} + * @see https://developer.chrome.com/extensions/contextMenus#event-onClicked + */ +chrome.contextMenus.onClicked; + + +/** + * @const + * @see https://developer.chrome.com/extensions/dev/cookies.html + */ +chrome.cookies = {}; + + +/** + * This typedef is used for the parameters to chrome.cookies.get, + * chrome.cookies.remove, and for the parameter to remove's callback. These uses + * all identify a single cookie uniquely without specifying its content, and the + * objects are identical except for the the storeId being optional vs required. + * If greater divergence occurs, then going to two typedefs is recommended. + * + * @typedef {?{ + * url: string, + * name: string, + * storeId: (string|undefined) + * }} + */ +chrome.cookies.CookieIdentifier; + + +/** + * @param {!chrome.cookies.CookieIdentifier} details + * @param {function(Cookie=): void} callback + * @return {undefined} + */ +chrome.cookies.get = function(details, callback) {}; + + +/** + * @param {Object} details + * @param {function(Array): void} callback + * @return {undefined} + */ +chrome.cookies.getAll = function(details, callback) {}; + + +/** + * @param {function(Array): void} callback + * @return {undefined} + */ +chrome.cookies.getAllCookieStores = function(callback) {}; + + +/** + * @param {!chrome.cookies.CookieIdentifier} details + * @param {function(chrome.cookies.CookieIdentifier): void=} opt_callback If + * removal failed for any reason, the parameter will be "null", and + * "chrome.runtime.lastError" will be set. + * @return {undefined} + */ +chrome.cookies.remove = function(details, opt_callback) {}; + + +/** + * @typedef {?{ + * url: string, + * name: (string|undefined), + * value: (string|undefined), + * domain: (string|undefined), + * path: (string|undefined), + * secure: (boolean|undefined), + * httpOnly: (boolean|undefined), + * expirationDate: (number|undefined), + * storeId: (string|undefined) + * }} + */ +chrome.cookies.CookieSetDetails; + + +/** + * @param {!chrome.cookies.CookieSetDetails} details + * @param {function(Cookie): void=} opt_callback If setting failed for any + * reason, the parameter will be "null", and "chrome.runtime.lastError" will + * be set. + * @return {undefined} + */ +chrome.cookies.set = function(details, opt_callback) {}; + + +/** + * @see https://developer.chrome.com/extensions/cookies.html#event-onChanged + * @type {!ChromeEvent} + */ +chrome.cookies.onChanged; + + + +/** @constructor */ +function CookieChangeInfo() {} + + +/** @type {boolean} */ +CookieChangeInfo.prototype.removed; + + +/** @type {Cookie} */ +CookieChangeInfo.prototype.cookie; + + +/** @type {string} */ +CookieChangeInfo.prototype.cause; + + +/** @const */ +chrome.management = {}; + + +/** + * @typedef {?{ + * showConfirmDialog: (boolean|undefined) + * }} + */ +chrome.management.InstallOptions; + + +/** + * @param {string} id + * @param {function(!ExtensionInfo): void=} opt_callback Optional callback + * function. + * @return {undefined} + */ +chrome.management.get = function(id, opt_callback) {}; + + +/** + * @param {function(!Array): void=} opt_callback Optional + * callback function. + * @return {!Array} + */ +chrome.management.getAll = function(opt_callback) {}; + + +/** + * @param {string} id The id of an already installed extension. + * @param {function(!Array)=} opt_callback Optional callback function. + * @return {undefined} + */ +chrome.management.getPermissionWarningsById = function(id, opt_callback) {}; + + +/** + * @param {string} manifestStr Extension's manifest JSON string. + * @param {function(!Array)=} opt_callback Optional callback function. + * @return {undefined} + */ +chrome.management.getPermissionWarningsByManifest = + function(manifestStr, opt_callback) {}; + + +/** + * @param {string} id The id of an already installed extension. + * @param {function(): void=} opt_callback Optional callback function. + * @return {undefined} + */ +chrome.management.launchApp = function(id, opt_callback) {}; + + +/** + * @param {string} id The id of an already installed extension. + * @param {boolean} enabled Whether this item should be enabled. + * @param {function(): void=} opt_callback Optional callback function. + * @return {undefined} + */ +chrome.management.setEnabled = function(id, enabled, opt_callback) {}; + + +/** + * @param {string} id The id of an already installed extension. + * @param {(!chrome.management.InstallOptions|function(): void)=} + * opt_optionsOrCallback An optional uninstall options object or an optional + * callback function. + * @param {function(): void=} opt_callback Optional callback function. + * @return {undefined} + */ +chrome.management.uninstall = + function(id, opt_optionsOrCallback, opt_callback) {}; + + +/** + * @param {(!chrome.management.InstallOptions|function(): void)=} + * opt_optionsOrCallback An optional uninstall options object or an optional + * callback function. + * @param {function(): void=} opt_callback An optional callback function. + * @return {undefined} + */ +chrome.management.uninstallSelf = + function(opt_optionsOrCallback, opt_callback) {}; + + +/** + * @param {string} id The id of an already installed extension. + * @param {function(): void=} opt_callback Optional callback function. + * @return {undefined} + */ +chrome.management.createAppShortcut = function(id, opt_callback) {}; + + +/** + * @param {string} id The id of an already installed extension. + * @param {string} launchType The LaunchType enum value to set. Make sure this + * value is in ExtensionInfo.availableLaunchTypes because the available + * launch types vary on different platforms and configurations. + * @param {function(): void=} opt_callback Optional callback function. + * @return {undefined} + */ +chrome.management.setLaunchType = function(id, launchType, opt_callback) {}; + + +/** + * @param {string} url The URL of a web page. The scheme of the URL can only be + * "http" or "https". + * @param {string} title The title of the generated app. + * @param {function(!ExtensionInfo): void=} opt_callback Optional callback + * function. + * @return {undefined} + */ +chrome.management.generateAppForLink = function(url, title, opt_callback) {}; + + +/** @type {!ChromeExtensionInfoEvent} */ +chrome.management.onDisabled; + + +/** @type {!ChromeExtensionInfoEvent} */ +chrome.management.onEnabled; + + +/** @type {!ChromeExtensionInfoEvent} */ +chrome.management.onInstalled; + + +/** @type {!ChromeStringEvent} */ +chrome.management.onUninstalled; + + +/** + * @const + * @see https://developer.chrome.com/extensions/idle.html + */ +chrome.idle = {}; + + +/** + * @param {number} thresholdSeconds Threshold in seconds, used to determine + * when a machine is in the idle state. + * @param {function(string): void} callback Callback to handle the state. + * @return {undefined} + */ +chrome.idle.queryState = function(thresholdSeconds, callback) {}; + + +/** + * @param {number} intervalInSeconds Threshold, in seconds, used to determine + * when the system is in an idle state. + * @return {undefined} + */ +chrome.idle.setDetectionInterval = function(intervalInSeconds) {}; + + +/** @type {!ChromeEvent} */ +chrome.idle.onStateChanged; + + +/** + * Chrome Text-to-Speech API. + * @const + * @see https://developer.chrome.com/extensions/tts.html + */ +chrome.tts = {}; + + + +/** + * An event from the TTS engine to communicate the status of an utterance. + * @constructor + */ +function TtsEvent() {} + + +/** @type {string} */ +TtsEvent.prototype.type; + + +/** @type {number} */ +TtsEvent.prototype.charIndex; + + +/** @type {string} */ +TtsEvent.prototype.errorMessage; + + + +/** + * A description of a voice available for speech synthesis. + * @constructor + */ +function TtsVoice() {} + + +/** @type {string} */ +TtsVoice.prototype.voiceName; + + +/** @type {string} */ +TtsVoice.prototype.lang; + + +/** @type {string} */ +TtsVoice.prototype.gender; + + +/** @type {string} */ +TtsVoice.prototype.extensionId; + + +/** @type {Array} */ +TtsVoice.prototype.eventTypes; + + +/** + * Gets an array of all available voices. + * @param {function(Array)=} opt_callback An optional callback + * function. + * @return {undefined} + */ +chrome.tts.getVoices = function(opt_callback) {}; + + +/** + * Checks if the engine is currently speaking. + * @param {function(boolean)=} opt_callback The callback function. + * @return {undefined} + */ +chrome.tts.isSpeaking = function(opt_callback) {}; + + +/** + * Speaks text using a text-to-speech engine. + * @param {string} utterance The text to speak, either plain text or a complete, + * well-formed SSML document. Speech engines that do not support SSML will + * strip away the tags and speak the text. The maximum length of the text is + * 32,768 characters. + * @param {Object=} opt_options The speech options. + * @param {function()=} opt_callback Called right away, before speech finishes. + * @return {undefined} + */ +chrome.tts.speak = function(utterance, opt_options, opt_callback) {}; + + +/** + * Stops any current speech. + * @return {undefined} + */ +chrome.tts.stop = function() {}; + + +/** + * @const + * @see https://developer.chrome.com/extensions/ttsEngine.html + */ +chrome.ttsEngine = {}; + + +/** @type {!ChromeEvent} */ +chrome.ttsEngine.onSpeak; + + +/** @type {!ChromeEvent} */ +chrome.ttsEngine.onStop; + + +/** + * @const + * @see https://developer.chrome.com/extensions/contentSettings.html + */ +chrome.contentSettings = {}; + + +/** @type {!ContentSetting} */ +chrome.contentSettings.cookies; + + +/** @type {!ContentSetting} */ +chrome.contentSettings.images; + + +/** @type {!ContentSetting} */ +chrome.contentSettings.javascript; + + +/** @type {!ContentSetting} */ +chrome.contentSettings.plugins; + + +/** @type {!ContentSetting} */ +chrome.contentSettings.popups; + + +/** @type {!ContentSetting} */ +chrome.contentSettings.notifications; + + +/** + * @const + * @see https://developer.chrome.com/extensions/fileBrowserHandler + */ +chrome.fileBrowserHandler = {}; + + +/** + * @typedef {?{ + * suggestedName: string, + * allowedFileExtensions: (!Array|undefined) + * }} + */ +chrome.fileBrowserHandler.SelectFileSelectionParams; + + +/** + * Prompts user to select file path under which file should be saved. + * @see https://developer.chrome.com/extensions/fileBrowserHandler#method-selectFile + * @param {!chrome.fileBrowserHandler.SelectFileSelectionParams} selectionParams + * Parameters that will be used while selecting the file. + * @param {function(!Object)} callback Function called upon completion. + * @return {undefined} + */ +chrome.fileBrowserHandler.selectFile = function(selectionParams, callback) {}; + + +/** + * @record + * @extends {ChromeBaseEvent} + * @see https://developer.chrome.com/extensions/fileBrowserHandler#event-onExecute + */ +chrome.fileBrowserHandler.ExecuteEvent = function() {}; + + +/** + * Fired when file system action is executed from ChromeOS file browser. + * @see https://developer.chrome.com/extensions/fileBrowserHandler#event-onExecute + * @type {!chrome.fileBrowserHandler.ExecuteEvent} + */ +chrome.fileBrowserHandler.onExecute; + + +/** + * @const + * @see https://developer.chrome.com/extensions/gcm + */ +chrome.gcm = {}; + + +/** + * @see https://developer.chrome.com/extensions/gcm#property-MAX_MESSAGE_SIZE + * @type {number} + */ +chrome.gcm.MAX_MESSAGE_SIZE; + + +/** + * Registers the application with GCM. The registration ID will be returned by + * the callback. If register is called again with the same list of senderIds, + * the same registration ID will be returned. + * @see https://developer.chrome.com/extensions/gcm#method-register + * @param {!Array} senderIds A list of server IDs that are allowed to + * send messages to the application. + * @param {function(string): void} callback Function called when + * registration completes with registration ID as argument. + * @return {undefined} + */ +chrome.gcm.register = function(senderIds, callback) {}; + + +/** + * Unregisters the application from GCM. + * @see https://developer.chrome.com/extensions/gcm#method-unregister + * @param {function(): void} callback Called when unregistration is done. + * @return {undefined} + */ +chrome.gcm.unregister = function(callback) {}; + + +/** + * Sends an upstream message using GCM. + * @see https://developer.chrome.com/extensions/gcm#method-send + * @param {!chrome.gcm.Message} message Message to be sent. + * @param {function(string): void} callback Called with message ID. + * @return {undefined} + */ +chrome.gcm.send = function(message, callback) {}; + + +/** + * Outgoing message. + * @typedef {?{ + * destinationId: string, + * messageId: string, + * timeToLive: (number|undefined), + * data: !Object + * }} + */ +chrome.gcm.Message; + + +/** + * An event, fired when a message is received through GCM. + * @see https://developer.chrome.com/extensions/gcm#event-onMessage + * @type {!chrome.gcm.OnMessageEvent} + */ +chrome.gcm.onMessage; + + +/** + * An event, fired when GCM server had to delete messages to the application + * from its queue in order to manage its size. + * @see https://developer.chrome.com/extensions/gcm#event-onMessagesDeleted + * @type {!ChromeEvent} + */ +chrome.gcm.onMessagesDeleted; + + +/** + * An event indicating problems with sending messages. + * @see https://developer.chrome.com/extensions/gcm#event-onSendError + * @type {!chrome.gcm.OnSendErrorEvent} + */ +chrome.gcm.onSendError; + + + +/** + * @record + * @extends {ChromeBaseEvent} + */ +chrome.gcm.OnMessageEvent = function() {}; + + +/** + * @record + * @extends {ChromeBaseEvent} + */ +chrome.gcm.OnSendErrorEvent = function() {}; + + +/** + * @const + * @see https://developer.chrome.com/extensions/history.html + */ +chrome.history = {}; + + +/** + * @param {Object} details Object with a 'url' key. + * @return {undefined} + */ +chrome.history.addUrl = function(details) {}; + + +/** + * @param {function(): void} callback Callback function. + * @return {undefined} + */ +chrome.history.deleteAll = function(callback) {}; + + +/** + * @param {Object} range Object with 'startTime' + * and 'endTime' keys. + * @param {function(): void} callback Callback function. + * @return {undefined} + */ +chrome.history.deleteRange = function(range, callback) {}; + + +/** + * @param {Object} details Object with a 'url' key. + * @return {undefined} + */ +chrome.history.deleteUrl = function(details) {}; + + +/** + * @param {Object} details Object with a 'url' key. + * @param {function(!Array): void} callback Callback function. + * @return {!Array} + */ +chrome.history.getVisits = function(details, callback) {}; + + +/** + * @param {Object} query Object with a 'text' (string) + * key and optional 'startTime' (number), 'endTime' (number) and + * 'maxResults' keys. + * @param {function(!Array): void} callback Callback function. + * @return {!Array} + */ +chrome.history.search = function(query, callback) {}; + + +/** @type {!ChromeEvent} */ +chrome.history.onVisitRemoved; + + +/** @type {!ChromeEvent} */ +chrome.history.onVisited; + + +/** + * @const + * @see http://developer.chrome.com/apps/identity.html + */ +chrome.identity = {}; + + +/** @typedef {?{id: string}} */ +chrome.identity.AccountInfo; + + +/** + * @param {function(!Array): void} callback + * @return {undefined} + */ +chrome.identity.getAccounts = function(callback) {}; + + +/** + * @param {(!chrome.identity.TokenDetails|function(string=): void)} + * detailsOrCallback Token options or a callback function if no options are + * specified. + * @param {function(string=): void=} opt_callback A callback function if options + * are specified. + * @return {undefined} + */ +chrome.identity.getAuthToken = function(detailsOrCallback, opt_callback) {}; + + +/** + * @typedef {?{ + * interactive: (boolean|undefined), + * account: (!chrome.identity.AccountInfo|undefined), + * scopes: (!Array|undefined) + * }} + */ +chrome.identity.TokenDetails; + + +/** + * @param {!chrome.identity.InvalidTokenDetails} details + * @param {function(): void=} opt_callback + * @return {undefined} + */ +chrome.identity.removeCachedAuthToken = function(details, opt_callback) {}; + + +/** @typedef {?{token: string}} */ +chrome.identity.InvalidTokenDetails; + + +/** + * @param {!chrome.identity.WebAuthFlowDetails} details + * @param {function(string=): void} callback + * @return {undefined} + */ +chrome.identity.launchWebAuthFlow = function(details, callback) {}; + + +/** @typedef {?{url: string, interactive: (boolean|undefined)}} */ +chrome.identity.WebAuthFlowDetails; + + +/** + * @param {function(!Object):void} callback + * @return {undefined} + */ +chrome.identity.getProfileUserInfo = function(callback) {}; + + + +/** + * @record + * @extends {ChromeBaseEvent} + */ +chrome.identity.OnSignInChangedEvent = function() {}; + + +/** @type {!chrome.identity.OnSignInChangedEvent} */ +chrome.identity.onSignInChanged; + + +/** + * @param {string=} opt_path + * @return {string} + */ +chrome.identity.getRedirectURL = function(opt_path) {}; + + +/** + * @const + * @see https://developer.chrome.com/extensions/input.ime.html + */ +chrome.input = {}; + + +/** @const */ +chrome.input.ime = {}; + + + +/** + * The OnKeyEvent event takes an extra argument. + * + * The addListener() method for this class takes more than one argument, so it + * isn't possible to just extend ChromeBaseEvent here. + * TODO(bradfordcsmith): These events won't automatically inherit new methods + * added to `ChromeBaseEvent`. + * @record + */ +function ChromeInputImeOnKeyEventEvent() {} + + +/** + * @param {function(string, !ChromeKeyboardEvent): (boolean|undefined)} callback + * callback. + * @param {Array=} opt_extraInfoSpec Array of extra information. + * @return {undefined} + */ +ChromeInputImeOnKeyEventEvent.prototype.addListener = + function(callback, opt_extraInfoSpec) {}; + + +/** + * @param {function(string, !ChromeKeyboardEvent): (boolean|undefined)} callback + * callback. + * @return {undefined} + */ +ChromeInputImeOnKeyEventEvent.prototype.removeListener = function(callback) {}; + + +/** + * @param {function(string, !ChromeKeyboardEvent): (boolean|undefined)} callback + * callback. + * @return {undefined} + */ +ChromeInputImeOnKeyEventEvent.prototype.hasListener = function(callback) {}; + + +/** + * @param {function(string, !ChromeKeyboardEvent): (boolean|undefined)} callback + * callback. + * @return {undefined} + */ +ChromeInputImeOnKeyEventEvent.prototype.hasListeners = function(callback) {}; + + +/** + * @param {!Object} parameters An object with a + * 'contextID' (number) key. + * @param {function(boolean): void} callback Callback function. + * @return {undefined} + */ +chrome.input.ime.clearComposition = function(parameters, callback) {}; + + +/** + * @param {!Object} parameters An object with + * 'contextID' (number) and 'text' (string) keys. + * @param {function(boolean): void=} opt_callback Callback function. + * @return {undefined} + */ +chrome.input.ime.commitText = function(parameters, opt_callback) {}; + + +/** + * @param {!Object} parameters An object with + * 'contextID' (number) and 'text' (string) keys. + * @param {function(boolean): void=} opt_callback Callback function. + * @return {undefined} + */ +chrome.input.ime.deleteSurroundingText = function(parameters, opt_callback) {}; + + +/** + * @param {!Object)>} + * parameters An object with 'engineID' (string) and 'properties' + * (Object) keys. + * @param {function(boolean): void=} opt_callback Callback function. + * @return {undefined} + */ +chrome.input.ime.setCandidateWindowProperties = + function(parameters, opt_callback) {}; + + +/** + * @param {!Object)>} + * parameters An object with 'contextID' (number) and 'candidates' + * (array of object) keys. + * @param {function(boolean): void=} opt_callback Callback function. + * @return {undefined} + */ +chrome.input.ime.setCandidates = function(parameters, opt_callback) {}; + + +/** + * @param {!Object)>} + * parameters An object with 'contextID' (number), 'text' (string), + * 'selectionStart (number), 'selectionEnd' (number), 'cursor' (number), + * and 'segments' (array of object) keys. + * @param {function(boolean): void=} opt_callback Callback function. + * @return {undefined} + */ +chrome.input.ime.setComposition = function(parameters, opt_callback) {}; + + +/** + * @param {!Object} parameters An object with + * 'contextID' (number) and 'candidateID' (number) keys. + * @param {function(boolean): void=} opt_callback Callback function. + * @return {undefined} + */ +chrome.input.ime.setCursorPosition = function(parameters, opt_callback) {}; + + +/** + * @param {!Object>)>} + * parameters An object with 'engineID' (string) and 'items' + * (array of object) keys. + * @param {function(): void=} opt_callback Callback function. + * @return {undefined} + */ +chrome.input.ime.setMenuItems = function(parameters, opt_callback) {}; + + +/** + * @param {!Object>)>} + * parameters An object with 'engineID' (string) and 'items' + * (array of object) keys. + * @param {function(): void=} opt_callback Callback function. + * @return {undefined} + */ +chrome.input.ime.updateMenuItems = function(parameters, opt_callback) {}; + + +/** + * @param {string} requestId Request id of the event that was handled. This + * should come from keyEvent.requestId. + * @param {boolean} response True if the keystroke was handled, false if not. + * @return {undefined} + */ +chrome.input.ime.keyEventHandled = function(requestId, response) {}; + + +/** @type {!ChromeEvent} */ +chrome.input.ime.onActivate; + + +/** @type {!ChromeEvent} */ +chrome.input.ime.onBlur; + + +/** @type {!ChromeEvent} */ +chrome.input.ime.onCandidateClicked; + + +/** @type {!ChromeEvent} */ +chrome.input.ime.onDeactivated; + + +/** @type {!ChromeEvent} */ +chrome.input.ime.onFocus; + + +/** @type {!ChromeEvent} */ +chrome.input.ime.onInputContextUpdate; + + +/** @type {!ChromeInputImeOnKeyEventEvent} */ +chrome.input.ime.onKeyEvent; + + +/** @type {!ChromeEvent} */ +chrome.input.ime.onMenuItemActivated; + + +/** @type {!ChromeEvent} */ +chrome.input.ime.onReset; + + +/** @type {!ChromeEvent} */ +chrome.input.ime.onSurroundingTextChanged; + + +/** + * namespace + * @see http://developer.chrome.com/apps/mediaGalleries + * @const + */ +chrome.mediaGalleries = {}; + + +/** + * @param {{interactive: (string|undefined)}|function(!Array)} + * detailsOrCallback A details object for whether the request should be + * interactive if permissions haven't been granted yet or the callback. + * @param {function(!Array)=} opt_callback A success callback if + * no details were supplied as arg1. + * @return {undefined} + */ +chrome.mediaGalleries.getMediaFileSystems = function( + detailsOrCallback, opt_callback) {}; + + +/** + * @param {function(!Array, string)} callback Callback function. + * @return {undefined} + */ +chrome.mediaGalleries.addUserSelectedFolder = function(callback) {}; + + +/** + * @param {string} galleryId ID of the media gallery. + * @param {function()=} opt_callback Optional callback function. + * @return {undefined} + */ +chrome.mediaGalleries.dropPermissionForMediaFileSystem = + function(galleryId, opt_callback) {}; + + +chrome.mediaGalleries.startMediaScan = function() {}; + + +chrome.mediaGalleries.cancelMediaScan = function() {}; + + +/** + * @param {function(!Array)} callback Callback function. + * @return {undefined} + */ +chrome.mediaGalleries.addScanResults = function(callback) {}; + + +/** + * @typedef {{ + * name: string, + * galleryId: string, + * deviceId: (string|undefined), + * isRemovable: boolean, + * isMediaDevice: boolean, + * isAvailable: boolean + * }} + */ +chrome.mediaGalleries.MediaFileSystemMetadata; + + +/** + * @param {!FileSystem} mediaFileSystem The file system to get metadata for. + * @return {!chrome.mediaGalleries.MediaFileSystemMetadata} + */ +chrome.mediaGalleries.getMediaFileSystemMetadata = function(mediaFileSystem) {}; + + +/** + * @param {function(!Array)} + * callback Callback function. + * @return {undefined} + */ +chrome.mediaGalleries.getAllMediaFileSystemMetadata = function(callback) {}; + + +/** + * @typedef {{ + * mimeType: string, + * height: (number|undefined), + * width: (number|undefined), + * xResolution: (number|undefined), + * yResolution: (number|undefined), + * duration: (number|undefined), + * rotation: (number|undefined), + * cameraMake: (string|undefined), + * cameraModel: (string|undefined), + * exposureTimeSeconds: (number|undefined), + * flashFired: (boolean|undefined), + * fNumber: (number|undefined), + * focalLengthMm: (number|undefined), + * isoEquivalent: (number|undefined), + * album: (string|undefined), + * artist: (string|undefined), + * comment: (string|undefined), + * copyright: (string|undefined), + * disc: (number|undefined), + * genre: (string|undefined), + * language: (string|undefined), + * title: (string|undefined), + * track: (number|undefined), + * rawTags: !Array, + * attachedImages: !Array + * }} + */ +chrome.mediaGalleries.MetaData; + + +/** @const */ +chrome.mediaGalleries.metadata = {}; + + +/** @constructor */ +chrome.mediaGalleries.metadata.RawTag = function() {}; + + +/** @type {string} */ +chrome.mediaGalleries.metadata.RawTag.prototype.type; + + +/** @type {!Object} */ +chrome.mediaGalleries.metadata.RawTag.prototype.tags; + + +/** + * @param {!Blob} mediaFile The media file for which to get metadata. + * @param {{metadataType: (string|undefined)}| + * function(!chrome.mediaGalleries.MetaData)} optionsOrCallback The options + * for the metadata to retrieve or the callback to invoke with the metadata. + * The metadataType should either be 'all' or 'mimeTypeOnly'. Defaults to + * 'all' if the metadataType is omitted. + * @param {function(!chrome.mediaGalleries.MetaData)=} opt_callback If options + * were passed as arg2, the callback to invoke with the metadata. + * @return {undefined} + */ +chrome.mediaGalleries.getMetadata = function( + mediaFile, optionsOrCallback, opt_callback) {}; + + +/** + * @typedef {function({galleryId: string, success: boolean}): void} + */ +chrome.mediaGalleries.AddGalleryWatchCallback; + + +/** + * @param {string} galleryId The media gallery's ID. + * @param {!chrome.mediaGalleries.AddGalleryWatchCallback} callback Fired with + * success or failure result. + * @return {undefined} + */ +chrome.mediaGalleries.addGalleryWatch = function(galleryId, callback) {}; + + +/** + * @param {string} galleryId The media gallery's ID. + * @return {undefined} + */ +chrome.mediaGalleries.removeGalleryWatch = function(galleryId) {}; + + +/** + * @param {function(!Array): void} callback Callback function notifies + * which galleries are being watched. + * @return {undefined} + */ +chrome.mediaGalleries.getAllGalleryWatch = function(callback) {}; + + +chrome.mediaGalleries.removeAllGalleryWatch = function() {}; + + + +/** + * @record + * @extends {ChromeBaseEvent} + */ +chrome.mediaGalleries.GalleryChangeEvent = function() {}; + + +/** + * @typedef {function({type: string, galleryId: string}): void} + */ +chrome.mediaGalleries.GalleryChangeCallback; + + +/** + * @type {!chrome.mediaGalleries.GalleryChangeEvent} + */ +chrome.mediaGalleries.onGalleryChanged; + + +/** + * @typedef {{ + * type: string, + * galleryCount: (number|undefined), + * audioCount: (number|undefined), + * imageCount: (number|undefined), + * videoCount: (number|undefined) + * }} + */ +chrome.mediaGalleries.OnScanProgressDetails; + + + +/** + * Event whose listeners take a chrome.mediaGalleries.OnScanProgressDetails + * parameter. + * @record + * @extends {ChromeBaseEvent} + */ +chrome.mediaGalleries.ScanProgressEvent = function() {}; + + +/** @type {!chrome.mediaGalleries.ScanProgressEvent} */ +chrome.mediaGalleries.onScanProgress; + + +/** + * @const + * @see https://developer.chrome.com/extensions/pageCapture.html + */ +chrome.pageCapture = {}; + + +/** + * @param {Object} details Object with a 'tabId' (number) key. + * @param {function(Blob=): void} callback Callback function. + * @return {undefined} + */ +chrome.pageCapture.saveAsMHTML = function(details, callback) {}; + + +/** + * @const + * @see https://developer.chrome.com/extensions/permissions.html + */ +chrome.permissions = {}; + + +/** + * @typedef {{ + * permissions: (Array|undefined), + * origins: (Array|undefined) + * }} + * @see http://developer.chrome.com/extensions/permissions.html#type-Permissions + */ +chrome.permissions.Permissions; + + +/** + * @param {!chrome.permissions.Permissions} permissions + * @param {function(boolean): void} callback Callback function. + * @return {undefined} + */ +chrome.permissions.contains = function(permissions, callback) {}; + + +/** + * @param {function(!chrome.permissions.Permissions): void} callback + * Callback function. + * @return {undefined} + */ +chrome.permissions.getAll = function(callback) {}; + + +/** + * @param {!chrome.permissions.Permissions} permissions + * @param {function(boolean): void=} opt_callback Callback function. + * @return {undefined} + */ +chrome.permissions.remove = function(permissions, opt_callback) {}; + + +/** + * @param {!chrome.permissions.Permissions} permissions + * @param {function(boolean): void=} opt_callback Callback function. + * @return {undefined} + */ +chrome.permissions.request = function(permissions, opt_callback) {}; + + +/** @type {!ChromeEvent} */ +chrome.permissions.onAdded; + + +/** @type {!ChromeEvent} */ +chrome.permissions.onRemoved; + + +/** + * @see http://developer.chrome.com/dev/extensions/power.html + */ +chrome.power = {}; + + +/** + * @param {string} level A string describing the degree to which power + * management should be disabled, should be either "system" or "display". + * @return {undefined} + */ +chrome.power.requestKeepAwake = function(level) {}; + + +/** + * Releases a request previously made via requestKeepAwake(). + * @return {undefined} + */ +chrome.power.releaseKeepAwake = function() {}; + + +/** + * @const + * @see https://developer.chrome.com/extensions/privacy.html + */ +chrome.privacy = {}; + + +/** @type {!Object} */ +chrome.privacy.network; + + +/** @type {!Object} */ +chrome.privacy.services; + + +/** @type {!Object} */ +chrome.privacy.websites; + + +/** + * @const + * @see https://developer.chrome.com/extensions/proxy.html + */ +chrome.proxy = {}; + + +/** @type {!Object} */ +chrome.proxy.settings; + + +/** @type {!ChromeEvent} */ +chrome.proxy.onProxyError; + + +/** + * @const + * @see http://developer.chrome.com/apps/socket.html + */ +chrome.socket = {}; + + + +/** + * @constructor + */ +chrome.socket.CreateInfo = function() {}; + + +/** @type {number} */ +chrome.socket.CreateInfo.prototype.socketId; + + + +/** + * @constructor + */ +chrome.socket.ReadInfo = function() {}; + + +/** @type {number} */ +chrome.socket.ReadInfo.prototype.resultCode; + + +/** @type {!ArrayBuffer} */ +chrome.socket.ReadInfo.prototype.data; + + + +/** + * @constructor + */ +chrome.socket.WriteInfo = function() {}; + + +/** @type {number} */ +chrome.socket.WriteInfo.prototype.bytesWritten; + + + +/** + * @constructor + */ +chrome.socket.RecvFromInfo = function() {}; + + +/** @type {number} */ +chrome.socket.RecvFromInfo.prototype.resultCode; + + +/** @type {!ArrayBuffer} */ +chrome.socket.RecvFromInfo.prototype.data; + + +/** @type {string} */ +chrome.socket.RecvFromInfo.prototype.address; + + +/** @type {number} */ +chrome.socket.RecvFromInfo.prototype.port; + + + +/** + * @constructor + */ +chrome.socket.AcceptInfo = function() {}; + + +/** @type {number} */ +chrome.socket.AcceptInfo.prototype.resultCode; + + +/** @type {(number|undefined)} */ +chrome.socket.AcceptInfo.prototype.socketId; + + + +/** + * @constructor + */ +chrome.socket.SocketInfo = function() {}; + + +/** @type {string} */ +chrome.socket.SocketInfo.prototype.socketType; + + +/** @type {boolean} */ +chrome.socket.SocketInfo.prototype.connected; + + +/** @type {(string|undefined)} */ +chrome.socket.SocketInfo.prototype.peerAddress; + + +/** @type {(number|undefined)} */ +chrome.socket.SocketInfo.prototype.peerPort; + + +/** @type {(string|undefined)} */ +chrome.socket.SocketInfo.prototype.localAddress; + + +/** @type {(number|undefined)} */ +chrome.socket.SocketInfo.prototype.localPort; + + + +/** + * @constructor + */ +chrome.socket.NetworkAdapterInfo = function() {}; + + +/** @type {string} */ +chrome.socket.NetworkAdapterInfo.prototype.name; + + +/** @type {string} */ +chrome.socket.NetworkAdapterInfo.prototype.address; + + +/** + * @param {string} type The type of socket to create. Must be 'tcp' or 'udp'. + * @param {(Object|function(!chrome.socket.CreateInfo))} optionsOrCallback The + * socket options or callback. + * @param {function(!chrome.socket.CreateInfo)=} opt_callback Called when the + * socket has been created. + * @return {undefined} + */ +chrome.socket.create = function(type, optionsOrCallback, opt_callback) {}; + + +/** + * @param {number} socketId The id of the socket to destroy. + * @return {undefined} + */ +chrome.socket.destroy = function(socketId) {}; + + +/** + * @param {number} socketId The id of the socket. + * @param {string} hostname The hostname or IP address of the remote machine. + * @param {number} port The port of the remote machine. + * @param {function(number)} callback Called when the connection attempt is + * complete. + * @return {undefined} + */ +chrome.socket.connect = function(socketId, hostname, port, callback) {}; + + +/** + * @param {number} socketId The id of the socket. + * @param {string} address The address of the local machine. + * @param {number} port The port of the local machine. + * @param {function(number)} callback Called when the bind attempt is complete. + * @return {undefined} + */ +chrome.socket.bind = function(socketId, address, port, callback) {}; + + +/** + * @param {number} socketId The id of the socket to disconnect. + * @return {undefined} + */ +chrome.socket.disconnect = function(socketId) {}; + + +/** + * @param {number} socketId The id of the socket to read from. + * @param {(number|function(!chrome.socket.ReadInfo))} bufferSizeOrCallback The + * read buffer size or the callback. + * @param {function(!chrome.socket.ReadInfo)=} opt_callback Called with data + * that was available to be read without blocking. + * @return {undefined} + */ +chrome.socket.read = function(socketId, bufferSizeOrCallback, opt_callback) {}; + + +/** + * @param {number} socketId The id of the socket to write to. + * @param {!ArrayBuffer} data The data to write. + * @param {function(!chrome.socket.WriteInfo)} callback Called when the write + * operation completes without blocking or an error occurs. + * @return {undefined} + */ +chrome.socket.write = function(socketId, data, callback) {}; + + +/** + * @param {number} socketId The id of the socket to read from. + * @param {(number|function(!chrome.socket.RecvFromInfo))} bufferSizeOrCallback + * The read buffer size or the callback. + * @param {function(!chrome.socket.RecvFromInfo)=} opt_callback Called with data + * that was available to be read without blocking. + * @return {undefined} + */ +chrome.socket.recvFrom = function(socketId, bufferSizeOrCallback, + opt_callback) {}; + + +/** + * @param {number} socketId The id of the socket to write to. + * @param {!ArrayBuffer} data The data to write. + * @param {string} address The address of the remote machine. + * @param {number} port The port of the remote machine. + * @param {function(!chrome.socket.WriteInfo)} callback Called when the write + * operation completes without blocking or an error occurs. + * @return {undefined} + */ +chrome.socket.sendTo = function(socketId, data, address, port, callback) {}; + + +/** + * @param {number} socketId The id of the socket to listen on. + * @param {string} address The address of the local machine to listen on. Use + * '0' to listen on all addresses. + * @param {number} port The port of the local machine. + * @param {(number|function(number))} backlogOrCallback The length of the + * socket's listen queue or the callback. + * @param {function(number)=} opt_callback Called when the listen operation + * completes. + * @return {undefined} + */ +chrome.socket.listen = + function(socketId, address, port, backlogOrCallback, opt_callback) {}; + + +/** + * @param {number} socketId The id of the socket to accept a connection on. + * @param {function(!chrome.socket.AcceptInfo)} callback Called when a new + * socket is accepted. + * @return {undefined} + */ +chrome.socket.accept = function(socketId, callback) {}; + + +/** + * @param {number} socketId The id of the socket to listen on. + * @param {boolean} enable If true, enable keep-alive functionality. + * @param {(number|function(boolean))} delayOrCallback The delay in seconds + * between the last packet received and the first keepalive probe (default + * is 0) or the callback + * @param {function(boolean)=} opt_callback Called when the setKeepAlive attempt + * is complete. + * @return {undefined} + */ +chrome.socket.setKeepAlive = function(socketId, enable, delayOrCallback, + opt_callback) {}; + + +/** + * @param {number} socketId The id of the socket to listen on. + * @param {boolean} noDelay If true, disables Nagle's algorithm. + * @param {function(boolean)} callback Called when the setNoDelay attempt is + * complete. + * @return {undefined} + */ +chrome.socket.setNoDelay = function(socketId, noDelay, callback) {}; + + +/** + * @param {number} socketId The id of the socket. + * @param {function(!chrome.socket.SocketInfo)} callback Called when the state + * is available. + * @return {undefined} + */ +chrome.socket.getInfo = function(socketId, callback) {}; + + +/** + * @param {function(!Array)} callback Called + * when local adapter information is available. + * @return {undefined} + */ +chrome.socket.getNetworkList = function(callback) {}; + + +/** + * @param {number} socketId The id of the socket. + * @param {string} address The group address to join. Domain names are not + * supported. + * @param {function(number)} callback Called when the join operation is done. + * @return {undefined} + */ +chrome.socket.joinGroup = function(socketId, address, callback) {}; + + +/** + * @param {number} socketId The id of the socket. + * @param {string} address The group address to leave. Domain names are not + * supported. + * @param {function(number)} callback Called when the leave operation is done. + * @return {undefined} + */ +chrome.socket.leaveGroup = function(socketId, address, callback) {}; + + +/** + * @param {number} socketId The id of the socket. + * @param {number} ttl The time-to-live value. + * @param {function(number)} callback Called when the configuration operation is + * done. + * @return {undefined} + */ +chrome.socket.setMulticastTimeToLive = function(socketId, ttl, callback) {}; + + +/** + * @param {number} socketId The id of the socket. + * @param {boolean} enabled True to enable loopback mode. + * @param {function(number)} callback Called when the configuration operation is + * done. + * @return {undefined} + */ +chrome.socket.setMulticastLoopbackMode = function(socketId, enabled, + callback) {}; + + +/** + * @param {number} socketId The id of the socket. + * @param {function(!Array)} callback Called with an array of string + * groups. + * @return {undefined} + */ +chrome.socket.getJoinedGroups = function(socketId, callback) {}; + + +/** + * @const + */ +chrome.sockets = {}; + + +/** + * @const + * @see https://developer.chrome.com/apps/sockets_tcp + */ +chrome.sockets.tcp = {}; + + + +/** + * @constructor + * @see https://developer.chrome.com/apps/sockets_tcp#type-SocketInfo + */ +chrome.sockets.tcp.SocketInfo = function() {}; + + +/** @type {number} */ +chrome.sockets.tcp.SocketInfo.prototype.socketId; + + +/** @type {boolean} */ +chrome.sockets.tcp.SocketInfo.prototype.persistent; + + +/** @type {string|undefined} */ +chrome.sockets.tcp.SocketInfo.prototype.name; + + +/** @type {number|undefined} */ +chrome.sockets.tcp.SocketInfo.prototype.bufferSize; + + +/** @type {boolean} */ +chrome.sockets.tcp.SocketInfo.prototype.paused; + + +/** @type {boolean} */ +chrome.sockets.tcp.SocketInfo.prototype.connected; + + +/** @type {string|undefined} */ +chrome.sockets.tcp.SocketInfo.prototype.localAddress; + + +/** @type {number|undefined} */ +chrome.sockets.tcp.SocketInfo.prototype.localPort; + + +/** @type {string|undefined} */ +chrome.sockets.tcp.SocketInfo.prototype.peerAddress; + + +/** @type {number|undefined} */ +chrome.sockets.tcp.SocketInfo.prototype.peerPort; + + +/** + * @typedef {?{ + * persistent: (boolean|undefined), + * name: (string|undefined), + * bufferSize: (number|undefined) + * }} + * @see https://developer.chrome.com/apps/sockets_tcp#type-SocketProperties + */ +chrome.sockets.tcp.SocketProperties; + + +/** + * @typedef {?{ + * min: (string|undefined), + * max: (string|undefined) + * }} + * @see https://developer.chrome.com/apps/sockets_tcp#method-secure + */ +chrome.sockets.tcp.SecurePropertiesTlsVersion; + + +/** + * @typedef {?{ + * tlsVersion: (chrome.sockets.tcp.SecurePropertiesTlsVersion|undefined) + * }} + * @see https://developer.chrome.com/apps/sockets_tcp#method-secure + */ +chrome.sockets.tcp.SecureProperties; + + +/** + * @param {!chrome.sockets.tcp.SocketProperties| + * function(!Object)} propertiesOrCallback + * @param {function(!Object)=} opt_callback + * @see https://developer.chrome.com/apps/sockets_tcp#method-create + * @return {undefined} + */ +chrome.sockets.tcp.create = function(propertiesOrCallback, opt_callback) {}; + + +/** + * @param {number} socketId + * @param {!chrome.sockets.tcp.SocketProperties} properties + * @param {function()=} opt_callback + * @see https://developer.chrome.com/apps/sockets_tcp#method-update + * @return {undefined} + */ +chrome.sockets.tcp.update = function(socketId, properties, opt_callback) {}; + + +/** + * @param {number} socketId + * @param {boolean} paused + * @param {function()=} opt_callback + * @see https://developer.chrome.com/apps/sockets_tcp#method-setPaused + * @return {undefined} + */ +chrome.sockets.tcp.setPaused = function(socketId, paused, opt_callback) {}; + + +/** + * @param {number} socketId + * @param {boolean} enable + * @param {(number|function(number))} delayOrCallback + * @param {function(number)=} opt_callback + * @see https://developer.chrome.com/apps/sockets_tcp#method-setKeepAlive + * @return {undefined} + */ +chrome.sockets.tcp.setKeepAlive = function(socketId, enable, delayOrCallback, + opt_callback) {}; + + +/** + * @param {number} socketId + * @param {boolean} noDelay + * @param {function(number)} callback + * @see https://developer.chrome.com/apps/sockets_tcp#method-setNoDelay + * @return {undefined} + */ +chrome.sockets.tcp.setNoDelay = function(socketId, noDelay, callback) {}; + + +/** + * @param {number} socketId + * @param {string} peerAddress + * @param {number} peerPort + * @param {function(number)} callback + * @see https://developer.chrome.com/apps/sockets_tcp#method-connect + * @return {undefined} + */ +chrome.sockets.tcp.connect = function(socketId, peerAddress, peerPort, + callback) {}; + + +/** + * @param {number} socketId The id of the socket to disconnect. + * @param {function()=} opt_callback + * @see https://developer.chrome.com/apps/sockets_tcp#method-disconnect + * @return {undefined} + */ +chrome.sockets.tcp.disconnect = function(socketId, opt_callback) {}; + + +/** + * @param {number} socketId + * @param {!chrome.sockets.tcp.SecureProperties|function(number)} + * optionsOrCallback + * @param {function(number)=} opt_callback + * @see https://developer.chrome.com/apps/sockets_tcp#method-secure + * @return {undefined} + */ +chrome.sockets.tcp.secure = function(socketId, optionsOrCallback, + opt_callback) {}; + + +/** + * @param {number} socketId + * @param {!ArrayBuffer} data + * @param {function(!Object)} callback + * @see https://developer.chrome.com/apps/sockets_tcp#method-send + * @return {undefined} + */ +chrome.sockets.tcp.send = function(socketId, data, callback) {}; + + +/** + * @param {number} socketId + * @param {function()=} opt_callback + * @see https://developer.chrome.com/apps/sockets_tcp#method-close + * @return {undefined} + */ +chrome.sockets.tcp.close = function(socketId, opt_callback) {}; + + +/** + * @param {number} socketId + * @param {function(!chrome.sockets.tcp.SocketInfo)} callback + * @see https://developer.chrome.com/apps/sockets_tcp#method-getInfo + * @return {undefined} + */ +chrome.sockets.tcp.getInfo = function(socketId, callback) {}; + + +/** + * @param {function(!Array)} callback + * @see https://developer.chrome.com/apps/sockets_tcp#method-getSockets + * @return {undefined} + */ +chrome.sockets.tcp.getSockets = function(callback) {}; + + + +/** + * @constructor + * @see https://developer.chrome.com/apps/sockets_tcp#event-onReceive + */ +chrome.sockets.tcp.ReceiveEventData = function() {}; + + +/** @type {number} */ +chrome.sockets.tcp.ReceiveEventData.prototype.socketId; + + +/** @type {!ArrayBuffer} */ +chrome.sockets.tcp.ReceiveEventData.prototype.data; + + + +/** + * Event whose listeners take a ReceiveEventData parameter. + * @record + * @extends {ChromeBaseEvent} + */ +chrome.sockets.tcp.ReceiveEvent = function() {}; + + +/** @type {!chrome.sockets.tcp.ReceiveEvent} */ +chrome.sockets.tcp.onReceive; + + + +/** + * @constructor + * @see https://developer.chrome.com/apps/sockets_tcp#event-onReceiveError + */ +chrome.sockets.tcp.ReceiveErrorEventData = function() {}; + + +/** @type {number} */ +chrome.sockets.tcp.ReceiveErrorEventData.prototype.socketId; + + +/** @type {number} */ +chrome.sockets.tcp.ReceiveErrorEventData.prototype.resultCode; + + + +/** + * Event whose listeners take a ReceiveErrorEventData parameter. + * @record + * @extends {ChromeBaseEvent} + */ +chrome.sockets.tcp.ReceiveErrorEvent = function() {}; + + +/** @type {!chrome.sockets.tcp.ReceiveErrorEvent} */ +chrome.sockets.tcp.onReceiveError; + + +/** + * @see https://developer.chrome.com/apps/sockets_udp + * @const + */ +chrome.sockets.udp = {}; + + +/** + * @typedef {?{ + * persistent: (boolean|undefined), + * name: (string|undefined), + * bufferSize: (number|undefined) + * }} + * @see https://developer.chrome.com/apps/sockets_udp#type-SocketProperties + */ +chrome.sockets.udp.SocketProperties; + + +/** + * @constructor + * @see https://developer.chrome.com/apps/sockets_udp#type-SocketInfo + */ +chrome.sockets.udp.SocketInfo = function() {}; + + +/** @type {number} */ +chrome.sockets.udp.SocketInfo.prototype.socketId; + + +/** @type {boolean} */ +chrome.sockets.udp.SocketInfo.prototype.persistent; + + +/** @type {string|undefined} */ +chrome.sockets.udp.SocketInfo.prototype.name; + + +/** @type {number|undefined} */ +chrome.sockets.udp.SocketInfo.prototype.bufferSize; + + +/** @type {boolean} */ +chrome.sockets.udp.SocketInfo.prototype.paused; + + +/** @type {string|undefined} */ +chrome.sockets.udp.SocketInfo.prototype.localAddress; + + +/** @type {number|undefined} */ +chrome.sockets.udp.SocketInfo.prototype.localPort; + + +/** + * @param { + * (!chrome.sockets.udp.SocketProperties|function(!Object)) + * } propertiesOrCallback + * @param {function(!Object)=} opt_callback + * @return {undefined} + * @see https://developer.chrome.com/apps/sockets_udp#method-create + */ +chrome.sockets.udp.create = function(propertiesOrCallback, opt_callback) {}; + + +/** + * @param {number} socketId + * @param {!chrome.sockets.udp.SocketProperties} properties + * @param {function(): void=} opt_callback + * @return {undefined} + * @see https://developer.chrome.com/apps/sockets_udp#method-update + */ +chrome.sockets.udp.update = function(socketId, properties, opt_callback) {}; + + +/** + * @param {number} socketId + * @param {boolean} paused + * @param {function(): void=} opt_callback + * @return {undefined} + * @see https://developer.chrome.com/apps/sockets_udp#method-setPaused + */ +chrome.sockets.udp.setPaused = function(socketId, paused, opt_callback) {}; + + +/** + * @param {number} socketId + * @param {string} address + * @param {number} port + * @param {function(number): void} callback + * @return {undefined} + * @see https://developer.chrome.com/apps/sockets_udp#method-bind + */ +chrome.sockets.udp.bind = function(socketId, address, port, callback) {}; + + +/** + * @param {number} socketId + * @param {!ArrayBuffer} data + * @param {string} address + * @param {number} port + * @param {function(!Object): void} callback + * @return {undefined} + * @see https://developer.chrome.com/apps/sockets_udp#method-send + */ +chrome.sockets.udp.send = function(socketId, data, address, port, callback) {}; + + +/** + * @param {number} socketId + * @param {function()} callback + * @return {undefined} + * @see https://developer.chrome.com/apps/sockets_udp#method-close + */ +chrome.sockets.udp.close = function(socketId, callback) {}; + + +/** + * @param {number} socketId + * @param {function(!chrome.sockets.udp.SocketInfo): void} callback + * @return {undefined} + * @see https://developer.chrome.com/apps/sockets_udp#method-getInfo + */ +chrome.sockets.udp.getInfo = function(socketId, callback) {}; + + +/** + * @param {function(!Array): void} callback + * @return {undefined} + * @see https://developer.chrome.com/apps/sockets_udp#method-getSockets + */ +chrome.sockets.udp.getSockets = function(callback) {}; + + +/** + * @param {number} socketId + * @param {string} address + * @param {function(number): void} callback + * @return {undefined} + * @see https://developer.chrome.com/apps/sockets_udp#method-joinGroup + */ +chrome.sockets.udp.joinGroup = function(socketId, address, callback) {}; + + +/** + * @param {number} socketId + * @param {string} address + * @param {function(number): void} callback + * @return {undefined} + * @see https://developer.chrome.com/apps/sockets_udp#method-leaveGroup + */ +chrome.sockets.udp.leaveGroup = function(socketId, address, callback) {}; + + +/** + * @param {number} socketId + * @param {number} ttl + * @param {function(number): void} callback + * @return {undefined} + * @see https://developer.chrome.com/apps/sockets_udp#method-setMulticastTimeToLive + */ +chrome.sockets.udp.setMulticastTimeToLive = + function(socketId, ttl, callback) {}; + + +/** + * @param {number} socketId + * @param {boolean} enabled + * @param {function(number): void} callback + * @return {undefined} + * @see https://developer.chrome.com/apps/sockets_udp#method-setMulticastLoopbackMode + */ +chrome.sockets.udp.setMulticastLoopbackMode = + function(socketId, enabled, callback) {}; + + +/** + * @param {number} socketId + * @param {function(!Array): void} callback + * @return {undefined} + * @see https://developer.chrome.com/apps/sockets_udp#method-getJoinedGroups + */ +chrome.sockets.udp.getJoinedGroups = function(socketId, callback) {}; + + +/** + * @param {number} socketId + * @param {boolean} enabled + * @param {function(number): void} callback + * @return {undefined} + * @see https://developer.chrome.com/apps/sockets_udp#method-send + */ +chrome.sockets.udp.setBroadcast = function(socketId, enabled, callback) {}; + + +/** + * @type {!ChromeObjectEvent} + * @see https://developer.chrome.com/apps/sockets_udp#event-onReceive + */ +chrome.sockets.udp.onReceive; + + +/** + * @type {!ChromeObjectEvent} + * @see https://developer.chrome.com/apps/sockets_udp#event-onReceiveError + */ +chrome.sockets.udp.onReceiveError; + + +/** + * @const + * @see https://developer.chrome.com/extensions/storage.html + */ +chrome.storage = {}; + + +/** @type {!StorageArea} */ +chrome.storage.sync; + + +/** @type {!StorageArea} */ +chrome.storage.local; + + +/** @type {!StorageArea} */ +chrome.storage.managed; + + +/** @type {!StorageChangeEvent} */ +chrome.storage.onChanged; + + +/** @const */ +chrome.system = {}; + + +/** + * @const + * @see https://developer.chrome.com/extensions/system_cpu.html + */ +chrome.system.cpu = {}; + + +/** + * @interface + * @see https://developer.chrome.com/extensions/system_cpu#method-getInfo + */ +chrome.system.cpu.CpuInformation = function() {}; + + +/** @type {number} */ +chrome.system.cpu.CpuInformation.prototype.numOfProcessors; + + +/** @type {string} */ +chrome.system.cpu.CpuInformation.prototype.archName; + + +/** @type {string} */ +chrome.system.cpu.CpuInformation.prototype.modelName; + + +/** @type {!Array} */ +chrome.system.cpu.CpuInformation.prototype.features; + + +/** @type {!Array} */ +chrome.system.cpu.CpuInformation.prototype.processors; + + +/** + * This field is expected to roll out in ChromeOS 60. See the following link + * for the implementing CL. https://codereview.chromium.org/2802593005/ + * + * TODO(b/38111360): Remove above documentation when this is released. + * + * @type {!Array|undefined} + */ +chrome.system.cpu.CpuInformation.prototype.temperatures; + + +/** + * @interface + * @see https://developer.chrome.com/extensions/system_cpu#method-getInfo + */ +chrome.system.cpu.ProcessorInformation = function() {}; + + +/** @type {number} */ +chrome.system.cpu.ProcessorInformation.prototype.user; + + +/** @type {number} */ +chrome.system.cpu.ProcessorInformation.prototype.kernel; + + +/** @type {number} */ +chrome.system.cpu.ProcessorInformation.prototype.idle; + + +/** @type {number} */ +chrome.system.cpu.ProcessorInformation.prototype.total; + + +/** + * @param {function(!chrome.system.cpu.CpuInformation)} callback + * @return {undefined} + */ +chrome.system.cpu.getInfo = function(callback) {}; + + +/** + * @const + * @see http://developer.chrome.com/apps/system_display.html + */ +chrome.system.display = {}; + + +/** + * @typedef {!{ + * left: number, + * top: number, + * width: number, + * height: number + * }} + * @see https://developer.chrome.com/extensions/system.display#type-Bounds + */ +chrome.system.display.Bounds; + + +/** + * @typedef {!{ + * left: number, + * top: number, + * right: number, + * bottom: number + * }} + * @see https://developer.chrome.com/extensions/system.display#type-Insets + */ +chrome.system.display.Insets; + + +/** + * @typedef {!{ + * x: number, + * y: number + * }} + * @see https://developer.chrome.com/extensions/system.display#type-Point + */ +chrome.system.display.Point; + + +/** + * @typedef {!{ + * width: number, + * height: number, + * widthInNativePixels: number, + * heightInNativePixels: number, + * uiScale: number, + * deviceScaleFactor: number, + * isNative: boolean, + * isSelected: boolean + * }} + * @see https://developer.chrome.com/extensions/system.display#type-DisplayMode + */ +chrome.system.display.DisplayMode; + + +/** + * @typedef {!{ + * id: string, + * parentId: string, + * position: string, + * offset: number + * }} + * @see https://developer.chrome.com/extensions/system.display#type-DisplayLayout + */ +chrome.system.display.DisplayLayout; + + + +/** + * An undocumented type that defines the objects passed to getInfo()'s callback. + * @constructor + */ +chrome.system.display.DisplayUnitInfo = function() {}; + + +/** @type {string} */ +chrome.system.display.DisplayUnitInfo.prototype.id; + + +/** @type {string} */ +chrome.system.display.DisplayUnitInfo.prototype.name; + + +/** @type {string} */ +chrome.system.display.DisplayUnitInfo.prototype.mirroringSourceId; + + +/** @type {boolean} */ +chrome.system.display.DisplayUnitInfo.prototype.isPrimary; + + +/** @type {boolean} */ +chrome.system.display.DisplayUnitInfo.prototype.isInternal; + + +/** @type {boolean} */ +chrome.system.display.DisplayUnitInfo.prototype.isEnabled; + + +/** @type {number} */ +chrome.system.display.DisplayUnitInfo.prototype.dpiX; + + +/** @type {number} */ +chrome.system.display.DisplayUnitInfo.prototype.dpiY; + + +/** @type {number} */ +chrome.system.display.DisplayUnitInfo.prototype.rotation; + + +/** @type {!chrome.system.display.Bounds} */ +chrome.system.display.DisplayUnitInfo.prototype.bounds; + + +/** @type {!chrome.system.display.Insets} */ +chrome.system.display.DisplayUnitInfo.prototype.overscan; + + +/** @type {!chrome.system.display.Bounds} */ +chrome.system.display.DisplayUnitInfo.prototype.workArea; + + +/** @type {!Array} */ +chrome.system.display.DisplayUnitInfo.prototype.modes; + + +/** @type {boolean} */ +chrome.system.display.DisplayUnitInfo.prototype.hasTouchSupport; + + +/** + * @param {function(!Array):void} callback Callbacks must declare their + * param to be an array of objects since there is no defined type. To + * achieve stronger type checking, cast the objects to + * chrome.system.display.DisplayUnitInfo. Called with an array of objects + * representing display info. + * @return {undefined} + * @see https://developer.chrome.com/extensions/system.display#method-getInfo + */ +chrome.system.display.getInfo = function(callback) {}; + + +/** + * @param {function(!Array):void} callback + * The callback to invoke with the results. + * @see https://developer.chrome.com/extensions/system.display#method-getDisplayLayout + */ +chrome.system.display.getDisplayLayout = function(callback) {}; + + +/** + * @param {string} id The display's unique identifier. + * @param {!Object} info The information about display properties that should be + * changed. A property will be changed only if a new value for it is + * specified in info. + * @param {function():void=} callback Empty function called when the function + * finishes. To find out whether the function succeeded, runtime.lastError + * should be queried. + * @see https://developer.chrome.com/extensions/system.display#method-setDisplayProperties + */ +chrome.system.display.setDisplayProperties = function(id, info, callback) {}; + + +/** + * @param {!Array} layouts The layout + * information, required for all displays except the primary display. + * @param {function():void=} callback Empty function called when the function + * finishes. To find out whether the function succeeded, runtime.lastError + * should be queried. + * @see https://developer.chrome.com/extensions/system.display#method-setDisplayLayout + */ +chrome.system.display.setDisplayLayout = function(layouts, callback) {}; + + +/** + * @param {boolean} enabled True if unified desktop should be enabled. + * @see https://developer.chrome.com/extensions/system.display#method-enableUnifiedDesktop + */ +chrome.system.display.enableUnifiedDesktop = function(enabled) {}; + + +/** + * @param {string} id The display's unique identifier. + * @see https://developer.chrome.com/extensions/system.display#method-overscanCalibrationStart + */ +chrome.system.display.overscanCalibrationStart = function(id) {}; + + +/** + * @param {string} id The display's unique identifier. + * @param {!chrome.system.display.Insets} delta The amount to change the + * overscan insets. + * @see https://developer.chrome.com/extensions/system.display#method-overscanCalibrationAdjust + */ +chrome.system.display.overscanCalibrationAdjust = function(id, delta) {}; + + +/** + * @param {string} id The display's unique identifier. + * @see https://developer.chrome.com/extensions/system.display#method-overscanCalibrationReset + */ +chrome.system.display.overscanCalibrationReset = function(id) {}; + + +/** + * @param {string} id The display's unique identifier. + * @see https://developer.chrome.com/extensions/system.display#method-overscanCalibrationComplete + */ +chrome.system.display.overscanCalibrationComplete = function(id) {}; + + +/** + * @param {string} id The display's unique identifier. + * @param {function(boolean):void=} callback Optional callback to inform the + * caller that the touch calibration has ended. The argument of the callback + * informs if the calibration was a success or not. + * @see https://developer.chrome.com/extensions/system.display#method-showNativeTouchCalibration + */ +chrome.system.display.showNativeTouchCalibration = function(id, callback) {}; + + +/** + * @param {string} id The display's unique identifier. + * @see https://developer.chrome.com/extensions/system.display#method-startCustomTouchCalibration + */ +chrome.system.display.startCustomTouchCalibration = function(id) {}; + + +/** + * @param {!Object} pairs The pairs of point used to calibrate the display. + * @param {!chrome.system.display.Bounds} bounds Bounds of the display when the + * touch calibration was performed. |bounds.left| and |bounds.top| values + * are ignored. + * @see https://developer.chrome.com/extensions/system.display#method-completeCustomTouchCalibration + */ +chrome.system.display.completeCustomTouchCalibration = function(pairs, bounds) { +}; + + +/** + * @param {string} id The display's unique identifier. + * @see https://developer.chrome.com/extensions/system.display#method-clearTouchCalibration + */ +chrome.system.display.clearTouchCalibration = function(id) {}; + + +/** + * @type {!ChromeEvent} + * @see https://developer.chrome.com/extensions/system.display#event-onDisplayChanged + */ +chrome.system.display.onDisplayChanged; + + +chrome.types = {}; + + +/** + * @typedef {?{ + * format: (string|undefined), + * quality: (number|undefined) + * }} + */ +chrome.types.ImageDetails; + + + +/** + * @const + * @see https://developer.chrome.com/extensions/types.html + */ +chrome.chromeSetting = {}; + + +/** @type {!ChromeEvent} */ +chrome.chromeSetting.onChange; + + +/** + * @const + * @see https://developer.chrome.com/extensions/webNavigation.html + */ +chrome.webNavigation = {}; + + +/** + * @param {Object} details Object with a 'tabId' (number) key. + * @param {function(!Array>)} callback + * Callback function. + * @return {undefined} + */ +chrome.webNavigation.getAllFrames = function(details, callback) {}; + + +/** + * @param {Object} details Object with 'tabId' (number) and 'frameId' (number) + * keys. + * @param {function(Object)} callback + * Callback function. + * @return {undefined} + */ +chrome.webNavigation.getFrame = function(details, callback) {}; + + +/** @type {!ChromeEvent} */ +chrome.webNavigation.onBeforeNavigate; + + +/** @type {!ChromeEvent} */ +chrome.webNavigation.onCommitted; + + +/** @type {!ChromeEvent} */ +chrome.webNavigation.onDOMContentLoaded; + + +/** @type {!ChromeEvent} */ +chrome.webNavigation.onCompleted; + + +/** @type {!ChromeEvent} */ +chrome.webNavigation.onErrorOccurred; + + +/** @type {!ChromeEvent} */ +chrome.webNavigation.onCreatedNavigationTarget; + + +/** @type {!ChromeEvent} */ +chrome.webNavigation.onReferenceFragmentUpdated; + + +/** @type {!ChromeEvent} */ +chrome.webNavigation.onTabReplaced; + + +/** @type {!ChromeEvent} */ +chrome.webNavigation.onHistoryStateUpdated; + + +/** + * Base event type for WebRequest-releated events. + * + * The `addListener()` methods for these take more than one argument, so they + * cannot just extend `ChromeBaseEvent`. + * TODO(bradfordcsmith): These events won't automatically inherit new methods + * added to `ChromeBaseEvent`. + * @record + * @template LISTENER + */ +function WebRequestBaseEvent() {} + + +/** + * @param {LISTENER} listener Listener function. + * @param {!RequestFilter} filter A set of filters that restrict + * the events that will be sent to this listener. + * @param {!Array=} opt_extraInfoSpec Array of extra information + * that should be passed to the listener function. + * @return {undefined} + */ +WebRequestBaseEvent.prototype.addListener = function( + listener, filter, opt_extraInfoSpec) {}; + + +/** + * @param {LISTENER} listener Listener function. + * @return {undefined} + */ +WebRequestBaseEvent.prototype.removeListener = function(listener) {}; + + +/** + * @param {LISTENER} listener Listener function. + * @return {undefined} + */ +WebRequestBaseEvent.prototype.hasListener = function(listener) {}; + + +/** + * @param {LISTENER} listener Listener function. + * @return {undefined} + */ +WebRequestBaseEvent.prototype.hasListeners = function(listener) {}; + + +/** + * Most event listeners for WebRequest take extra arguments. + * @see https://developer.chrome.com/extensions/webRequest + * @record + * @extends {WebRequestBaseEvent} + */ +function WebRequestEvent() {} + + +/** + * Some event listeners can be optionally synchronous. + * @see https://developer.chrome.com/extensions/webRequest + * @record + * @extends {WebRequestBaseEvent} + */ +function WebRequestOptionallySynchronousEvent() {} + + +/** + * The onAuthRequired event listener can be optionally synchronous, and can also + * optionally take a callback. + * @see https://developer.chrome.com/extensions/webRequest + * @record + * @extends {WebRequestBaseEvent< + * function( + * !Object, + * function(!BlockingResponse)=): (undefined|!BlockingResponse)>} + */ +function WebRequestOnAuthRequiredEvent() {} + + +/** + * The onErrorOccurred event takes one fewer parameter than the others. + * + * The `addListener()` methods for these take more than one argument, so they + * cannot just extend `ChromeBaseEvent`. + * TODO(bradfordcsmith): These events won't automatically inherit new methods + * added to `ChromeBaseEvent`. + * @see https://developer.chrome.com/extensions/webRequest + * @record + */ +function WebRequestOnErrorOccurredEvent() {} + + +/** + * @param {function(!Object): void} listener Listener function. + * @param {!RequestFilter} filter A set of filters that restrict + * the events that will be sent to this listener. + * @return {undefined} + */ +WebRequestOnErrorOccurredEvent.prototype.addListener = + function(listener, filter) {}; + + +/** + * @param {function(!Object): void} listener Listener function. + * @return {undefined} + */ +WebRequestOnErrorOccurredEvent.prototype.removeListener = function(listener) {}; + + +/** + * @param {function(!Object): void} listener Listener function. + * @return {undefined} + */ +WebRequestOnErrorOccurredEvent.prototype.hasListener = function(listener) {}; + + +/** + * @param {function(!Object): void} listener Listener function. + * @return {undefined} + */ +WebRequestOnErrorOccurredEvent.prototype.hasListeners = function(listener) {}; + + +/** + * @const + * @see https://developer.chrome.com/extensions/webRequest + */ +chrome.webRequest = {}; + + +/** + * @param {function(): void=} opt_callback Callback function. + * @return {undefined} + */ +chrome.webRequest.handlerBehaviorChanged = function(opt_callback) {}; + + +/** @type {!WebRequestOnAuthRequiredEvent} */ +chrome.webRequest.onAuthRequired; + + +/** @type {!WebRequestEvent} */ +chrome.webRequest.onBeforeRedirect; + + +/** @type {!WebRequestOptionallySynchronousEvent} */ +chrome.webRequest.onBeforeRequest; + + +/** @type {!WebRequestOptionallySynchronousEvent} */ +chrome.webRequest.onBeforeSendHeaders; + + +/** @type {!WebRequestEvent} */ +chrome.webRequest.onCompleted; + + +/** @type {!WebRequestOnErrorOccurredEvent} */ +chrome.webRequest.onErrorOccurred; + + +/** @type {!WebRequestOptionallySynchronousEvent} */ +chrome.webRequest.onHeadersReceived; + + +/** @type {!WebRequestEvent} */ +chrome.webRequest.onResponseStarted; + + +/** @type {!WebRequestEvent} */ +chrome.webRequest.onSendHeaders; + + +// Classes + + + +/** + * @see https://developer.chrome.com/extensions/management.html + * @constructor + */ +function ExtensionInfo() {} + + +/** @type {string} */ +ExtensionInfo.prototype.id; + + +/** @type {string} */ +ExtensionInfo.prototype.name; + + +/** @type {string} */ +ExtensionInfo.prototype.shortName; + + +/** @type {string} */ +ExtensionInfo.prototype.description; + + +/** @type {string} */ +ExtensionInfo.prototype.version; + + +/** @type {boolean} */ +ExtensionInfo.prototype.mayDisable; + + +/** @type {boolean} */ +ExtensionInfo.prototype.enabled; + + +/** @type {string|undefined} */ +ExtensionInfo.prototype.disabledReason; + + +/** @type {boolean} */ +ExtensionInfo.prototype.isApp; + + +/** @type {string} */ +ExtensionInfo.prototype.type; + + +/** @type {string|undefined} */ +ExtensionInfo.prototype.appLaunchUrl; + + +/** @type {string|undefined} */ +ExtensionInfo.prototype.homepageUrl; + + +/** @type {string|undefined} */ +ExtensionInfo.prototype.updateUrl; + + +/** @type {boolean} */ +ExtensionInfo.prototype.offlineEnabled; + + +/** @type {string} */ +ExtensionInfo.prototype.optionsUrl; + + +/** @type {!Array|undefined} */ +ExtensionInfo.prototype.icons; + + +/** @type {!Array} */ +ExtensionInfo.prototype.permissions; + + +/** @type {!Array} */ +ExtensionInfo.prototype.hostPermissions; + + +/** @type {string} */ +ExtensionInfo.prototype.installType; + + +/** @type {string|undefined} */ +ExtensionInfo.prototype.launchType; + + +/** @type {!Array|undefined} */ +ExtensionInfo.prototype.availableLaunchTypes; + + + +/** + * @see https://developer.chrome.com/extensions/management.html + * @constructor + */ +function IconInfo() {} + + +/** @type {number} */ +IconInfo.prototype.size; + + +/** @type {string} */ +IconInfo.prototype.url; + + + + + +/** + * @see https://developer.chrome.com/extensions/windows.html + * @constructor + */ +function ChromeWindow() {} + + +/** @type {number} */ +ChromeWindow.prototype.id; + + +/** @type {boolean} */ +ChromeWindow.prototype.focused; + + +/** @type {number} */ +ChromeWindow.prototype.top; + + +/** @type {number} */ +ChromeWindow.prototype.left; + + +/** @type {number} */ +ChromeWindow.prototype.width; + + +/** @type {number} */ +ChromeWindow.prototype.height; + + +/** @type {Array} */ +ChromeWindow.prototype.tabs; + + +/** @type {boolean} */ +ChromeWindow.prototype.incognito; + + +/** @type {string} */ +ChromeWindow.prototype.type; + + +/** @type {string} */ +ChromeWindow.prototype.state; + + +/** @type {boolean} */ +ChromeWindow.prototype.alwaysOnTop; + + + +/** + * Event whose listeners take an ExtensionInfo parameter. + * @record + * @extends {ChromeBaseEvent} + */ +function ChromeExtensionInfoEvent() {} + + +/** + * @see http://developer.chrome.com/extensions/pushMessaging.html + * @const + */ +chrome.pushMessaging = {}; + + +/** + * @type {!chrome.pushMessaging.PushMessageEvent} + */ +chrome.pushMessaging.onMessage; + + +/** + * @param {boolean|function(!chrome.pushMessaging.ChannelIdResult)} + * interactiveOrCallback Either a flag(optional), if set to true, user will + * be asked to log in if they are not already logged in, or, when he flag is + * not given, the callback. + * @param {function(!chrome.pushMessaging.ChannelIdResult)=} opt_callback + * Callback. + * @return {undefined} + */ +chrome.pushMessaging.getChannelId = + function(interactiveOrCallback, opt_callback) {}; + + + +/** + * Event whose listeners take a chrome.pushMessaging.Message parameter. + * @record + * @extends {ChromeBaseEvent} + */ +chrome.pushMessaging.PushMessageEvent = function() {}; + + +/** + * @see https://developer.chrome.com/extensions/bookmarks.html#type-BookmarkTreeNode + * @constructor + */ +function BookmarkTreeNode() {} + + +/** @type {string} */ +BookmarkTreeNode.prototype.id; + + +/** @type {string|undefined} */ +BookmarkTreeNode.prototype.parentId; + + +/** @type {number|undefined} */ +BookmarkTreeNode.prototype.index; + + +/** @type {string|undefined} */ +BookmarkTreeNode.prototype.url; + + +/** @type {string} */ +BookmarkTreeNode.prototype.title; + + +/** @type {number|undefined} */ +BookmarkTreeNode.prototype.dateAdded; + + +/** @type {number|undefined} */ +BookmarkTreeNode.prototype.dateGroupModified; + + +/** @type {string|undefined} */ +BookmarkTreeNode.prototype.unmodifiable; + + +/** @type {!Array|undefined} */ +BookmarkTreeNode.prototype.children; + + + +/** + * @see https://developer.chrome.com/extensions/dev/cookies.html#type-Cookie + * @constructor + */ +function Cookie() {} + + +/** @type {string} */ +Cookie.prototype.name; + + +/** @type {string} */ +Cookie.prototype.value; + + +/** @type {string} */ +Cookie.prototype.domain; + + +/** @type {boolean} */ +Cookie.prototype.hostOnly; + + +/** @type {string} */ +Cookie.prototype.path; + + +/** @type {boolean} */ +Cookie.prototype.secure; + + +/** @type {boolean} */ +Cookie.prototype.httpOnly; + + +/** @type {boolean} */ +Cookie.prototype.session; + + +/** @type {number} */ +Cookie.prototype.expirationDate; + + +/** @type {string} */ +Cookie.prototype.storeId; + + + +/** + * @see https://developer.chrome.com/extensions/dev/cookies.html#type-CookieStore + * @constructor + */ +function CookieStore() {} + + +/** @type {string} */ +CookieStore.prototype.id; + + +/** @type {Array} */ +CookieStore.prototype.tabIds; + + + +/** + * @see https://developer.chrome.com/extensions/dev/contextMenus.html#type-OnClickData + * @constructor + */ +function OnClickData() {} + + +/** @type {number|string} */ +OnClickData.prototype.menuItemId; + + +/** @type {number|string} */ +OnClickData.prototype.parentMenuItemId; + + +/** @type {string} */ +OnClickData.prototype.mediaType; + + +/** @type {string} */ +OnClickData.prototype.linkUrl; + + +/** @type {string} */ +OnClickData.prototype.srcUrl; + + +/** @type {string} */ +OnClickData.prototype.pageUrl; + + +/** @type {string} */ +OnClickData.prototype.frameUrl; + + +/** @type {number} */ +OnClickData.prototype.frameId; + + +/** @type {string} */ +OnClickData.prototype.selectionText; + + +/** @type {boolean} */ +OnClickData.prototype.editable; + + +/** @type {boolean} */ +OnClickData.prototype.wasChecked; + + +/** @type {boolean} */ +OnClickData.prototype.checked; + + + +/** + * @see https://developer.chrome.com/extensions/debugger.html#type-Debuggee + * @constructor + */ +function Debuggee() {} + + +/** @type {number} */ +Debuggee.prototype.tabId; + + +/** + * @see https://developer.chrome.com/extensions/contentSettings.html#type-ResourceIdentifier + * @constructor + */ +function ResourceIdentifier() {} + + +/** @type {string} */ +ResourceIdentifier.prototype.id; + + +/** @type {string} */ +ResourceIdentifier.prototype.description; + + + +/** + * @see https://developer.chrome.com/extensions/contentSettings.html#type-ContentSetting + * @constructor + */ +function ContentSetting() {} + + +/** + * @param {!Object} details Settings details. + * @param {function(): void=} opt_callback Callback function. + * @return {undefined} + */ +ContentSetting.prototype.clear = function(details, opt_callback) {}; + + +/** + * @param {!Object} details + * Settings details. + * @param {function(): void} callback Callback function. + * @return {undefined} + */ +ContentSetting.prototype.get = function(details, callback) {}; + + +/** + * @param {function(): void} callback Callback function. + * @return {undefined} + */ +ContentSetting.prototype.getResourceIdentifiers = function(callback) {}; + + +/** + * @param {!Object} details + * Settings details. + * @param {function(): void=} opt_callback Callback function. + * @return {undefined} + */ +ContentSetting.prototype.set = function(details, opt_callback) {}; + + + +/** + * @see https://developer.chrome.com/extensions/history.html#type-HistoryItem + * @constructor + */ +function HistoryItem() {} + + +/** @type {string} */ +HistoryItem.prototype.id; + + +/** @type {string} */ +HistoryItem.prototype.url; + + +/** @type {string} */ +HistoryItem.prototype.title; + + +/** @type {number} */ +HistoryItem.prototype.lastVisitTime; + + +/** @type {number} */ +HistoryItem.prototype.visitCount; + + +/** @type {number} */ +HistoryItem.prototype.typedCount; + + + +/** + * @see https://developer.chrome.com/extensions/history.html#type-VisitItem + * @constructor + */ +function VisitItem() {} + + +/** @type {string} */ +VisitItem.prototype.id; + + +/** @type {string} */ +VisitItem.prototype.visitId; + + +/** @type {number} */ +VisitItem.prototype.visitTime; + + +/** @type {string} */ +VisitItem.prototype.referringVisitId; + + +/** @type {string} */ +VisitItem.prototype.transition; + + + +/** + * @see https://developer.chrome.com/extensions/fileBrowserHandler.html#type-FileHandlerExecuteEventDetails + * @constructor + */ +function FileHandlerExecuteEventDetails() {} + + +/** @type {!Array} */ +FileHandlerExecuteEventDetails.prototype.entries; + + +/** @type {number|undefined} */ +FileHandlerExecuteEventDetails.prototype.tab_id; + + + +/** + * @see https://developer.chrome.com/extensions/input.ime.html#type-KeyboardEvent + * @constructor + */ +function ChromeKeyboardEvent() {} + + +/** @type {string} */ +ChromeKeyboardEvent.prototype.type; + + +/** @type {string} */ +ChromeKeyboardEvent.prototype.requestId; + + +/** @type {string|undefined} */ +ChromeKeyboardEvent.prototype.extensionId; + + +/** @type {string} */ +ChromeKeyboardEvent.prototype.key; + + +/** @type {string} */ +ChromeKeyboardEvent.prototype.code; + + +/** @type {number|undefined} */ +ChromeKeyboardEvent.prototype.keyCode; + + +/** @type {boolean|undefined} */ +ChromeKeyboardEvent.prototype.altKey; + + +/** @type {boolean|undefined} */ +ChromeKeyboardEvent.prototype.ctrlKey; + + +/** @type {boolean|undefined} */ +ChromeKeyboardEvent.prototype.shiftKey; + + +/** @type {boolean|undefined} */ +ChromeKeyboardEvent.prototype.capsLock; + + + +/** + * @see https://developer.chrome.com/extensions/input.ime.html#type-InputContext + * @constructor + */ +function InputContext() {} + + +/** @type {number} */ +InputContext.prototype.contextID; + + +/** @type {string} */ +InputContext.prototype.type; + + + +/** + * @see https://developer.chrome.com/extensions/proxy.html#type-ProxyServer + * @constructor + */ +function ProxyServer() {} + + +/** @type {string} */ +ProxyServer.prototype.scheme; + + +/** @type {string} */ +ProxyServer.prototype.host; + + +/** @type {number} */ +ProxyServer.prototype.port; + + + +/** + * @see https://developer.chrome.com/extensions/proxy.html#type-ProxyRules + * @constructor + */ +function ProxyRules() {} + + +/** @type {ProxyServer} */ +ProxyRules.prototype.singleProxy; + + +/** @type {ProxyServer} */ +ProxyRules.prototype.proxyForHttp; + + +/** @type {ProxyServer} */ +ProxyRules.prototype.proxyForHttps; + + +/** @type {ProxyServer} */ +ProxyRules.prototype.proxyForFtp; + + +/** @type {ProxyServer} */ +ProxyRules.prototype.fallbackProxy; + + +/** @type {!Array} */ +ProxyRules.prototype.bypassList; + + + +/** + * @see https://developer.chrome.com/extensions/proxy.html#type-PacScript + * @constructor + */ +function PacScript() {} + + +/** @type {string} */ +PacScript.prototype.url; + + +/** @type {string} */ +PacScript.prototype.data; + + +/** @type {boolean} */ +PacScript.prototype.mandatory; + + + +/** + * @see https://developer.chrome.com/extensions/proxy.html#type-ProxyConfig + * @constructor + */ +function ProxyConfig() {} + + +/** @type {ProxyRules} */ +ProxyConfig.prototype.rules; + + +/** @type {PacScript} */ +ProxyConfig.prototype.pacScript; + + +/** @type {string} */ +ProxyConfig.prototype.mode; + + + +/** + * The event listener for Storage receives an Object mapping each + * key that changed to its corresponding StorageChange for that item. + * + * Listener will receive an object that maps each key to its StorageChange, + * and the namespace ("sync" or "local") of the storage area the changes + * are for. + * @see https://developer.chrome.com/extensions/storage.html + * @record + * @extends {ChromeBaseEvent, string)>} + */ +function StorageChangeEvent() {} + + +/** + * @see https://developer.chrome.com/extensions/storage.html#type-StorageChange + * @constructor + */ +function StorageChange() {} + + +/** @type {?} */ +StorageChange.prototype.oldValue; + + +/** @type {?} */ +StorageChange.prototype.newValue; + + + +/** + * @see https://developer.chrome.com/extensions/storage.html#type-StorageArea + * @constructor + */ +function StorageArea() {} + + +/** + * @param {(string|!Array|!Object|null|function(!Object))=} + * keysOrCallback + * A single key to get, list of keys to get, or a dictionary + * specifying default values (see description of the + * object). An empty list or object will return an empty + * result object. Pass in null to get the entire contents of storage. + * @param {function(!Object)=} opt_callback Callback with storage items, or null + * on failure. + * @return {undefined} + */ +StorageArea.prototype.get = function(keysOrCallback, opt_callback) {}; + + +/** + * @param {(string|!Array|null|function(!Object))=} keysOrCallback + * A single key or list of keys to get the total usage for. An empty list + * will return 0. Pass in null to get the total usage of all of storage. + * @param {function(number)=} opt_callback + * Callback with the amount of space being used by storage. + * @return {undefined} + */ +StorageArea.prototype.getBytesInUse = function(keysOrCallback, opt_callback) {}; + + +/** + * @param {!Object} items + * Object specifying items to augment storage + * with. Values that cannot be serialized (functions, etc) will be ignored. + * @param {function()=} opt_callback Callback. + * @return {undefined} + */ +StorageArea.prototype.set = function(items, opt_callback) { }; + + +/** + * @param {(string|!Array)} keys + * A single key or a list of keys for items to remove. + * @param {function()=} opt_callback Callback. + * @return {undefined} + */ +StorageArea.prototype.remove = function(keys, opt_callback) {}; + + +/** + * Removes all items from storage. + * @param {function(): void=} opt_callback Callback function. + * @return {undefined} + */ +StorageArea.prototype.clear = function(opt_callback) {}; + + + +/** + * @see https://developer.chrome.com/extensions/types.html#type-ChromeSetting + * @constructor + */ +function ChromeSetting() {} + + +/** + * @param {Object} details Object with a 'scope' (string) key. + * @param {function(): void=} opt_callback Callback function. + * @return {undefined} + */ +ChromeSetting.prototype.clear = function(details, opt_callback) {}; + + +/** + * @param {Object} details Object with an 'incognito' (boolean) key. + * @param {function(Object): void} callback Callback function. + * @return {undefined} + */ +ChromeSetting.prototype.get = function(details, callback) {}; + + +/** + * @param {Object} details Object with a 'value' (*) key and an optional + * 'scope' (string) key. + * @param {function(): void=} opt_callback Callback function. + * @return {undefined} + */ +ChromeSetting.prototype.set = function(details, opt_callback) {}; + + +/** @type {!ChromeObjectEvent} */ +ChromeSetting.prototype.onChange; + + + +/** + * @see https://developer.chrome.com/extensions/webRequest#type-RequestFilter + * @typedef {?{ + * urls: !Array, + * types: (!Array|undefined), + * tabId: (number|undefined), + * windowId: (number|undefined), + * }} + */ +var RequestFilter; + + + +/** + * @see https://developer.chrome.com/extensions/webRequest#type-HttpHeaders + * @typedef {?{ + * name: string, + * value: (string|undefined), + * binaryValue: (!Array|undefined), + * }} + */ +var HttpHeader; + + + +/** + * @see https://developer.chrome.com/extensions/webRequest#type-HttpHeaders + * @typedef {?Array} + */ +chrome.webRequest.HttpHeaders; + + + +/** + * @see https://developer.chrome.com/extensions/webRequest#type-BlockingResponse + * @typedef {?{ + * cancel: (boolean|undefined), + * redirectUrl: (string|undefined), + * requestHeaders: (!chrome.webRequest.HttpHeaders|undefined), + * responseHeaders: (!chrome.webRequest.HttpHeaders|undefined), + * authCredentials: (!{username: string, password: string}|undefined), + * }} + */ +var BlockingResponse; + + + +/** + * @see http://developer.chrome.com/extensions/pushMessaging.html#type-Message + * @constructor + */ +chrome.pushMessaging.Message = function() {}; + + +/** + * @type {number} + */ +chrome.pushMessaging.Message.prototype.subchannelId; + + +/** + * @type {string} + */ +chrome.pushMessaging.Message.prototype.payload; + + + +/** + * @see http://developer.chrome.com/extensions/pushMessaging.html#type-ChannelIdResult + * @constructor + */ +chrome.pushMessaging.ChannelIdResult = function() {}; + + +/** + * @type {string} + */ +chrome.pushMessaging.ChannelIdResult.prototype.channelId; + + +/** + * The {@code chrome.fileSystem} API makes use of the Entry and FileEntry types + * defined in {@code javascript/externs/fileapi.js}. + * @const + * @see http://developer.chrome.com/apps/fileSystem.html + */ +chrome.fileSystem = {}; + + +/** + * @param {!Entry} entry The entry to get the display path for. The entry can + * originally be obtained through + * {@code chrome.fileSystem.chooseEntry} or + * {@code chrome.fileSystem.restoreEntry}. + * @param {function(string)} callback A success callback. + * @see http://developer.chrome.com/apps/fileSystem.html#method-getDisplayPath + * @return {undefined} + */ +chrome.fileSystem.getDisplayPath = function(entry, callback) {}; + + +/** + * @param {!Entry} entry The entry to get a writable entry for. + * @param {function(!Entry)} callback A success callback. + * @see http://developer.chrome.com/apps/fileSystem.html#method-getWritableEntry + * @return {undefined} + */ +chrome.fileSystem.getWritableEntry = function(entry, callback) {}; + + +/** + * @param {!Entry} entry The entry to query writability. + * @param {function(boolean)} callback A success callback. + * @see http://developer.chrome.com/apps/fileSystem.html#method-isWritableEntry + * @return {undefined} + */ +chrome.fileSystem.isWritableEntry = function(entry, callback) {}; + + +/** + * @typedef {{ + * description: (string|undefined), + * mimeTypes: (!Array|undefined), + * extensions: (!Array|undefined) + * }} + * @see http://developer.chrome.com/apps/fileSystem.html#method-chooseEntry + */ +chrome.fileSystem.AcceptsOption; + + +/** + * @typedef {{ + * type: (string|undefined), + * suggestedName: (string|undefined), + * accepts: (!Array|undefined), + * acceptsAllTypes: (boolean|undefined), + * acceptsMultiple: (boolean|undefined) + * }} + * @see http://developer.chrome.com/apps/fileSystem.html#method-chooseEntry + */ +chrome.fileSystem.ChooseEntryOptions; + + +/** + * @typedef {?{ + * volumeId: string, + * writable: (boolean|undefined) + * }} + * @see http://developer.chrome.com/apps/fileSystem.html#method-requestFileSystem + */ +chrome.fileSystem.RequestFileSystemOptions; + + +/** + * @see http://developer.chrome.com/apps/fileSystem.html#method-getVolumeList + * @constructor + */ +chrome.fileSystem.Volume = function() {}; + + +/** @type {string} */ +chrome.fileSystem.Volume.prototype.volumeId; + + +/** @type {boolean} */ +chrome.fileSystem.Volume.prototype.writable; + + +/** + * @param {!chrome.fileSystem.ChooseEntryOptions| + * function(Entry=, !Array=)} optionsOrCallback The + * options for the file prompt or the callback. + * @param {function(Entry=, !Array=)=} opt_callback A success + * callback, if arg1 is options. + * @see http://developer.chrome.com/apps/fileSystem.html#method-chooseEntry + * @return {undefined} + */ +chrome.fileSystem.chooseEntry = function(optionsOrCallback, opt_callback) {}; + + +/** + * @param {string} id The ID of the file entry to restore. + * @param {function(!Entry)} callback A success callback. + * @see http://developer.chrome.com/apps/fileSystem.html#method-restoreEntry + * @return {undefined} + */ +chrome.fileSystem.restoreEntry = function(id, callback) {}; + + +/** + * @param {string} id The ID of the file entry to query restorability. + * @param {function(boolean)} callback A success callback. + * @see http://developer.chrome.com/apps/fileSystem.html#method-isRestorable + * @return {undefined} + */ +chrome.fileSystem.isRestorable = function(id, callback) {}; + + +/** + * @param {!Entry} entry The entry to regain access to. + * @return {string} The ID that can be passed to restoreEntry to regain access + * to the given file entry. + * @see http://developer.chrome.com/apps/fileSystem.html#method-retainEntry + */ +chrome.fileSystem.retainEntry = function(entry) {}; + + +/** + * @param {!chrome.fileSystem.RequestFileSystemOptions} options Options for the + * request. + * @param {function(!FileSystem=)} callback A completion callback with the file + * system in case of a success. Otherwise the error is passed as + * chrome.runtime.lastError. + * @see http://developer.chrome.com/apps/fileSystem.html#method-requestFileSystem + * @return {undefined} + */ +chrome.fileSystem.requestFileSystem = function(options, callback) {}; + + +/** + * @param {function(!Array=)} callback A completion + * callback with the file system list in case of a success. Otherwise the + * error is passed as chrome.runtime.lastError. + * @see http://developer.chrome.com/apps/fileSystem.html#method-getVolumeList + * @return {undefined} + */ +chrome.fileSystem.getVolumeList = function(callback) {}; + + +/** + * @const + * @see https://developer.chrome.com/apps/syncFileSystem + */ +chrome.syncFileSystem = {}; + + +/** + * Returns a syncable filesystem backed by Google Drive. The returned + * DOMFileSystem instance can be operated on in the same way as + * the Temporary and Persistant file systems (see + * http://www.w3.org/TR/file-system-api/), except that the filesystem + * object returned for Sync FileSystem does NOT support directory + * operations (yet). You can get a list of file entries by reading + * the root directory (by creating a new DirectoryReader), + * but cannot create a new directory in it. + * + *

Calling this multiple times from the same app will return the same + * handle to the same file system. + * + *

Note this call can fail. For example, if the user is not signed in + * to Chrome or if there is no network operation. To handle these errors + * it is important chrome.runtime.lastError is checked in the callback. + * + * @param {function(!FileSystem)} callback A callback type for + * requestFileSystem. + * @see https://developer.chrome.com/apps/syncFileSystem#method-requestFileSystem + * @return {undefined} + */ +chrome.syncFileSystem.requestFileSystem = function(callback) {}; + + +/** + * Sets the default conflict resolution policy for the 'syncable' file + * storage for the app. By default it is set to 'last_write_win'. + * When conflict resolution policy is set to 'last_write_win' conflicts + * for existing files are automatically resolved next time the file is updated. + * {@code callback} can be optionally given to know if the request has + * succeeded or not. + * + * @param {string} policy Any of 'last_write_win' or 'manual' + * @param {function()=} opt_callback + * + * @see https://developer.chrome.com/apps/syncFileSystem#method-setConflictResolutionPolicy + * @return {undefined} + */ +chrome.syncFileSystem.setConflictResolutionPolicy = + function(policy, opt_callback) {}; + + +/** + * Gets the current conflict resolution policy. + * + * @param {function(string)} callback Accepting any of 'last_write_win' + * or 'manual'. + * @see https://developer.chrome.com/apps/syncFileSystem#method-getConflictResolutionPolicy + * @return {undefined} + */ +chrome.syncFileSystem.getConflictResolutionPolicy = function(callback) {}; + + +/** + * Returns the current usage and quota in bytes for the 'syncable' file + * storage for the app. + * + * @param {!FileSystem} fileSystem + * @param {function(!Object)} callback Taking an object substantially similar + * to {@code {'usageBytes': number, quotaBytes: number}}. + * @see https://developer.chrome.com/apps/syncFileSystem#method-getUsageAndQuota + * @return {undefined} + */ +chrome.syncFileSystem.getUsageAndQuota = function(fileSystem, callback) {}; + + +/** + * Returns the FileStatus for the given fileEntry. The status value can be + * 'synced', 'pending' or 'conflicting'. Note that 'conflicting' state only + * happens when the service's conflict resolution policy is set to 'manual'. + * + * @param {!Entry} fileEntry + * @param {function(string)} callback Called with any of 'synced', 'pending' + * or 'conflicting'. + * + * @see https://developer.chrome.com/apps/syncFileSystem#method-getFileStatus + * @return {undefined} + */ +chrome.syncFileSystem.getFileStatus = function(fileEntry, callback) {}; + + +/** + * Returns each FileStatus for the given fileEntry array. Typically called + * with the result from dirReader.readEntries(). + * + * @param {!Array} fileEntries + * @param {function(!Array)} callback Each object will look like: + * {@code {'fileEntry': Entry, 'status': string, 'error': string?}}. + * + * @see https://developer.chrome.com/apps/syncFileSystem#method-getFileStatuses + * @return {undefined} + */ +chrome.syncFileSystem.getFileStatuses = function(fileEntries, callback) {}; + + +/** + * Since Chrome 31. + * + *

Returns the current sync backend status. + * + * @param {function(string)} callback Arg is any of 'initializing', 'running', + * 'authentication_required', 'temporary_unavailable', or 'disabled'. + * + * @see https://developer.chrome.com/apps/syncFileSystem#method-getServiceStatus + * @return {undefined} + */ +chrome.syncFileSystem.getServiceStatus = function(callback) {}; + + +/** + * Fired when an error or other status change has happened in the sync + * backend (for example, when the sync is temporarily disabled due + * to network or authentication error). + * + * @type {!ChromeObjectEvent} + * + * @see https://developer.chrome.com/apps/syncFileSystem#event-onServiceStatusChanged + */ +chrome.syncFileSystem.onServiceStatusChanged; + + +/** + * Fired when a file has been updated by the background sync service. + * + * @type {!ChromeObjectEvent} + * + * @see https://developer.chrome.com/apps/syncFileSystem#event-onFileStatusChanged + */ +chrome.syncFileSystem.onFileStatusChanged; + + +/** + * @const + * @see http://developer.chrome.com/extensions/alarms.html + */ +chrome.alarms = {}; + + +/** + * Creates an alarm. Near the time(s) specified by alarmInfo, the onAlarm event + * is fired. If there is another alarm with the same name (or no name if none is + * specified), it will be cancelled and replaced by this alarm. + * @param {string|!chrome.alarms.AlarmCreateInfo} nameOrAlarmCreateInfo Either + * the name to identify this alarm or the info used to create the alarm. If + * no name is passed, the empty string is used to identify the alarm. + * @param {!chrome.alarms.AlarmCreateInfo=} opt_alarmInfo If a name was passed + * as arg1, the info used to create the alarm. + * @see http://developer.chrome.com/extensions/alarms.html#method-create + * @return {undefined} + */ +chrome.alarms.create = function(nameOrAlarmCreateInfo, opt_alarmInfo) {}; + + +/** + * Retrieves details about the specified alarm. + * @param {string|function(!chrome.alarms.Alarm)} nameOrCallback The name + * of the alarm to get or the callback to invoke with the alarm. If no name + * is passed, the empty string is used to get the alarm. + * @param {function(!chrome.alarms.Alarm)=} opt_callback If a name was passed + * as arg1, the callback to invoke with the alarm. + * @see http://developer.chrome.com/extensions/alarms.html#method-get + * @return {undefined} + */ +chrome.alarms.get = function(nameOrCallback, opt_callback) {}; + + +/** + * Gets an array of all the alarms. + * @param {function(!Array)} callback + * @see http://developer.chrome.com/extensions/alarms.html#method-getAll + * @return {undefined} + */ +chrome.alarms.getAll = function(callback) {}; + + +/** + * Clears the alarm with the given name. + * @param {string=} opt_name + * @param {function(boolean)=} opt_callback A callback that will be called with + * a boolean for whether the alarm was cleared. + * @see http://developer.chrome.com/extensions/alarms.html#method-clear + * @return {undefined} + */ +chrome.alarms.clear = function(opt_name, opt_callback) {}; + + +/** + * Clears all alarms. + * @param {function(boolean)=} opt_callback A callback that will be called with + * a boolean for whether the alarms were cleared. + * @see http://developer.chrome.com/extensions/alarms.html#method-clearAll + * @return {undefined} + */ +chrome.alarms.clearAll = function(opt_callback) {}; + + +/** + * Fired when an alarm has elapsed. Useful for event pages. + * @type {!chrome.alarms.AlarmEvent} + * @see http://developer.chrome.com/extensions/alarms.html#event-onAlarm + */ +chrome.alarms.onAlarm; + + + +/** + * @record + * @extends {ChromeBaseEvent} + */ +chrome.alarms.AlarmEvent = function() {}; + + +/** + * @interface + * @see http://developer.chrome.com/extensions/alarms.html#type-Alarm + */ +chrome.alarms.Alarm = function() {}; + + +/** + * Name of this alarm. + * @type {string} + */ +chrome.alarms.Alarm.prototype.name; + + +/** + * Time at which this alarm was scheduled to fire, in milliseconds past the + * epoch (e.g. Date.now() + n). For performance reasons, the alarm may have been + * delayed an arbitrary amount beyond this. + * @type {number} + */ +chrome.alarms.Alarm.prototype.scheduledTime; + + +/** + * If not null, the alarm is a repeating alarm and will fire again in + * periodInMinutes minutes. + * @type {?number} + */ +chrome.alarms.Alarm.prototype.periodInMinutes; + + +/** + * @typedef {{ + * when: (number|undefined), + * delayInMinutes: (number|undefined), + * periodInMinutes: (number|undefined) + * }} + * @see http://developer.chrome.com/extensions/alarms.html#method-create + */ +chrome.alarms.AlarmCreateInfo; + + +/** + * @see https://developer.chrome.com/apps/hid + * @const + */ +chrome.hid = {}; + + + +/** + * @constructor + * @see https://developer.chrome.com/apps/hid#type-DeviceFilter + */ +chrome.hid.DeviceFilter = function() {}; + + +/** + * Device vendor ID. + * @type {number|undefined} + */ +chrome.hid.DeviceFilter.prototype.vendorId; + + +/** + * Device product ID, only checked if the vendor ID matches. + * @type {number|undefined} + */ +chrome.hid.DeviceFilter.prototype.productId; + + +/** + * HID usage page identifier. + * @type {number|undefined} + */ +chrome.hid.DeviceFilter.prototype.usagePage; + + +/** + * HID usage identifier, checked only if the HID usage page matches. + * @type {number|undefined} + */ +chrome.hid.DeviceFilter.prototype.usage; + + +/** + * @typedef {?{ + * vendorId: (number|undefined), + * productId: (number|undefined), + * filters: (!Array|undefined) + * }} + * Deprecated since Chrome 39: vendorId, productId + * Since Chrome 39: filters + * @see https://developer.chrome.com/apps/hid#method-getDevices + */ +chrome.hid.HidGetDevicesOptions; + + +/** + * @typedef {?{ + * multiple: (boolean|undefined), + * filters: (!Array|undefined) + * }} + * @see https://developer.chrome.com/apps/hid#method-getUserSelectedDevices + */ +chrome.hid.HidGetUserSelectedDevicesOptions; + + +/** + * @typedef {?{ + * usagePage: number, + * usage: number, + * reportIds: !Array + * }} +* @see https://developer.chrome.com/apps/hid#method-getDevices +*/ +chrome.hid.HidDeviceUsage; + + + +/** + * @constructor + * @see https://developer.chrome.com/apps/hid#type-HidDeviceInfo + */ +chrome.hid.HidDeviceInfo = function() {}; + + +/** + * Opaque device ID. + * @type {number} + */ +chrome.hid.HidDeviceInfo.prototype.deviceId; + + +/** + * Vendor ID. + * @type {number} + */ +chrome.hid.HidDeviceInfo.prototype.vendorId; + + +/** + * Product ID. + * @type {number} + */ +chrome.hid.HidDeviceInfo.prototype.productId; + + +/** + * The product name read from the device, if available. + * Since Chrome 46. + * @type {string} + */ +chrome.hid.HidDeviceInfo.prototype.productName; + + +/** + * The serial number read from the device, if available. + * Since Chrome 46. + * @type {string} + */ +chrome.hid.HidDeviceInfo.prototype.serialNumber; + + +/** + * Top-level collections from this device's report descriptors. + * @type {!Array} + */ +chrome.hid.HidDeviceInfo.prototype.collections; + + +/** + * Top-level collection's maximum input report size. + * @type {number} + */ +chrome.hid.HidDeviceInfo.prototype.maxInputReportSize; + + +/** + * Top-level collection's maximum output report size. + * @type {number} + */ +chrome.hid.HidDeviceInfo.prototype.maxOutputReportSize; + + +/** + * Top-level collection's maximum feature report size. + * @type {number} + */ +chrome.hid.HidDeviceInfo.prototype.maxFeatureReportSize; + + +/** + * Raw device report descriptor (not available on Windows). + * Since Chrome 42. + * @type {!ArrayBuffer} + */ +chrome.hid.HidDeviceInfo.prototype.reportDescriptor; + + +/** + * @typedef {?{ + * connectionId: number + * }} + * @see https://developer.chrome.com/apps/hid#method-connect + */ +chrome.hid.HidConnectInfo; + + +/** + * @see https://developer.chrome.com/apps/hid#method-getDevices + * Enumerates all the connected HID devices specified by the + * vendorId/productId/interfaceId tuple. + * @param {!chrome.hid.HidGetDevicesOptions} options The properties to search + * for on target devices. + * @param {function(!Array)} callback Invoked with a + * list of |HidDeviceInfo|s on complete. + * @return {undefined} + */ +chrome.hid.getDevices = function(options, callback) {}; + + +/** + * @see https://developer.chrome.com/apps/hid#method-getUserSelectedDevices + * Presents a device picker to the user and returns HidDeviceInfo objects for + * the devices selected. If the user cancels the picker devices will be empty. A + * user gesture is required for the dialog to display. Without a user gesture, + * the callback will run as though the user cancelled. If multiple filters are + * provided devices matching any filter will be displayed. + * @param {!chrome.hid.HidGetUserSelectedDevicesOptions} options + * @param {function(!Array)} callback Invoked with a + * list of |HidDeviceInfo|s on complete. + * @return {undefined} + */ +chrome.hid.getUserSelectedDevices = function(options, callback) {}; + + +/** + * @see https://developer.chrome.com/apps/hid#method-connect + * Opens a connection to a HID device for communication. + * @param {number} deviceId The ID of the device to open. + * @param {function(!Object=)} callback Invoked with an |HidConnectInfo| if the + * connection succeeds, or undefined if it fails. + * @return {undefined} + */ +chrome.hid.connect = function(deviceId, callback) {}; + + +/** + * @see https://developer.chrome.com/apps/hid#method-disconnect + * Disconnects from a device. + * @param {number} connectionId The connection to close. + * @param {function()=} opt_callback The callback to invoke once the connection + * is closed. + * @return {undefined} + */ +chrome.hid.disconnect = function(connectionId, opt_callback) {}; + + +/** + * @see https://developer.chrome.com/apps/hid#method-receive + * Receives an input report from an HID device. + * @param {number} connectionId The connection from which to receive the report. + * @param {function(number, !ArrayBuffer)} callback The callback to invoke with + * the received report. + * @return {undefined} + */ +chrome.hid.receive = function(connectionId, callback) {}; + + +/** + * @see https://developer.chrome.com/apps/hid#method-send + * Sends an output report to an HID device. + * @param {number} connectionId The connection to which to send the report. + * @param {number} reportId The report ID to use, or 0 if none. + * @param {!ArrayBuffer} data The report data. + * @param {function()} callback The callback to invoke once the write is + * finished. + * @return {undefined} + */ +chrome.hid.send = function(connectionId, reportId, data, callback) {}; + + +/** + * @see https://developer.chrome.com/apps/hid#method-receiveFeatureReport + * Receives a feature report from the device. + * @param {number} connectionId The connection from which to read the feature + * report. + * @param {number} reportId The report ID to use, or 0 if none. + * @param {number} size The size of the feature report to receive. + * @param {function(!ArrayBuffer)} callback The callback to invoke with the + * received report. + * @return {undefined} + */ +chrome.hid.receiveFeatureReport = + function(connectionId, reportId, size, callback) {}; + + +/** + * @see https://developer.chrome.com/apps/hid#method-sendFeatureReport + * Sends a feature report to the device. + * @param {number} connectionId The connection to which to send the feature + * report. + * @param {number} reportId The report ID to use, or 0 if none. + * @param {!ArrayBuffer} data The report data. + * @param {function()} callback The callback to invoke once the write is + * finished. + * @return {undefined} + */ +chrome.hid.sendFeatureReport = + function(connectionId, reportId, data, callback) {}; + + + +/** + * Event whose listeners take an HidDeviceInfo parameter. + * @record + * @extends {ChromeBaseEvent} + */ +chrome.hid.DeviceAddedEvent = function() {}; + + +/** + * @type {!chrome.hid.DeviceAddedEvent} + * @see https://developer.chrome.com/apps/hid#event-onDeviceAdded + */ +chrome.hid.onDeviceAdded; + + +/** + * @type {!ChromeNumberEvent} + * @see https://developer.chrome.com/apps/hid#event-onDeviceRemoved + */ +chrome.hid.onDeviceRemoved; + + +/** + * @see http://developer.chrome.com/extensions/notifications.html + * @const + */ +chrome.notifications = {}; + + +/** + * @typedef {{ + * title: string, + * iconUrl: (string|undefined) + * }} + * @see http://developer.chrome.com/extensions/notifications.html#type-NotificationOptions + */ +chrome.notifications.NotificationButton; + + +/** + * @typedef {{ + * title: string, + * message: string + * }} + * @see http://developer.chrome.com/extensions/notifications.html#type-NotificationOptions + */ +chrome.notifications.NotificationItem; + + +/** + * @typedef {{ + * type: (string|undefined), + * iconUrl: (string|undefined), + * title: (string|undefined), + * message: (string|undefined), + * contextMessage: (string|undefined), + * priority: (number|undefined), + * eventTime: (number|undefined), + * buttons: (!Array|undefined), + * imageUrl: (string|undefined), + * items: (!Array|undefined), + * progress: (number|undefined), + * isClickable: (boolean|undefined) + * }} + * @see http://developer.chrome.com/extensions/notifications.html#type-NotificationOptions + */ +chrome.notifications.NotificationOptions; + + +/** + * @typedef {function(boolean): void} + * @see http://developer.chrome.com/extensions/notifications.html#method-update + * @see http://developer.chrome.com/extensions/notifications.html#method-clear + */ +chrome.notifications.BooleanCallback; + + +/** + * @typedef {function(!Object): void} + * @see http://developer.chrome.com/extensions/notifications.html#method-getAll + */ +chrome.notifications.ObjectCallback; + + +/** + * @typedef {function(string, boolean): void} + * @see http://developer.chrome.com/extensions/notifications.html#event-onClosed + */ +chrome.notifications.ClosedCallback; + + +/** + * @typedef {function(string, number): void} + * @see http://developer.chrome.com/extensions/notifications.html#event-onButtonClicked + */ +chrome.notifications.ButtonCallback; + + +/** + * @param {string|!chrome.notifications.NotificationOptions} + * notificationIdOrOptions + * @param {(!chrome.notifications.NotificationOptions|function(string): void)=} + * opt_optionsOrCallback + * @param {(function(string): void)=} opt_callback + * @see http://developer.chrome.com/extensions/notifications.html#method-create + * @return {undefined} + */ +chrome.notifications.create = function(notificationIdOrOptions, + opt_optionsOrCallback, opt_callback) {}; + + +/** + * @param {string} notificationId + * @param {!chrome.notifications.NotificationOptions} options + * @param {chrome.notifications.BooleanCallback=} opt_callback + * @see http://developer.chrome.com/extensions/notifications.html#method-update + * @return {undefined} + */ +chrome.notifications.update = + function(notificationId, options, opt_callback) {}; + + +/** + * @param {string} notificationId + * @param {!chrome.notifications.BooleanCallback=} opt_callback + * @see http://developer.chrome.com/extensions/notifications.html#method-clear + * @return {undefined} + */ +chrome.notifications.clear = function(notificationId, opt_callback) {}; + + +/** + * @see http://developer.chrome.com/extensions/notifications.html#method-getAll + * @param {!chrome.notifications.ObjectCallback} callback + * @return {undefined} + */ +chrome.notifications.getAll = function(callback) {}; + + +/** + * @see http://developer.chrome.com/extensions/notifications.html#method-getPermissionLevel + * @param {function(string): void} callback takes 'granted' or 'denied' + * @return {undefined} + */ +chrome.notifications.getPermissionLevel = function(callback) {}; + + +/** + * @type {!chrome.notifications.ClosedEvent} + * @see http://developer.chrome.com/extensions/notifications.html#event-onClosed + */ +chrome.notifications.onClosed; + + +/** + * The user clicked a non-button area of the notification. Callback receives a + * notificationId. + * @type {!ChromeStringEvent} + * @see http://developer.chrome.com/extensions/notifications.html#event-onClicked + */ +chrome.notifications.onClicked; + + +/** + * @type {!chrome.notifications.ButtonClickedEvent} + * @see http://developer.chrome.com/extensions/notifications.html#event-onButtonClicked + */ +chrome.notifications.onButtonClicked; + + +/** + * Indicates permission level change. Callback should expect 'granted' or + * 'denied'. + * @type {!ChromeStringEvent} + * @see http://developer.chrome.com/extensions/notifications.html#event-onPermissionLevelChanged + */ +chrome.notifications.onPermissionLevelChanged; + + +/** + * @type {!ChromeEvent} + * @see http://developer.chrome.com/extensions/notifications.html#event-onShowSettings + */ +chrome.notifications.onShowSettings; + + + +/** + * @record + * @extends {ChromeBaseEvent} + * @see http://developer.chrome.com/extensions/notifications.html#event-onClosed + */ +chrome.notifications.ClosedEvent = function() {}; + + +/** + * @record + * @extends {ChromeBaseEvent} + * @see http://developer.chrome.com/extensions/notifications.html#event-onButtonClicked + */ +chrome.notifications.ButtonClickedEvent = function() {}; + + +/** + * @const + * @see http://developer.chrome.com/apps/system_storage.html + */ +chrome.system.storage = {}; + + + +/** @constructor */ +chrome.system.storage.StorageUnitInfo = function() {}; + + +/** @type {string} */ +chrome.system.storage.StorageUnitInfo.id; + + +/** @type {string} */ +chrome.system.storage.StorageUnitInfo.name; + + +/** @type {string} Any of 'fixed', 'removable', or 'unknown' */ +chrome.system.storage.StorageUnitInfo.type; + + +/** @type {number} */ +chrome.system.storage.StorageUnitInfo.capacity; + + + +/** + * Event whose listeners take a StorageUnitInfoEvent parameter. + * @record + * @extends {ChromeBaseEvent} + */ +chrome.system.storage.StorageUnitInfoEvent = function() {}; + + +/** @type {chrome.system.storage.StorageUnitInfoEvent} */ +chrome.system.storage.onAttached; + + +/** @type {!ChromeStringEvent} */ +chrome.system.storage.onDetached; + + +/** + * Gets the storage information from the system. + * @param {function(!Array)} callback + * @return {undefined} + */ +chrome.system.storage.getInfo = function(callback) {}; + + +/** + * Ejects a removable storage device. + * @param {string} id The transient device ID from StorageUnitInfo. + * @param {function(string)} callback Callback function where the value + * is any of: "success", "in_use", "no_such_device", "failure" + * @return {undefined} + */ +chrome.system.storage.ejectDevice = function(id, callback) {}; + + +/** + * Gets the available capacity of a specified storage device. + * @param {string} id The transient device ID from StorageUnitInfo. + * @param {function(Object)} callback A callback function that + * accepts an object with {@code id} and {@code availableCapacity} fields. + * @return {undefined} + */ +chrome.system.storage.getAvailableCapacity = function(id, callback) {}; + + +/** + * @see http://developer.chrome.com/apps/usb.html + * @const + */ +chrome.usb = {}; + + + +/** @constructor */ +chrome.usb.Device = function Device() {}; + + +/** @type {number} */ +chrome.usb.Device.prototype.device; + + +/** @type {number} */ +chrome.usb.Device.prototype.vendorId; + + +/** @type {number} */ +chrome.usb.Device.prototype.productId; + + +/** @type {number} */ +chrome.usb.Device.prototype.version; + + +/** + * The product name read from the device, if available. + * Since Chrome 46. + * @type {string} + */ +chrome.usb.Device.prototype.productName; + +/** + * The manufacturer name read from the device, if available. + * Since Chrome 46. + * @type {string} + */ +chrome.usb.Device.prototype.manufacturerName; + +/** + * The serial number read from the device, if available. + * Since Chrome 46. + * @type {string} + */ +chrome.usb.Device.prototype.serialNumber; + + + +/** @constructor */ +chrome.usb.ConnectionHandle = function ConnectionHandle() {}; + + +/** @type {number} */ +chrome.usb.ConnectionHandle.prototype.handle; + + +/** @type {number} */ +chrome.usb.ConnectionHandle.prototype.vendorId; + + +/** @type {number} */ +chrome.usb.ConnectionHandle.prototype.productId; + + +/** + * @typedef {?{ + * direction: string, + * endpoint: number, + * length: (number|undefined), + * data: (!ArrayBuffer|undefined), + * timeout: (number|undefined) + * }} + */ +chrome.usb.GenericTransferInfo; + + +/** + * @typedef {?{ + * direction: string, + * recipient: string, + * requestType: string, + * request: number, + * value: number, + * index: number, + * length: (number|undefined), + * data: (!ArrayBuffer|undefined), + * timeout: (number|undefined) + * }} + */ +chrome.usb.ControlTransferInfo; + + + +/** @constructor */ +chrome.usb.TransferResultInfo = function() {}; + + +/** @type {number|undefined} */ +chrome.usb.TransferResultInfo.prototype.resultCode; + + +/** @type {!ArrayBuffer|undefined} */ +chrome.usb.TransferResultInfo.prototype.data; + + +/** + * @typedef {?{ + * vendorId: number, + * productId: number, + * interfaceId: (number|undefined) + * }} + */ +chrome.usb.FindDevicesOptions; + + +/** + * @typedef {?{ + * vendorId: (number|undefined), + * producId: (number|undefined), + * interfaceClass: (number|undefined), + * interfaceSubclass: (number|undefined), + * interfaceProtocol: (number|undefined) + * }} + */ +chrome.usb.DeviceFilter; + + +/** + * @typedef {?{ + * vendorId: (number|undefined), + * productId: (number|undefined), + * filters: (!Array|undefined) + * }} + */ +chrome.usb.GetDevicesOptions; + + +/** + * @typedef {?{ + * multiple: (boolean|undefined), + * filters: (!Array|undefined) + * }} + */ +chrome.usb.GetUserSelectedDevicesOptions; + + +/** + * @typedef {?{ + * transferInfo: !chrome.usb.GenericTransferInfo, + * packets: number, + * packetLength: number + * }} + */ +chrome.usb.IsochronousTransferInfo; + + + +/** @constructor */ +chrome.usb.EndpointDescriptor = function() {}; + + +/** @type {number} */ +chrome.usb.EndpointDescriptor.prototype.address; + +/** @type {string} */ +chrome.usb.EndpointDescriptor.prototype.type; + + +/** @type {string} */ +chrome.usb.EndpointDescriptor.prototype.direction; + + +/** @type {number} */ +chrome.usb.EndpointDescriptor.prototype.maximumPacketSize; + + +/** @type {(string|undefined)} */ +chrome.usb.EndpointDescriptor.prototype.synchronization; + + +/** @type {(string|undefined)} */ +chrome.usb.EndpointDescriptor.prototype.usage; + + +/** @type {(number|undefined)} */ +chrome.usb.EndpointDescriptor.prototype.pollingInterval; + + +/** @type {!ArrayBuffer} */ +chrome.usb.EndpointDescriptor.prototype.extra_data; + + + +/** @constructor */ +chrome.usb.InterfaceDescriptor = function() {}; + + +/** @type {number} */ +chrome.usb.InterfaceDescriptor.prototype.interfaceNumber; + + +/** @type {number} */ +chrome.usb.InterfaceDescriptor.prototype.alternateSetting; + + +/** @type {number} */ +chrome.usb.InterfaceDescriptor.prototype.interfaceClass; + + +/** @type {number} */ +chrome.usb.InterfaceDescriptor.prototype.interfaceSubclass; + + +/** @type {number} */ +chrome.usb.InterfaceDescriptor.prototype.interfaceProtocol; + + +/** @type {(string|undefined)} */ +chrome.usb.InterfaceDescriptor.prototype.description; + + +/** @type {!Array.} */ +chrome.usb.InterfaceDescriptor.prototype.endpoints; + + +/** @type {!ArrayBuffer} */ +chrome.usb.InterfaceDescriptor.prototype.extra_data; + + + +/** @constructor */ +chrome.usb.ConfigDescriptor = function() {}; + + +/** @type {boolean} */ +chrome.usb.ConfigDescriptor.prototype.active; + + +/** @type {number} */ +chrome.usb.ConfigDescriptor.prototype.configurationValue; + + +/** @type {string|undefined} */ +chrome.usb.ConfigDescriptor.prototype.description; + + +/** @type {boolean} */ +chrome.usb.ConfigDescriptor.prototype.selfPowered; + + +/** @type {boolean} */ +chrome.usb.ConfigDescriptor.prototype.remoteWakeup; + + +/** @type {number} */ +chrome.usb.ConfigDescriptor.prototype.maxPower; + + +/** @type {!Array} */ +chrome.usb.ConfigDescriptor.prototype.interfaces; + + +/** @type {!ArrayBuffer} */ +chrome.usb.ConfigDescriptor.prototype.extra_data; + + +/** + * @see http://developer.chrome.com/apps/usb.html#method-getDevices + * @param {!chrome.usb.GetDevicesOptions} options The properties to + * search for on target devices. + * @param {function(!Array)} callback Invoked with a list + * of |Device|s on complete. + * @return {undefined} + */ +chrome.usb.getDevices = function(options, callback) {}; + + +/** + * @see http://developer.chrome.com/apps/usb.html#method-getUserSelectedDevices + * @param {!chrome.usb.GetUserSelectedDevicesOptions} options Configuration of + * the device picker dialog box. + * @param {function(!Array)} callback Invoked with a list + * of |Device|s on complete. + * @return {undefined} + */ +chrome.usb.getUserSelectedDevices = function(options, callback) {}; + + +/** + * @see http://developer.chrome.com/apps/usb.html#method-getConfigurations + * @param {!chrome.usb.Device} device The device to fetch descriptors from. + * @param {function(!Array)} callback Invoked with + * the full set of device configuration descriptors. + * @return {undefined} + */ +chrome.usb.getConfigurations = function(device, callback) {}; + + +/** + * @see http://developer.chrome.com/apps/usb.html#method-requestAccess + * @param {!chrome.usb.Device} device The device to request access to. + * @param {number} interfaceId + * @param {function(boolean)} callback + * @return {undefined} + */ +chrome.usb.requestAccess = function(device, interfaceId, callback) {}; + + +/** + * @see http://developer.chrome.com/apps/usb.html#method-openDevice + * @param {!chrome.usb.Device} device The device to open. + * @param {function(!chrome.usb.ConnectionHandle)} callback Invoked with the + * created ConnectionHandle on complete. + * @return {undefined} + */ +chrome.usb.openDevice = function(device, callback) {}; + + +/** + * @see http://developer.chrome.com/apps/usb.html#method-findDevices + * @param {!chrome.usb.FindDevicesOptions} options The properties to search for + * on target devices. + * @param {function(!Array)} callback Invoked + * with the opened ConnectionHandle on complete. + * @return {undefined} + */ +chrome.usb.findDevices = function(options, callback) {}; + + +/** + * @see http://developer.chrome.com/apps/usb.html#method-closeDevice + * @param {!chrome.usb.ConnectionHandle} handle The connection handle to close. + * @param {function()=} opt_callback The callback to invoke once the device is + * closed. + * @return {undefined} + */ +chrome.usb.closeDevice = function(handle, opt_callback) {}; + + +/** + * @see http://developer.chrome.com/apps/usb.html#method-setConfiguration + * @param {!chrome.usb.ConnectionHandle} handle The connection handle for which + * to select a device configuration. + * @param {number} configurationValue The configuration to select. + * @param {function()} callback The callback to invoke on complete. + * @return {undefined} + */ +chrome.usb.setConfiguration = function(handle, configurationValue, callback) {}; + + +/** + * @see http://developer.chrome.com/apps/usb.html#method-getConfiguration + * @param {!chrome.usb.ConnectionHandle} handle The connection handle for which + * to get the current device configuration descriptor. + * @param {function(!chrome.usb.ConfigDescriptor)} callback The callback to + * invoke on complete. + * @return {undefined} + */ +chrome.usb.getConfiguration = function(handle, callback) {}; + + +/** + * @see http://developer.chrome.com/apps/usb.html#method-listInterfaces + * @param {!chrome.usb.ConnectionHandle} handle The device from which the + * interfaces should be listed. + * @param {function(!Array)} callback The + * callback to invoke when the interfaces are enumerated. + * @return {undefined} + */ +chrome.usb.listInterfaces = function(handle, callback) {}; + + +/** + * @see http://developer.chrome.com/apps/usb.html#method-claimInterface + * @param {!chrome.usb.ConnectionHandle} handle The device on which the + * interface is to be claimed. + * @param {number} interfaceNumber + * @param {function()} callback The callback to invoke once the interface is + * claimed. + * @return {undefined} + */ +chrome.usb.claimInterface = function(handle, interfaceNumber, callback) {}; + + +/** + * @see http://developer.chrome.com/apps/usb.html#method-releaseInterface + * @param {!chrome.usb.ConnectionHandle} handle The device on which the + * interface is to be released. + * @param {number} interfaceNumber + * @param {function()} callback The callback to invoke once the interface is + * released. + * @return {undefined} + */ +chrome.usb.releaseInterface = function(handle, interfaceNumber, callback) {}; + + +/** + * @see http://developer.chrome.com/apps/usb.html#method-setInterfaceAlternateSetting + * @param {!chrome.usb.ConnectionHandle} handle The device on which the + * interface settings are to be set. + * @param {number} interfaceNumber + * @param {number} alternateSetting The alternate setting to set. + * @param {function()} callback The callback to invoke once the interface + * setting is set. + * @return {undefined} + */ +chrome.usb.setInterfaceAlternateSetting = function( + handle, interfaceNumber, alternateSetting, callback) {}; + + +/** + * @see http://developer.chrome.com/apps/usb.html#method-controlTransfer + * @param {!chrome.usb.ConnectionHandle} handle A connection handle to make the + * transfer on. + * @param {!chrome.usb.ControlTransferInfo} transferInfo The parameters to the + * transfer. + * @param {function(!chrome.usb.TransferResultInfo)} callback Invoked once the + * transfer has completed. + * @return {undefined} + */ +chrome.usb.controlTransfer = function(handle, transferInfo, callback) {}; + + +/** + * @see http://developer.chrome.com/apps/usb.html#method-bulkTransfer + * @param {!chrome.usb.ConnectionHandle} handle A connection handle to make + * the transfer on. + * @param {!chrome.usb.GenericTransferInfo} transferInfo The parameters to the + * transfer. See GenericTransferInfo. + * @param {function(!chrome.usb.TransferResultInfo)} callback Invoked once the + * transfer has completed. + * @return {undefined} + */ +chrome.usb.bulkTransfer = function(handle, transferInfo, callback) {}; + + +/** + * @see http://developer.chrome.com/apps/usb.html#method-interruptTransfer + * @param {!chrome.usb.ConnectionHandle} handle A connection handle to make the + * transfer on. + * @param {!chrome.usb.GenericTransferInfo} transferInfo The parameters to the + * transfer. See GenericTransferInfo. + * @param {function(!chrome.usb.TransferResultInfo)} callback Invoked once the + * transfer has completed. + * @return {undefined} + */ +chrome.usb.interruptTransfer = function(handle, transferInfo, callback) {}; + + +/** + * @see http://developer.chrome.com/apps/usb.html#method-isochronousTransfer + * @param {!chrome.usb.ConnectionHandle} handle A connection handle to make the + * transfer on. + * @param {!chrome.usb.IsochronousTransferInfo} transferInfo The parameters to + * the transfer. + * @param {function(!chrome.usb.TransferResultInfo)} callback Invoked once the + * transfer has been completed. + * @return {undefined} + */ +chrome.usb.isochronousTransfer = function(handle, transferInfo, callback) {}; + + +/** + * @see http://developer.chrome.com/apps/usb.html#method-resetDevice + * @param {!chrome.usb.ConnectionHandle} handle A connection handle to reset. + * @param {function(boolean)} callback Invoked once the device is reset with a + * boolean indicating whether the reset completed successfully. + * @return {undefined} + */ +chrome.usb.resetDevice = function(handle, callback) {}; + + + +/** + * Event whose listeners take an chrome.usb.Device parameter. + * @record + * @extends {ChromeBaseEvent} + */ +chrome.usb.DeviceEvent = function() {}; + + +/** + * @type {!chrome.usb.DeviceEvent} + * @see https://developer.chrome.com/apps/usb#event-onDeviceAdded + */ +chrome.usb.onDeviceAdded; + + +/** + * @type {!chrome.usb.DeviceEvent} + * @see https://developer.chrome.com/apps/usb#event-onDeviceRemoved + */ +chrome.usb.onDeviceRemoved; + + +/** + * @see https://developer.chrome.com/apps/serial + * @const + */ +chrome.serial = {}; + + + +/** + * @typedef {?{ + * persistent: (boolean|undefined), + * name: (string|undefined), + * bufferSize: (number|undefined), + * bitRate: (number|undefined), + * dataBits: (string|undefined), + * parityBits: (string|undefined), + * stopBits: (string|undefined), + * ctsFlowControl: (boolean|undefined), + * receiveTimeout: (number|undefined), + * sendTimeout: (number|undefined) + * }} + * @see https://developer.chrome.com/apps/serial#type-ConnectionOptions + */ +chrome.serial.ConnectionOptions; + + +/** + * @typedef {?{ + * connectionId: number, + * paused: boolean, + * persistent: boolean, + * name: string, + * bufferSize: number, + * receiveTimeout: number, + * sendTimeout: number, + * bitRate: (number|undefined), + * dataBits: (string|undefined), + * parityBits: (string|undefined), + * stopBits: (string|undefined), + * ctsFlowControl: (boolean|undefined) + * }} + * @see https://developer.chrome.com/apps/serial#type-ConnectionInfo + */ +chrome.serial.ConnectionInfo; + + +/** + * Returns information about available serial devices on the system. The + * list is regenerated each time this method is called. + * @param {function(!Array)} callback Invoked with a + * list of ports on complete. + * @see https://developer.chrome.com/apps/serial#method-getDevices + * @return {undefined} + */ +chrome.serial.getDevices = function(callback) {}; + + +/** + * Connects to a given serial port. + * @param {string} path The system path of the serial port to open. + * @param {!chrome.serial.ConnectionOptions| + * function(!chrome.serial.ConnectionInfo)} optionsOrCallback + * Port configuration options, or the callback invoked with the created + * ConnectionInfo on complete. + * @param {function(!chrome.serial.ConnectionInfo)=} opt_callback Invoked with + * the created ConnectionInfo on complete. + * @see https://developer.chrome.com/apps/serial#method-connect + * @return {undefined} + */ +chrome.serial.connect = function(path, optionsOrCallback, opt_callback) {}; + + +/** + * Update the option settings on an open serial port connection. + * @param {number} connectionId The id of the opened connection. + * @param {!chrome.serial.ConnectionOptions} options Port configuration + * options. + * @param {function(boolean)} callback Called when the configuration has + * completed. + * @see https://developer.chrome.com/apps/serial#method-update + * @return {undefined} + */ +chrome.serial.update = function(connectionId, options, callback) {}; + + +/** + * Disconnects from a serial port. + * @param {number} connectionId The id of the opened connection. + * @param {function(boolean)} callback Called when the connection + * has been closed. + * @see https://developer.chrome.com/apps/serial#method-disconnect + * @return {undefined} + */ +chrome.serial.disconnect = function(connectionId, callback) {}; + + +/** + * Pauses or unpauses an open connection. + * @param {number} connectionId The id of the opened connection. + * @param {boolean} paused Flag to indicate whether to pause or unpause. + * @param {function()} callback Called when the configuration has completed. + * @see https://developer.chrome.com/apps/serial#method-setPaused + * @return {undefined} + */ +chrome.serial.setPaused = function(connectionId, paused, callback) {}; + + +/** + * Retrieves the state of a given connection. + * @param {number} connectionId The id of the opened connection. + * @param {function(!chrome.serial.ConnectionInfo)} callback + * Called with connection state information when available. + * @see https://developer.chrome.com/apps/serial#method-getInfo + * @return {undefined} + */ +chrome.serial.getInfo = function(connectionId, callback) {}; + + +/** + * Retrieves the list of currently opened serial port connections owned by + * the application. + * @param {function(!Array)} callback + * Called with the list of |ConnectionInfo|s when available. + * @see https://developer.chrome.com/apps/serial#method-getConnections + * @return {undefined} + */ +chrome.serial.getConnections = function(callback) {}; + + +/** + * Writes data to the given connection. + * @param {number} connectionId The id of the opened connection. + * @param {!ArrayBuffer} data The data to send. + * @param {function(!Object)} callback Called when the operation has + * completed. + * @see https://developer.chrome.com/apps/serial#method-send + * @return {undefined} + */ +chrome.serial.send = function(connectionId, data, callback) {}; + + +/** + * Flushes all bytes in the given connection's input and output buffers. + * @param {number} connectionId The id of the opened connection. + * @param {function(boolean)} callback + * @see https://developer.chrome.com/apps/serial#method-flush + * @return {undefined} + */ +chrome.serial.flush = function(connectionId, callback) {}; + + + + +/** + * Retrieves the state of control signals on a given connection. + * @param {number} connectionId The id of the opened connection. + * @param {function(!Object)} callback + * @see https://developer.chrome.com/apps/serial#method-getControlSignals + * @return {undefined} + */ +chrome.serial.getControlSignals = function(connectionId, callback) {}; + + +/** + * @typedef {?{ + * dtr: (boolean|undefined), + * rts: (boolean|undefined) + * }} + */ +chrome.serial.ControlSignals; + + +/** + * Sets the state of control signals on a given connection. + * @param {number} connectionId The id of the opened connection. + * @param {!chrome.serial.ControlSignals} signals + * The set of signal changes to send to the device. + * @param {function(boolean)} callback Called once the control signals + * have been set. + * @see https://developer.chrome.com/apps/serial#method-setControlSignals + * @return {undefined} + */ +chrome.serial.setControlSignals = function(connectionId, signals, callback) {}; + + +/** + * Event raised when data has been read from the connection. + * @type {!ChromeObjectEvent} + * @see https://developer.chrome.com/apps/serial#event-onReceive + */ +chrome.serial.onReceive; + + +/** + * Event raised when an error occurred while the runtime was waiting for + * data on the serial port. Once this event is raised, the connection may + * be set to paused. A "timeout" error does not pause the connection. + * @type {!ChromeObjectEvent} + * @see https://developer.chrome.com/apps/serial#event-onReceiveError + */ +chrome.serial.onReceiveError; + + + +//////////////////////////////////////////////////////////////////////////////// +/////////////////////////// Chrome Private APIs //////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + +/** @const */ +chrome.screenlockPrivate = {}; + + +/** + * @param {string} message Displayed on the unlock screen. + * @return {undefined} + */ +chrome.screenlockPrivate.showMessage = function(message) {}; + + +/** + * @param {function(boolean)} callback + * @return {undefined} + */ +chrome.screenlockPrivate.getLocked = function(callback) {}; + + +/** + * @param {boolean} locked If true and the screen is unlocked, locks the screen. + * If false and the screen is locked, unlocks the screen. + * @return {undefined} + */ +chrome.screenlockPrivate.setLocked = function(locked) {}; + + +/** @type {!ChromeBooleanEvent} */ +chrome.screenlockPrivate.onChanged; + + +/** + * @const + */ +chrome.musicManagerPrivate = {}; + + +/** + * @param {function(string): void} callback + * @return {undefined} + */ +chrome.musicManagerPrivate.getDeviceId = function(callback) {}; + + +/** + * @const + */ +chrome.mediaGalleriesPrivate = {}; + + +/** + * @typedef {function({deviceId: string, deviceName: string}): void} + */ +chrome.mediaGalleriesPrivate.DeviceCallback; + + +/** + * @typedef {function({galleryId: string}): void} + */ +chrome.mediaGalleriesPrivate.GalleryChangeCallback; + + +/** + * @typedef {function({galleryId: string, success: boolean}): void} + */ +chrome.mediaGalleriesPrivate.AddGalleryWatchCallback; + + +/** + * @param {string} galleryId + * @param {!chrome.mediaGalleriesPrivate.AddGalleryWatchCallback} callback + * @return {undefined} + */ +chrome.mediaGalleriesPrivate.addGalleryWatch = function(galleryId, callback) {}; + + +/** + * @type {!chrome.mediaGalleriesPrivate.DeviceEvent} + * @deprecated Use {chrome.system.storage.onAttach}. + */ +chrome.mediaGalleriesPrivate.onDeviceAttached; + + +/** + * @type {!chrome.mediaGalleriesPrivate.DeviceEvent} + * @deprecated Use {chrome.system.storage.onDetach}. + */ +chrome.mediaGalleriesPrivate.onDeviceDetached; + + +/** + * @type {!chrome.mediaGalleriesPrivate.GalleryChangeEvent} + */ +chrome.mediaGalleriesPrivate.onGalleryChanged; + + + +/** + * @record + * @extends {ChromeBaseEvent} + * @deprecated Use {chrome.system.storage.DeviceEvent}. + */ +chrome.mediaGalleriesPrivate.DeviceEvent = function() {}; + + +/** + * @record + * @extends {ChromeBaseEvent} + */ +chrome.mediaGalleriesPrivate.GalleryChangeEvent = function() {}; + + +/** + * Externs for networking_private.idl: + * https://code.google.com/p/chromium/codesearch#chromium/src/extensions/common/api/networking_private.idl + * WARNING(2015/04/09): This API is still under active development and has a few + * issues with typing: + * + * 1. This API uses the ONC specification: + * http://www.chromium.org/chromium-os/chromiumos-design-docs/open-network-configuration + * 2. The types for getProperties and getManagedProperties are not currently + * defined. They correspond to ONC Property dictionaries. They are treated as + * Objects rather than types. + * 3. NetworkStateProperties defines a subset of NetworkProperties used by + * getState and getNetworks. Since these match ONC property names they + * use ONC PascalCase naming conventions instead of traditional JS + * camelCase naming. + * 4. The types for setProperties and createNetwork are not currently defined. + * These use a subset of ONC properties and the complete set (and their + * relationship to the type for getProperties) is still being determined. + * + * Because of the above issues, this API should not be used as an example for + * other APIs. Please contact stevenjb@ for questions on and maintenance. + * @const + * @see https://developer.chrome.com/extensions/networkingPrivate + */ +chrome.networkingPrivate = {}; + + +/** + * @constructor + * @struct + * @see https://developer.chrome.com/extensions/networkingPrivate#type-CellularStateProperties + */ +chrome.networkingPrivate.CellularStateProperties = function() {}; + + +/** + * @type {string|undefined} + */ +chrome.networkingPrivate.CellularStateProperties.prototype.ActivationState; + + +/** + * @type {string|undefined} + */ +chrome.networkingPrivate.CellularStateProperties.prototype.NetworkTechnology; + + +/** + * @type {string|undefined} + */ +chrome.networkingPrivate.CellularStateProperties.prototype.RoamingState; + + +/** + * @type {number|undefined} + */ +chrome.networkingPrivate.CellularStateProperties.prototype.SignalStrength; + + +/** + * @constructor + * @struct + * @see https://developer.chrome.com/extensions/networkingPrivate#type-DeviceStateProperties + */ +chrome.networkingPrivate.DeviceStateProperties = function() {}; + + +/** + * @type {boolean|undefined} + */ +chrome.networkingPrivate.DeviceStateProperties.prototype.Scanning; + + +/** + * @type {string} + */ +chrome.networkingPrivate.DeviceStateProperties.prototype.State; + + +/** + * @type {string} + */ +chrome.networkingPrivate.DeviceStateProperties.prototype.Type; + + +/** + * @constructor + * @struct + * @see https://developer.chrome.com/extensions/networkingPrivate#type-EthernetStateProperties + */ +chrome.networkingPrivate.EthernetStateProperties = function() {}; + + +/** + * @type {string} + */ +chrome.networkingPrivate.EthernetStateProperties.prototype.Authentication; + + +/** + * @constructor + * @struct + * @see https://developer.chrome.com/extensions/networkingPrivate#type-IPSecProperties + */ +chrome.networkingPrivate.IPSecProperties = function() {}; + + +/** + * @type {string} + */ +chrome.networkingPrivate.IPSecProperties.prototype.AuthenticationType; + + +/** + * @constructor + * @struct + * @see https://developer.chrome.com/extensions/networkingPrivate#type-ThirdPartyVPNProperties + */ +chrome.networkingPrivate.ThirdPartyVPNProperties = function() {}; + + +/** + * @type {string} + */ +chrome.networkingPrivate.ThirdPartyVPNProperties.prototype.ExtensionID; + + +/** + * @constructor + * @struct + * @see https://developer.chrome.com/extensions/networkingPrivate#type-VPNStateProperties + */ +chrome.networkingPrivate.VPNStateProperties = function() {}; + + +/** + * @type {!chrome.networkingPrivate.IPSecProperties|undefined} + */ +chrome.networkingPrivate.VPNStateProperties.prototype.IPSec; + + +/** + * @type {!chrome.networkingPrivate.ThirdPartyVPNProperties|undefined} + */ +chrome.networkingPrivate.VPNStateProperties.prototype.ThirdPartyVPN; + + +/** + * @type {string} + */ +chrome.networkingPrivate.VPNStateProperties.prototype.Type; + + +/** + * @constructor + * @struct + * @see https://developer.chrome.com/extensions/networkingPrivate#type-WiFiStateProperties + */ +chrome.networkingPrivate.WiFiStateProperties = function() {}; + + +/** + * @type {string} + */ +chrome.networkingPrivate.WiFiStateProperties.prototype.Security; + + +/** + * @type {number|undefined} + */ +chrome.networkingPrivate.WiFiStateProperties.prototype.SignalStrength; + + +/** + * @constructor + * @struct + * @see https://developer.chrome.com/extensions/networkingPrivate#type-WiFiStateProperties + */ +chrome.networkingPrivate.WiMAXStateProperties = function() {}; + + +/** + * @type {number|undefined} + */ +chrome.networkingPrivate.WiMAXStateProperties.prototype.SignalStrength; + + +/** + * @typedef {?{ + * Cellular: (!chrome.networkingPrivate.CellularStateProperties|undefined), + * Connectable: (boolean|undefined), + * ConnectionState: (string|undefined), + * ErrorState: (string|undefined), + * Ethernet: (!chrome.networkingPrivate.EthernetStateProperties|undefined), + * GUID: string, + * Name: (string|undefined), + * Priority: (number|undefined), + * Source: (string|undefined), + * Type: string, + * VPN: (!chrome.networkingPrivate.VPNStateProperties|undefined), + * WiFi: (!chrome.networkingPrivate.WiFiStateProperties|undefined), + * WiMAX: (!chrome.networkingPrivate.WiMAXStateProperties|undefined) + * }} + */ +chrome.networkingPrivate.NetworkStateProperties; + + +/** + * @typedef {?{ + * certificate: string, + * intermediateCertificates: (!Array|undefined), + * publicKey: string, + * nonce: string, + * signedData: string, + * deviceSerial: string, + * deviceSsid: string, + * deviceBssid: string + * }} + */ +chrome.networkingPrivate.VerificationProperties; + + +/** + * @typedef {?{ + * networkType: string, + * visible: (boolean|undefined), + * configured: (boolean|undefined), + * limit: (number|undefined) + * }} + */ +chrome.networkingPrivate.NetworkFilter; + + +/** + * @param {string} guid + * @param {function(!Object)} callback + * @return {undefined} + */ +chrome.networkingPrivate.getProperties = function(guid, callback) {}; + + +/** + * @param {string} guid + * @param {function(!Object)} callback + * @return {undefined} + */ +chrome.networkingPrivate.getManagedProperties = function(guid, callback) {}; + + +/** + * @param {string} guid + * @param {function(!chrome.networkingPrivate.NetworkStateProperties)} callback + * @return {undefined} + */ +chrome.networkingPrivate.getState = function(guid, callback) {}; + + +/** + * TODO: Use NetworkConfigProperties for |properties| once fully + * defined. + * @param {string} guid + * @param {!Object} properties + * @param {function()=} opt_callback + * @return {undefined} + */ +chrome.networkingPrivate.setProperties = + function(guid, properties, opt_callback) {}; + + +/** + * TODO: Use NetworkConfigProperties for |properties| once fully + * defined. + * @param {boolean} shared + * @param {!Object} properties + * @param {function(string)=} opt_callback Returns guid of the configured + * configuration. + * @return {undefined} + */ +chrome.networkingPrivate.createNetwork = + function(shared, properties, opt_callback) {}; + + +/** + * @param {string} guid + * @param {function()=} opt_callback Called when the operation has completed. + * @return {undefined} + */ +chrome.networkingPrivate.forgetNetwork = function(guid, opt_callback) {}; + + +/** + * @param {!chrome.networkingPrivate.NetworkFilter} filter + * @param {function(!Array)} + * callback + * @return {undefined} + */ +chrome.networkingPrivate.getNetworks = function(filter, callback) {}; + + +/** + * @param {string} type + * @param {function(!Array)} + * callback + * @deprecated Use chrome.networkingPrivate.getNetworks with filter.visible=true + * @return {undefined} + */ +chrome.networkingPrivate.getVisibleNetworks = function(type, callback) {}; + + +/** + * @param {function(!Array)} callback + * @deprecated Use chrome.networkingPrivate.getDeviceStates. + * @return {undefined} + */ +chrome.networkingPrivate.getEnabledNetworkTypes = function(callback) {}; + + +/** + * @param {function(!Array)} + * callback + * @return {undefined} + */ +chrome.networkingPrivate.getDeviceStates = function(callback) {}; + + +/** + * @param {string} networkType + * @return {undefined} + */ +chrome.networkingPrivate.enableNetworkType = function(networkType) {}; + + +/** + * @param {string} networkType + * @return {undefined} + */ +chrome.networkingPrivate.disableNetworkType = function(networkType) {}; + + +/** + * Requests that the networking subsystem scan for new networks and update the + * list returned by getVisibleNetworks. + * @return {undefined} + */ +chrome.networkingPrivate.requestNetworkScan = function() {}; + + +/** + * @param {string} guid + * @param {function()=} opt_callback + * @return {undefined} + */ +chrome.networkingPrivate.startConnect = function(guid, opt_callback) {}; + + +/** + * @param {string} guid + * @param {function()=} opt_callback + * @return {undefined} + */ +chrome.networkingPrivate.startDisconnect = function(guid, opt_callback) {}; + + +/** + * @param {string} guid + * @param {(string|function())=} opt_carrierOrCallback + * @param {function()=} opt_callback + * @return {undefined} + */ +chrome.networkingPrivate.startActivate = + function(guid, opt_carrierOrCallback, opt_callback) {}; + + +/** + * @param {!chrome.networkingPrivate.VerificationProperties} verificationInfo + * @param {function(boolean)} callback + * @return {undefined} + */ +chrome.networkingPrivate.verifyDestination = + function(verificationInfo, callback) {}; + + +/** + * @param {!chrome.networkingPrivate.VerificationProperties} verificationInfo + * @param {string} guid + * @param {function(string)} callback + * @return {undefined} + */ +chrome.networkingPrivate.verifyAndEncryptCredentials = + function(verificationInfo, guid, callback) {}; + + +/** + * @param {!chrome.networkingPrivate.VerificationProperties} verificationInfo + * @param {string} data + * @param {function(string)} callback + * @return {undefined} + */ +chrome.networkingPrivate.verifyAndEncryptData = + function(verificationInfo, data, callback) {}; + + +/** + * @param {string} ipOrMacAddress + * @param {boolean} enabled + * @param {function(string)=} opt_callback + * @return {undefined} + */ +chrome.networkingPrivate.setWifiTDLSEnabledState = + function(ipOrMacAddress, enabled, opt_callback) {}; + + +/** + * @param {string} ipOrMacAddress + * @param {function(string)} callback + * @return {undefined} + */ +chrome.networkingPrivate.getWifiTDLSStatus = + function(ipOrMacAddress, callback) {}; + + +/** + * @param {string} guid + * @param {function(string)} callback + * @return {undefined} + */ +chrome.networkingPrivate.getCaptivePortalStatus = function(guid, callback) {}; + + +/** @type {!ChromeStringArrayEvent} */ +chrome.networkingPrivate.onNetworksChanged; + + +/** @type {!ChromeStringArrayEvent} */ +chrome.networkingPrivate.onNetworkListChanged; + + +/** @type {!ChromeEvent} */ +chrome.networkingPrivate.onDeviceStateListChanged; + + +/** @type {!ChromeStringStringEvent} */ +chrome.networkingPrivate.onPortalDetectionCompleted; + + +/** + * WARNING(2014/08/14): This API is still under active initial development and + * unstable. The types are not well defined or documented, and this API + * definition here should not be used as an example for other APIs added to this + * file. Please contact mednik@ for questions on and maintenance for this API. + * @const + * @see http://goo.gl/afV8wB + */ +chrome.mdns = {}; + + +/** + * Data type sent to the event handler of chrome.mdns.onServiceList. + * @constructor + */ +chrome.mdns.MdnsService = function() {}; + + +/** @type {string} */ +chrome.mdns.MdnsService.prototype.serviceName; + + +/** @type {string} */ +chrome.mdns.MdnsService.prototype.serviceHostPort; + + +/** @type {string} */ +chrome.mdns.MdnsService.prototype.ipAddress; + + +/** @type {!Array} */ +chrome.mdns.MdnsService.prototype.serviceData; + + +/** + * Event whose listeners take an array of MdnsService parameter. + * + * The `addListener()` methods for these take more than one argument, so they + * cannot just extend `ChromeBaseEvent`. + * TODO(bradfordcsmith): These events won't automatically inherit new methods + * added to `ChromeBaseEvent`. + * @record + */ +chrome.mdns.ServiceListEvent = function() {}; + + +/** + * @param {function(!Array): void} callback + * @param {!Object=} opt_filter + * @return {undefined} + */ +chrome.mdns.ServiceListEvent.prototype.addListener = + function(callback, opt_filter) {}; + + +/** + * @param {function(!Array): void} callback + * @return {undefined} + */ +chrome.mdns.ServiceListEvent.prototype.removeListener = function(callback) {}; + + +/** + * @param {function(!Array): void} callback + * @return {boolean} + */ +chrome.mdns.ServiceListEvent.prototype.hasListener = function(callback) {}; + + +/** @return {boolean} */ +chrome.mdns.ServiceListEvent.prototype.hasListeners = function() {}; + + +/** @type {!chrome.mdns.ServiceListEvent} */ +chrome.mdns.onServiceList; + + +/** + * @param {function()} callback + * @return {undefined} + */ +chrome.mdns.forceDiscovery = function(callback) {}; + + +/** + * @const + * @see http://goo.gl/79p5h5 + */ +chrome.gcdPrivate = {}; + + +/** + * Represents a GCD device discovered locally or registered to a given user. + * deviceId: Opaque device identifier to be passed to API. + * setupType: How this device was discovered. + * cloudId: Cloud identifier string. + * deviceName: Device human readable name. + * deviceType: Device type (camera, printer, etc). + * deviceDescription: Device human readable description. + * @typedef {?{ + * deviceId: string, + * setupType: string, + * cloudId: (string|undefined), + * deviceType: string, + * deviceName: string, + * deviceDescription: string + * }} + */ +chrome.gcdPrivate.Device; + + +/** + * Returns the list of cloud devices visible locally or available in the + * cloud for user account. + * @param {function(!Array): void} callback + * @return {undefined} + */ +chrome.gcdPrivate.getCloudDeviceList = function(callback) {}; + + +/** + * Queries network for local devices. Triggers onDeviceStateChanged and + * onDeviceRemoved events. Call this function *only* after registering for + * onDeviceStateChanged and onDeviceRemoved events, or it will do nothing. + * @return {undefined} + */ +chrome.gcdPrivate.queryForNewLocalDevices = function() {}; + + +/** + * Cache the WiFi password in the browser process for use during + * provisioning. This is done to allow the gathering of the wifi password to + * not be done while connected to the device's network. Callback is called + * with true if wifi password was cached and false if it was unavailable. + * @param {string} ssid + * @param {function(boolean): void} callback + * @return {undefined} + */ +chrome.gcdPrivate.prefetchWifiPassword = function(ssid, callback) {}; + + +/** + * Returns local device information. + * @param {string} serviceName The mDNS service name of the device. + * @param {function(string, !Object): void} + * callback Called when when the device info is available or on error. + * |status|: The status of the operation (success or type of error). + * |deviceInfo|: Content of /privet/info response. + * https://developers.google.com/cloud-devices/v1/reference/local-api/info + * @return {undefined} + */ +chrome.gcdPrivate.getDeviceInfo = function(serviceName, callback) {}; + + +/** + * Create new pairing session. + * @param {string} serviceName The mDNS service name of the device. + * @param {function(number, string, !Array): void} + * callback Called when the session is established or on error. 1st param, + * |sessionId|, is the session ID (identifies the session for future calls). + * 2nd param, |status|, is the status (success or type of error). 3rd param, + * |pairingTypes|, is a list of pairing types supported by this device. + * @return {undefined} + */ +chrome.gcdPrivate.createSession = function(serviceName, callback) {}; + + +/** + * Start pairing with the selected method. + * @param {number} sessionId + * @param {string} pairingType + * @param {function(string): void} callback + * @return {undefined} + */ +chrome.gcdPrivate.startPairing = function(sessionId, pairingType, callback) {}; + + +/** + * Confirm pairing code. + * @param {number} sessionId + * @param {string} code + * @param {function(string): void} callback + * @return {undefined} + */ +chrome.gcdPrivate.confirmCode = function(sessionId, code, callback) {}; + + +/** + * Send an encrypted message to the device. If the message is a setup message + * with a wifi ssid specified but no password, the password cached from + * prefetchWifiPassword() will be used and the call will fail if it's not + * available. For open networks use an empty string as the password. + * @param {number} sessionId + * @param {string} api The API path. + * @param {!Object} input The input message to be sent over the encrypted + * channel. + * @param {function(string, ?Object): void} callback + * @return {undefined} + */ +chrome.gcdPrivate.sendMessage = function(sessionId, api, input, callback) {}; + + +/** + * Terminate the session with the device. + * @param {number} sessionId + * @return {undefined} + */ +chrome.gcdPrivate.terminateSession = function(sessionId) {}; + + +/** + * Returns command definitions. + * @param {string} deviceId The device to get command definitions for. + * @param {function(!Object): void} callback The result callback. + * @return {undefined} + */ +chrome.gcdPrivate.getCommandDefinitions = function(deviceId, callback) {}; + + +/** + * Creates and sends a new command. + * @param {string} deviceId The device to send the command to. + * @param {number} expireInMs The number of milliseconds since now before the + * command expires. An expired command should not be executed by the device. + * Acceptable values are 10 sec (10000 ms) to 30 days (2592000000 ms), + * inclusive. All values outside that range will be replaced by 30 days. + * @param {!Object} command Described at + * https://developers.google.com/cloud-devices/v1/reference/commands. + * @param {function(!Object): void} callback The result callback. + * @return {undefined} + */ +chrome.gcdPrivate.insertCommand = function( + deviceId, expireInMs, command, callback) {}; + + +/** + * Returns a particular command. + * @param {string} commandId Unique command ID. + * @param {function(!Object): void} callback The result callback. + * @return {undefined} + */ +chrome.gcdPrivate.getCommand = function(commandId, callback) {}; + + +/** + * Cancels a command. + * @param {string} commandId Unique command ID. + * @param {function(!Object): void} callback The result callback. + * @return {undefined} + */ +chrome.gcdPrivate.cancelCommand = function(commandId, callback) {}; + + +/** + * Lists all commands in order of creation. + * @param {string} deviceId The device to send the command to. + * @param {string} byUser List all the commands issued by the user. Special + * value 'me' can be used to list by the current user. + * @param {string} state Command state. + * @param {function(!Array): void} callback The result callback. + * @return {undefined} + */ +chrome.gcdPrivate.getCommandsList = function( + deviceId, byUser, state, callback) {}; + + + +/** + * Event whose listeners take a chrome.gcdPrivate.Device. + * @record + * @extends {ChromeBaseEvent} + */ +chrome.gcdPrivate.DeviceEvent = function() {}; + + +/** + * Fires when a device's state changes. When a listener is first added, this + * event fires for all known devices on the network. Afterwards, it will fire + * with device status updates. + * @type {!chrome.gcdPrivate.DeviceEvent} + */ +chrome.gcdPrivate.onDeviceStateChanged; + + +/** + * Fires when a given device disappears. + * |deviceId| The device that has disappeared. + * @type {!ChromeStringEvent} + */ +chrome.gcdPrivate.onDeviceRemoved; + + +/** + * @const + * @see https://cs.chromium.org/chromium/src/extensions/common/api/bluetooth_private.idl + */ +chrome.bluetoothPrivate = {}; + + + +/** @constructor */ +chrome.bluetoothPrivate.PairingEvent = function() {}; + + +/** @type {string} */ +chrome.bluetoothPrivate.PairingEvent.prototype.pairing; + + +/** @type {!chrome.bluetooth.Device} */ +chrome.bluetoothPrivate.PairingEvent.prototype.device; + + +/** @type {string|undefined} */ +chrome.bluetoothPrivate.PairingEvent.prototype.pincode; + + +/** @type {number|undefined} */ +chrome.bluetoothPrivate.PairingEvent.prototype.passkey; + + +/** @type {number|undefined} */ +chrome.bluetoothPrivate.PairingEvent.prototype.enteredKey; + + +/** + * @typedef {{ + * name: (string|undefined), + * powered: (boolean|undefined), + * discoverable: (boolean|undefined) + * }} + */ +chrome.bluetoothPrivate.NewAdapterState; + + +/** + * @typedef {{ + * device: !chrome.bluetooth.Device, + * response: (string|undefined), + * pincode: (string|undefined), + * passkey: (number|undefined), + * enteredKey: (number|undefined) + * }} + */ +chrome.bluetoothPrivate.SetPairingResponseOptions; + + +/** + * @param {!chrome.bluetoothPrivate.NewAdapterState} adapterState + * @param {function()} callback + * @return {undefined} + */ +chrome.bluetoothPrivate.setAdapterState = function(adapterState, callback) {}; + + +/** + * @param {!chrome.bluetoothPrivate.SetPairingResponseOptions} options + * @param {function()} callback + * @return {undefined} + */ +chrome.bluetoothPrivate.setPairingResponse = function(options, callback) {}; + + +/** + * @param {string} deviceAddress + * @param {function():void=} callback + */ +chrome.bluetoothPrivate.disconnectAll = function(deviceAddress, callback) {}; + + +/** + * @param {string} deviceAddress + * @param {function():void=} callback + * @return {undefined} + */ +chrome.bluetoothPrivate.forgetDevice = function(deviceAddress, callback) {}; + + +/** + * @typedef {{ + * transport: (!chrome.bluetoothPrivate.TransportType|undefined), + * uuids: ((string|!Array)|undefined), + * rssi: (number|undefined), + * pathloss: (number|undefined) + * }} + */ +chrome.bluetoothPrivate.DiscoveryFilter; + + +/** + * Set or clear discovery filter. + * @param {!chrome.bluetoothPrivate.DiscoveryFilter} discoveryFilter + * @param {function():void=} callback + */ +chrome.bluetoothPrivate.setDiscoveryFilter = function(discoveryFilter, callback) {}; + + +/** + * Event whose listeners take a PairingEvent parameter. + * @record + * @extends {ChromeBaseEvent} + */ +chrome.bluetoothPrivate.PairingEventEvent = function() {}; + + +/** @type {!chrome.bluetoothPrivate.PairingEventEvent} */ +chrome.bluetoothPrivate.onPairing; + + +/** + * @param {string} deviceAddress + * @param {function(number, string): void=} opt_callback + */ +chrome.bluetoothPrivate.pair = function(deviceAddress, opt_callback) {}; + + +/** + * @enum {string} + * @see https://developer.chrome.com/extensions/bluetoothPrivate#type-PairingResponse + */ +chrome.bluetoothPrivate.PairingResponse = { + CONFIRM: '', + REJECT: '', + CANCEL: '', +}; + + +/** + * @enum {string} + * @see https://developer.chrome.com/extensions/bluetoothPrivate#type-PairingEventType + */ +chrome.bluetoothPrivate.PairingEventType = { + REQUEST_PINCODE: '', + DISPLAY_PINCODE: '', + REQUEST_PASSKEY: '', + DISPLAY_PASSKEY: '', + KEYS_ENTERED: '', + CONFIRM_PASSKEY: '', + REQUEST_AUTHORIZATION: '', + COMPLETE: '', +}; + + +/** + * @enum {string} + * @see https://developer.chrome.com/extensions/bluetoothPrivate#type-ConnectResultType + */ +chrome.bluetoothPrivate.ConnectResultType = { + ALREADY_CONNECTED: '', + ATTRIBUTE_LENGTH_INVALID: '', + AUTH_CANCELED: '', + AUTH_FAILED: '', + AUTH_REJECTED: '', + AUTH_TIMEOUT: '', + CONNECTION_CONGESTED: '', + FAILED: '', + IN_PROGRESS: '', + INSUFFICIENT_ENCRYPTION: '', + OFFSET_INVALID: '', + READ_NOT_PERMITTED: '', + REQUEST_NOT_SUPPORTED: '', + SUCCESS: '', + UNKNOWN_ERROR: '', + UNSUPPORTED_DEVICE: '', + WRITE_NOT_PERMITTED: '', +}; + + +/** + * @enum {string} + * @see https://developer.chrome.com/extensions/bluetoothPrivate#type-TransportType + */ +chrome.bluetoothPrivate.TransportType = { + LE: '', + BREDR: '', + DUAL: '', +}; + + +/** + * @const + * @see http://goo.gl/XmVdHm + */ +chrome.inlineInstallPrivate = {}; + + +/** + * Installs the given app ID. + * @param {string} id + * @param {function(string, string): void=} opt_callback Response callback that + * returns two string: (1) an error string (or empty string on success) and + * (2) an error code in case of error + * @return {undefined} + */ +chrome.inlineInstallPrivate.install = function(id, opt_callback) {}; + + +/** + * @const + * @see https://goo.gl/7dvJFW + */ +chrome.wallpaper = {}; + + +/** + * @enum {string} + * @see https://goo.gl/7dvJFW#type-WallpaperLayout + */ +chrome.wallpaper.WallpaperLayout = { + STRETCH: '', + CENTER: '', + CENTER_CROPPED: '', +}; + + +/** + * Sets wallpaper to the image at url or wallpaperData with the specified + * layout. + * @param {{ + * data: (ArrayBuffer|undefined), + * url: (string|undefined), + * layout: (chrome.wallpaper.WallpaperLayout|string), + * filename: string, + * thumbnail: (boolean|undefined) + * }} details + * @param {function(ArrayBuffer=)} callback + * @return {undefined} + * @see https://goo.gl/7dvJFW#method-setWallpaper + */ +chrome.wallpaper.setWallpaper = function(details, callback) {}; + + +/** + * @const + * @see https://developer.chrome.com/extensions/downloads + */ +chrome.downloads = {}; + + +/** + * @enum {string} + * @see https://developer.chrome.com/extensions/downloads#type-FilenameConflictAction + */ +chrome.downloads.FilenameConflictAction = { + UNIQUIFY: '', + OVERWRITE: '', + PROMPT: '' +}; + + +/** + * @enum {string} + * @see https://developer.chrome.com/extensions/downloads#type-InterruptReason + */ +chrome.downloads.InterruptReason = { + FILE_FAILED: '', + FILE_ACCESS_DENIED: '', + FILE_NO_SPACE: '', + FILE_NAME_TOO_LONG: '', + FILE_TOO_LARGE: '', + FILE_VIRUS_INFECTED: '', + FILE_TRANSIENT_ERROR: '', + FILE_BLOCKED: '', + FILE_SECURITY_CHECK_FAILED: '', + FILE_TOO_SHORT: '', + FILE_HASH_MISMATCH: '', + NETWORK_FAILED: '', + NETWORK_TIMEOUT: '', + NETWORK_DISCONNECTED: '', + NETWORK_SERVER_DOWN: '', + NETWORK_INVALID_REQUEST: '', + SERVER_FAILED: '', + SERVER_NO_RANGE: '', + SERVER_BAD_CONTENT: '', + SERVER_UNAUTHORIZED: '', + SERVER_CERT_PROBLEM: '', + SERVER_FORBIDDEN: '', + SERVER_UNREACHABLE: '', + USER_CANCELED: '', + USER_SHUTDOWN: '', + CRASH: '', +}; + + +/** + * @enum {string} + * @see https://developer.chrome.com/extensions/downloads#type-DangerType + */ +chrome.downloads.DangerType = { + FILE: '', + URL: '', + CONTENT: '', + UNCOMMON: '', + HOST: '', + UNWANTED: '', + SAFE: '', + ACCEPTED: '' +}; + + +/** + * @enum {string} + * @see https://developer.chrome.com/extensions/downloads#type-State + */ +chrome.downloads.State = { + IN_PROGRESS: '', + INTERRUPTED: '', + COMPLETE: '', +}; + + +/** + * @constructor + * @see https://developer.chrome.com/extensions/downloads#type-DownloadItem + */ +chrome.downloads.DownloadItem = function() {}; + + +/** @type {number} */ +chrome.downloads.DownloadItem.prototype.id; + + +/** @type {string} */ +chrome.downloads.DownloadItem.prototype.url; + + +/** @type {string} */ +chrome.downloads.DownloadItem.prototype.finalUrl; + + +/** @type {string} */ +chrome.downloads.DownloadItem.prototype.referrer; + + +/** @type {string} */ +chrome.downloads.DownloadItem.prototype.filename; + + +/** @type {boolean} */ +chrome.downloads.DownloadItem.prototype.incognito; + + +/** @type {!chrome.downloads.DangerType|string} */ +chrome.downloads.DownloadItem.prototype.danger; + + +/** @type {string} */ +chrome.downloads.DownloadItem.prototype.mime; + + +/** @type {string} */ +chrome.downloads.DownloadItem.prototype.startTime; + + +/** @type {?string} */ +chrome.downloads.DownloadItem.prototype.endTime; + + +/** @type {?string} */ +chrome.downloads.DownloadItem.prototype.estimatedEndTime; + + +/** @type {!chrome.downloads.State|string} */ +chrome.downloads.DownloadItem.prototype.state; + + +/** @type {boolean} */ +chrome.downloads.DownloadItem.prototype.paused; + + +/** @type {boolean} */ +chrome.downloads.DownloadItem.prototype.canResume; + + +/** @type {!chrome.downloads.InterruptReason|string|undefined} */ +chrome.downloads.DownloadItem.prototype.error; + + +/** @type {number} */ +chrome.downloads.DownloadItem.prototype.bytesReceived; + + +/** @type {number} */ +chrome.downloads.DownloadItem.prototype.totalBytes; + + +/** @type {number} */ +chrome.downloads.DownloadItem.prototype.fileSize; + + +/** @type {boolean} */ +chrome.downloads.DownloadItem.prototype.exists; + + +/** @type {?string} */ +chrome.downloads.DownloadItem.prototype.byExtensionId; + + +/** @type {?string} */ +chrome.downloads.DownloadItem.prototype.byExtensionName; + + +/** + * @constructor + * @see https://developer.chrome.com/extensions/downloads#type-StringDelta + */ +chrome.downloads.StringDelta = function() {}; + + +/** @type {?string} */ +chrome.downloads.StringDelta.prototype.previous; + + +/** @type {?string} */ +chrome.downloads.StringDelta.prototype.current; + + +/** + * @constructor + * @see https://developer.chrome.com/extensions/downloads#type-DoubleDelta + */ +chrome.downloads.DoubleDelta = function() {}; + + +/** @type {?number} */ +chrome.downloads.DoubleDelta.prototype.previous; + + +/** @type {?number} */ +chrome.downloads.DoubleDelta.prototype.current; + + +/** + * @constructor + * @see https://developer.chrome.com/extensions/downloads#type-BooleanDelta + */ +chrome.downloads.BooleanDelta = function() {}; + + +/** @type {?boolean} */ +chrome.downloads.BooleanDelta.prototype.previous; + + +/** @type {?boolean} */ +chrome.downloads.BooleanDelta.prototype.current; + + +/** + * @param {{ + * url: string, + * filename: (string|undefined), + * conflictAction: + * (!chrome.downloads.FilenameConflictAction|string|undefined), + * saveAs: (boolean|undefined), + * method: (string|undefined), + * headers: (!Array<{name:string, value:string}>|undefined), + * body: (string|undefined) + * }} details + * @param {function(number)=} opt_callback + * @see https://developer.chrome.com/extensions/downloads#method-download + */ +chrome.downloads.download = function(details, opt_callback) {}; + + +/** + * @typedef {?{ + * query: (!Array|undefined), + * startedBefore: (string|undefined), + * startedAfter: (string|undefined), + * endedBefore: (string|undefined), + * endedAfter: (string|undefined), + * totalBytesGreater: (number|undefined), + * totalBytesLess: (number|undefined), + * filenameRegex: (string|undefined), + * urlRegex: (string|undefined), + * finalUrlRegex: (string|undefined), + * limit: (number|undefined), + * orderedBy: (!Array|undefined), + * id: (number|undefined), + * url: (string|undefined), + * finalUrl: (string|undefined), + * filename: (string|undefined), + * danger: (!chrome.downloads.DangerType|string|undefined), + * mime: (string|undefined), + * startTime: (string|undefined), + * endTime: (string|undefined), + * state: (!chrome.downloads.State|string|undefined), + * paused: (boolean|undefined), + * error: (!chrome.downloads.InterruptReason|string|undefined), + * bytesReceived: (number|undefined), + * totalBytes: (number|undefined), + * fileSize: (number|undefined), + * exists: (boolean|undefined) + * }} + */ +chrome.downloads.Query; + + +/** + * @param {!chrome.downloads.Query} query + * @param {function(!Array)} callback + * @see https://developer.chrome.com/extensions/downloads#method-search + */ +chrome.downloads.search = function(query, callback) {}; + + +/** + * @param {number} id + * @param {function()=} opt_callback + * + * @see https://developer.chrome.com/extensions/downloads#method-pause + */ +chrome.downloads.pause = function(id, opt_callback) {}; + + +/** + * @param {string} id + * @param {function()=} opt_callback + * + * @see https://developer.chrome.com/extensions/downloads#method-resume + */ +chrome.downloads.resume = function(id, opt_callback) {}; + + +/** + * @param {number} id + * @param {function()=} opt_callback + * + * @see https://developer.chrome.com/extensions/downloads#method-cancel + */ +chrome.downloads.cancel = function(id, opt_callback) {}; + + +/** + * @param {number} id + * @param {{size:(number|undefined)}|function(string)} optionsOrCallback + * @param {function(string)=} opt_callback + * + * @see https://developer.chrome.com/extensions/downloads#method-getFileIcon + */ +chrome.downloads.getFileIcon = function(id, optionsOrCallback, opt_callback) {}; + + +/** + * @param {number} id + * @see https://developer.chrome.com/extensions/downloads#method-open + */ +chrome.downloads.open = function(id) {}; + + +/** + * @param {number} id + * @see https://developer.chrome.com/extensions/downloads#method-show + */ +chrome.downloads.show = function(id) {}; + + +/** @see https://developer.chrome.com/extensions/downloads#method-showDefaultFolder */ +chrome.downloads.showDefaultFolder = function() {}; + + +/** + * @param {!chrome.downloads.Query} query + * @param {function(!Array)} callback + * @see https://developer.chrome.com/extensions/downloads#method-erase + */ +chrome.downloads.erase = function(query, callback) {}; + + +/** + * @param {number} id + * @param {function()=} opt_callback + * + * @see https://developer.chrome.com/extensions/downloads#method-removeFile + */ +chrome.downloads.removeFile = function(id, opt_callback) {}; + + +/** + * @param {number} id + * @param {function()=} opt_callback + * + * @see https://developer.chrome.com/extensions/downloads#method-acceptDanger + */ +chrome.downloads.acceptDanger = function(id, opt_callback) {}; + + +/** + * @param {number} id + * + * @see https://developer.chrome.com/extensions/downloads#method-drag + */ +chrome.downloads.drag = function(id) {}; + + +/** + * @param {boolean} enabled + * + * @see https://developer.chrome.com/extensions/downloads#method-setShelfEnabled + */ +chrome.downloads.setShelfEnabled = function(enabled) {}; + + +/** + * @record + * @extends {ChromeBaseEvent} + * @see https://developer.chrome.com/extensions/downloads#event-onCreated + */ +chrome.downloads.CreatedEvent = function() {}; + + +/** + * @type {!chrome.downloads.CreatedEvent} + * https://developer.chrome.com/extensions/downloads#event-onCreated + */ +chrome.downloads.onCreated; + + +/** + * @type {!ChromeNumberEvent} + * https://developer.chrome.com/extensions/downloads#event-onErased + */ +chrome.downloads.onErased; + + +/** + * @type {!ChromeObjectEvent} + * https://developer.chrome.com/extensions/downloads#event-onChanged + */ +chrome.downloads.onChanged; + + +/** + * @typedef {?{ + * filename: string, + * conflictAction: (!chrome.downloads.FilenameConflictAction|undefined) + * }} + * @see https://developer.chrome.com/extensions/downloads#event-onDeterminingFilename + */ +chrome.downloads.FilenameSuggestion; + + +/** + * @record + * @extends {ChromeBaseEvent< + * function( + * !chrome.downloads.DownloadItem, + * function(!chrome.downloads.FilenameSuggestion=))>} + * @see https://developer.chrome.com/extensions/downloads#event-onDeterminingFilename + */ +chrome.downloads.DeterminingFilenameEvent = function() {}; + + +/** + * @type {!chrome.downloads.DeterminingFilenameEvent} + * https://developer.chrome.com/extensions/downloads#event-onDeterminingFilename + */ +chrome.downloads.onDeterminingFilename; diff --git a/cljs-src/externs/echarts.ext.js b/cljs-src/externs/echarts.ext.js new file mode 100644 index 0000000..66698a3 --- /dev/null +++ b/cljs-src/externs/echarts.ext.js @@ -0,0 +1,1224 @@ +var zrender = { + "version": {}, + "init": function () {}, + "dispose": function () {}, + "getInstance": function () {}, + "delInstance": function () {}, + "tool": { + "color": { + "customPalette": function () {}, + "resetPalette": function () {}, + "getColor": function () {}, + "getHighlightColor": function () {}, + "customHighlight": function () {}, + "resetHighlight": function () {}, + "getRadialGradient": function () {}, + "getLinearGradient": function () {}, + "getGradientColors": function () {}, + "getStepColors": function () {}, + "reverse": function () {}, + "mix": function () {}, + "lift": function () {}, + "trim": function () {}, + "random": function () {}, + "toRGB": function () {}, + "toRGBA": function () {}, + "toHex": function () {}, + "toHSL": function () {}, + "toHSLA": function () {}, + "toHSB": function () {}, + "toHSBA": function () {}, + "toHSV": function () {}, + "toHSVA": function () {}, + "toName": function () {}, + "toColor": function () {}, + "toArray": function () {}, + "alpha": function () {}, + "getData": function () {} + }, + "math": { + "sin": function () {}, + "cos": function () {}, + "degreeToRadian": function () {}, + "radianToDegree": function () {} + }, + "util": { + "inherits": function () {}, + "clone": function () {}, + "merge": function () {}, + "getContext": function () {}, + "indexOf": function () {}, + "each": function () {}, + "map": function () {}, + "filter": function () {}, + "bind": function () {} + }, + "vector": { + "create": function () {}, + "copy": function () {}, + "clone": function () {}, + "set": function () {}, + "add": function () {}, + "scaleAndAdd": function () {}, + "sub": function () {}, + "len": function () {}, + "lenSquare": function () {}, + "mul": function () {}, + "div": function () {}, + "dot": function () {}, + "scale": function () {}, + "normalize": function () {}, + "distance": function () {}, + "distanceSquare": function () {}, + "negate": function () {}, + "lerp": function () {}, + "applyTransform": function () {}, + "min": function () {}, + "max": function () {}, + "length": function () {}, + "lengthSquare": function () {}, + "dist": function () {}, + "distSquare": function () {} + }, + "area": { + "isInside": function () {}, + "isOutside": function () {}, + "getTextWidth": function () {}, + "getTextHeight": function () {}, + "isInsidePath": function () {}, + "isInsidePolygon": function () {}, + "isInsideSector": function () {}, + "isInsideCircle": function () {}, + "isInsideLine": function () {}, + "isInsideRect": function () {}, + "isInsidePolyline": function () {}, + "isInsideCubicStroke": function () {}, + "isInsideQuadraticStroke": function () {} + }, + "event": { + "getX": function () {}, + "getY": function () {}, + "getDelta": function () {}, + "stop": function () {}, + "Dispatcher": function () {} + } + }, + "animation": { + "Animation": function () {}, + "Cip": function () {}, + "easing": { + "Linear": function () {}, + "QuadraticIn": function () {}, + "QuadraticOut": function () {}, + "QuadraticInOut": function () {}, + "CubicIn": function () {}, + "CubicOut": function () {}, + "CubicInOut": function () {}, + "QuarticIn": function () {}, + "QuarticOut": function () {}, + "QuarticInOut": function () {}, + "QuinticIn": function () {}, + "QuinticOut": function () {}, + "QuinticInOut": function () {}, + "SinusoidalIn": function () {}, + "SinusoidalOut": function () {}, + "SinusoidalInOut": function () {}, + "ExponentialIn": function () {}, + "ExponentialOut": function () {}, + "ExponentialInOut": function () {}, + "CircularIn": function () {}, + "CircularOut": function () {}, + "CircularInOut": function () {}, + "ElasticIn": function () {}, + "ElasticOut": function () {}, + "ElasticInOut": function () {}, + "BackIn": function () {}, + "BackOut": function () {}, + "BackInOut": function () {}, + "BounceIn": function () {}, + "BounceOut": function () {}, + "BounceInOut": function () {} + } + } +} + +var echarts = { + "version": {}, + "dependencies": { + "zrender": {} + }, + "init": function () {}, + "getInstanceById": function () {}, + "config": { + "CHART_TYPE_LINE": {}, + "CHART_TYPE_BAR": {}, + "CHART_TYPE_SCATTER": {}, + "CHART_TYPE_PIE": {}, + "CHART_TYPE_RADAR": {}, + "CHART_TYPE_VENN": {}, + "CHART_TYPE_TREEMAP": {}, + "CHART_TYPE_TREE": {}, + "CHART_TYPE_MAP": {}, + "CHART_TYPE_K": {}, + "CHART_TYPE_ISLAND": {}, + "CHART_TYPE_FORCE": {}, + "CHART_TYPE_CHORD": {}, + "CHART_TYPE_GAUGE": {}, + "CHART_TYPE_FUNNEL": {}, + "CHART_TYPE_EVENTRIVER": {}, + "CHART_TYPE_WORDCLOUD": {}, + "CHART_TYPE_HEATMAP": {}, + "COMPONENT_TYPE_TITLE": {}, + "COMPONENT_TYPE_LEGEND": {}, + "COMPONENT_TYPE_DATARANGE": {}, + "COMPONENT_TYPE_DATAVIEW": {}, + "COMPONENT_TYPE_DATAZOOM": {}, + "COMPONENT_TYPE_TOOLBOX": {}, + "COMPONENT_TYPE_TOOLTIP": {}, + "COMPONENT_TYPE_GRID": {}, + "COMPONENT_TYPE_AXIS": {}, + "COMPONENT_TYPE_POLAR": {}, + "COMPONENT_TYPE_X_AXIS": {}, + "COMPONENT_TYPE_Y_AXIS": {}, + "COMPONENT_TYPE_AXIS_CATEGORY": {}, + "COMPONENT_TYPE_AXIS_VALUE": {}, + "COMPONENT_TYPE_TIMELINE": {}, + "COMPONENT_TYPE_ROAMCONTROLLER": {}, + "backgroundColor": {}, + "color": { + "0": {}, + "1": {}, + "2": {}, + "3": {}, + "4": {}, + "5": {}, + "6": {}, + "7": {}, + "8": {}, + "9": {}, + "10": {}, + "11": {}, + "12": {}, + "13": {}, + "14": {}, + "15": {}, + "16": {}, + "17": {}, + "18": {}, + "19": {} + }, + "markPoint": { + "clickable": {}, + "symbol": {}, + "symbolSize": {}, + "large": {}, + "effect": { + "show": {}, + "loop": {}, + "period": {}, + "type": {}, + "scaleSize": {}, + "bounceDistance": {} + }, + "itemStyle": { + "normal": { + "borderWidth": {}, + "label": { + "show": {}, + "position": {} + } + }, + "emphasis": { + "label": { + "show": {} + } + } + } + }, + "markLine": { + "clickable": {}, + "symbol": { + "0": {}, + "1": {} + }, + "symbolSize": { + "0": {}, + "1": {} + }, + "smoothness": {}, + "precision": {}, + "effect": { + "show": {}, + "loop": {}, + "period": {}, + "scaleSize": {} + }, + "bundling": { + "enable": {}, + "maxTurningAngle": {} + }, + "itemStyle": { + "normal": { + "borderWidth": {}, + "label": { + "show": {}, + "position": {} + }, + "lineStyle": { + "type": {} + } + }, + "emphasis": { + "label": { + "show": {} + }, + "lineStyle": function () {} + } + } + }, + "textStyle": { + "decoration": {}, + "fontFamily": {}, + "fontFamily2": {}, + "fontSize": {}, + "fontStyle": {}, + "fontWeight": {} + }, + "EVENT": { + "REFRESH": {}, + "RESTORE": {}, + "RESIZE": {}, + "CLICK": {}, + "DBLCLICK": {}, + "HOVER": {}, + "MOUSEOUT": {}, + "DATA_CHANGED": {}, + "DATA_ZOOM": {}, + "DATA_RANGE": {}, + "DATA_RANGE_SELECTED": {}, + "DATA_RANGE_HOVERLINK": {}, + "LEGEND_SELECTED": {}, + "LEGEND_HOVERLINK": {}, + "MAP_SELECTED": {}, + "PIE_SELECTED": {}, + "MAGIC_TYPE_CHANGED": {}, + "DATA_VIEW_CHANGED": {}, + "TIMELINE_CHANGED": {}, + "MAP_ROAM": {}, + "FORCE_LAYOUT_END": {}, + "TOOLTIP_HOVER": {}, + "TOOLTIP_IN_GRID": {}, + "TOOLTIP_OUT_GRID": {}, + "ROAMCONTROLLER": {} + }, + "DRAG_ENABLE_TIME": {}, + "EFFECT_ZLEVEL": {}, + "effectBlendAlpha": {}, + "symbolList": { + "0": {}, + "1": {}, + "2": {}, + "3": {}, + "4": {}, + "5": {}, + "6": {}, + "7": {} + }, + "loadingEffect": {}, + "loadingText": {}, + "noDataEffect": {}, + "noDataText": {}, + "calculable": {}, + "calculableColor": {}, + "calculableHolderColor": {}, + "nameConnector": {}, + "valueConnector": {}, + "animation": {}, + "addDataAnimation": {}, + "animationThreshold": {}, + "animationDuration": {}, + "animationDurationUpdate": {}, + "animationEasing": {}, + "grid": { + "zlevel": {}, + "z": {}, + "x": {}, + "y": {}, + "x2": {}, + "y2": {}, + "backgroundColor": {}, + "borderWidth": {}, + "borderColor": {} + }, + "dataZoom": { + "zlevel": {}, + "z": {}, + "show": {}, + "orient": {}, + "backgroundColor": {}, + "dataBackgroundColor": {}, + "fillerColor": {}, + "handleColor": {}, + "handleSize": {}, + "showDetail": {}, + "realtime": {} + }, + "line": { + "zlevel": {}, + "z": {}, + "clickable": {}, + "legendHoverLink": {}, + "xAxisIndex": {}, + "yAxisIndex": {}, + "dataFilter": {}, + "itemStyle": { + "normal": { + "label": { + "show": {} + }, + "lineStyle": { + "width": {}, + "type": {}, + "shadowColor": {}, + "shadowBlur": {}, + "shadowOffsetX": {}, + "shadowOffsetY": {} + } + }, + "emphasis": { + "label": { + "show": {} + } + } + }, + "symbolSize": {}, + "showAllSymbol": {} + }, + "bar": { + "zlevel": {}, + "z": {}, + "clickable": {}, + "legendHoverLink": {}, + "xAxisIndex": {}, + "yAxisIndex": {}, + "barMinHeight": {}, + "barGap": {}, + "barCategoryGap": {}, + "itemStyle": { + "normal": { + "barBorderColor": {}, + "barBorderRadius": {}, + "barBorderWidth": {}, + "label": { + "show": {} + } + }, + "emphasis": { + "barBorderColor": {}, + "barBorderRadius": {}, + "barBorderWidth": {}, + "label": { + "show": {} + } + } + } + }, + "dataRange": { + "zlevel": {}, + "z": {}, + "show": {}, + "orient": {}, + "x": {}, + "y": {}, + "backgroundColor": {}, + "borderColor": {}, + "borderWidth": {}, + "padding": {}, + "itemGap": {}, + "itemWidth": {}, + "itemHeight": {}, + "precision": {}, + "splitNumber": {}, + "splitList": function () {}, + "calculable": {}, + "selectedMode": {}, + "hoverLink": {}, + "realtime": {}, + "color": { + "0": {}, + "1": {} + }, + "textStyle": { + "color": {} + } + }, + "scatter": { + "zlevel": {}, + "z": {}, + "clickable": {}, + "legendHoverLink": {}, + "xAxisIndex": {}, + "yAxisIndex": {}, + "symbolSize": {}, + "large": {}, + "largeThreshold": {}, + "itemStyle": { + "normal": { + "label": { + "show": {} + } + }, + "emphasis": { + "label": { + "show": {} + } + } + } + }, + "k": { + "zlevel": {}, + "z": {}, + "clickable": {}, + "hoverable": {}, + "legendHoverLink": {}, + "xAxisIndex": {}, + "yAxisIndex": {}, + "itemStyle": { + "normal": { + "color": {}, + "color0": {}, + "lineStyle": { + "width": {}, + "color": {}, + "color0": {} + }, + "label": { + "show": {} + } + }, + "emphasis": { + "label": { + "show": {} + } + } + } + }, + "pie": { + "zlevel": {}, + "z": {}, + "clickable": {}, + "legendHoverLink": {}, + "center": { + "0": {}, + "1": {} + }, + "radius": { + "0": {}, + "1": {} + }, + "clockWise": {}, + "startAngle": {}, + "minAngle": {}, + "selectedOffset": {}, + "itemStyle": { + "normal": { + "borderColor": {}, + "borderWidth": {}, + "label": { + "show": {}, + "position": {} + }, + "labelLine": { + "show": {}, + "length": {}, + "lineStyle": { + "width": {}, + "type": {} + } + } + }, + "emphasis": { + "borderColor": {}, + "borderWidth": {}, + "label": { + "show": {} + }, + "labelLine": { + "show": {}, + "length": {}, + "lineStyle": { + "width": {}, + "type": {} + } + } + } + } + }, + "polar": { + "zlevel": {}, + "z": {}, + "center": { + "0": {}, + "1": {} + }, + "radius": {}, + "startAngle": {}, + "boundaryGap": { + "0": {}, + "1": {} + }, + "splitNumber": {}, + "name": { + "show": {}, + "textStyle": { + "color": {} + } + }, + "axisLine": { + "show": {}, + "lineStyle": { + "color": {}, + "width": {}, + "type": {} + } + }, + "axisLabel": { + "show": {}, + "textStyle": { + "color": {} + } + }, + "splitArea": { + "show": {}, + "areaStyle": { + "color": { + "0": {}, + "1": {} + } + } + }, + "splitLine": { + "show": {}, + "lineStyle": { + "width": {}, + "color": {} + } + }, + "type": {} + }, + "radar": { + "zlevel": {}, + "z": {}, + "clickable": {}, + "legendHoverLink": {}, + "polarIndex": {}, + "itemStyle": { + "normal": { + "label": { + "show": {} + }, + "lineStyle": { + "width": {}, + "type": {} + } + }, + "emphasis": { + "label": { + "show": {} + } + } + }, + "symbolSize": {} + }, + "chord": { + "zlevel": {}, + "z": {}, + "clickable": {}, + "radius": { + "0": {}, + "1": {} + }, + "center": { + "0": {}, + "1": {} + }, + "padding": {}, + "sort": {}, + "sortSub": {}, + "startAngle": {}, + "clockWise": {}, + "ribbonType": {}, + "minRadius": {}, + "maxRadius": {}, + "symbol": {}, + "showScale": {}, + "showScaleText": {}, + "itemStyle": { + "normal": { + "borderWidth": {}, + "borderColor": {}, + "label": { + "show": {}, + "rotate": {}, + "distance": {} + }, + "chordStyle": { + "width": {}, + "color": {}, + "borderWidth": {}, + "borderColor": {}, + "opacity": {} + } + }, + "emphasis": { + "borderWidth": {}, + "borderColor": {}, + "chordStyle": { + "width": {}, + "color": {}, + "borderWidth": {}, + "borderColor": {} + } + } + } + }, + "force": { + "zlevel": {}, + "z": {}, + "center": { + "0": {}, + "1": {} + }, + "size": {}, + "preventOverlap": {}, + "coolDown": {}, + "minRadius": {}, + "maxRadius": {}, + "ratioScaling": {}, + "large": {}, + "useWorker": {}, + "steps": {}, + "scaling": {}, + "gravity": {}, + "symbol": {}, + "symbolSize": {}, + "linkSymbol": function () {}, + "linkSymbolSize": { + "0": {}, + "1": {} + }, + "draggable": {}, + "clickable": {}, + "roam": {}, + "itemStyle": { + "normal": { + "label": { + "show": {}, + "position": {} + }, + "nodeStyle": { + "brushType": {}, + "borderColor": {}, + "borderWidth": {} + }, + "linkStyle": { + "color": {}, + "width": {}, + "type": {} + } + }, + "emphasis": { + "label": { + "show": {} + }, + "nodeStyle": function () {}, + "linkStyle": { + "opacity": {} + } + } + } + }, + "roamController": { + "zlevel": {}, + "z": {}, + "show": {}, + "x": {}, + "y": {}, + "width": {}, + "height": {}, + "backgroundColor": {}, + "borderColor": {}, + "borderWidth": {}, + "padding": {}, + "handleColor": {}, + "fillerColor": {}, + "step": {}, + "mapTypeControl": function () {} + }, + "map": { + "zlevel": {}, + "z": {}, + "mapType": {}, + "showLegendSymbol": {}, + "dataRangeHoverLink": {}, + "hoverable": {}, + "clickable": {}, + "itemStyle": { + "normal": { + "borderColor": {}, + "borderWidth": {}, + "areaStyle": { + "color": {} + }, + "label": { + "show": {}, + "textStyle": { + "color": {} + } + } + }, + "emphasis": { + "borderColor": {}, + "borderWidth": {}, + "areaStyle": { + "color": {} + }, + "label": { + "show": {}, + "textStyle": { + "color": {} + } + } + } + } + }, + "gauge": { + "zlevel": {}, + "z": {}, + "center": { + "0": {}, + "1": {} + }, + "clickable": {}, + "legendHoverLink": {}, + "radius": {}, + "startAngle": {}, + "endAngle": {}, + "min": {}, + "max": {}, + "splitNumber": {}, + "axisLine": { + "show": {}, + "lineStyle": { + "color": { + "0": { + "0": {}, + "1": {} + }, + "1": { + "0": {}, + "1": {} + }, + "2": { + "0": {}, + "1": {} + } + }, + "width": {} + } + }, + "axisTick": { + "show": {}, + "splitNumber": {}, + "length": {}, + "lineStyle": { + "color": {}, + "width": {}, + "type": {} + } + }, + "axisLabel": { + "show": {}, + "textStyle": { + "color": {} + } + }, + "splitLine": { + "show": {}, + "length": {}, + "lineStyle": { + "color": {}, + "width": {}, + "type": {} + } + }, + "pointer": { + "show": {}, + "length": {}, + "width": {}, + "color": {} + }, + "title": { + "show": {}, + "offsetCenter": { + "0": {}, + "1": {} + }, + "textStyle": { + "color": {}, + "fontSize": {} + } + }, + "detail": { + "show": {}, + "backgroundColor": {}, + "borderWidth": {}, + "borderColor": {}, + "width": {}, + "height": {}, + "offsetCenter": { + "0": {}, + "1": {} + }, + "textStyle": { + "color": {}, + "fontSize": {} + } + } + }, + "funnel": { + "zlevel": {}, + "z": {}, + "clickable": {}, + "legendHoverLink": {}, + "x": {}, + "y": {}, + "x2": {}, + "y2": {}, + "min": {}, + "max": {}, + "minSize": {}, + "maxSize": {}, + "sort": {}, + "gap": {}, + "funnelAlign": {}, + "itemStyle": { + "normal": { + "borderColor": {}, + "borderWidth": {}, + "label": { + "show": {}, + "position": {} + }, + "labelLine": { + "show": {}, + "length": {}, + "lineStyle": { + "width": {}, + "type": {} + } + } + }, + "emphasis": { + "borderColor": {}, + "borderWidth": {}, + "label": { + "show": {} + }, + "labelLine": { + "show": {} + } + } + } + }, + "eventRiver": { + "zlevel": {}, + "z": {}, + "clickable": {}, + "legendHoverLink": {}, + "itemStyle": { + "normal": { + "borderColor": {}, + "borderWidth": {}, + "label": { + "show": {}, + "position": {}, + "formatter": {} + } + }, + "emphasis": { + "borderColor": {}, + "borderWidth": {}, + "label": { + "show": {} + } + } + } + }, + "venn": { + "zlevel": {}, + "z": {}, + "calculable": {} + }, + "treemap": { + "zlevel": {}, + "z": {}, + "calculable": {}, + "clickable": {}, + "center": { + "0": {}, + "1": {} + }, + "size": { + "0": {}, + "1": {} + }, + "root": {}, + "itemStyle": { + "normal": { + "label": { + "show": {}, + "x": {}, + "y": {}, + "textStyle": { + "align": {}, + "color": {}, + "fontFamily": {}, + "fontSize": {}, + "fontStyle": {}, + "fontWeight": {} + } + }, + "breadcrumb": { + "show": {}, + "textStyle": function () {} + }, + "borderWidth": {}, + "borderColor": {}, + "childBorderWidth": {}, + "childBorderColor": {} + }, + "emphasis": function () {} + } + }, + "tree": { + "zlevel": {}, + "z": {}, + "calculable": {}, + "clickable": {}, + "rootLocation": function () {}, + "orient": {}, + "symbol": {}, + "symbolSize": {}, + "nodePadding": {}, + "layerPadding": {}, + "itemStyle": { + "normal": { + "label": { + "show": {} + }, + "lineStyle": { + "width": {}, + "color": {}, + "type": {} + } + }, + "emphasis": function () {} + } + }, + "wordCloud": { + "zlevel": {}, + "z": {}, + "clickable": {}, + "center": { + "0": {}, + "1": {} + }, + "size": { + "0": {}, + "1": {} + }, + "textRotation": { + "0": {}, + "1": {} + }, + "textPadding": {}, + "autoSize": { + "enable": {}, + "minSize": {} + }, + "itemStyle": { + "normal": { + "textStyle": { + "fontSize": function () {} + } + } + } + }, + "heatmap": { + "zlevel": {}, + "z": {}, + "clickable": {} + } + }, + "util": { + "mapData": { + "params": { + "decode": function () {}, + "params": { + "none": { + "getGeoJson": function () {} + }, + "world": { + "getGeoJson": function () {} + }, + "china": { + "getGeoJson": function () {} + }, + "南海诸岛": { + "textCoord": { + "0": {}, + "1": {} + }, + "getPath": function () {} + }, + "新疆": { + "getGeoJson": function () {} + }, + "西藏": { + "getGeoJson": function () {} + }, + "内蒙古": { + "getGeoJson": function () {} + }, + "青海": { + "getGeoJson": function () {} + }, + "四川": { + "getGeoJson": function () {} + }, + "黑龙江": { + "getGeoJson": function () {} + }, + "甘肃": { + "getGeoJson": function () {} + }, + "云南": { + "getGeoJson": function () {} + }, + "广西": { + "getGeoJson": function () {} + }, + "湖南": { + "getGeoJson": function () {} + }, + "陕西": { + "getGeoJson": function () {} + }, + "广东": { + "getGeoJson": function () {} + }, + "吉林": { + "getGeoJson": function () {} + }, + "河北": { + "getGeoJson": function () {} + }, + "湖北": { + "getGeoJson": function () {} + }, + "贵州": { + "getGeoJson": function () {} + }, + "山东": { + "getGeoJson": function () {} + }, + "江西": { + "getGeoJson": function () {} + }, + "河南": { + "getGeoJson": function () {} + }, + "辽宁": { + "getGeoJson": function () {} + }, + "山西": { + "getGeoJson": function () {} + }, + "安徽": { + "getGeoJson": function () {} + }, + "福建": { + "getGeoJson": function () {} + }, + "浙江": { + "getGeoJson": function () {} + }, + "江苏": { + "getGeoJson": function () {} + }, + "重庆": { + "getGeoJson": function () {} + }, + "宁夏": { + "getGeoJson": function () {} + }, + "海南": { + "getGeoJson": function () {} + }, + "台湾": { + "getGeoJson": function () {} + }, + "北京": { + "getGeoJson": function () {} + }, + "天津": { + "getGeoJson": function () {} + }, + "上海": { + "getGeoJson": function () {} + }, + "香港": { + "getGeoJson": function () {} + }, + "澳门": { + "getGeoJson": function () {} + } + } + } + } + } +} + +function MessageCenter() {} +function Echarts(dom) {} + +Echarts.prototype.restore = function() {}; +Echarts.prototype.refresh = function(param) {}; +Echarts.prototype.setOption = function(option, notMerge) {}; +Echarts.prototype.getOption = function() {}; +Echarts.prototype.setSeries = function(series, notMerge) {}; +Echarts.prototype.getSeries = function() {}; +Echarts.prototype.addData = function(seriesIdx, data, isHead, dataGrow, additionData) {}; +Echarts.prototype.addMarkPoint = function(seriesIdx, markData) {}; +Echarts.prototype.addMarkLine = function(seriesIdx, markData) {}; +Echarts.prototype.delMarkPoint = function(seriesIdx, markName) {}; +Echarts.prototype.delMarkLine = function(seriesIdx, markName) {}; +Echarts.prototype.getDom = function() {}; +Echarts.prototype.getZrender = function() {}; +Echarts.prototype.getDataURL = function(imgType) {}; +Echarts.prototype.getImage = function(imgType) {}; +Echarts.prototype.getConnectedDataURL = function(imgType) {}; +Echarts.prototype.getConnectedImage = function(imgType) {}; +Echarts.prototype.on = function(eventName, eventListener) {}; +Echarts.prototype.un = function(eventName, eventListener) {}; +Echarts.prototype.connect = function(connectTarget) {}; +Echarts.prototype.disConnect = function(connectTarget) {}; +Echarts.prototype.connectedEventHandler = function(param) {}; +Echarts.prototype.isConnected = function() {}; +Echarts.prototype.showLoading = function(loadingOption) {}; +Echarts.prototype.hideLoading = function() {}; +Echarts.prototype.setTheme = function(theme) {}; +Echarts.prototype.resize = function() {}; +Echarts.prototype.clear = function() {}; +Echarts.prototype.dispose = function() {}; diff --git a/cljs-src/project.clj b/cljs-src/project.clj new file mode 100644 index 0000000..ac226a6 --- /dev/null +++ b/cljs-src/project.clj @@ -0,0 +1,48 @@ +(defproject history-master "2.0.0" + :description "Visualize browsing history, Discover your unknown habits, downloads supported." + :url "https://github.com/jiacai2050/history-master" + :min-lein-version "2.7.1" + :dependencies [[org.clojure/clojure "1.8.0"] + [cljsjs/antd "3.0.1-0"] + [antizer "0.2.2" :exclusions [cljsjs/antd]] + [reagent "0.7.0"] + [re-frame "0.10.3-beta1"] + [org.clojure/core.async "0.3.465"] + [org.clojure/clojurescript "1.9.946"] + [cljsjs/moment "2.17.1-1"]] + :target-path "target/%s/" + :profiles {:dev {:dependencies [[figwheel-sidecar "0.5.14"] + [com.cemerick/piggieback "0.2.2"]] + :plugins [[lein-figwheel "0.5.14"] + [lein-cljsbuild "1.1.7"] + [lein-doo "0.1.8"]] + :repl-options {:nrepl-middleware [cemerick.piggieback/wrap-cljs-repl]} + :source-paths ["src/background" "src/option"]} + :dev-option {:clean-targets ^{:protect false} [:target-path "resources/dev/option/js"] + :cljsbuild {:builds [{:id "dev" + :figwheel true + :source-paths ["src/option"] + :compiler {:output-to "resources/dev/option/js/main.js" + :output-dir "resources/dev/option/js/out" + :source-map true + :optimizations :none + :main history_master.option}}]} + :figwheel {:server-port 8001 + :http-server-root "dev/option" + :css-dirs ["resources/dev/option/css"] + :server-logfile ".figwheel_option.log" + :repl true}} + :release {:clean-targets ^{:protect false} ["resources/release/option/js"] + :cljsbuild {:builds [{:id "option" + :source-paths ["src/option"] + :compiler {:output-to "resources/release/option/js/main.js" + :output-dir "resources/release/option/js/out" + :externs ["externs/chrome_extensions.js" "externs/chrome.js" "externs/echarts.ext.js"] + :optimizations :advanced + :main history_master.option}}]}}} + :aliases {"option" ["with-profile" "dev-option" "do" + ["clean"] + ["figwheel" "dev"]] + "bg" ["with-profile" "dev-background" "do" + ["clean"] + ["figwheel" "dev"]]}) diff --git a/cljs-src/release.sh b/cljs-src/release.sh new file mode 100755 index 0000000..3e0bab5 --- /dev/null +++ b/cljs-src/release.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +set -xe + +lein with-profile release do clean, cljsbuild once option +rm -rf resources/release/option/js/out + +cd resources/release +zip -x *.DS_Store -r ~/history_master_`date +%s`.zip * diff --git a/cljs-src/resources/background.js b/cljs-src/resources/background.js new file mode 100644 index 0000000..cb28454 --- /dev/null +++ b/cljs-src/resources/background.js @@ -0,0 +1,5 @@ +chrome.browserAction.onClicked.addListener((tab) => { + chrome.tabs.create({ + url: "option/index.html" + }); +}); diff --git a/cljs-src/resources/dev/background.js b/cljs-src/resources/dev/background.js new file mode 100644 index 0000000..cb28454 --- /dev/null +++ b/cljs-src/resources/dev/background.js @@ -0,0 +1,5 @@ +chrome.browserAction.onClicked.addListener((tab) => { + chrome.tabs.create({ + url: "option/index.html" + }); +}); diff --git a/cljs-src/resources/dev/manifest.json b/cljs-src/resources/dev/manifest.json new file mode 100644 index 0000000..a7f8906 --- /dev/null +++ b/cljs-src/resources/dev/manifest.json @@ -0,0 +1,35 @@ +{ + "name": "History Master", + "version": "2.0.0", + "description": "Visualize browsing history, Discover your unknown habits.", + "background": { + "scripts": ["background.js"] + }, + "chrome_url_overrides": { + "history": "option/index.html" + }, + "options_ui": { + "page": "option/index.html", + "chrome_style": false, + "open_in_tab": true + }, + "browser_action": { + "browser_style": true, + "default_icon": { + "16": "option/images/16.png", + "32": "option/images/32.png", + "64": "option/images/64.png", + "128": "option/images/128.png" + }, + "default_title": "History Master" + }, + "icons": { + "16": "option/images/16.png", + "32": "option/images/32.png", + "64": "option/images/64.png", + "128": "option/images/128.png" + }, + "permissions": ["history", "tabs", "downloads"], + "content_security_policy": "default-src 'self'; style-src https://cdn.bootcss.com 'unsafe-inline'; connect-src http://* ws://localhost:* ; font-src https://* ;script-src https://cdn.bootcss.com 'self' 'unsafe-eval'", + "manifest_version": 2 +} diff --git a/cljs-src/resources/dev/option/images b/cljs-src/resources/dev/option/images new file mode 120000 index 0000000..847b03e --- /dev/null +++ b/cljs-src/resources/dev/option/images @@ -0,0 +1 @@ +../../images/ \ No newline at end of file diff --git a/cljs-src/resources/dev/option/index.html b/cljs-src/resources/dev/option/index.html new file mode 100644 index 0000000..b07e29e --- /dev/null +++ b/cljs-src/resources/dev/option/index.html @@ -0,0 +1,17 @@ + + + + + + + + + + History Master + + +

+
+ + + diff --git a/cljs-src/resources/dev/option/init.js b/cljs-src/resources/dev/option/init.js new file mode 100644 index 0000000..05d6032 --- /dev/null +++ b/cljs-src/resources/dev/option/init.js @@ -0,0 +1,2 @@ +goog.require("figwheel.connect.build_dev"); +goog.require("history_master.option"); diff --git a/assets/img/128.png b/cljs-src/resources/images/128.png similarity index 100% rename from assets/img/128.png rename to cljs-src/resources/images/128.png diff --git a/assets/img/16.png b/cljs-src/resources/images/16.png similarity index 100% rename from assets/img/16.png rename to cljs-src/resources/images/16.png diff --git a/assets/img/32.png b/cljs-src/resources/images/32.png similarity index 100% rename from assets/img/32.png rename to cljs-src/resources/images/32.png diff --git a/assets/img/64.png b/cljs-src/resources/images/64.png similarity index 100% rename from assets/img/64.png rename to cljs-src/resources/images/64.png diff --git a/cljs-src/resources/manifest.json b/cljs-src/resources/manifest.json new file mode 100644 index 0000000..a7f8906 --- /dev/null +++ b/cljs-src/resources/manifest.json @@ -0,0 +1,35 @@ +{ + "name": "History Master", + "version": "2.0.0", + "description": "Visualize browsing history, Discover your unknown habits.", + "background": { + "scripts": ["background.js"] + }, + "chrome_url_overrides": { + "history": "option/index.html" + }, + "options_ui": { + "page": "option/index.html", + "chrome_style": false, + "open_in_tab": true + }, + "browser_action": { + "browser_style": true, + "default_icon": { + "16": "option/images/16.png", + "32": "option/images/32.png", + "64": "option/images/64.png", + "128": "option/images/128.png" + }, + "default_title": "History Master" + }, + "icons": { + "16": "option/images/16.png", + "32": "option/images/32.png", + "64": "option/images/64.png", + "128": "option/images/128.png" + }, + "permissions": ["history", "tabs", "downloads"], + "content_security_policy": "default-src 'self'; style-src https://cdn.bootcss.com 'unsafe-inline'; connect-src http://* ws://localhost:* ; font-src https://* ;script-src https://cdn.bootcss.com 'self' 'unsafe-eval'", + "manifest_version": 2 +} diff --git a/cljs-src/resources/release/background.js b/cljs-src/resources/release/background.js new file mode 100644 index 0000000..cb28454 --- /dev/null +++ b/cljs-src/resources/release/background.js @@ -0,0 +1,5 @@ +chrome.browserAction.onClicked.addListener((tab) => { + chrome.tabs.create({ + url: "option/index.html" + }); +}); diff --git a/cljs-src/resources/release/manifest.json b/cljs-src/resources/release/manifest.json new file mode 100644 index 0000000..a7f8906 --- /dev/null +++ b/cljs-src/resources/release/manifest.json @@ -0,0 +1,35 @@ +{ + "name": "History Master", + "version": "2.0.0", + "description": "Visualize browsing history, Discover your unknown habits.", + "background": { + "scripts": ["background.js"] + }, + "chrome_url_overrides": { + "history": "option/index.html" + }, + "options_ui": { + "page": "option/index.html", + "chrome_style": false, + "open_in_tab": true + }, + "browser_action": { + "browser_style": true, + "default_icon": { + "16": "option/images/16.png", + "32": "option/images/32.png", + "64": "option/images/64.png", + "128": "option/images/128.png" + }, + "default_title": "History Master" + }, + "icons": { + "16": "option/images/16.png", + "32": "option/images/32.png", + "64": "option/images/64.png", + "128": "option/images/128.png" + }, + "permissions": ["history", "tabs", "downloads"], + "content_security_policy": "default-src 'self'; style-src https://cdn.bootcss.com 'unsafe-inline'; connect-src http://* ws://localhost:* ; font-src https://* ;script-src https://cdn.bootcss.com 'self' 'unsafe-eval'", + "manifest_version": 2 +} diff --git a/cljs-src/resources/release/option/images b/cljs-src/resources/release/option/images new file mode 120000 index 0000000..847b03e --- /dev/null +++ b/cljs-src/resources/release/option/images @@ -0,0 +1 @@ +../../images/ \ No newline at end of file diff --git a/cljs-src/resources/release/option/index.html b/cljs-src/resources/release/option/index.html new file mode 100644 index 0000000..f6343cc --- /dev/null +++ b/cljs-src/resources/release/option/index.html @@ -0,0 +1,15 @@ + + + + + + + + History Master + + +
+
+ + + diff --git a/cljs-src/src/option/history_master/activity.cljs b/cljs-src/src/option/history_master/activity.cljs new file mode 100644 index 0000000..65b0ea2 --- /dev/null +++ b/cljs-src/src/option/history_master/activity.cljs @@ -0,0 +1,60 @@ +(ns history-master.activity + (:require [re-frame.core :as rf] + [reagent.core :as r] + [antizer.reagent :as ant] + [history-master.common :refer [default-range] :as c])) + +(defn timeline-sidebar [availiable-ranges selected-day] + (let [pv-map @(rf/subscribe [:pv-map])] + [ant/layout-sider + [ant/affix + [ant/menu {:selected-keys [@selected-day] :theme "dark" + :on-click (fn [clicked-menu] (reset! selected-day (.-key clicked-menu)))} + (for [current-day availiable-ranges] + ^{:key current-day} [ant/menu-item + [ant/tooltip {:title (pv-map current-day "0") :placement "rightBottom"} + (c/date->human current-day)]])]]])) + +(defn comparsion [a b index-key] + (apply compare (map index-key (js->clj [a b] :keywordize-keys true)))) + +(defn visit-details-table [selected-day] + (let [histories @(rf/subscribe [:visit-details-by-day (js/parseInt @selected-day)])] + [ant/table {:dataSource histories :bordered true :row-key "id" :size "small" :style {:width "80%"} + :title (constantly (r/as-element [:center (c/date->human (js/parseInt @selected-day))]) ) + :scroll {:y 900} + :columns [{:title "Visit Time" :dataIndex "visit-time" :width 150 + :render #(c/time->human %) + :sorter #(comparsion %1 %2 :visit-time) :defaultSortOrder "descend" + ;; FIXME why on-filter can't work + :onFilter (fn [value record] + (= value (c/extract-hour-from-date (:visit-time (js->clj record :keywordize-keys true))))) + :filters (->> histories + (map #(-> % :visit-time c/extract-hour-from-date)) + set + (map #(do {:text % :value %})) + (sort-by #(- (js/parseInt (:value %)))) + clj->js)} + {:title "Title" :dataIndex "title" :width 500 + :render (fn [text record idx] + (let [url (.-url record)] + (r/as-element [ant/popover {:content (r/as-element [:a {:target "_blank" :href url} url])} + [:a {:href url :target "_blank"} (subs text 0 300)]])))} + {:title "Visit Count" :dataIndex "visit-count" :width 130 :sorter #(comparsion %1 %2 :visit-count)} + {:title "Action" :key "action" :width 80 + :render (fn [text record] + (r/as-element [ant/popconfirm {:title "Are you sure?" + :on-confirm #(rf/dispatch [:delete-history {:via :single + :item (js->clj record :keywordize-keys true)}])} + [ant/button {:icon "delete" :type "danger"}]]))}] + :pagination {:show-size-changer true + :default-page-size 50 + :page-size-options ["50" "100" "200" "500"] + :show-total #(str "Total: " % " ")}}])) + +(defn activity-tab [availiable-ranges] + (let [selected-day (r/atom (str (first availiable-ranges)))] + [ant/layout + [timeline-sidebar availiable-ranges selected-day] + [ant/layout-content + [visit-details-table selected-day]]])) diff --git a/cljs-src/src/option/history_master/chrome.cljs b/cljs-src/src/option/history_master/chrome.cljs new file mode 100644 index 0000000..d5c3ecb --- /dev/null +++ b/cljs-src/src/option/history_master/chrome.cljs @@ -0,0 +1,168 @@ +(ns history-master.chrome + (:require [cljs.core.async :refer [! chan] :refer-macros [go]] + [re-frame.core :as rf] + [reagent.core :as r] + [history-master.common :refer [search-limit default-range] :as c])) + +(rf/reg-fx + :chrome-query + (fn [[start end text]] + (println "search with" (mapv #(c/datetime->human %) [start end]) text) + (js/chrome.history.search (clj->js {:text (or text "") + :startTime start + :endTime end + :maxResults search-limit}) + (fn [items] + ;; (.log js/console items) + (rf/dispatch [:query-result items]))))) + +(rf/reg-event-fx + :boot + (fn [{:keys [db]} _] + (let [range-in-ms (map #(-> % (.valueOf) c/trim-date->today) + default-range)] + {:db (assoc db + :loading? true + :date-range range-in-ms) + :chrome-query range-in-ms}))) + +(rf/reg-event-fx + :query-history + (fn [{:keys [db]} [_ start end text]] + (let [[start-ts end-ts] (map #(-> % (.valueOf) c/trim-date->today) + [start end])] + {:db (assoc db + :loading? true + :date-range [start-ts end-ts]) + :chrome-query [start-ts end-ts text]}))) + + +(rf/reg-event-db + :query-result + (fn [db [_ items]] + (assoc db + :histories (js->clj items :keywordize-keys true) + :loading? false))) + +(rf/reg-sub + :date-range + (fn [db _] + (:date-range db))) + +(rf/reg-sub + :loading? + (fn [db _] + (:loading? db))) + +(rf/reg-sub + :histories + (fn [{:keys [histories]} _] + (map (fn [item] + {:visit-time (:lastVisitTime item) + :title (some #(when-not (empty? %) %) ((juxt :title :url) item)) + :visit-count (:visitCount item) + :typed-count (:typedCount item) + :id (:id item) + :url (:url item)}) + histories))) + +(rf/reg-sub + :visit-details-by-day + :<- [:histories] + (fn [histories [_ current-day]] + (let [lower (c/trim-date->today current-day) + upper (c/trim-date->tomorrow current-day)] + (->> histories + (filter (fn [{:keys [visit-time]}] + (and + (<= lower visit-time) + (< visit-time upper)))) + (sort-by #(- (:visit-time %))))))) + +(rf/reg-sub + :pv-trend + :<- [:histories] + (fn [histories _] + (->> histories + (map (fn [{:keys [visit-time]}] + {:visit-day (c/trim-date->today visit-time)})) + (group-by :visit-day) + (map (fn [[visit-day items]] + {:visit-day visit-day + :pv (count items)})) + (sort-by :visit-day)))) + +(rf/reg-sub + :pv-map + :<- [:pv-trend] + (fn [pv-trend _] + (reduce + (fn [m {:keys [visit-day pv]}] + (assoc m visit-day pv)) + {} + pv-trend))) + +(rf/reg-sub + :total + :<- [:histories] + (fn [histories _] + (count histories))) + +(rf/reg-sub + :scheme-percentage + :<- [:histories] + (fn [histories _] + (->> histories + (map (fn [{:keys [url]}] + {:scheme (second (re-find #"(.+?)://" url))})) + (group-by :scheme) + (map (fn [[scheme items]] + {:name scheme + :value (count items)})) + (sort-by #(- (:value %)))))) + +(rf/reg-sub + :topn-percentage + :<- [:histories] + (fn [histories [_ group-key top-n]] + (->> (case group-key + :title (map (fn [{:keys [title]}] + {:title (subs title 0 50)}) + histories) + :domain (map (fn [{:keys [url]}] + {:domain (or (second (re-find #"://(.+?)/" url)) + url)}) + histories)) + (group-by group-key) + (map (fn [[k items]] + {:name k + :value (count items)})) + (sort-by #(- (:value %))) + (take top-n)))) + +;; remove history +(rf/reg-fx + :chrome-delete + (fn [[start end]] + (js/chrome.history.deleteRange (clj->js + {:startTime start + :endTime end}) + #(rf/dispatch [:delete-done start end])))) + +(rf/reg-event-fx + :delete-history + (fn [_ [_ {:keys [via] :as opts}]] + {:chrome-delete (case via + :range (let [{:keys [start end]} opts] + [start end]) + :single (let [{:keys [item]} opts + {:keys [visit-time]} item + delta 0.1] + ;; Chrome extension doesn't support deleteById, so we deleteByRange + [(- visit-time delta) (+ visit-time delta)]))})) + +(rf/reg-event-db + :delete-done + (fn [db [_ start end]] + (update db :histories #(remove (fn [item] (<= start (:lastVisitTime item) end)) + %)))) diff --git a/cljs-src/src/option/history_master/common.cljs b/cljs-src/src/option/history_master/common.cljs new file mode 100644 index 0000000..13bc43d --- /dev/null +++ b/cljs-src/src/option/history_master/common.cljs @@ -0,0 +1,61 @@ +(ns history-master.common + (:require [clojure.string :as str])) + +(def homepage "https://github.com/jiacai2050/history-master") +(def default-range [(-> (js/moment) (.subtract 7 "days")) (js/moment)]) +(def search-limit (dec (.pow js/Math 2 31))) +(def date-format "YYYY-MM-DD") +(def time-format "HH:mm:SS") +(def datetime-format (str date-format " " time-format)) + +(def one-day-in-ms (* 1000 60 60 24)) + +(defn date->human [timestamp] + (-> timestamp + js/moment + (.format date-format))) + +(defn time->human [timestamp] + (-> timestamp + js/moment + (.format time-format))) + +(defn datetime->human [timestamp] + (-> timestamp + js/moment + (.format datetime-format))) + +(defn date->computer [timestamp] + (-> timestamp + js/moment + (.format date-format))) + +(defn trim-date->today [timestamp] + (.. (js/moment timestamp) + (startOf "day") + (valueOf))) + +(defn trim-date->tomorrow [timestamp] + (.. (js/moment timestamp) + (add 1 "days") + (startOf "day") + (valueOf))) + +(defn extract-hour-from-date [timestamp] + (.. (js/moment timestamp) + (format "HH"))) + +(defn gen-date-ranges [start end] + (rest (range end (dec start) (- one-day-in-ms)))) + +(defn to-csv [histories] + (let [[[first] more] (split-at 1 histories) + columns (keys first)] + (->> more + (map (fn [item] + (->> (map (fn [column] + (clojure.string/replace (str (column item)) "," " ")) + columns) + (str/join ",")))) + (into [(str/join "," (map name columns))]) + (str/join "\n")))) diff --git a/cljs-src/src/option/history_master/option.cljs b/cljs-src/src/option/history_master/option.cljs new file mode 100644 index 0000000..3d9a24a --- /dev/null +++ b/cljs-src/src/option/history_master/option.cljs @@ -0,0 +1,77 @@ +(ns history-master.option + (:require [history-master.chrome] + [history-master.stat :refer [stat-tab]] + [history-master.activity :refer [activity-tab]] + [antizer.reagent :as ant] + [history-master.common :refer [default-range] :as c] + [goog.dom :as gdom] + [re-frame.core :as rf] + [cljsjs.moment] + [reagent.core :as r] + [clojure.string :as str])) + +(enable-console-print!) + +(defn download-csv [] + (let [content (js/Blob. [(c/to-csv @(rf/subscribe [:histories]))]) + filename (str (str/join "_" (map c/date->human @(rf/subscribe [:date-range]))) ".csv")] + (.download js/chrome.downloads (clj->js {:url (.createObjectURL js/window.URL content) + :saveAs true + :filename filename})))) + +(defn top-nav [selected-menu] + (r/with-let [selected-range (r/atom default-range)] + [ant/affix + [:div {:style {:background-color "#001529"}} + [ant/row {:type "flex" :align "middle"} + [ant/col {:span 3} [ant/button {:type "primary" :icon "dashboard" :ghost true :size "large" :target "_blank" + :href c/homepage} "History Master"]] + [ant/col {:span 7} [ant/menu {:selected-keys [@selected-menu] :theme "dark" :mode "horizontal" + :on-click (fn [e] (let [clicked-menu (.-key e)] + (if (= "download" clicked-menu) + (download-csv) + (reset! selected-menu (.-key e))))) } + [ant/menu-item {:key "activity"} [ant/icon {:type "profile"}] "Activity"] + [ant/menu-item {:key "stat"} [ant/icon {:type "area-chart"}] "Statistics"] + [ant/menu-item {:key "download"} [ant/icon {:type "download"}] "Download as CSV"]]] + [ant/col {:span 14} + [ant/button {:ghost true :type "primary" + :on-click #(ant/message-info "Have a nice day!")} + (str @(rf/subscribe [:total]) " results.")] + [ant/date-picker-range-picker + {:ranges {:Today [(js/moment) (-> (js/moment) (.add 1 "days"))] + :Yesterday [(-> (js/moment) (.subtract 1 "days")) (js/moment)] + "Last 7 Days" default-range + "Last 30 Days" [(-> (js/moment) (.subtract 30 "days")) (js/moment)]} + :disabled-date (fn [current] + (> (.valueOf current) (-> (js/moment) (.add 1 "days") (.valueOf)))) + :default-value @selected-range + :on-change (fn [dates date-strs] + (reset! selected-range dates))}] +[ant/input-search {:placeholder "Leave this to retrieve all" :enter-button "Search" :style {:width 300} + :on-search (fn [v] (rf/dispatch (conj (into [:query-history] @selected-range) v)))}]] + ;; [ant/col {:span 5} + ;; ] + ]]])) + +(defn main-body [] + (r/with-let [selected-menu (r/atom "activity")] + [ant/layout + [top-nav selected-menu] + [ant/spin {:size "large" :tip "Loading...." :spinning @(rf/subscribe [:loading?])} + (case @selected-menu + "activity" [activity-tab (apply c/gen-date-ranges @(rf/subscribe [:date-range]))] + "stat" [stat-tab])] + [ant/layout-footer {:style {:text-align "center"}} + [:p [:a {:href c/homepage :target "_blank"} + [ant/icon {:type "left"}] + [ant/icon {:type "right"}]] + " With " + [ant/icon {:type "heart"}] + " by " + [:a {:href "http://liujiacai.net" :target "_blank"} "Jiacai Liu."] + " Current version: " (->> js/chrome.runtime (.getManifest) (.-version))]]])) + +(rf/dispatch-sync [:boot]) +(r/render [main-body] + (gdom/getElement "app")) diff --git a/cljs-src/src/option/history_master/stat.cljs b/cljs-src/src/option/history_master/stat.cljs new file mode 100644 index 0000000..c5c06ee --- /dev/null +++ b/cljs-src/src/option/history_master/stat.cljs @@ -0,0 +1,98 @@ +(ns history-master.stat + (:require [goog.string :as gstr] + [goog.string.format] + [goog.dom :as gdom] + [reagent.core :as r] + [history-master.common :refer [date->human]] + [antizer.reagent :as ant] + [re-frame.core :as rf])) + +(def chart-width (* 0.95 (.-innerWidth js/window))) + +(defn pv-trend + "Param isn't used directly in render fn, instead extract it in component-did-update fn to render. + Param as prop is used to trigger rerender with lifecycle functions. + https://github.com/Day8/re-frame/wiki/When-do-components-update%3F" + [_] + (let [render-chart (fn [div daily-visits] + (let [chart (.init js/echarts div) + opts {:color ["#23B7E5"] + :tooltip {:trigger "item" + :formatter (fn [params] + (let [[visit-day pv] (.-value params)] + (gstr/format "%s
PV: %s" + (date->human visit-day) + pv)))} + :toolbox {:show true + :feature {:magicType {:show true :type ["line" "bar"]} + :dataView {:show true} + :restore {:show true} + :dataZoom {:show true} + :saveAsImage {:show true}}} + :dataZoom {:show true :start 0} + :legend {:data ["Page Views"]} + :grid {:y2 100} + :xAxis [{:type "time" :splitNumber 10}] + :yAxis [{:name "PV" :type "value"}] + :series [{:name "Page View" :type "line" :showAllSymbol true + :symbolSize (fn [[_ pv]] (+ 2 (.round js/Math (/ pv 100)))) + :data (map (fn [{:keys [visit-day pv]}] + [(js/Date. visit-day) pv]) + daily-visits)}]}] + (.setOption chart (clj->js opts)))) + init-component (fn [this] + (render-chart (r/dom-node this) (second (r/argv this))))] + (r/create-class + {:display-name "pv-trend" + :reagent-render (fn [] [:div {:style {:width chart-width :height 400}}]) + :component-did-mount init-component + :component-did-update init-component}))) + +(defn pie-chart + [_] + (let [render-chart (fn [div items] + (let [chart (.init js/echarts div) + opts {:tooltip {:trigger "item" + :formatter "{b} : {c} ({d}%)"} + :legend {:orient "vertical" :x "left" :data (map :name items)} + :toolbox {:show true + :feature {:magicType {:show true :type ["pie" "funnel"] + :option {:funnel {:x "25%" :width "50%" :funnelAlign "left" :max 1548}}} + :dataView {:show true} + :restore {:show true} + :saveAsImage {:show true}}} + :calculable true + :series [{:type "pie" :radius "75%" :center ["50%" "60%"] + :data items}]}] + (.setOption chart (clj->js opts)))) + init-component (fn [this] + (render-chart (r/dom-node this) (second (r/argv this))))] + (r/create-class + {:display-name "visit-percentage" + :reagent-render (fn [] [:div {:style {:width chart-width :height 400}}]) + :component-did-mount init-component + :component-did-update init-component}))) + +(defn stat-tab [] + [ant/layout-content + [ant/card {:title "Page Views"} + [ant/row {:type "flex" :justify "center"} + [ant/col + [pv-trend @(rf/subscribe [:pv-trend])]]]] + + (r/with-let [group-key (r/atom "title") + top-n (r/atom 10)] + [ant/card {:title (r/as-element [:div "TOP " [ant/input-number {:min 5 :max 50 :value @top-n :on-change #(when (number? %) + (reset! top-n %))}] "Websites"]) + :extra (r/as-element + [:div "Group by: " + [ant/radio-group {:default-value @group-key + :on-change (fn [evt] (reset! group-key (goog.object/getValueByKeys evt "target" "value")))} + [ant/radio {:value "title"} "Title"] + [ant/radio {:value "domain"} "Domain"]]])} + [ant/row {:type "flex" :justify "center"} + [ant/col [pie-chart @(rf/subscribe [:topn-percentage (keyword @group-key) @top-n])]]] + ]) + [ant/card {:title "URL Schemes"} + [ant/row {:type "flex" :justify "center"} + [ant/col [pie-chart @(rf/subscribe [:scheme-percentage])]]]]]) diff --git a/assets/css/bootstrap.min.css b/legacy-js-src/assets/css/bootstrap.min.css similarity index 100% rename from assets/css/bootstrap.min.css rename to legacy-js-src/assets/css/bootstrap.min.css diff --git a/assets/css/daterangepicker.css b/legacy-js-src/assets/css/daterangepicker.css similarity index 100% rename from assets/css/daterangepicker.css rename to legacy-js-src/assets/css/daterangepicker.css diff --git a/assets/css/nav.css b/legacy-js-src/assets/css/nav.css similarity index 100% rename from assets/css/nav.css rename to legacy-js-src/assets/css/nav.css diff --git a/assets/details.html b/legacy-js-src/assets/details.html similarity index 100% rename from assets/details.html rename to legacy-js-src/assets/details.html diff --git a/assets/fonts/glyphicons-halflings-regular.ttf b/legacy-js-src/assets/fonts/glyphicons-halflings-regular.ttf similarity index 100% rename from assets/fonts/glyphicons-halflings-regular.ttf rename to legacy-js-src/assets/fonts/glyphicons-halflings-regular.ttf diff --git a/assets/fonts/glyphicons-halflings-regular.woff b/legacy-js-src/assets/fonts/glyphicons-halflings-regular.woff similarity index 100% rename from assets/fonts/glyphicons-halflings-regular.woff rename to legacy-js-src/assets/fonts/glyphicons-halflings-regular.woff diff --git a/assets/fonts/glyphicons-halflings-regular.woff2 b/legacy-js-src/assets/fonts/glyphicons-halflings-regular.woff2 similarity index 100% rename from assets/fonts/glyphicons-halflings-regular.woff2 rename to legacy-js-src/assets/fonts/glyphicons-halflings-regular.woff2 diff --git a/legacy-js-src/assets/img/128.png b/legacy-js-src/assets/img/128.png new file mode 100644 index 0000000..7caeaa1 Binary files /dev/null and b/legacy-js-src/assets/img/128.png differ diff --git a/legacy-js-src/assets/img/16.png b/legacy-js-src/assets/img/16.png new file mode 100644 index 0000000..046a7bd Binary files /dev/null and b/legacy-js-src/assets/img/16.png differ diff --git a/legacy-js-src/assets/img/32.png b/legacy-js-src/assets/img/32.png new file mode 100644 index 0000000..69e1a39 Binary files /dev/null and b/legacy-js-src/assets/img/32.png differ diff --git a/legacy-js-src/assets/img/64.png b/legacy-js-src/assets/img/64.png new file mode 100644 index 0000000..a769a22 Binary files /dev/null and b/legacy-js-src/assets/img/64.png differ diff --git a/assets/index.html b/legacy-js-src/assets/index.html similarity index 100% rename from assets/index.html rename to legacy-js-src/assets/index.html diff --git a/assets/js/bootstrap.min.js b/legacy-js-src/assets/js/bootstrap.min.js similarity index 100% rename from assets/js/bootstrap.min.js rename to legacy-js-src/assets/js/bootstrap.min.js diff --git a/assets/js/chart/bar.js b/legacy-js-src/assets/js/chart/bar.js similarity index 100% rename from assets/js/chart/bar.js rename to legacy-js-src/assets/js/chart/bar.js diff --git a/assets/js/chart/chord.js b/legacy-js-src/assets/js/chart/chord.js similarity index 100% rename from assets/js/chart/chord.js rename to legacy-js-src/assets/js/chart/chord.js diff --git a/assets/js/chart/eventRiver.js b/legacy-js-src/assets/js/chart/eventRiver.js similarity index 100% rename from assets/js/chart/eventRiver.js rename to legacy-js-src/assets/js/chart/eventRiver.js diff --git a/assets/js/chart/force.js b/legacy-js-src/assets/js/chart/force.js similarity index 100% rename from assets/js/chart/force.js rename to legacy-js-src/assets/js/chart/force.js diff --git a/assets/js/chart/funnel.js b/legacy-js-src/assets/js/chart/funnel.js similarity index 100% rename from assets/js/chart/funnel.js rename to legacy-js-src/assets/js/chart/funnel.js diff --git a/assets/js/chart/gauge.js b/legacy-js-src/assets/js/chart/gauge.js similarity index 100% rename from assets/js/chart/gauge.js rename to legacy-js-src/assets/js/chart/gauge.js diff --git a/assets/js/chart/heatmap.js b/legacy-js-src/assets/js/chart/heatmap.js similarity index 100% rename from assets/js/chart/heatmap.js rename to legacy-js-src/assets/js/chart/heatmap.js diff --git a/assets/js/chart/k.js b/legacy-js-src/assets/js/chart/k.js similarity index 100% rename from assets/js/chart/k.js rename to legacy-js-src/assets/js/chart/k.js diff --git a/assets/js/chart/line.js b/legacy-js-src/assets/js/chart/line.js similarity index 100% rename from assets/js/chart/line.js rename to legacy-js-src/assets/js/chart/line.js diff --git a/assets/js/chart/map.js b/legacy-js-src/assets/js/chart/map.js similarity index 100% rename from assets/js/chart/map.js rename to legacy-js-src/assets/js/chart/map.js diff --git a/assets/js/chart/pie.js b/legacy-js-src/assets/js/chart/pie.js similarity index 100% rename from assets/js/chart/pie.js rename to legacy-js-src/assets/js/chart/pie.js diff --git a/assets/js/chart/radar.js b/legacy-js-src/assets/js/chart/radar.js similarity index 100% rename from assets/js/chart/radar.js rename to legacy-js-src/assets/js/chart/radar.js diff --git a/assets/js/chart/scatter.js b/legacy-js-src/assets/js/chart/scatter.js similarity index 100% rename from assets/js/chart/scatter.js rename to legacy-js-src/assets/js/chart/scatter.js diff --git a/assets/js/chart/tree.js b/legacy-js-src/assets/js/chart/tree.js similarity index 100% rename from assets/js/chart/tree.js rename to legacy-js-src/assets/js/chart/tree.js diff --git a/assets/js/chart/treemap.js b/legacy-js-src/assets/js/chart/treemap.js similarity index 100% rename from assets/js/chart/treemap.js rename to legacy-js-src/assets/js/chart/treemap.js diff --git a/assets/js/chart/venn.js b/legacy-js-src/assets/js/chart/venn.js similarity index 100% rename from assets/js/chart/venn.js rename to legacy-js-src/assets/js/chart/venn.js diff --git a/assets/js/chart/wordCloud.js b/legacy-js-src/assets/js/chart/wordCloud.js similarity index 100% rename from assets/js/chart/wordCloud.js rename to legacy-js-src/assets/js/chart/wordCloud.js diff --git a/assets/js/daterangepicker.js b/legacy-js-src/assets/js/daterangepicker.js similarity index 100% rename from assets/js/daterangepicker.js rename to legacy-js-src/assets/js/daterangepicker.js diff --git a/assets/js/details.js b/legacy-js-src/assets/js/details.js similarity index 100% rename from assets/js/details.js rename to legacy-js-src/assets/js/details.js diff --git a/assets/js/echarts.js b/legacy-js-src/assets/js/echarts.js similarity index 100% rename from assets/js/echarts.js rename to legacy-js-src/assets/js/echarts.js diff --git a/assets/js/jquery-1.11.3.min.js b/legacy-js-src/assets/js/jquery-1.11.3.min.js similarity index 100% rename from assets/js/jquery-1.11.3.min.js rename to legacy-js-src/assets/js/jquery-1.11.3.min.js diff --git a/assets/js/main.js b/legacy-js-src/assets/js/main.js similarity index 100% rename from assets/js/main.js rename to legacy-js-src/assets/js/main.js diff --git a/assets/js/moment.min.js b/legacy-js-src/assets/js/moment.min.js similarity index 100% rename from assets/js/moment.min.js rename to legacy-js-src/assets/js/moment.min.js diff --git a/assets/js/underscore-min.js b/legacy-js-src/assets/js/underscore-min.js similarity index 100% rename from assets/js/underscore-min.js rename to legacy-js-src/assets/js/underscore-min.js diff --git a/assets/js/util.js b/legacy-js-src/assets/js/util.js similarity index 100% rename from assets/js/util.js rename to legacy-js-src/assets/js/util.js diff --git a/background.js b/legacy-js-src/background.js similarity index 100% rename from background.js rename to legacy-js-src/background.js diff --git a/manifest.json b/legacy-js-src/manifest.json similarity index 100% rename from manifest.json rename to legacy-js-src/manifest.json diff --git a/package.sh b/legacy-js-src/package.sh similarity index 100% rename from package.sh rename to legacy-js-src/package.sh diff --git a/screenshots/activity.jpg b/screenshots/activity.jpg new file mode 100644 index 0000000..905de42 Binary files /dev/null and b/screenshots/activity.jpg differ diff --git a/screenshots/pv.png b/screenshots/pv.png new file mode 100644 index 0000000..edeb310 Binary files /dev/null and b/screenshots/pv.png differ diff --git a/screenshots/url_scheme.png b/screenshots/url_scheme.png new file mode 100644 index 0000000..f8f336f Binary files /dev/null and b/screenshots/url_scheme.png differ