Merge remote-tracking branch 'atom/master'
This commit is contained in:
commit
ad24c11f32
171 changed files with 4032 additions and 968 deletions
68
docs/README-es.md
Normal file
68
docs/README-es.md
Normal file
|
@ -0,0 +1,68 @@
|
|||
## Guías
|
||||
|
||||
* [Distribución de aplicaciones](tutorial/application-distribution-es.md)
|
||||
* [Empaquetamiento de aplicaciones](tutorial/application-packaging-es.md)
|
||||
* [Utilizando módulos nativos](tutorial/using-native-node-modules-es.md)
|
||||
* [Depurando el proceso principal](tutorial/debugging-main-process-es.md)
|
||||
* [Utilizando Selenium y WebDriver](tutorial/using-selenium-and-webdriver-es.md)
|
||||
* [Extensión DevTools](tutorial/devtools-extension-es.md)
|
||||
* [Utilizando el plugin pepper flash](tutorial/using-pepper-flash-plugin-es.md)
|
||||
|
||||
## Tutoriales
|
||||
|
||||
* [Introducción](tutorial/quick-start.md)
|
||||
* [Integración con el entorno de escritorio](tutorial/desktop-environment-integration.md)
|
||||
* [Detección del evento en línea/fuera de línea](tutorial/online-offline-events.md)
|
||||
|
||||
## API
|
||||
|
||||
* [Sinopsis](api/synopsis.md)
|
||||
* [Proceso](api/process.md)
|
||||
* [Parámetros CLI soportados (Chrome)](api/chrome-command-line-switches.md)
|
||||
|
||||
Elementos DOM customizados:
|
||||
|
||||
* [Objeto `File`](api/file-object.md)
|
||||
* [Etiqueta `<webview>`](api/web-view-tag.md)
|
||||
* [Función `window.open`](api/window-open.md)
|
||||
|
||||
Módulos del proceso principal:
|
||||
|
||||
* [app](api/app.md)
|
||||
* [auto-updater](api/auto-updater.md)
|
||||
* [browser-window](api/browser-window.md)
|
||||
* [content-tracing](api/content-tracing.md)
|
||||
* [dialog](api/dialog.md)
|
||||
* [global-shortcut](api/global-shortcut.md)
|
||||
* [ipc (main process)](api/ipc-main-process.md)
|
||||
* [menu](api/menu.md)
|
||||
* [menu-item](api/menu-item.md)
|
||||
* [power-monitor](api/power-monitor.md)
|
||||
* [power-save-blocker](api/power-save-blocker.md)
|
||||
* [protocol](api/protocol.md)
|
||||
* [tray](api/tray.md)
|
||||
|
||||
Módulos del renderer (página web):
|
||||
|
||||
* [ipc (renderer)](api/ipc-renderer.md)
|
||||
* [remote](api/remote.md)
|
||||
* [web-frame](api/web-frame.md)
|
||||
|
||||
Módulos de ambos procesos:
|
||||
|
||||
* [clipboard](api/clipboard.md)
|
||||
* [crash-reporter](api/crash-reporter.md)
|
||||
* [native-image](api/native-image.md)
|
||||
* [screen](api/screen.md)
|
||||
* [shell](api/shell.md)
|
||||
|
||||
## Desarrollo
|
||||
|
||||
* [Guía de estilo](development/coding-style.md)
|
||||
* [Estructura de directorio](development/source-code-directory-structure.md)
|
||||
* [Diferencias técnicas con NW.js (anteriormente conocido como node-webkit)](development/atom-shell-vs-node-webkit.md)
|
||||
* [Sistema de compilación](development/build-system-overview.md)
|
||||
* [Instrucciones de compilación (Mac)](development/build-instructions-mac.md)
|
||||
* [Instrucciones de compilación (Windows)](development/build-instructions-windows.md)
|
||||
* [Instrucciones de compilación (Linux)](development/build-instructions-linux.md)
|
||||
* [Configurando un servidor de símbolos en el depurador](development/setting-up-symbol-server.md)
|
|
@ -1,6 +1,6 @@
|
|||
# Accelerator
|
||||
|
||||
An accelerator is string that represents a keyboard shortcut, it can contain
|
||||
An accelerator is a string that represents a keyboard shortcut. It can contain
|
||||
multiple modifiers and key codes, combined by the `+` character.
|
||||
|
||||
Examples:
|
||||
|
@ -10,7 +10,7 @@ Examples:
|
|||
|
||||
## Platform notice
|
||||
|
||||
On Linux and Windows, the `Command` key would not have any effect, you can
|
||||
On Linux and Windows, the `Command` key does not have any effect so
|
||||
use `CommandOrControl` which represents `Command` on OS X and `Control` on
|
||||
Linux and Windows to define some accelerators.
|
||||
|
||||
|
|
148
docs/api/app.md
148
docs/api/app.md
|
@ -1,8 +1,8 @@
|
|||
# app
|
||||
|
||||
The `app` module is responsible for controlling the application's life time.
|
||||
The `app` module is responsible for controlling the application's lifecycle.
|
||||
|
||||
The example of quitting the whole application when the last window is closed:
|
||||
The following example shows how to quit the application when the last window is closed:
|
||||
|
||||
```javascript
|
||||
var app = require('app');
|
||||
|
@ -13,26 +13,26 @@ app.on('window-all-closed', function() {
|
|||
|
||||
## Event: will-finish-launching
|
||||
|
||||
Emitted when application has done basic startup. On Windows and Linux it is the
|
||||
same with `ready` event, on OS X this event represents the
|
||||
`applicationWillFinishLaunching` message of `NSApplication`, usually you would
|
||||
setup listeners to `open-file` and `open-url` events here, and start the crash
|
||||
reporter and auto updater.
|
||||
Emitted when the application has finished basic startup. On Windows and Linux,
|
||||
the `will-finish-launching` event is the same as the `ready` event; on OS X,
|
||||
this event represents the `applicationWillFinishLaunching` notification of `NSApplication`.
|
||||
You would usually set up listeners for the `open-file` and `open-url` events here,
|
||||
and start the crash reporter and auto updater.
|
||||
|
||||
Under most cases you should just do everything in `ready` event.
|
||||
In most cases, you should just do everything in the `ready` event handler.
|
||||
|
||||
## Event: ready
|
||||
|
||||
Emitted when Electron has done everything initialization.
|
||||
Emitted when Electron has finished initialization.
|
||||
|
||||
## Event: window-all-closed
|
||||
|
||||
Emitted when all windows have been closed.
|
||||
|
||||
This event is only emitted when the application is not going to quit. If a
|
||||
This event is only emitted when the application is not going to quit. If the
|
||||
user pressed `Cmd + Q`, or the developer called `app.quit()`, Electron would
|
||||
first try to close all windows and then emit the `will-quit` event, and in
|
||||
this case the `window-all-closed` would not be emitted.
|
||||
first try to close all the windows and then emit the `will-quit` event, and in
|
||||
this case the `window-all-closed` event would not be emitted.
|
||||
|
||||
## Event: before-quit
|
||||
|
||||
|
@ -50,23 +50,23 @@ Emitted when all windows have been closed and the application will quit.
|
|||
Calling `event.preventDefault()` will prevent the default behaviour, which is
|
||||
terminating the application.
|
||||
|
||||
See description of `window-all-closed` for the differences between `will-quit`
|
||||
and it.
|
||||
See the description of the `window-all-closed` event for the differences between the `will-quit`
|
||||
and `window-all-closed` events.
|
||||
|
||||
## Event: quit
|
||||
|
||||
Emitted when application is quitting.
|
||||
Emitted when the application is quitting.
|
||||
|
||||
## Event: open-file
|
||||
|
||||
* `event` Event
|
||||
* `path` String
|
||||
|
||||
Emitted when user wants to open a file with the application, it usually happens
|
||||
when the application is already opened and then OS wants to reuse the
|
||||
application to open file. But it is also emitted when a file is dropped onto the
|
||||
dock and the application is not yet running. Make sure to listen to open-file
|
||||
very early in your application startup to handle this case (even before the
|
||||
Emitted when the user wants to open a file with the application. The `open-file` event
|
||||
is usually emitted when the application is already open and the OS wants to reuse the
|
||||
application to open the file. `open-file` is also emitted when a file is dropped onto the
|
||||
dock and the application is not yet running. Make sure to listen for the `open-file`
|
||||
event very early in your application startup to handle this case (even before the
|
||||
`ready` event is emitted).
|
||||
|
||||
You should call `event.preventDefault()` if you want to handle this event.
|
||||
|
@ -76,16 +76,16 @@ You should call `event.preventDefault()` if you want to handle this event.
|
|||
* `event` Event
|
||||
* `url` String
|
||||
|
||||
Emitted when user wants to open a URL with the application, this URL scheme
|
||||
Emitted when the user wants to open a URL with the application. The URL scheme
|
||||
must be registered to be opened by your application.
|
||||
|
||||
You should call `event.preventDefault()` if you want to handle this event.
|
||||
|
||||
## Event: activate-with-no-open-windows
|
||||
|
||||
Emitted when the application is activated while there is no opened windows. It
|
||||
usually happens when user has closed all of application's windows and then
|
||||
click on the application's dock icon.
|
||||
Emitted when the application is activated while there are no open windows, which
|
||||
usually happens when the user has closed all of the application's windows and then
|
||||
clicks on the application's dock icon.
|
||||
|
||||
## Event: browser-window-blur
|
||||
|
||||
|
@ -103,7 +103,7 @@ Emitted when a [browserWindow](browser-window.md) gets focused.
|
|||
|
||||
### Event: 'select-certificate'
|
||||
|
||||
Emitted when client certificate is requested.
|
||||
Emitted when a client certificate is requested.
|
||||
|
||||
* `event` Event
|
||||
* `webContents` [WebContents](browser-window.md#class-webcontents)
|
||||
|
@ -120,24 +120,24 @@ app.on('select-certificate', function(event, host, url, list, callback) {
|
|||
})
|
||||
```
|
||||
|
||||
`url` corresponds to the navigation entry requesting the client certificate,
|
||||
`url` corresponds to the navigation entry requesting the client certificate.
|
||||
`callback` needs to be called with an entry filtered from the list.
|
||||
`event.preventDefault()` prevents from using the first certificate from
|
||||
the store.
|
||||
`event.preventDefault()` prevents the application from using the first certificate
|
||||
from the store.
|
||||
|
||||
### Event: 'gpu-process-crashed'
|
||||
|
||||
Emitted when the gpu process is crashed.
|
||||
Emitted when the gpu process crashes.
|
||||
|
||||
## app.quit()
|
||||
|
||||
Try to close all windows. The `before-quit` event will first be emitted. If all
|
||||
windows are successfully closed, the `will-quit` event will be emitted and by
|
||||
default the application would be terminated.
|
||||
default the application will terminate.
|
||||
|
||||
This method guarantees all `beforeunload` and `unload` handlers are correctly
|
||||
This method guarantees that all `beforeunload` and `unload` event handlers are correctly
|
||||
executed. It is possible that a window cancels the quitting by returning
|
||||
`false` in `beforeunload` handler.
|
||||
`false` in the `beforeunload` event handler.
|
||||
|
||||
## app.getAppPath()
|
||||
|
||||
|
@ -148,19 +148,19 @@ Returns the current application directory.
|
|||
* `name` String
|
||||
|
||||
Retrieves a path to a special directory or file associated with `name`. On
|
||||
failure an `Error` would throw.
|
||||
failure an `Error` is thrown.
|
||||
|
||||
You can request following paths by the names:
|
||||
You can request the following paths by the name:
|
||||
|
||||
* `home`: User's home directory
|
||||
* `appData`: Per-user application data directory, by default it is pointed to:
|
||||
* `appData`: Per-user application data directory, which by default points to:
|
||||
* `%APPDATA%` on Windows
|
||||
* `$XDG_CONFIG_HOME` or `~/.config` on Linux
|
||||
* `~/Library/Application Support` on OS X
|
||||
* `userData`: The directory for storing your app's configuration files, by
|
||||
* `userData`: The directory for storing your app's configuration files, which by
|
||||
default it is the `appData` directory appended with your app's name
|
||||
* `cache`: Per-user application cache directory, by default it is pointed to:
|
||||
* `%APPDATA%` on Window, which doesn't has a universal place for cache
|
||||
* `cache`: Per-user application cache directory, which by default points to:
|
||||
* `%APPDATA%` on Windows (which doesn't have a universal cache location)
|
||||
* `$XDG_CACHE_HOME` or `~/.cache` on Linux
|
||||
* `~/Library/Caches` on OS X
|
||||
* `userCache`: The directory for placing your app's caches, by default it is the
|
||||
|
@ -175,30 +175,30 @@ You can request following paths by the names:
|
|||
* `name` String
|
||||
* `path` String
|
||||
|
||||
Overrides the `path` to a special directory or file associated with `name`. if
|
||||
Overrides the `path` to a special directory or file associated with `name`. If
|
||||
the path specifies a directory that does not exist, the directory will be
|
||||
created by this method. On failure an `Error` would throw.
|
||||
created by this method. On failure an `Error` is thrown.
|
||||
|
||||
You can only override paths of `name`s defined in `app.getPath`.
|
||||
|
||||
By default web pages' cookies and caches will be stored under `userData`
|
||||
directory, if you want to change this location, you have to override the
|
||||
`userData` path before the `ready` event of `app` module gets emitted.
|
||||
By default, web pages' cookies and caches will be stored under the `userData`
|
||||
directory. If you want to change this location, you have to override the
|
||||
`userData` path before the `ready` event of the `app` module is emitted.
|
||||
|
||||
## app.getVersion()
|
||||
|
||||
Returns the version of loaded application, if no version is found in
|
||||
application's `package.json`, the version of current bundle or executable would
|
||||
be returned.
|
||||
Returns the version of the loaded application. If no version is found in the
|
||||
application's `package.json` file, the version of the current bundle or executable is
|
||||
returned.
|
||||
|
||||
## app.getName()
|
||||
|
||||
Returns current application's name, the name in `package.json` would be
|
||||
used.
|
||||
Returns the current application's name, which is the name in the application's
|
||||
`package.json` file.
|
||||
|
||||
Usually the `name` field of `package.json` is a short lowercased name, according
|
||||
to the spec of npm modules. So usually you should also specify a `productName`
|
||||
field, which is your application's full capitalized name, and it will be
|
||||
to the npm modules spec. You should usually also specify a `productName`
|
||||
field, which is your application's full capitalized name, and which will be
|
||||
preferred over `name` by Electron.
|
||||
|
||||
## app.resolveProxy(url, callback)
|
||||
|
@ -206,17 +206,17 @@ preferred over `name` by Electron.
|
|||
* `url` URL
|
||||
* `callback` Function
|
||||
|
||||
Resolves the proxy information for `url`, the `callback` would be called with
|
||||
`callback(proxy)` when the request is done.
|
||||
Resolves the proxy information for `url`. The `callback` will be called with
|
||||
`callback(proxy)` when the request is performed.
|
||||
|
||||
## app.addRecentDocument(path)
|
||||
|
||||
* `path` String
|
||||
|
||||
Adds `path` to recent documents list.
|
||||
Adds `path` to the recent documents list.
|
||||
|
||||
This list is managed by the system, on Windows you can visit the list from task
|
||||
bar, and on Mac you can visit it from dock menu.
|
||||
This list is managed by the OS. On Windows you can visit the list from the task
|
||||
bar, and on OS X you can visit it from dock menu.
|
||||
|
||||
## app.clearRecentDocuments()
|
||||
|
||||
|
@ -226,20 +226,20 @@ Clears the recent documents list.
|
|||
|
||||
* `tasks` Array - Array of `Task` objects
|
||||
|
||||
Adds `tasks` to the [Tasks][tasks] category of JumpList on Windows.
|
||||
Adds `tasks` to the [Tasks][tasks] category of the JumpList on Windows.
|
||||
|
||||
The `tasks` is an array of `Task` objects in following format:
|
||||
`tasks` is an array of `Task` objects in following format:
|
||||
|
||||
* `Task` Object
|
||||
* `program` String - Path of the program to execute, usually you should
|
||||
specify `process.execPath` which opens current program
|
||||
* `arguments` String - The arguments of command line when `program` is
|
||||
specify `process.execPath` which opens the current program
|
||||
* `arguments` String - The command line arguments when `program` is
|
||||
executed
|
||||
* `title` String - The string to be displayed in a JumpList
|
||||
* `description` String - Description of this task
|
||||
* `iconPath` String - The absolute path to an icon to be displayed in a
|
||||
JumpList, it can be arbitrary resource file that contains an icon, usually
|
||||
you can specify `process.execPath` to show the icon of the program
|
||||
JumpList, which can be an arbitrary resource file that contains an icon. You can
|
||||
usually specify `process.execPath` to show the icon of the program
|
||||
* `iconIndex` Integer - The icon index in the icon file. If an icon file
|
||||
consists of two or more icons, set this value to identify the icon. If an
|
||||
icon file consists of one icon, this value is 0
|
||||
|
@ -255,25 +255,25 @@ to control some low-level Chromium behaviors.
|
|||
|
||||
## app.commandLine.appendArgument(value)
|
||||
|
||||
Append an argument to Chromium's command line. The argument will quoted properly.
|
||||
Append an argument to Chromium's command line. The argument will be quoted correctly.
|
||||
|
||||
**Note:** This will not affect `process.argv`.
|
||||
|
||||
## app.dock.bounce([type])
|
||||
|
||||
* `type` String - Can be `critical` or `informational`, the default is
|
||||
* `type` String - Can be `critical` or `informational`. The default is
|
||||
`informational`
|
||||
|
||||
When `critical` is passed, the dock icon will bounce until either the
|
||||
application becomes active or the request is canceled.
|
||||
|
||||
When `informational` is passed, the dock icon will bounce for one second. The
|
||||
request, though, remains active until either the application becomes active or
|
||||
When `informational` is passed, the dock icon will bounce for one second. However,
|
||||
the request remains active until either the application becomes active or
|
||||
the request is canceled.
|
||||
|
||||
An ID representing the request would be returned.
|
||||
An ID representing the request is returned.
|
||||
|
||||
**Note:** This API is only available on Mac.
|
||||
**Note:** This API is only available on OS X.
|
||||
|
||||
## app.dock.cancelBounce(id)
|
||||
|
||||
|
@ -281,7 +281,7 @@ An ID representing the request would be returned.
|
|||
|
||||
Cancel the bounce of `id`.
|
||||
|
||||
**Note:** This API is only available on Mac.
|
||||
**Note:** This API is only available on OS X.
|
||||
|
||||
## app.dock.setBadge(text)
|
||||
|
||||
|
@ -289,33 +289,33 @@ Cancel the bounce of `id`.
|
|||
|
||||
Sets the string to be displayed in the dock’s badging area.
|
||||
|
||||
**Note:** This API is only available on Mac.
|
||||
**Note:** This API is only available on OS X.
|
||||
|
||||
## app.dock.getBadge()
|
||||
|
||||
Returns the badge string of the dock.
|
||||
|
||||
**Note:** This API is only available on Mac.
|
||||
**Note:** This API is only available on OS X.
|
||||
|
||||
## app.dock.hide()
|
||||
|
||||
Hides the dock icon.
|
||||
|
||||
**Note:** This API is only available on Mac.
|
||||
**Note:** This API is only available on OS X.
|
||||
|
||||
## app.dock.show()
|
||||
|
||||
Shows the dock icon.
|
||||
|
||||
**Note:** This API is only available on Mac.
|
||||
**Note:** This API is only available on OS X.
|
||||
|
||||
## app.dock.setMenu(menu)
|
||||
|
||||
* `menu` Menu
|
||||
|
||||
Sets the application [dock menu][dock-menu].
|
||||
Sets the application's [dock menu][dock-menu].
|
||||
|
||||
**Note:** This API is only available on Mac.
|
||||
**Note:** This API is only available on OS X.
|
||||
|
||||
[dock-menu]:https://developer.apple.com/library/mac/documentation/Carbon/Conceptual/customizing_docktile/concepts/dockconcepts.html#//apple_ref/doc/uid/TP30000986-CH2-TPXREF103
|
||||
[tasks]:http://msdn.microsoft.com/en-us/library/windows/desktop/dd378460(v=vs.85).aspx#tasks
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
**This module has only been implemented for OS X.**
|
||||
|
||||
Check out [atom/grunt-electron-installer](https://github.com/atom/grunt-electron-installer)
|
||||
for building a Windows installer for your app.
|
||||
to build a Windows installer for your app.
|
||||
|
||||
The `auto-updater` module is a simple wrap around the
|
||||
The `auto-updater` module is a simple wrapper around the
|
||||
[Squirrel.Mac](https://github.com/Squirrel/Squirrel.Mac) framework.
|
||||
|
||||
Squirrel.Mac requires that your `.app` folder is signed using the
|
||||
|
@ -26,11 +26,11 @@ body so that your server has the context it needs in order to supply the most
|
|||
suitable update.
|
||||
|
||||
The update JSON Squirrel requests should be dynamically generated based on
|
||||
criteria in the request, and whether an update is required. Squirrel relies
|
||||
on server side support for determining whether an update is required, see
|
||||
criteria in the request and whether an update is required. Squirrel relies
|
||||
on server-side support to determine whether an update is required. See
|
||||
[Server Support](#server-support).
|
||||
|
||||
Squirrel's installer is also designed to be fault tolerant, and ensure that any
|
||||
Squirrel's installer is designed to be fault tolerant and ensures that any
|
||||
updates installed are valid.
|
||||
|
||||
## Update Requests
|
||||
|
@ -40,11 +40,11 @@ update checking. `Accept: application/json` is added to the request headers
|
|||
because Squirrel is responsible for parsing the response.
|
||||
|
||||
For the requirements imposed on the responses and the body format of an update
|
||||
response see [Server Support](#server-support).
|
||||
response, see [Server Support](#server-support).
|
||||
|
||||
Your update request must *at least* include a version identifier so that the
|
||||
server can determine whether an update for this specific version is required. It
|
||||
may also include other identifying criteria such as operating system version or
|
||||
may also include other identifying criteria, such as operating system version or
|
||||
username, to allow the server to deliver as fine grained an update as you
|
||||
would like.
|
||||
|
||||
|
@ -64,7 +64,7 @@ autoUpdater.setFeedUrl('http://mycompany.com/myapp/latest?version=' + app.getVer
|
|||
Your server should determine whether an update is required based on the
|
||||
[Update Request](#update-requests) your client issues.
|
||||
|
||||
If an update is required your server should respond with a status code of
|
||||
If an update is required, your server should respond with a status code of
|
||||
[200 OK](http://tools.ietf.org/html/rfc2616#section-10.2.1) and include the
|
||||
[update JSON](#update-json-format) in the body. Squirrel **will** download and
|
||||
install this update, even if the version of the update is the same as the
|
||||
|
@ -85,33 +85,33 @@ to the update request provided:
|
|||
"url": "http://mycompany.com/myapp/releases/myrelease",
|
||||
"name": "My Release Name",
|
||||
"notes": "Theses are some release notes innit",
|
||||
"pub_date": "2013-09-18T12:29:53+01:00",
|
||||
"pub_date": "2013-09-18T12:29:53+01:00"
|
||||
}
|
||||
```
|
||||
|
||||
The only required key is "url", the others are optional.
|
||||
The only required key is "url"; the others are optional.
|
||||
|
||||
Squirrel will request "url" with `Accept: application/zip` and only supports
|
||||
installing ZIP updates. If future update formats are supported their MIME type
|
||||
will be added to the `Accept` header so that your server can return the
|
||||
appropriate format.
|
||||
|
||||
`pub_date` if present must be formatted according to ISO 8601.
|
||||
`pub_date` (if present) must be formatted according to ISO 8601.
|
||||
|
||||
## Event: error
|
||||
|
||||
* `event` Event
|
||||
* `message` String
|
||||
|
||||
Emitted when there is an error updating.
|
||||
Emitted when there is an error while updating.
|
||||
|
||||
## Event: checking-for-update
|
||||
|
||||
Emitted when checking for update has started.
|
||||
Emitted when checking if an update has started.
|
||||
|
||||
## Event: update-available
|
||||
|
||||
Emitted when there is an available update, the update would be downloaded
|
||||
Emitted when there is an available update. The update is downloaded
|
||||
automatically.
|
||||
|
||||
## Event: update-not-available
|
||||
|
@ -127,17 +127,17 @@ Emitted when there is no available update.
|
|||
* `updateUrl` String
|
||||
* `quitAndUpdate` Function
|
||||
|
||||
Emitted when update has been downloaded, calling `quitAndUpdate()` would restart
|
||||
Emitted when an update has been downloaded. Calling `quitAndUpdate()` will restart
|
||||
the application and install the update.
|
||||
|
||||
## autoUpdater.setFeedUrl(url)
|
||||
|
||||
* `url` String
|
||||
|
||||
Set the `url` and initialize the auto updater. The `url` could not be changed
|
||||
Set the `url` and initialize the auto updater. The `url` cannot be changed
|
||||
once it is set.
|
||||
|
||||
## autoUpdater.checkForUpdates()
|
||||
|
||||
Ask the server whether there is an update, you have to call `setFeedUrl` before
|
||||
Ask the server whether there is an update. You must call `setFeedUrl` before
|
||||
using this API.
|
||||
|
|
|
@ -76,7 +76,14 @@ You can also create a window without chrome by using
|
|||
textured window. Defaults to `true`.
|
||||
* `web-preferences` Object - Settings of web page's features
|
||||
* `javascript` Boolean
|
||||
* `web-security` Boolean
|
||||
* `web-security` Boolean - When setting `false`, it will disable the same-origin
|
||||
policy(Usually using testing websites by people), and set `allow_displaying_insecure_content`
|
||||
and `allow_running_insecure_content` to `true` if these two options are not
|
||||
set by user.
|
||||
* `allow-displaying-insecure-content` Boolean - Allow a https page to display
|
||||
content like image from http URLs.
|
||||
* `allow-running-insecure-content` Boolean - Allow a https page to run JavaScript,
|
||||
CSS or plugins from http URLs.
|
||||
* `images` Boolean
|
||||
* `java` Boolean
|
||||
* `text-areas-are-resizable` Boolean
|
||||
|
@ -361,6 +368,19 @@ Sets whether the window should be in fullscreen mode.
|
|||
|
||||
Returns whether the window is in fullscreen mode.
|
||||
|
||||
### BrowserWindow.setAspectRatio(aspectRatio[, extraSize])
|
||||
|
||||
* `aspectRatio` The aspect ratio we want to maintain for some portion of the content view.
|
||||
* `rect` Object - The extra size to not be included in the aspect ratio to be maintained.
|
||||
* `width` Integer
|
||||
* `height` Integer
|
||||
|
||||
This will have a window maintain an aspect ratio. The extra size allows a developer to be able to have space, specifified in pixels, not included within the aspect ratio calculations. This API already takes into account the difference between a window's size and it's content size.
|
||||
|
||||
Consider a normal window with an HD video player and associated controls. Perhaps there are 15 pixels of controls on the left edge, 25 pixels of controls on the right edge and 50 pixels of controls below the player. In order to maintain a 16:9 aspect ratio (standard aspect ratio for HD @1920x1080) within the player itself we would call this function with arguments of 16/9 and [ 40, 50 ]. The second argument doesn't care where the extra width and height are within the content view — only that they exist. Just sum any extra width and height areas you have within the overall content view.
|
||||
|
||||
__Note__: This API is only implemented on OS X.
|
||||
|
||||
### BrowserWindow.setBounds(options)
|
||||
|
||||
* `options` Object
|
||||
|
@ -623,6 +643,39 @@ Sets a 16px overlay onto the current taskbar icon, usually used to convey some s
|
|||
|
||||
__Note:__ This API is only available on Windows (Windows 7 and above)
|
||||
|
||||
|
||||
### BrowserWindow.setThumbarButtons(buttons)
|
||||
|
||||
* `buttons` Array
|
||||
* `button` Object
|
||||
* `icon` [NativeImage](native-image.md) - The icon showing in thumbnail
|
||||
toolbar.
|
||||
* `tooltip` String (optional) - The text of the button's tooltip.
|
||||
* `flags` Array (optional) - Control specific states and behaviors
|
||||
of the button. By default, it uses `enabled`. It can include following
|
||||
Strings:
|
||||
* `enabled` - The button is active and available to the user.
|
||||
* `disabled` - The button is disabled. It is present, but has a visual
|
||||
state that indicates that it will not respond to user action.
|
||||
* `dismissonclick` - When the button is clicked, the taskbar button's
|
||||
flyout closes immediately.
|
||||
* `nobackground` - Do not draw a button border, use only the image.
|
||||
* `hidden` - The button is not shown to the user.
|
||||
* `noninteractive` - The button is enabled but not interactive; no
|
||||
pressed button state is drawn. This value is intended for instances
|
||||
where the button is used in a notification.
|
||||
* `click` - Function
|
||||
|
||||
Add a thumbnail toolbar with a specified set of buttons to the thumbnail image
|
||||
of a window in a taskbar button layout. Returns a `Boolean` object indicates
|
||||
whether the thumbnail has been added successfully.
|
||||
|
||||
__Note:__ This API is only available on Windows (Windows 7 and above).
|
||||
The number of buttons in thumbnail toolbar should be no greater than 7 due to
|
||||
the limited room. Once you setup the thumbnail toolbar, the toolbar cannot be
|
||||
removed due to the platform's limitation. But you can call the API with an empty
|
||||
array to clean the buttons.
|
||||
|
||||
### BrowserWindow.showDefinitionForSelection()
|
||||
|
||||
Shows pop-up dictionary that searches the selected word on the page.
|
||||
|
@ -760,7 +813,7 @@ Calling `event.preventDefault()` can prevent creating new windows.
|
|||
* `event` Event
|
||||
* `url` String
|
||||
|
||||
Emitted when user or the page wants to start an navigation, it can happen when
|
||||
Emitted when user or the page wants to start a navigation, it can happen when
|
||||
`window.location` object is changed or user clicks a link in the page.
|
||||
|
||||
This event will not emit when the navigation is started programmatically with APIs
|
||||
|
@ -875,18 +928,27 @@ Whether the renderer process has crashed.
|
|||
|
||||
Overrides the user agent for this page.
|
||||
|
||||
### WebContents.getUserAgent()
|
||||
|
||||
Returns a `String` represents the user agent for this page.
|
||||
|
||||
### WebContents.insertCSS(css)
|
||||
|
||||
* `css` String
|
||||
|
||||
Injects CSS into this page.
|
||||
|
||||
### WebContents.executeJavaScript(code)
|
||||
### WebContents.executeJavaScript(code[, userGesture])
|
||||
|
||||
* `code` String
|
||||
* `userGesture` Boolean
|
||||
|
||||
Evaluates `code` in page.
|
||||
|
||||
In browser some HTML APIs like `requestFullScreen` can only be invoked if it
|
||||
is started by user gesture, by specifying `userGesture` to `true` developers
|
||||
can ignore this limitation.
|
||||
|
||||
### WebContents.setAudioMuted(muted)
|
||||
|
||||
+ `muted` Boolean
|
||||
|
@ -984,6 +1046,12 @@ size.
|
|||
* 0 - default
|
||||
* 1 - none
|
||||
* 2 - minimum
|
||||
* `pageSize` String - Specify page size of the generated PDF
|
||||
* `A4`
|
||||
* `A3`
|
||||
* `Legal`
|
||||
* `Letter`
|
||||
* `Tabloid`
|
||||
* `printBackground` Boolean - Whether to print CSS backgrounds.
|
||||
* `printSelectionOnly` Boolean - Whether to print selection only.
|
||||
* `landscape` Boolean - `true` for landscape, `false` for portrait.
|
||||
|
@ -1010,14 +1078,27 @@ win.webContents.on("did-finish-load", function() {
|
|||
// Use default printing options
|
||||
win.webContents.printToPDF({}, function(error, data) {
|
||||
if (error) throw error;
|
||||
fs.writeFile(dist, data, function(error) {
|
||||
fs.writeFile("/tmp/print.pdf", data, function(error) {
|
||||
if (err)
|
||||
alert('write pdf file error', error);
|
||||
throw error;
|
||||
console.log("Write PDF successfully.");
|
||||
})
|
||||
})
|
||||
});
|
||||
```
|
||||
|
||||
### WebContents.addWorkSpace(path)
|
||||
|
||||
* `path` String
|
||||
|
||||
Adds the specified path to devtools workspace.
|
||||
|
||||
### WebContents.removeWorkSpace(path)
|
||||
|
||||
* `path` String
|
||||
|
||||
Removes the specified path from devtools workspace.
|
||||
|
||||
### WebContents.send(channel[, args...])
|
||||
|
||||
* `channel` String
|
||||
|
@ -1167,3 +1248,46 @@ Clears the session's HTTP cache.
|
|||
* `callback` Function - Called when operation is done
|
||||
|
||||
Clears the data of web storages.
|
||||
|
||||
### Session.setProxy(config, callback)
|
||||
|
||||
* `config` String
|
||||
* `callback` Function - Called when operation is done
|
||||
|
||||
Parses the `config` indicating which proxies to use for the session.
|
||||
|
||||
```
|
||||
config = scheme-proxies[";"<scheme-proxies>]
|
||||
scheme-proxies = [<url-scheme>"="]<proxy-uri-list>
|
||||
url-scheme = "http" | "https" | "ftp" | "socks"
|
||||
proxy-uri-list = <proxy-uri>[","<proxy-uri-list>]
|
||||
proxy-uri = [<proxy-scheme>"://"]<proxy-host>[":"<proxy-port>]
|
||||
|
||||
For example:
|
||||
"http=foopy:80;ftp=foopy2" -- use HTTP proxy "foopy:80" for http://
|
||||
URLs, and HTTP proxy "foopy2:80" for
|
||||
ftp:// URLs.
|
||||
"foopy:80" -- use HTTP proxy "foopy:80" for all URLs.
|
||||
"foopy:80,bar,direct://" -- use HTTP proxy "foopy:80" for all URLs,
|
||||
failing over to "bar" if "foopy:80" is
|
||||
unavailable, and after that using no
|
||||
proxy.
|
||||
"socks4://foopy" -- use SOCKS v4 proxy "foopy:1080" for all
|
||||
URLs.
|
||||
"http=foopy,socks5://bar.com -- use HTTP proxy "foopy" for http URLs,
|
||||
and fail over to the SOCKS5 proxy
|
||||
"bar.com" if "foopy" is unavailable.
|
||||
"http=foopy,direct:// -- use HTTP proxy "foopy" for http URLs,
|
||||
and use no proxy if "foopy" is
|
||||
unavailable.
|
||||
"http=foopy;socks=foopy2 -- use HTTP proxy "foopy" for http URLs,
|
||||
and use socks4://foopy2 for all other
|
||||
URLs.
|
||||
```
|
||||
|
||||
### Session.setDownloadPath(path)
|
||||
|
||||
* `path` String - The download location
|
||||
|
||||
Sets download saving directory. By default, the download directory will be the
|
||||
`Downloads` under the respective app folder.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# Supported Chrome command line switches
|
||||
|
||||
The following command lines switches in Chrome browser are also supported in
|
||||
Electron, you can use [app.commandLine.appendSwitch][append-switch] to append
|
||||
This page lists the command line switches used by the Chrome browser that are also supported by
|
||||
Electron. You can use [app.commandLine.appendSwitch][append-switch] to append
|
||||
them in your app's main script before the [ready][ready] event of [app][app]
|
||||
module is emitted:
|
||||
|
||||
|
@ -17,11 +17,11 @@ app.on('ready', function() {
|
|||
|
||||
## --client-certificate=`path`
|
||||
|
||||
Sets `path` of client certificate file.
|
||||
Sets the `path` of client certificate file.
|
||||
|
||||
## --ignore-connections-limit=`domains`
|
||||
|
||||
Ignore the connections limit for `domains` list seperated by `,`.
|
||||
Ignore the connections limit for `domains` list separated by `,`.
|
||||
|
||||
## --disable-http-cache
|
||||
|
||||
|
@ -29,11 +29,11 @@ Disables the disk cache for HTTP requests.
|
|||
|
||||
## --remote-debugging-port=`port`
|
||||
|
||||
Enables remote debug over HTTP on the specified `port`.
|
||||
Enables remote debugging over HTTP on the specified `port`.
|
||||
|
||||
## --proxy-server=`address:port`
|
||||
|
||||
Uses a specified proxy server, overrides system settings. This switch only
|
||||
Use a specified proxy server, which overrides the system setting. This switch only
|
||||
affects HTTP and HTTPS requests.
|
||||
|
||||
## --proxy-pac-url=`url`
|
||||
|
@ -42,12 +42,12 @@ Uses the PAC script at the specified `url`.
|
|||
|
||||
## --no-proxy-server
|
||||
|
||||
Don't use a proxy server, always make direct connections. Overrides any other
|
||||
Don't use a proxy server and always make direct connections. Overrides any other
|
||||
proxy server flags that are passed.
|
||||
|
||||
## --host-rules=`rules`
|
||||
|
||||
Comma-separated list of `rules` that control how hostnames are mapped.
|
||||
A comma-separated list of `rules` that control how hostnames are mapped.
|
||||
|
||||
For example:
|
||||
|
||||
|
@ -60,7 +60,7 @@ For example:
|
|||
"www.google.com".
|
||||
|
||||
These mappings apply to the endpoint host in a net request (the TCP connect
|
||||
and host resolver in a direct connection, and the `CONNECT` in an http proxy
|
||||
and host resolver in a direct connection, and the `CONNECT` in an HTTP proxy
|
||||
connection, and the endpoint host in a `SOCKS` proxy connection).
|
||||
|
||||
## --host-resolver-rules=`rules`
|
||||
|
@ -77,15 +77,15 @@ Ignores certificate related errors.
|
|||
|
||||
## --ppapi-flash-path=`path`
|
||||
|
||||
Sets `path` of pepper flash plugin.
|
||||
Sets the `path` of the pepper flash plugin.
|
||||
|
||||
## --ppapi-flash-version=`version`
|
||||
|
||||
Sets `version` of pepper flash plugin.
|
||||
Sets the `version` of the pepper flash plugin.
|
||||
|
||||
## --log-net-log=`path`
|
||||
|
||||
Enables saving net log events and writes them to `path`.
|
||||
Enables net log events to be saved and writes them to `path`.
|
||||
|
||||
## --v=`log_level`
|
||||
|
||||
|
@ -102,7 +102,7 @@ source files `my_module.*` and `foo*.*`.
|
|||
|
||||
Any pattern containing a forward or backward slash will be tested against the
|
||||
whole pathname and not just the module. E.g. `*/foo/bar/*=2` would change the
|
||||
logging level for all code in source files under a `foo/bar` directory.
|
||||
logging level for all code in the source files under a `foo/bar` directory.
|
||||
|
||||
To disable all chromium related logs and only enable your application logs you
|
||||
can do:
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
# clipboard
|
||||
|
||||
The `clipboard` provides methods to do copy/paste operations. An example of
|
||||
writing a string to clipboard:
|
||||
The `clipboard` provides methods to perform copy and paste operations. The following example
|
||||
shows how to write a string to the clipboard:
|
||||
|
||||
```javascript
|
||||
var clipboard = require('clipboard');
|
||||
clipboard.writeText('Example String');
|
||||
```
|
||||
|
||||
On X Window systems, there is also a selection clipboard, to manipulate in it
|
||||
On X Window systems, there is also a selection clipboard. To manipulate it
|
||||
you need to pass `selection` to each method:
|
||||
|
||||
```javascript
|
||||
|
@ -21,46 +21,46 @@ console.log(clipboard.readText('selection'));
|
|||
|
||||
* `type` String
|
||||
|
||||
Returns the content in clipboard as plain text.
|
||||
Returns the content in the clipboard as plain text.
|
||||
|
||||
## clipboard.writeText(text[, type])
|
||||
|
||||
* `text` String
|
||||
* `type` String
|
||||
|
||||
Writes the `text` into clipboard as plain text.
|
||||
Writes the `text` into the clipboard as plain text.
|
||||
|
||||
## clipboard.readHtml([type])
|
||||
|
||||
* `type` String
|
||||
|
||||
Returns the content in clipboard as markup.
|
||||
Returns the content in the clipboard as markup.
|
||||
|
||||
## clipboard.writeHtml(markup[, type])
|
||||
|
||||
* `markup` String
|
||||
* `type` String
|
||||
|
||||
Writes the `markup` into clipboard.
|
||||
Writes `markup` into the clipboard.
|
||||
|
||||
## clipboard.readImage([type])
|
||||
|
||||
* `type` String
|
||||
|
||||
Returns the content in clipboard as [NativeImage](native-image.md).
|
||||
Returns the content in the clipboard as a [NativeImage](native-image.md).
|
||||
|
||||
## clipboard.writeImage(image[, type])
|
||||
|
||||
* `image` [NativeImage](native-image.md)
|
||||
* `type` String
|
||||
|
||||
Writes the `image` into clipboard.
|
||||
Writes `image` into the clipboard.
|
||||
|
||||
## clipboard.clear([type])
|
||||
|
||||
* `type` String
|
||||
|
||||
Clears everything in clipboard.
|
||||
Clears the clipboard.
|
||||
|
||||
## clipboard.availableFormats([type])
|
||||
|
||||
|
@ -71,7 +71,7 @@ Returns an array of supported `format` for the clipboard `type`.
|
|||
* `data` String
|
||||
* `type` String
|
||||
|
||||
Returns whether clipboard supports the format of specified `data`.
|
||||
Returns whether the clipboard supports the format of specified `data`.
|
||||
|
||||
```javascript
|
||||
var clipboard = require('clipboard');
|
||||
|
@ -85,7 +85,7 @@ console.log(clipboard.has('<p>selection</p>'));
|
|||
* `data` String
|
||||
* `type` String
|
||||
|
||||
Reads the `data` in clipboard.
|
||||
Reads `data` from the clipboard.
|
||||
|
||||
**Note:** This API is experimental and could be removed in future.
|
||||
|
||||
|
@ -101,4 +101,4 @@ Reads the `data` in clipboard.
|
|||
var clipboard = require('clipboard');
|
||||
clipboard.write({text: 'test', html: "<b>test</b>"});
|
||||
```
|
||||
Writes the `data` iinto clipboard.
|
||||
Writes `data` into clipboard.
|
||||
|
|
|
@ -28,10 +28,10 @@ are reached.
|
|||
Once all child processes have acked to the `getCategories` request, `callback`
|
||||
is invoked with an array of category groups.
|
||||
|
||||
## tracing.startRecording(categoryFilter, options, callback)
|
||||
## tracing.startRecording(categoryFilter, traceOptions, callback)
|
||||
|
||||
* `categoryFilter` String
|
||||
* `options` Integer
|
||||
* `traceOptions` String
|
||||
* `callback` Function
|
||||
|
||||
Start recording on all processes.
|
||||
|
@ -51,9 +51,23 @@ Examples:
|
|||
* `test_MyTest*,test_OtherStuff`,
|
||||
* `"-excluded_category1,-excluded_category2`
|
||||
|
||||
`options` controls what kind of tracing is enabled, it could be a OR-ed
|
||||
combination of `tracing.DEFAULT_OPTIONS`, `tracing.ENABLE_SYSTRACE`,
|
||||
`tracing.ENABLE_SAMPLING` and `tracing.RECORD_CONTINUOUSLY`.
|
||||
`traceOptions` controls what kind of tracing is enabled, it is a comma-delimited list.
|
||||
Possible options are:
|
||||
|
||||
* `record-until-full`
|
||||
* `record-continuously`
|
||||
* `trace-to-console`
|
||||
* `enable-sampling`
|
||||
* `enable-systrace`
|
||||
|
||||
The first 3 options are trace recoding modes and hence mutually exclusive.
|
||||
If more than one trace recording modes appear in the `traceOptions` string,
|
||||
the last one takes precedence. If none of the trace recording mode is specified,
|
||||
recording mode is `record-until-full`.
|
||||
|
||||
The trace option will first be reset to the default option (record_mode set to
|
||||
`record-until-full`, enable_sampling and enable_systrace set to false)
|
||||
before options parsed from `traceOptions` are applied on it.
|
||||
|
||||
## tracing.stopRecording(resultFilePath, callback)
|
||||
|
||||
|
@ -75,10 +89,10 @@ Trace data will be written into `resultFilePath` if it is not empty, or into a
|
|||
temporary file. The actual file path will be passed to `callback` if it's not
|
||||
null.
|
||||
|
||||
## tracing.startMonitoring(categoryFilter, options, callback)
|
||||
## tracing.startMonitoring(categoryFilter, traceOptions, callback)
|
||||
|
||||
* `categoryFilter` String
|
||||
* `options` Integer
|
||||
* `traceOptions` String
|
||||
* `callback` Function
|
||||
|
||||
Start monitoring on all processes.
|
||||
|
@ -107,7 +121,7 @@ Get the current monitoring traced data.
|
|||
|
||||
Child processes typically are caching trace data and only rarely flush and send
|
||||
trace data back to the main process. That is because it may be an expensive
|
||||
operation to send the trace data over IPC, and we would like to avoid unneeded
|
||||
operation to send the trace data over IPC, and we would like to avoid unneeded
|
||||
runtime overhead of tracing. So, to end tracing, we must asynchronously ask all
|
||||
child processes to flush any pending trace data.
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# crash-reporter
|
||||
|
||||
An example of automatically submitting crash reporters to a remote server:
|
||||
The following is an example of automatically submitting a crash report to a remote server:
|
||||
|
||||
```javascript
|
||||
crashReporter = require('crash-reporter');
|
||||
|
@ -18,31 +18,30 @@ crashReporter.start({
|
|||
* `productName` String, default: Electron
|
||||
* `companyName` String, default: GitHub, Inc
|
||||
* `submitUrl` String, default: http://54.249.141.255:1127/post
|
||||
* URL that crash reports would be sent to as POST
|
||||
* URL that crash reports will be sent to as POST
|
||||
* `autoSubmit` Boolean, default: true
|
||||
* Send the crash report without user interaction
|
||||
* `ignoreSystemCrashHandler` Boolean, default: false
|
||||
* `extra` Object
|
||||
* An object you can define which content will be send along with the report.
|
||||
* An object you can define that will be sent along with the report.
|
||||
* Only string properties are sent correctly.
|
||||
* Nested objects are not supported.
|
||||
|
||||
Developers are required to call this method before using other crashReporter APIs.
|
||||
Developers are required to call this method before using other `crashReporter` APIs.
|
||||
|
||||
|
||||
**Note:** On OS X, electron uses a new `crashpad` client, which is different
|
||||
with the `breakpad` on Windows and Linux. To enable crash collection feature,
|
||||
you are required to call `crashReporter.start` API to initialize `crashpad` in
|
||||
main process and in each renderer process that you wish to collect crash reports.
|
||||
**Note:** On OS X, Electron uses a new `crashpad` client, which is different
|
||||
from `breakpad` on Windows and Linux. To enable the crash collection feature,
|
||||
you are required to call `crashReporter.start` API to initialize `crashpad` in the
|
||||
main process and in each renderer process from which you wish to collect crash reports.
|
||||
|
||||
## crashReporter.getLastCrashReport()
|
||||
|
||||
Returns the date and ID of the last crash report, when there was no crash report
|
||||
sent or the crash reporter is not started, `null` will be returned.
|
||||
Returns the date and ID of the last crash report. If no crash reports have been
|
||||
sent or the crash reporter has not been started, `null` is returned.
|
||||
|
||||
## crashReporter.getUploadedReports()
|
||||
|
||||
Returns all uploaded crash reports, each report contains date and uploaded ID.
|
||||
Returns all uploaded crash reports. Each report contains the date and uploaded ID.
|
||||
|
||||
# crash-reporter payload
|
||||
|
||||
|
@ -54,8 +53,8 @@ The crash reporter will send the following data to the `submitUrl` as `POST`:
|
|||
* `process_type` String - e.g. 'renderer'
|
||||
* `ptime` Number
|
||||
* `_version` String - The version in `package.json`
|
||||
* `_productName` String - The product name in the crashReporter `options` object
|
||||
* `_productName` String - The product name in the `crashReporter` `options` object
|
||||
* `prod` String - Name of the underlying product. In this case Electron
|
||||
* `_companyName` String - The company name in the crashReporter `options` object
|
||||
* `_companyName` String - The company name in the `crashReporter` `options` object
|
||||
* `upload_file_minidump` File - The crashreport as file
|
||||
* All level one properties of the `extra` object in the crashReporter `options` object
|
||||
* All level one properties of the `extra` object in the `crashReporter` `options` object
|
||||
|
|
|
@ -70,7 +70,7 @@ will be passed via `callback(filename)`
|
|||
|
||||
* `browserWindow` BrowserWindow
|
||||
* `options` Object
|
||||
* `type` String - Can be `"none"`, `"info"`, `"error"`, `"question"` or `"warning"`
|
||||
* `type` String - Can be `"none"`, `"info"`, `"error"`, `"question"` or `"warning"`. On Windows, "question" displays the same icon as "info", unless if you set an icon using the "icon" option
|
||||
* `buttons` Array - Array of texts for buttons
|
||||
* `title` String - Title of the message box, some platforms will not show it
|
||||
* `message` String - Content of the message box
|
||||
|
@ -80,7 +80,12 @@ will be passed via `callback(filename)`
|
|||
instead of clicking the buttons of the dialog. By default it is the index
|
||||
of the buttons that have "cancel" or "no" as label, or 0 if there is no such
|
||||
buttons. On OS X and Windows the index of "Cancel" button will always be
|
||||
used as `cancelId`, not matter whether it is already specified.
|
||||
used as `cancelId`, not matter whether it is already specified
|
||||
* `noLink` Boolean - On Windows Electron would try to figure out which ones of
|
||||
the `buttons` are common buttons (like "Cancel" or "Yes"), and show the
|
||||
others as command links in the dialog, this can make the dialog appear in
|
||||
the style of modern Windows apps. If you don't like this behavior, you can
|
||||
specify `noLink` to `true`
|
||||
* `callback` Function
|
||||
|
||||
Shows a message box, it will block until the message box is closed. It returns
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
# global-shortcut
|
||||
|
||||
The `global-shortcut` module can register/unregister a global keyboard shortcut
|
||||
in operating system, so that you can customize the operations for various shortcuts.
|
||||
Note that the shortcut is global, even if the app does not get focused, it will still work.
|
||||
You should not use this module until the ready event of app module gets emitted.
|
||||
with the operating system, so that you can customize the operations for various shortcuts.
|
||||
Note that the shortcut is global; it will work even if the app does not have the keyboard focus.
|
||||
You should not use this module until the `ready` event of the app module is emitted.
|
||||
|
||||
```javascript
|
||||
var app = require('app');
|
||||
|
@ -37,14 +37,14 @@ app.on('will-quit', function() {
|
|||
* `accelerator` [Accelerator](accelerator.md)
|
||||
* `callback` Function
|
||||
|
||||
Registers a global shortcut of `accelerator`, the `callback` would be called when
|
||||
the registered shortcut is pressed by user.
|
||||
Registers a global shortcut of `accelerator`. The `callback` is called when
|
||||
the registered shortcut is pressed by the user.
|
||||
|
||||
## globalShortcut.isRegistered(accelerator)
|
||||
|
||||
* `accelerator` [Accelerator](accelerator.md)
|
||||
|
||||
Returns `true` or `false` depending on if the shortcut `accelerator` is registered.
|
||||
Returns `true` or `false` depending on whether the shortcut `accelerator` is registered.
|
||||
|
||||
## globalShortcut.unregister(accelerator)
|
||||
|
||||
|
|
|
@ -29,6 +29,8 @@ window.addEventListener('contextmenu', function (e) {
|
|||
|
||||
Another example of creating the application menu with the simple template API:
|
||||
|
||||
**Note to Window and Linux users** the `selector` member of each menu item is a Mac-only [Accelerator option](https://github.com/atom/electron/blob/master/docs/api/accelerator.md).
|
||||
|
||||
```html
|
||||
<!-- index.html -->
|
||||
<script>
|
||||
|
@ -54,12 +56,12 @@ var template = [
|
|||
},
|
||||
{
|
||||
label: 'Hide Electron',
|
||||
accelerator: 'Command+H',
|
||||
accelerator: 'CmdOrCtrl+H',
|
||||
selector: 'hide:'
|
||||
},
|
||||
{
|
||||
label: 'Hide Others',
|
||||
accelerator: 'Command+Shift+H',
|
||||
accelerator: 'CmdOrCtrl+Shift+H',
|
||||
selector: 'hideOtherApplications:'
|
||||
},
|
||||
{
|
||||
|
@ -71,7 +73,7 @@ var template = [
|
|||
},
|
||||
{
|
||||
label: 'Quit',
|
||||
accelerator: 'Command+Q',
|
||||
accelerator: 'CmdOrCtrl+Q',
|
||||
selector: 'terminate:'
|
||||
},
|
||||
]
|
||||
|
@ -81,12 +83,12 @@ var template = [
|
|||
submenu: [
|
||||
{
|
||||
label: 'Undo',
|
||||
accelerator: 'Command+Z',
|
||||
accelerator: 'CmdOrCtrl+Z',
|
||||
selector: 'undo:'
|
||||
},
|
||||
{
|
||||
label: 'Redo',
|
||||
accelerator: 'Shift+Command+Z',
|
||||
accelerator: 'Shift+CmdOrCtrl+Z',
|
||||
selector: 'redo:'
|
||||
},
|
||||
{
|
||||
|
@ -94,22 +96,22 @@ var template = [
|
|||
},
|
||||
{
|
||||
label: 'Cut',
|
||||
accelerator: 'Command+X',
|
||||
accelerator: 'CmdOrCtrl+X',
|
||||
selector: 'cut:'
|
||||
},
|
||||
{
|
||||
label: 'Copy',
|
||||
accelerator: 'Command+C',
|
||||
accelerator: 'CmdOrCtrl+C',
|
||||
selector: 'copy:'
|
||||
},
|
||||
{
|
||||
label: 'Paste',
|
||||
accelerator: 'Command+V',
|
||||
accelerator: 'CmdOrCtrl+V',
|
||||
selector: 'paste:'
|
||||
},
|
||||
{
|
||||
label: 'Select All',
|
||||
accelerator: 'Command+A',
|
||||
accelerator: 'CmdOrCtrl+A',
|
||||
selector: 'selectAll:'
|
||||
}
|
||||
]
|
||||
|
@ -119,12 +121,12 @@ var template = [
|
|||
submenu: [
|
||||
{
|
||||
label: 'Reload',
|
||||
accelerator: 'Command+R',
|
||||
accelerator: 'CmdOrCtrl+R',
|
||||
click: function() { remote.getCurrentWindow().reload(); }
|
||||
},
|
||||
{
|
||||
label: 'Toggle DevTools',
|
||||
accelerator: 'Alt+Command+I',
|
||||
accelerator: 'Alt+CmdOrCtrl+I',
|
||||
click: function() { remote.getCurrentWindow().toggleDevTools(); }
|
||||
},
|
||||
]
|
||||
|
@ -134,12 +136,12 @@ var template = [
|
|||
submenu: [
|
||||
{
|
||||
label: 'Minimize',
|
||||
accelerator: 'Command+M',
|
||||
accelerator: 'CmdOrCtrl+M',
|
||||
selector: 'performMiniaturize:'
|
||||
},
|
||||
{
|
||||
label: 'Close',
|
||||
accelerator: 'Command+W',
|
||||
accelerator: 'CmdOrCtrl+W',
|
||||
selector: 'performClose:'
|
||||
},
|
||||
{
|
||||
|
|
|
@ -137,3 +137,7 @@ Returns the size of the image.
|
|||
* `option` Boolean
|
||||
|
||||
Marks the image as template image.
|
||||
|
||||
### NativeImage.isTemplateImage()
|
||||
|
||||
Returns whether the image is a template image.
|
||||
|
|
|
@ -37,6 +37,11 @@ Registers a custom protocol of `scheme`, the `handler` would be called with
|
|||
You need to return a request job in the `handler` to specify which type of
|
||||
response you would like to send.
|
||||
|
||||
By default the scheme is treated like `http:`, which is parsed differently
|
||||
from protocols that follows "generic URI syntax" like `file:`, so you probably
|
||||
want to call `protocol.registerStandardSchemes` to make your scheme treated as
|
||||
standard scheme.
|
||||
|
||||
## protocol.unregisterProtocol(scheme, callback)
|
||||
|
||||
* `scheme` String
|
||||
|
@ -48,7 +53,11 @@ Unregisters the custom protocol of `scheme`.
|
|||
|
||||
* `value` Array
|
||||
|
||||
`value` is an array of custom schemes to be registered to the standard.
|
||||
`value` is an array of custom schemes to be registered as standard schemes.
|
||||
|
||||
A standard scheme adheres to what RFC 3986 calls
|
||||
[generic URI syntax](https://tools.ietf.org/html/rfc3986#section-3). This
|
||||
includes `file:` and `filesystem:`.
|
||||
|
||||
## protocol.isHandledProtocol(scheme, callback)
|
||||
|
||||
|
@ -101,6 +110,9 @@ Create a request job which sends a buffer as response.
|
|||
## Class: protocol.RequestHttpJob(options)
|
||||
|
||||
* `options` Object
|
||||
* `session` [Session](browser-window.md#class-session) - By default it is
|
||||
the app's default session, setting it to `null` will create a new session
|
||||
for the requests
|
||||
* `url` String
|
||||
* `method` String - Default is `GET`
|
||||
* `referrer` String
|
||||
|
|
|
@ -20,7 +20,8 @@ var win = new BrowserWindow({ width: 800, height: 600 });
|
|||
win.loadUrl('https://github.com');
|
||||
```
|
||||
|
||||
Note: for the reverse (access renderer process from main process), you can use [webContents.executeJavascript](https://github.com/atom/electron/blob/master/docs/api/browser-window.md#browserwindowwebcontents).
|
||||
Note: for the reverse (access renderer process from main process), you can use
|
||||
[webContents.executeJavascript](browser-window.md#webcontents-executejavascript-code).
|
||||
|
||||
## Remote objects
|
||||
|
||||
|
|
|
@ -25,9 +25,10 @@ app.on('ready', function(){
|
|||
|
||||
__Platform limitations:__
|
||||
|
||||
* On OS X `clicked` event will be ignored if the tray icon has context menu.
|
||||
* On Linux app indicator will be used if it is supported, otherwise
|
||||
`GtkStatusIcon` will be used instead.
|
||||
* On Linux distributions that only have app indicator support, you have to
|
||||
install `libappindicator1` to make tray icon work.
|
||||
* App indicator will only be showed when it has context menu.
|
||||
* When app indicator is used on Linux, `clicked` event is ignored.
|
||||
|
||||
|
@ -46,7 +47,11 @@ Creates a new tray icon associated with the `image`.
|
|||
|
||||
### Event: 'clicked'
|
||||
|
||||
* `event`
|
||||
* `event` Event
|
||||
* `altKey` Boolean
|
||||
* `shiftKey` Boolean
|
||||
* `ctrlKey` Boolean
|
||||
* `metaKey` Boolean
|
||||
* `bounds` Object - the bounds of tray icon
|
||||
* `x` Integer
|
||||
* `y` Integer
|
||||
|
@ -55,13 +60,41 @@ Creates a new tray icon associated with the `image`.
|
|||
|
||||
Emitted when the tray icon is clicked.
|
||||
|
||||
__Note:__ The `bounds` payload is only implemented on OS X and Windows 7 or newer.
|
||||
__Note:__ The `bounds` payload is only implemented on OS X and Windows.
|
||||
|
||||
### Event: 'right-clicked'
|
||||
|
||||
* `event` Event
|
||||
* `altKey` Boolean
|
||||
* `shiftKey` Boolean
|
||||
* `ctrlKey` Boolean
|
||||
* `metaKey` Boolean
|
||||
* `bounds` Object - the bounds of tray icon
|
||||
* `x` Integer
|
||||
* `y` Integer
|
||||
* `width` Integer
|
||||
* `height` Integer
|
||||
|
||||
Emitted when the tray icon is right clicked.
|
||||
|
||||
__Note:__ This is only implemented on OS X and Windows.
|
||||
|
||||
### Event: 'double-clicked'
|
||||
|
||||
* `event` Event
|
||||
* `altKey` Boolean
|
||||
* `shiftKey` Boolean
|
||||
* `ctrlKey` Boolean
|
||||
* `metaKey` Boolean
|
||||
* `bounds` Object - the bounds of tray icon
|
||||
* `x` Integer
|
||||
* `y` Integer
|
||||
* `width` Integer
|
||||
* `height` Integer
|
||||
|
||||
Emitted when the tray icon is double clicked.
|
||||
|
||||
__Note:__ This is only implemented on OS X.
|
||||
__Note:__ This is only implemented on OS X and Windows.
|
||||
|
||||
### Event: 'balloon-show'
|
||||
|
||||
|
@ -82,6 +115,15 @@ closes it.
|
|||
|
||||
__Note:__ This is only implemented on Windows.
|
||||
|
||||
### Event: 'drop-files'
|
||||
|
||||
* `event`
|
||||
* `files` Array - the file path of dropped files.
|
||||
|
||||
Emitted when dragged files are dropped in the tray icon.
|
||||
|
||||
__Note:__ This is only implemented on OS X.
|
||||
|
||||
### Tray.destroy()
|
||||
|
||||
Destroys the tray icon immediately.
|
||||
|
@ -131,6 +173,16 @@ Displays a tray balloon.
|
|||
|
||||
__Note:__ This is only implemented on Windows.
|
||||
|
||||
### Tray.popUpContextMenu([position])
|
||||
|
||||
* `position` Object - The pop position
|
||||
* `x` Integer
|
||||
* `y` Integer
|
||||
|
||||
The `position` is only available on Windows, and it is (0, 0) by default.
|
||||
|
||||
__Note:__ This is only implemented on OS X and Windows.
|
||||
|
||||
### Tray.setContextMenu(menu)
|
||||
|
||||
* `menu` Menu
|
||||
|
|
|
@ -57,10 +57,17 @@ require('web-frame').setSpellCheckProvider("en-US", true, {
|
|||
|
||||
* `scheme` String
|
||||
|
||||
Sets the `scheme` as secure scheme.
|
||||
Registers the `scheme` as secure scheme.
|
||||
|
||||
Secure schemes do not trigger mixed content warnings. For example, `https` and
|
||||
`data` are secure schemes because they cannot be corrupted by active network
|
||||
attackers.
|
||||
|
||||
## webFrame.registerUrlSchemeAsBypassingCsp(scheme)
|
||||
|
||||
* `scheme` String
|
||||
|
||||
Resources will be loaded from this `scheme` regardless of
|
||||
page's Content Security Policy.
|
||||
|
||||
[spellchecker]: https://github.com/atom/node-spellchecker
|
||||
|
|
|
@ -130,10 +130,10 @@ If "on", the guest page will have web security disabled.
|
|||
|
||||
## Methods
|
||||
|
||||
The webview element must be loaded before using the methods.
|
||||
The webview element must be loaded before using the methods.
|
||||
**Example**
|
||||
```javascript
|
||||
webview.addEventListener("dom-ready", function(){
|
||||
webview.addEventListener("dom-ready", function() {
|
||||
webview.openDevTools();
|
||||
});
|
||||
```
|
||||
|
@ -215,17 +215,24 @@ Whether the renderer process has crashed.
|
|||
|
||||
Overrides the user agent for guest page.
|
||||
|
||||
### `<webview>`.getUserAgent()
|
||||
|
||||
Returns a `String` represents the user agent for guest page.
|
||||
|
||||
### `<webview>`.insertCSS(css)
|
||||
|
||||
* `css` String
|
||||
|
||||
Injects CSS into guest page.
|
||||
|
||||
### `<webview>`.executeJavaScript(code)
|
||||
### `<webview>`.executeJavaScript(code, userGesture)
|
||||
|
||||
* `code` String
|
||||
* `userGesture` Boolean - Default false
|
||||
|
||||
Evaluates `code` in guest page.
|
||||
Evaluates `code` in page. If `userGesture` is set will create user gesture context,
|
||||
HTML api like `requestFullScreen` which require user action can take advantage
|
||||
of this option for automation.
|
||||
|
||||
### `<webview>`.openDevTools()
|
||||
|
||||
|
@ -308,11 +315,11 @@ Executes editing command `replace` in page.
|
|||
|
||||
Executes editing command `replaceMisspelling` in page.
|
||||
|
||||
### `<webview>.print([options])`
|
||||
### `<webview>`.print([options])
|
||||
|
||||
Prints webview's web page. Same with `webContents.print([options])`.
|
||||
|
||||
### `<webview>.printToPDF(options, callback)`
|
||||
### `<webview>`.printToPDF(options, callback)
|
||||
|
||||
Prints webview's web page as PDF, Same with `webContents.printToPDF(options, callback)`
|
||||
|
||||
|
@ -328,6 +335,15 @@ examples.
|
|||
|
||||
## DOM events
|
||||
|
||||
### load-commit
|
||||
|
||||
* `url` String
|
||||
* `isMainFrame` Boolean
|
||||
|
||||
Fired when a load has committed. This includes navigation within the current
|
||||
document as well as subframe document-level loads, but does not include
|
||||
asynchronous resource loads.
|
||||
|
||||
### did-finish-load
|
||||
|
||||
Fired when the navigation is done, i.e. the spinner of the tab will stop
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
When `window.open` is called to create a new window in web page, a new instance
|
||||
of `BrowserWindow` will be created for the `url`, and a proxy will be returned
|
||||
to `window.open` to let the page to have limited control over it.
|
||||
to `window.open` to let the page have limited control over it.
|
||||
|
||||
The proxy only has some limited standard functionality implemented to be
|
||||
compatible with traditional web pages, for full control of the created window
|
||||
|
|
|
@ -17,7 +17,7 @@ On Ubuntu, install the following libraries:
|
|||
$ sudo apt-get install build-essential clang libdbus-1-dev libgtk2.0-dev \
|
||||
libnotify-dev libgnome-keyring-dev libgconf2-dev \
|
||||
libasound2-dev libcap-dev libcups2-dev libxtst-dev \
|
||||
libxss1 gcc-multilib g++-multilib
|
||||
libxss1 libnss3-dev gcc-multilib g++-multilib
|
||||
```
|
||||
|
||||
Other distributions may offer similar packages for installation via package
|
||||
|
@ -106,8 +106,8 @@ Make sure you have installed all the build dependencies.
|
|||
|
||||
### error while loading shared libraries: libtinfo.so.5
|
||||
|
||||
Prebulit `clang` will try to link to `libtinfo.so.5`. Depending on the host architecture,
|
||||
symlink to appropirate `libncurses`
|
||||
Prebulit `clang` will try to link to `libtinfo.so.5`. Depending on the host
|
||||
architecture, symlink to appropriate `libncurses`
|
||||
|
||||
```bash
|
||||
$ sudo ln -s /usr/lib/libncurses.so.5 /usr/lib/libtinfo.so.5
|
||||
|
@ -115,6 +115,14 @@ $ sudo ln -s /usr/lib/libncurses.so.5 /usr/lib/libtinfo.so.5
|
|||
|
||||
## Tests
|
||||
|
||||
Test your changes confirm to the project coding style using:
|
||||
|
||||
```bash
|
||||
$ ./script/cpplint.py
|
||||
```
|
||||
|
||||
Test functionality using:
|
||||
|
||||
```bash
|
||||
$ ./script/test.py
|
||||
```
|
||||
|
|
|
@ -51,6 +51,14 @@ support 32bit OS X in future.
|
|||
|
||||
## Tests
|
||||
|
||||
Test your changes confirm to the project coding style using:
|
||||
|
||||
```bash
|
||||
$ ./script/cpplint.py
|
||||
```
|
||||
|
||||
Test functionality using:
|
||||
|
||||
```bash
|
||||
$ ./script/test.py
|
||||
```
|
||||
|
|
|
@ -67,6 +67,14 @@ The other building steps are exactly the same.
|
|||
|
||||
## Tests
|
||||
|
||||
Test your changes confirm to the project coding style using:
|
||||
|
||||
```powershell
|
||||
python script\cpplint.py
|
||||
```
|
||||
|
||||
Test functionality using:
|
||||
|
||||
```powershell
|
||||
python script\test.py
|
||||
```
|
||||
|
|
114
docs/tutorial/application-distribution-es.md
Normal file
114
docs/tutorial/application-distribution-es.md
Normal file
|
@ -0,0 +1,114 @@
|
|||
# Distribución de aplicaciones
|
||||
|
||||
Para distribuir tu aplicación con Electron, debes nombrar al directorio de tu aplicación
|
||||
como `app`, y ponerlo bajo el directorio de recursos de Electron (en OSX es `Electron.app/Contents/Resources/`,
|
||||
en Linux y Windows es `resources/`):
|
||||
|
||||
En OSX:
|
||||
|
||||
```text
|
||||
electron/Electron.app/Contents/Resources/app/
|
||||
├── package.json
|
||||
├── main.js
|
||||
└── index.html
|
||||
```
|
||||
|
||||
En Windows y Linux:
|
||||
|
||||
```text
|
||||
electron/resources/app
|
||||
├── package.json
|
||||
├── main.js
|
||||
└── index.html
|
||||
```
|
||||
|
||||
Posteriormente ejecutas `Electron.app` (o `electron` en Linux, `electron.exe` en Windows),
|
||||
y Electron iniciará la aplicación. El directorio `electron` será la distribución que recibirán los usuarios finales.
|
||||
|
||||
## Empaquetando tu aplicación como un archivo
|
||||
|
||||
Además de copiar todos tus archivos fuente para la distribución, también puedes
|
||||
empaquetar tu aplicación como un archivo [asar](https://github.com/atom/asar)
|
||||
y de esta forma evitar la exposición del código fuente de tu aplicación a los usuarios.
|
||||
|
||||
Para usar un archivo `asar` en reemplazo de la carpeta `app`, debes renombrar
|
||||
el archivo a `app.asar`, y ponerlo bajo el directorio de recursos de Electron (como arriba),
|
||||
Electron intentará leer el archivo y ejecutar la aplicación desde él.
|
||||
|
||||
En OS X:
|
||||
|
||||
```text
|
||||
electron/Electron.app/Contents/Resources/
|
||||
└── app.asar
|
||||
```
|
||||
|
||||
En Windows y Linux:
|
||||
|
||||
```text
|
||||
electron/resources/
|
||||
└── app.asar
|
||||
```
|
||||
|
||||
Más detalles en [Empaquetamiento de aplicaciones](application-packaging-es.md).
|
||||
|
||||
## Rebranding con binarios descargados
|
||||
|
||||
Luego de empaquetar tu aplicación con Electron, podría ser útil agregar tu marca
|
||||
antes de realizar la distribución.
|
||||
|
||||
### Windows
|
||||
|
||||
Puedes renombrar `electron.exe` a cualquier nombre que desees, y editar su ícono y otras informaciones
|
||||
con herramientas como [rcedit](https://github.com/atom/rcedit) o [ResEdit](http://www.resedit.net).
|
||||
|
||||
### OS X
|
||||
|
||||
Puedes renombrar `Electron.app` a cualquier nombre que desees. También debes modificar los campos
|
||||
`CFBundleDisplayName`, `CFBundleIdentifier` y `CFBundleName` en los siguientes archivos:
|
||||
|
||||
* `Electron.app/Contents/Info.plist`
|
||||
* `Electron.app/Contents/Frameworks/Electron Helper.app/Contents/Info.plist`
|
||||
|
||||
También puedes renombrar el helper de la aplicación para evitar que aparezca como `Electron Helper`
|
||||
en el Monitor de Actividades.
|
||||
|
||||
La estructura de una aplicación renombrada sería así:
|
||||
|
||||
```
|
||||
MyApp.app/Contents
|
||||
├── Info.plist
|
||||
├── MacOS/
|
||||
│ └── MyApp
|
||||
└── Frameworks/
|
||||
├── MyApp Helper EH.app
|
||||
| ├── Info.plist
|
||||
| └── MacOS/
|
||||
| └── MyApp Helper EH
|
||||
├── MyApp Helper NP.app
|
||||
| ├── Info.plist
|
||||
| └── MacOS/
|
||||
| └── MyApp Helper NP
|
||||
└── MyApp Helper.app
|
||||
├── Info.plist
|
||||
└── MacOS/
|
||||
└── MyApp Helper
|
||||
```
|
||||
|
||||
### Linux
|
||||
|
||||
Puedes renombrar el ejectuable `electron` a cualquier nombre que desees.
|
||||
|
||||
## Rebranding desde el código fuente de Electron
|
||||
|
||||
También es posible agregar tu marca a Electron mediante un build personalizado.
|
||||
Para realizar esto debes modificar el archivo `atom.gyp`.
|
||||
|
||||
### grunt-build-atom-shell
|
||||
|
||||
La modificación del código de Electron para agregar tu marca puede resultar complicada, una tarea Grunt
|
||||
se ha creado para manejar esto de forma automatizada:
|
||||
|
||||
[grunt-build-atom-shell](https://github.com/paulcbetts/grunt-build-atom-shell).
|
||||
|
||||
Esta tarea se encargará de modificar el archivo `.gyp`, compilar el código
|
||||
y reconstruir los módulos nativos de la aplicación para que coincidan con el nuevo nombre.
|
157
docs/tutorial/application-packaging-es.md
Normal file
157
docs/tutorial/application-packaging-es.md
Normal file
|
@ -0,0 +1,157 @@
|
|||
# Empaquetamiento de aplicaciones
|
||||
|
||||
Para proteger los recursos y el código fuente de tu aplicación, puedes optar por empaquetar
|
||||
tu aplicación en un paquete [asar][asar].
|
||||
|
||||
## Generando un archivo `asar`
|
||||
|
||||
Un paquete [asar][asar] es un formato sencillo similar a tar, este formato concatena todos los archivos en uno,
|
||||
Electron puede leer el contenido sin desempaquetar todos los archivos.
|
||||
|
||||
A continuación, los pasos para empaquetar tu aplicación con `asar`:
|
||||
|
||||
### 1. Instalar asar
|
||||
|
||||
```bash
|
||||
$ npm install -g asar
|
||||
```
|
||||
|
||||
### 2. Empaquetar utilizando `asar pack`
|
||||
|
||||
```bash
|
||||
$ asar pack your-app app.asar
|
||||
```
|
||||
|
||||
## Utilizando los paquetes `asar`
|
||||
|
||||
En Electron existen dos tipos de APIs: las APIs de Node, proveídas por Node.js,
|
||||
y las APIs Web, proveídas por Chromium. Ambas APIs soportan la lecutra de paquetes `asar`.
|
||||
|
||||
### API Node
|
||||
|
||||
Con parches especiales en Electron, las APIs de Node como `fs.readFile` and `require`
|
||||
tratan los paquetes `asar` como directorios virtuales, y el contenido es accesible como si se tratara
|
||||
de archivos normales en el sistema de archivos.
|
||||
|
||||
Por ejemplo, supongamos que tenemos un paquete `example.asar` bajo `/path/to`:
|
||||
|
||||
```bash
|
||||
$ asar list /path/to/example.asar
|
||||
/app.js
|
||||
/file.txt
|
||||
/dir/module.js
|
||||
/static/index.html
|
||||
/static/main.css
|
||||
/static/jquery.min.js
|
||||
```
|
||||
|
||||
Leer un archivo de nuestro paquete `asar`:
|
||||
|
||||
```javascript
|
||||
var fs = require('fs');
|
||||
fs.readFileSync('/path/to/example.asar/file.txt');
|
||||
```
|
||||
|
||||
Listar todos los archivos de la raíz:
|
||||
|
||||
```javascript
|
||||
var fs = require('fs');
|
||||
fs.readdirSync('/path/to/example.asar');
|
||||
```
|
||||
|
||||
Utilizar un módulo que se encuentra dentro del archivo:
|
||||
|
||||
```javascript
|
||||
require('/path/to/example.asar/dir/module.js');
|
||||
```
|
||||
|
||||
También puedes mostrar una página web contenida en un `asar` utilizando `BrowserWindow`.
|
||||
|
||||
```javascript
|
||||
var BrowserWindow = require('browser-window');
|
||||
var win = new BrowserWindow({width: 800, height: 600});
|
||||
win.loadUrl('file:///path/to/example.asar/static/index.html');
|
||||
```
|
||||
|
||||
### API Web
|
||||
|
||||
En una págin web, los archivos que se encuentran en el paquete son accesibles a través del protocolo `file:`.
|
||||
Al igual que la API Node, los paquetes `asar` son tratados como directorios.
|
||||
|
||||
Por ejemplo, para obtener un archivo con `$.get`:
|
||||
|
||||
```html
|
||||
<script>
|
||||
var $ = require('./jquery.min.js');
|
||||
$.get('file:///path/to/example.asar/file.txt', function(data) {
|
||||
console.log(data);
|
||||
});
|
||||
</script>
|
||||
```
|
||||
|
||||
### Utilizando un paquete `asar` como un archivo normal
|
||||
|
||||
En algunas situaciones necesitaremos acceder al paquete `asar` como archivo, por ejemplo,
|
||||
si necesitaramos verificar la integridad del archivo con un checksum.
|
||||
Para casos así es posible utilizar el módulo `original-fs`, que provee la API `fs` original:
|
||||
|
||||
```javascript
|
||||
var originalFs = require('original-fs');
|
||||
originalFs.readFileSync('/path/to/example.asar');
|
||||
```
|
||||
|
||||
## Limitaciones de la API Node:
|
||||
|
||||
A pesar de que hemos intentado que los paquetes `asar` funcionen como directorios de la mejor forma posible,
|
||||
aún existen limitaciones debido a la naturaleza de bajo nivel de la API Node.
|
||||
|
||||
### Los paquetes son de sólo lecutra
|
||||
|
||||
Los paquetes `asar` no pueden ser modificados, por lo cual todas las funciones que modifiquen archivos
|
||||
no funcionarán.
|
||||
|
||||
## Los directorios del paquete no pueden establecerse como working directories
|
||||
|
||||
A pesar de que los paquetes `asar` son manejados virtualmente como directorios,
|
||||
estos directorios no existen en el sistema de archivos, por lo cual no es posible establecerlos
|
||||
como working directory, el uso de la opción `cwd` en algunas APIs podría causar errores.
|
||||
|
||||
### Desempaquetamiento adicional en algunas APIs
|
||||
|
||||
La mayoría de las APIs `fs` pueden leer u obtener información sobre un archivo en un paquete `asar` sin
|
||||
la necesidad de desempaquetarlo, pero algunas APIs requieren la ruta real. En estos casos Electron extraerá
|
||||
el archivo a una ruta temporal. Esto agrega un overhead a algunas APIs.
|
||||
|
||||
Las APIs que requieren el desempaquetamiento adicional son:
|
||||
|
||||
* `child_process.execFile`
|
||||
* `fs.open`
|
||||
* `fs.openSync`
|
||||
* `process.dlopen` - Utilizado po `require` en los módulos nativos
|
||||
|
||||
### Información falsa en `fs.stat`
|
||||
|
||||
El objeto `Stats` retornado por `fs.stat` y otras funciones relacionadas,
|
||||
no es preciso, ya que los archivos del paquete `asar` no existen el sistema de archivos.
|
||||
La utilización del objeto `Stats` sólo es recomendable para obtener el tamaño del archivo y/o
|
||||
comprobar el tipo de archivo.
|
||||
|
||||
|
||||
## Agregando archivos al paquete `asar`
|
||||
|
||||
Como se menciona arriba, algunas APIs de Node desempaquetarán archivos cuando exista una llamada
|
||||
que los referencie, además de los problemas de rendimiento que esto podría ocasionar, también
|
||||
podría accionar alertas falsas en software antivirus.
|
||||
|
||||
Para lidiar con esto, puedes desempaquetar algunos archivos utilizando la opción `--unpack`,
|
||||
a continuación un ejemplo que excluye las librerías compartidas de los módulos nativos:
|
||||
|
||||
```bash
|
||||
$ asar pack app app.asar --unpack *.node
|
||||
```
|
||||
|
||||
Después de ejecutar este comando, además del archivo `app.asar`, también se creará
|
||||
un directorio `app.asar.unpacked`, que contendrá los archivos desempaquetados.
|
||||
Este directorio deberá copiarse junto con el archivo `app.asar` a la hora de distribuir la aplicación.
|
||||
|
||||
[asar]: https://github.com/atom/asar
|
|
@ -1,6 +1,6 @@
|
|||
# Application packaging
|
||||
|
||||
To protect your app's resources and source code from the users, you can choose
|
||||
To mitigate [issues](https://github.com/joyent/node/issues/6960) around long path names on Windows, slightly speed up `require` and conceal your source code from cursory inspection you can choose
|
||||
to package your app into an [asar][asar] archive with little changes to your
|
||||
source code.
|
||||
|
||||
|
@ -161,3 +161,4 @@ After running the command, apart from the `app.asar`, there is also an
|
|||
should copy it together with `app.asar` when shipping it to users.
|
||||
|
||||
[asar]: https://github.com/atom/asar
|
||||
|
||||
|
|
45
docs/tutorial/debugging-main-process-es.md
Normal file
45
docs/tutorial/debugging-main-process-es.md
Normal file
|
@ -0,0 +1,45 @@
|
|||
# Depurando el proceso principal
|
||||
|
||||
Los devtools sólo pueden depurar las páginas web (el código del proceso renderer).
|
||||
Para depurar el código del proceso principal, Electron provee dos opciones para la línea de comandos: `--debug` y `--debug-brk`.
|
||||
|
||||
## Opciones para la línea de comandos
|
||||
|
||||
### `--debug=[port]`
|
||||
|
||||
Esta opción escuchará mensajes del protocolo de depuración V8 en `port`, por defecto `port` es `5858`.
|
||||
|
||||
### `--debug-brk=[port]`
|
||||
|
||||
Similar a `--debug` pero realiza una pausa en la primera línea del script.
|
||||
|
||||
## Utilizando node-inspector para depuración
|
||||
|
||||
__Nota:__ Electron utiliza node v0.11.13, esta versión aún no funciona bien con node-inspector,
|
||||
el proceso principal podría fallar al inspeccionar el objeto `process`.
|
||||
|
||||
### 1. Iniciar [node-inspector][node-inspector]
|
||||
|
||||
```bash
|
||||
$ node-inspector
|
||||
```
|
||||
|
||||
### 2. Activar el modo de depuración en Electron
|
||||
|
||||
Es posible iniciar Electron con la opción de depuración:
|
||||
|
||||
```bash
|
||||
$ electron --debug=5858 your/app
|
||||
```
|
||||
|
||||
o, pausar el script en la primera línea:
|
||||
|
||||
```bash
|
||||
$ electron --debug-brk=5858 your/app
|
||||
```
|
||||
|
||||
### 3. Cargar la interfaz del depurador
|
||||
|
||||
Abre http://127.0.0.1:8080/debug?ws=127.0.0.1:8080&port=5858 en Chrome.
|
||||
|
||||
[node-inspector]: https://github.com/node-inspector/node-inspector
|
171
docs/tutorial/desktop-environment-integration-es.md
Normal file
171
docs/tutorial/desktop-environment-integration-es.md
Normal file
|
@ -0,0 +1,171 @@
|
|||
# Integración con el entorno de escritorio
|
||||
|
||||
Los sistemas operativos proveen diferentes características para integrar aplicaciones
|
||||
en sus entornos de escritorio. Por ejemplo, en Windows, las aplicaciones pueden agregar accesos directos
|
||||
en la JumpList de la barra de tareas, y en Mac, las aplicaciones pueden agregar un menú personalizado en el dock.
|
||||
|
||||
Esta guía explica cómo integrar tu aplicación en esos entornos de escritorio a través de las APIs de Electron.
|
||||
|
||||
## Documentos recientes (Windows y OS X)
|
||||
|
||||
Windows y OS X proveen un acceso sencillo a la lista de documentos recientes.
|
||||
|
||||
__JumpList:__
|
||||
|
||||

|
||||
|
||||
__Menú Dock:__
|
||||
|
||||
<img src="https://cloud.githubusercontent.com/assets/639601/5069610/2aa80758-6e97-11e4-8cfb-c1a414a10774.png" height="353" width="428" >
|
||||
|
||||
Para agregar un archivo a la lista de documentos recientes, puedes utilizar:
|
||||
[app.addRecentDocument][addrecentdocument] API:
|
||||
|
||||
```javascript
|
||||
var app = require('app');
|
||||
app.addRecentDocument('/Users/USERNAME/Desktop/work.type');
|
||||
```
|
||||
|
||||
También puedes utilizar [app.clearRecentDocuments](clearrecentdocuments) para vaciar la lista de documentos recientes:
|
||||
|
||||
```javascript
|
||||
app.clearRecentDocuments();
|
||||
```
|
||||
|
||||
### Notas sobre Windows
|
||||
|
||||
Para activar esta característica en Windows, tu aplicación debe registrar un handler
|
||||
para el tipo de archivo que quieres utilizar, de lo contrario el archivo no aparecerá
|
||||
en la JumpList, aún después de agregarlo. Puedes encontrar más información sobre el proceso de
|
||||
registrar tu aplicación en [Application Registration][app-registration].
|
||||
|
||||
Cuando un usuario haga click en un archivo de la JumpList, una nueva instancia de tu aplicación
|
||||
se iniciará, la ruta del archivo se agregará como un argumento de la línea de comandos.
|
||||
|
||||
### Notas sobre OS X
|
||||
|
||||
Cuando un archivo es solicitado desde el menú de documentos recientes, el evento `open-file`
|
||||
del módulo `app` será emitido.
|
||||
|
||||
## Menú dock personalizado (OS X)
|
||||
|
||||
OS X permite a los desarrolladores definir un menú personalizado para el dock,
|
||||
el cual usualmente contiene algunos accesos directos a las características más comunes
|
||||
de tu aplicación:
|
||||
|
||||
__Menú dock de Terminal.app:__
|
||||
|
||||
<img src="https://cloud.githubusercontent.com/assets/639601/5069962/6032658a-6e9c-11e4-9953-aa84006bdfff.png" height="354" width="341" >
|
||||
|
||||
Para establecer tu menú dock, puedes utilizar la API `app.dock.setMenu`, la cual sólo está disponible para OSX:
|
||||
|
||||
```javascript
|
||||
var app = require('app');
|
||||
var Menu = require('menu');
|
||||
var dockMenu = Menu.buildFromTemplate([
|
||||
{ label: 'New Window', click: function() { console.log('New Window'); } },
|
||||
{ label: 'New Window with Settings', submenu: [
|
||||
{ label: 'Basic' },
|
||||
{ label: 'Pro'}
|
||||
]},
|
||||
{ label: 'New Command...'}
|
||||
]);
|
||||
app.dock.setMenu(dockMenu);
|
||||
```
|
||||
|
||||
## Tareas de usuario (Windows)
|
||||
|
||||
En Windows puedes especificar acciones personalizadas en la categoría `Tasks` del JumpList,
|
||||
tal como menciona MSDN:
|
||||
|
||||
|
||||
> Las aplicaciones definen tareas basadas en las características del programa
|
||||
> y las acciones clave que se esperan de un usuario. Las tareas deben ser
|
||||
> libres de contexto, es decir, la aplicación no debe encontrarse en ejecución
|
||||
> para que estas acciones funcionen. También deberían ser las acciones estadísticamente
|
||||
> más comunes que un usuario normal realizaría en tu aplicación, como por ejemplo,
|
||||
> redactar un mensaje de correo electrónico, crear un documento en el procesador de textos,
|
||||
> ejecutar una aplicación en cierto modo, o ejecutar alguno de sus subcomandos. Una aplicación
|
||||
> no debería popular el menú con características avanzadas que el usuario estándar no necesita
|
||||
> ni con acciones que sólo se realizan una vez, como por ejemplo, el registro. No utilices
|
||||
> las tareas para mostrar elementos promocionales como actualizaciones u ofertas especiales.
|
||||
>
|
||||
> Es recomendable que la lista de tareas sea estática. Debe mantenerse a pesar
|
||||
> de los cambios de estado de la aplicación. Aunque exista la posibilidad de variar
|
||||
> el contenido de la lista dinámicamente, debes considerar que podría ser confuso
|
||||
> para un usuario que no espera que el destino de la lista cambie.
|
||||
|
||||
__Tareas de Internet Explorer:__
|
||||
|
||||

|
||||
|
||||
A diferencia del menú dock en OS X, el cual es un menú real, las tareas de usuario en Windows
|
||||
funcionan como accesos directos de aplicación, que al ser clickeados, lanzan el programa
|
||||
con argumentos específicos.
|
||||
|
||||
Para establecer las tareas de usuario en tu aplicación, puedes utilizar:
|
||||
[app.setUserTasks][setusertaskstasks] API:
|
||||
|
||||
```javascript
|
||||
var app = require('app');
|
||||
app.setUserTasks([
|
||||
{
|
||||
program: process.execPath,
|
||||
arguments: '--new-window',
|
||||
iconPath: process.execPath,
|
||||
iconIndex: 0,
|
||||
title: 'New Window',
|
||||
description: 'Create a new window'
|
||||
}
|
||||
]);
|
||||
```
|
||||
|
||||
Para purgar la lista de tareas, puedes llamar a `app.setUserTasks` con un array vacío:
|
||||
|
||||
```javascript
|
||||
app.setUserTasks([]);
|
||||
```
|
||||
|
||||
Las tareas de usuario aún serán visibles después de cerrar tu aplicación, por lo cual
|
||||
el ícono y la ruta del programa deben existir hasta que la aplicación sea desinstalada.
|
||||
|
||||
## Accesos directos en el lanzador Unity (Linux)
|
||||
|
||||
En Unity, es posible agregar algunas entradas personalizadas, modificando el archivo `.desktop`,
|
||||
ver [Adding shortcuts to a launcher][unity-launcher].
|
||||
|
||||
__Accesos directos de Audacious:__
|
||||
|
||||

|
||||
|
||||
## Barra de progreso en la barra de tareas (Windows y Unity)
|
||||
|
||||
En Windows, un botón en la barra de tareas puede utilizarse para mostrar una barra de progreso. Esto permite
|
||||
que una ventana muestre la información de progreso al usuario, sin que el usuario tenga la ventana de la aplicación activa.
|
||||
|
||||
El entorno de escritorio Unity también posee una característica similar que permite mostrar una barra de progreso en el lanzador.
|
||||
|
||||
__Barra de progreso en un botón de la barra de herramientas:__
|
||||
|
||||

|
||||
|
||||
__Barra de progreso en el lanzador Unity:__
|
||||
|
||||

|
||||
|
||||
Para establecer la barra de progreso de una ventana, puedes utilizar
|
||||
[BrowserWindow.setProgressBar][setprogressbar] API:
|
||||
|
||||
```javascript
|
||||
var window = new BrowserWindow({...});
|
||||
window.setProgressBar(0.5);
|
||||
```
|
||||
|
||||
[addrecentdocument]: ../api/app.md#appaddrecentdocumentpath
|
||||
[clearrecentdocuments]: ../api/app.md#appclearrecentdocuments
|
||||
[setusertaskstasks]: ../api/app.md#appsetusertaskstasks
|
||||
[setprogressbar]: ../api/browser-window.md#browserwindowsetprogressbarprogress
|
||||
[setrepresentedfilename]: ../api/browser-window.md#browserwindowsetrepresentedfilenamefilename
|
||||
[setdocumentedited]: ../api/browser-window.md#browserwindowsetdocumenteditededited
|
||||
[app-registration]: http://msdn.microsoft.com/en-us/library/windows/desktop/ee872121(v=vs.85).aspx
|
||||
[unity-launcher]: https://help.ubuntu.com/community/UnityLaunchersAndDesktopFiles#Adding_shortcuts_to_a_launcher
|
|
@ -134,6 +134,59 @@ The user tasks will still show even after your application closes, so the icon
|
|||
and program path specified for a task should exist until your application is
|
||||
uninstalled.
|
||||
|
||||
## Thumbnail Toolbars
|
||||
|
||||
On Windows, you can add a thumbnail toolbar with specified buttons in a taskbar
|
||||
layout of an application window. It provides users a way to access to a particualr
|
||||
window's command without restoring or activating the window.
|
||||
|
||||
From MSDN, it's illustrated:
|
||||
|
||||
> This toolbar is simply the familiar standard toolbar common control. It has a
|
||||
> maximum of seven buttons. Each button's ID, image, tooltip, and state are defined
|
||||
> in a structure, which is then passed to the taskbar. The application can show,
|
||||
> enable, disable, or hide buttons from the thumbnail toolbar as required by its
|
||||
> current state.
|
||||
>
|
||||
> For example, Windows Media Player might offer standard media transport controls
|
||||
> such as play, pause, mute, and stop.
|
||||
|
||||
__Thumbnail toolbar of Windows Media Player:__
|
||||
|
||||

|
||||
|
||||
You can use [BrowserWindow.setThumbarButtons][setthumbarbuttons] to set thumbnail
|
||||
toolbar in your application:
|
||||
|
||||
```
|
||||
var BrowserWindow = require('browser-window');
|
||||
var path = require('path');
|
||||
var win = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600
|
||||
});
|
||||
win.setThumbarButtons([
|
||||
{
|
||||
tooltip: "button1",
|
||||
icon: path.join(__dirname, 'button1.png'),
|
||||
click: function() { console.log("button2 clicked"); }
|
||||
},
|
||||
{
|
||||
tooltip: "button2",
|
||||
icon: path.join(__dirname, 'button2.png'),
|
||||
flags:['enabled', 'dismissonclick'],
|
||||
click: function() { console.log("button2 clicked."); }
|
||||
}
|
||||
]);
|
||||
```
|
||||
|
||||
To clean thumbnail toolbar buttons, just call `BrowserWindow.setThumbarButtons`
|
||||
with an empty array:
|
||||
|
||||
```javascript
|
||||
win.setThumbarButtons([]);
|
||||
```
|
||||
|
||||
## Unity launcher shortcuts (Linux)
|
||||
|
||||
In Unity, you can add custom entries to its launcher via modifying `.desktop`
|
||||
|
@ -199,3 +252,4 @@ window.setDocumentEdited(true);
|
|||
[setdocumentedited]: ../api/browser-window.md#browserwindowsetdocumenteditededited
|
||||
[app-registration]: http://msdn.microsoft.com/en-us/library/windows/desktop/ee872121(v=vs.85).aspx
|
||||
[unity-launcher]: https://help.ubuntu.com/community/UnityLaunchersAndDesktopFiles#Adding_shortcuts_to_a_launcher
|
||||
[setthumbarbuttons]: ../api/browser-window.md#browserwindowsetthumbarbuttonsbuttons
|
||||
|
|
49
docs/tutorial/devtools-extension-es.md
Normal file
49
docs/tutorial/devtools-extension-es.md
Normal file
|
@ -0,0 +1,49 @@
|
|||
# Extensión DevTools
|
||||
|
||||
Para facilitar la depuración, Electron provee un soporte básico para la extensión
|
||||
[Chrome DevTools Extension][devtools-extension].
|
||||
|
||||
Para la mayoría de las extensiones devtools, simplemente puedes descargar el código fuente
|
||||
y utilizar `BrowserWindow.addDevToolsExtension` para cargarlas, las extensiones cargadas
|
||||
serán recordadas para que no sea necesario llamar a la función cada vez que creas una ventana.
|
||||
|
||||
Por ejemplo, para usar la extensión [React DevTools Extension](https://github.com/facebook/react-devtools), primero debes descargar el código fuente:
|
||||
|
||||
```bash
|
||||
$ cd /some-directory
|
||||
$ git clone --recursive https://github.com/facebook/react-devtools.git
|
||||
```
|
||||
|
||||
Luego cargas la aplicación en Electron, abriendo devtools en cualquier ventana,
|
||||
y ejecutando este código en la consola devtools:
|
||||
|
||||
```javascript
|
||||
require('remote').require('browser-window').addDevToolsExtension('/some-directory/react-devtools');
|
||||
```
|
||||
|
||||
Para remover una extensión, puedes utilizar `BrowserWindow.removeDevToolsExtension`
|
||||
especificando el nombre, y esta ya no se cargará la siguiente vez que abras devtools:
|
||||
|
||||
```javascript
|
||||
require('remote').require('browser-window').removeDevToolsExtension('React Developer Tools');
|
||||
```
|
||||
|
||||
## Formato de las extensiones devtools
|
||||
|
||||
Idealmente todas las extensiones devtools escritas para Chrome pueden ser cargadas por Electron,
|
||||
pero para ello deben estar en un directorio plano, las extensiones empaquetadas como `crx`
|
||||
no pueden ser cargadas por Chrome a no ser que halles una forma de extraerlas a un directorio.
|
||||
|
||||
## Páginas en segundo plano (background)
|
||||
|
||||
Electron no soporta la característica de páginas en segundo plano de las extensiones de Chrome,
|
||||
las extensiones que utilizan esta característica podrían no funcionar.
|
||||
|
||||
## APIs `chrome.*`
|
||||
|
||||
Algunas extensiones utilizan las APIs `chrome.*`, hemos realizado un esfuerzo
|
||||
para implementar esas APIs en Electron, sin embargo no han sido implementadas en su totalidad.
|
||||
|
||||
Dado que no todas las funciones `chrome.*` han sido implementadas, si la extensión devtools está utilizando otras APIs más allá de `chrome.devtools.*`, es muy probable que no funcione. Puedes reportar fallos en el issue tracker para que podamos agregar soporte a esas APIs.
|
||||
|
||||
[devtools-extension]: https://developer.chrome.com/extensions/devtools
|
80
docs/tutorial/online-offline-events-es.md
Normal file
80
docs/tutorial/online-offline-events-es.md
Normal file
|
@ -0,0 +1,80 @@
|
|||
# Detección del evento en línea/fuera de línea
|
||||
|
||||
La detección de estos eventos puede ser implementada en el proceso renderer utilizando las APIs HTML5 estándar,
|
||||
como en este ejemplo:
|
||||
|
||||
_main.js_
|
||||
|
||||
```javascript
|
||||
var app = require('app');
|
||||
var BrowserWindow = require('browser-window');
|
||||
var onlineStatusWindow;
|
||||
|
||||
app.on('ready', function() {
|
||||
onlineStatusWindow = new BrowserWindow({ width: 0, height: 0, show: false });
|
||||
onlineStatusWindow.loadUrl('file://' + __dirname + '/online-status.html');
|
||||
});
|
||||
```
|
||||
|
||||
_online-status.html_
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<script>
|
||||
var alertOnlineStatus = function() {
|
||||
window.alert(navigator.onLine ? 'online' : 'offline');
|
||||
};
|
||||
|
||||
window.addEventListener('online', alertOnlineStatus);
|
||||
window.addEventListener('offline', alertOnlineStatus);
|
||||
|
||||
alertOnlineStatus();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
Existen casos en donde necesitas responder a estos eventos desde el proceso principal.
|
||||
El proceso principal no posee un objeto `navigator`, por lo tanto no puede detectar estos eventos directamente.
|
||||
Es posible reenviar el evento al proceso principal mediante la utilidad de intercomunicación entre procesos (ipc):
|
||||
|
||||
_main.js_
|
||||
|
||||
```javascript
|
||||
var app = require('app');
|
||||
var ipc = require('ipc');
|
||||
var BrowserWindow = require('browser-window');
|
||||
var onlineStatusWindow;
|
||||
|
||||
app.on('ready', function() {
|
||||
onlineStatusWindow = new BrowserWindow({ width: 0, height: 0, show: false });
|
||||
onlineStatusWindow.loadUrl('file://' + __dirname + '/online-status.html');
|
||||
});
|
||||
|
||||
ipc.on('online-status-changed', function(event, status) {
|
||||
console.log(status);
|
||||
});
|
||||
```
|
||||
|
||||
_online-status.html_
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<script>
|
||||
var ipc = require('ipc');
|
||||
var updateOnlineStatus = function() {
|
||||
ipc.send('online-status-changed', navigator.onLine ? 'online' : 'offline');
|
||||
};
|
||||
|
||||
window.addEventListener('online', updateOnlineStatus);
|
||||
window.addEventListener('offline', updateOnlineStatus);
|
||||
|
||||
updateOnlineStatus();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
154
docs/tutorial/quick-start-es.md
Normal file
154
docs/tutorial/quick-start-es.md
Normal file
|
@ -0,0 +1,154 @@
|
|||
# Intro
|
||||
|
||||
## Introducción
|
||||
|
||||
Electron permite la creación de aplicaciones de escritorio utilizando JavaScript puro, a través de un runtime con APIs nativas. Puedes verlo como una variante de io.js, enfocado en aplicaciones de escritorio, en vez de servidores web.
|
||||
|
||||
Esto no significa que Electron sea un binding de librerías GUI para JavaScript.
|
||||
Electron utiliza páginas web como su GUI, por lo cual puedes verlo como un navegador Chromium mínimo,
|
||||
controlado por JavaScript.
|
||||
|
||||
### El proceso principal (main process)
|
||||
|
||||
En Electron, el proceso que ejecuta el script `main` del `package.json` se llama __el proceso principal__.
|
||||
El script que corre en el proceso principal puede crear páginas para mostrar la GUI.
|
||||
|
||||
### El proceso renderer (renderer process)
|
||||
|
||||
Dado que Electron utiliza Chromium para mostrar las páginas web,
|
||||
también es utilizada la arquitectura multiproceso de Chromium.
|
||||
Cada página web en Electron se ejecuta en su propio proceso,
|
||||
el cual es llamado __el proceso renderer__.
|
||||
|
||||
En los navegadores normales, las páginas web usualmente se ejecutan en un entorno
|
||||
sandbox y no tienen acceso a los recursos nativos. Los usuarios de Electron tienen el poder
|
||||
de utilizar las APIs de io.js en las páginas web, permitiendo interacciones de bajo nivel con el sistema operativo.
|
||||
|
||||
### Diferencias entre el proceso principal y el proceso renderer
|
||||
|
||||
El proceso principal crea páginas web mediante instancias de `BrowserWindow`. Cada instancia de `BrowserWindow` ejecuta su propia página web y su propio proceso renderer.
|
||||
Cuando una instancia de `BrowserWindow` es destruida, también su proceso renderer correspondiente acaba.
|
||||
|
||||
El proceso principal gestiona las páginas web y sus correspondientes procesos renderer.
|
||||
Cada proceso renderer es aislado y sólo considera relevante la página web que corre en él.
|
||||
|
||||
En las páginas web, no está permitido llamar a APIs relacionadas a la GUI nativa
|
||||
porque la gestión de los recursos GUI nativos es peligrosa, y tiende a que ocurran leaks de memoria.
|
||||
Si deseas realizar operaciones GUI en una página web, el proceso renderer de la página web debe comunicarse
|
||||
con el proceso principal, y solicitar a este que realice esas operaciones.
|
||||
|
||||
En Electron, hemos proveído el módulo [ipc](../api/ipc-renderer.md) para la comunicación
|
||||
entre el proceso principal y el proceso renderer. Y también hay un módulo [remote](../api/remote.md)
|
||||
para comunicación al estilo RPC.
|
||||
|
||||
## Escribe tu primera aplicación Electron
|
||||
|
||||
Generalmente, una aplicación Electron tendrá la siguiente estructura:
|
||||
|
||||
```text
|
||||
your-app/
|
||||
├── package.json
|
||||
├── main.js
|
||||
└── index.html
|
||||
```
|
||||
|
||||
El formato de `package.json` es exactamente el mismo que cualquier módulo Node,
|
||||
y el script especificado en el campo `main` será el script de arranque de tu aplicación,
|
||||
a ser ejecutado por el proceso principal. Un ejemplo de `package.json` podría verse así:
|
||||
|
||||
```json
|
||||
{
|
||||
"name" : "your-app",
|
||||
"version" : "0.1.0",
|
||||
"main" : "main.js"
|
||||
}
|
||||
```
|
||||
|
||||
El `main.js` debería crear las ventanas y gestionar los eventos del sistema, un ejemplo típico sería:
|
||||
example being:
|
||||
|
||||
```javascript
|
||||
var app = require('app'); // Módulo para controlar el ciclo de vida de la aplicación.
|
||||
var BrowserWindow = require('browser-window'); // Módulo para crear uan ventana de navegador.
|
||||
|
||||
// Reportar crashes a nuestro servidor.
|
||||
require('crash-reporter').start();
|
||||
|
||||
// Mantener una referencia global al objeto window, si no lo haces, esta ventana
|
||||
// se cerrará automáticamente cuando el objeto JavaScript sea recolectado (garbage collected):
|
||||
var mainWindow = null;
|
||||
|
||||
// Salir de todas las ventanas cuando se cierren.
|
||||
app.on('window-all-closed', function() {
|
||||
// En OS X es común que las aplicaciones y su barra de menú
|
||||
// se mantengan activas hasta que el usuario cierre la aplicación
|
||||
// explícitamente utilizando Cmd + Q
|
||||
if (process.platform != 'darwin') {
|
||||
app.quit();
|
||||
}
|
||||
});
|
||||
|
||||
// Este método será llamado cuando Electron haya finalizado la inicialización
|
||||
// y esté listo para crear ventanas de navegador.
|
||||
app.on('ready', function() {
|
||||
// Crear la ventana.
|
||||
mainWindow = new BrowserWindow({width: 800, height: 600});
|
||||
|
||||
// cargar el index.html de nuestra aplicación.
|
||||
mainWindow.loadUrl('file://' + __dirname + '/index.html');
|
||||
|
||||
// Desplegar devtools.
|
||||
mainWindow.openDevTools();
|
||||
|
||||
// Evento emitido cuando se cierra la ventana.
|
||||
mainWindow.on('closed', function() {
|
||||
// Eliminar la referencia del objeto window.
|
||||
// En el caso de soportar multiples ventanas, es usual almacenar
|
||||
// los objetos window en un array, este es el momento en el que debes eliminar el elemento correspondiente.
|
||||
mainWindow = null;
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
Finalmente el `index.html` es la página web que mostraremos:
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Hello World!</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello World!</h1>
|
||||
We are using io.js <script>document.write(process.version)</script>
|
||||
and Electron <script>document.write(process.versions['electron'])</script>.
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
## Ejecutar la aplicación
|
||||
|
||||
Cuando termines de escribir tu aplicación, puedes distribuirla
|
||||
siguiendo la [guía de distribución](./application-distribution-es.md)
|
||||
y luego ejecutar la aplicación empaquetada. También puedes utilizar el binario de Electron
|
||||
para ejecutar tu aplicación de forma directa.
|
||||
|
||||
En Windows:
|
||||
|
||||
```bash
|
||||
$ .\electron\electron.exe your-app\
|
||||
```
|
||||
|
||||
En Linux:
|
||||
|
||||
```bash
|
||||
$ ./electron/electron your-app/
|
||||
```
|
||||
|
||||
En OS X:
|
||||
|
||||
```bash
|
||||
$ ./Electron.app/Contents/MacOS/Electron your-app/
|
||||
```
|
||||
|
||||
`Electron.app` es parte del paquete de release de Electron, puedes descargarlo [aquí](https://github.com/atom/electron/releases).
|
|
@ -4,39 +4,40 @@
|
|||
|
||||
Electron enables you to create desktop applications with pure JavaScript by providing a runtime with rich native APIs. You could see it as a variant of the io.js runtime which is focused on desktop applications instead of web servers.
|
||||
|
||||
It doesn't mean Electron is a JavaScript binding to GUI libraries. Instead,
|
||||
This doesn't mean Electron is a JavaScript binding to GUI libraries. Instead,
|
||||
Electron uses web pages as its GUI, so you could also see it as a minimal
|
||||
Chromium browser, controlled by JavaScript.
|
||||
|
||||
### Main process
|
||||
|
||||
In Electron, the process that runs `package.json`'s `main` script is called
|
||||
__the main process__. The script that runs in the main process, can display GUI by
|
||||
__the main process__. The script that runs in the main process can display a GUI by
|
||||
creating web pages.
|
||||
|
||||
### Renderer process
|
||||
|
||||
Since Electron uses Chromium for displaying web pages, Chromium's
|
||||
multi-processes architecture is also used. Each web page in Electron runs in
|
||||
multi-process architecture is also used. Each web page in Electron runs in
|
||||
its own process, which is called __the renderer process__.
|
||||
|
||||
In normal browsers web pages usually run in a sandboxed environment and are not
|
||||
allowed access to native resources. Electron users however, have the power to use
|
||||
In normal browsers, web pages usually run in a sandboxed environment and are not
|
||||
allowed access to native resources. Electron users, however, have the power to use
|
||||
io.js APIs in web pages allowing lower level operating system interactions.
|
||||
|
||||
### Differences between main process and renderer process
|
||||
|
||||
The main process creates web pages by creating `BrowserWindow` instances. Each `BrowserWindow` instance runs the web page in its own renderer process. When a `BrowserWindow` instance is destroyed, the corresponding renderer process
|
||||
would also be terminated.
|
||||
is also terminated.
|
||||
|
||||
The main process manages all web pages and their corresponding renderer
|
||||
processes, each renderer process is isolated and only cares
|
||||
processes. Each renderer process is isolated and only cares
|
||||
about the web page running in it.
|
||||
|
||||
In web pages, it is not allowed to call native GUI related APIs because managing
|
||||
native GUI resources in web pages is very dangerous and easy to leak resources.
|
||||
If you want to do GUI operations in web pages, you have to communicate with
|
||||
the main process to do it there.
|
||||
native GUI resources in web pages is very dangerous and it is easy to leak resources.
|
||||
If you want to perform GUI operations in a web page, the renderer process of the web
|
||||
page must communicate with the main process to request the main process perform those
|
||||
operations.
|
||||
|
||||
In Electron, we have provided the [ipc](../api/ipc-renderer.md) module for
|
||||
communication between main process and renderer process. And there is also a
|
||||
|
@ -77,20 +78,20 @@ var BrowserWindow = require('browser-window'); // Module to create native brows
|
|||
require('crash-reporter').start();
|
||||
|
||||
// Keep a global reference of the window object, if you don't, the window will
|
||||
// be closed automatically when the javascript object is GCed.
|
||||
// be closed automatically when the JavaScript object is GCed.
|
||||
var mainWindow = null;
|
||||
|
||||
// Quit when all windows are closed.
|
||||
app.on('window-all-closed', function() {
|
||||
// On OSX it is common for applications and their menu bar
|
||||
// On OS X it is common for applications and their menu bar
|
||||
// to stay active until the user quits explicitly with Cmd + Q
|
||||
if (process.platform != 'darwin') {
|
||||
app.quit();
|
||||
}
|
||||
});
|
||||
|
||||
// This method will be called when Electron has done everything
|
||||
// initialization and ready for creating browser windows.
|
||||
// This method will be called when Electron has finished
|
||||
// initialization and is ready to create browser windows.
|
||||
app.on('ready', function() {
|
||||
// Create the browser window.
|
||||
mainWindow = new BrowserWindow({width: 800, height: 600});
|
||||
|
@ -129,24 +130,41 @@ Finally the `index.html` is the web page you want to show:
|
|||
|
||||
## Run your app
|
||||
|
||||
After you're done writing your app, you can create a distribution by
|
||||
following the [Application distribution](./application-distribution.md) guide
|
||||
and then execute the packaged app. You can also just use the downloaded
|
||||
Electron binary to execute your app directly.
|
||||
Once you've created your initial `main.js`, `index.html`, and `package.json` files,
|
||||
you'll probably want to try running your app locally to test it and make sure it's
|
||||
working as expected.
|
||||
|
||||
On Windows:
|
||||
### electron-prebuilt
|
||||
If you've installed `electron-prebuilt` globally with `npm`, then you need only
|
||||
run the following in your app's source directory:
|
||||
|
||||
```bash
|
||||
electron .
|
||||
```
|
||||
|
||||
If you've installed it locally, then run:
|
||||
|
||||
```bash
|
||||
./node_modules/.bin/electron .
|
||||
```
|
||||
|
||||
### Manually Downloaded Electron Binary
|
||||
If you downloaded Electron manually, you can also just use the included
|
||||
binary to execute your app directly.
|
||||
|
||||
#### Windows
|
||||
|
||||
```bash
|
||||
$ .\electron\electron.exe your-app\
|
||||
```
|
||||
|
||||
On Linux:
|
||||
#### Linux
|
||||
|
||||
```bash
|
||||
$ ./electron/electron your-app/
|
||||
```
|
||||
|
||||
On OS X:
|
||||
#### OS X
|
||||
|
||||
```bash
|
||||
$ ./Electron.app/Contents/MacOS/Electron your-app/
|
||||
|
@ -154,3 +172,8 @@ $ ./Electron.app/Contents/MacOS/Electron your-app/
|
|||
|
||||
`Electron.app` here is part of the Electron's release package, you can download
|
||||
it from [here](https://github.com/atom/electron/releases).
|
||||
|
||||
### Run as a distribution
|
||||
After you're done writing your app, you can create a distribution by
|
||||
following the [Application distribution](./application-distribution.md) guide
|
||||
and then executing the packaged app.
|
||||
|
|
57
docs/tutorial/using-native-node-modules-es.md
Normal file
57
docs/tutorial/using-native-node-modules-es.md
Normal file
|
@ -0,0 +1,57 @@
|
|||
# Utilizando módulos Node nativos
|
||||
|
||||
Los módulos Node nativos son soportados por Electron, pero dado que Electron
|
||||
está utilizando una versión distinta de V8, debes especificar manualmente la
|
||||
ubicación de las cabeceras de Electron a la hora de compilar módulos nativos.
|
||||
|
||||
## Compatibilidad de módulos nativos
|
||||
|
||||
A partir de Node v0.11.x han habido cambios vitales en la API de V8.
|
||||
Es de esperar que los módulos escritos para Node v0.10.x no funcionen con Node v0.11.x.
|
||||
Electron utiliza Node v.0.11.13 internamente, y por este motivo tiene el mismo problema.
|
||||
|
||||
Para resolver esto, debes usar módulos que soporten Node v0.11.x,
|
||||
[muchos módulos](https://www.npmjs.org/browse/depended/nan) soportan ambas versiones.
|
||||
En el caso de los módulos antiguos que sólo soportan Node v0.10.x, debes usar el módulo
|
||||
[nan](https://github.com/rvagg/nan) para portarlos a v0.11.x.
|
||||
|
||||
## ¿Cómo instalar módulos nativos?
|
||||
|
||||
### La forma fácil
|
||||
|
||||
La forma más sencilla de recompilar módulos nativos es a través del paquete
|
||||
[`electron-rebuild`](https://github.com/paulcbetts/electron-rebuild),
|
||||
el cual abstrae y maneja los pasos de descargar las cabeceras y compilar los módulos nativos:
|
||||
|
||||
```sh
|
||||
npm install --save-dev electron-rebuild
|
||||
|
||||
# Ejecuta esto cada vez que ejecutes npm install
|
||||
./node_modules/.bin/electron-rebuild
|
||||
```
|
||||
|
||||
### La forma node-gyp
|
||||
|
||||
Para compilar módulos Node con las cabeceras de Electron, debes indicar a `node-gyp`
|
||||
desde dónde descargar las cabeceras y cuál versión usar:
|
||||
|
||||
```bash
|
||||
$ cd /path-to-module/
|
||||
$ HOME=~/.electron-gyp node-gyp rebuild --target=0.29.1 --arch=x64 --dist-url=https://atom.io/download/atom-shell
|
||||
```
|
||||
|
||||
Los cambios en `HOME=~/.electron-gyp` fueron para especificar la ruta de las cabeceras.
|
||||
La opción `--target=0.29.1` es la versión de Electron. La opción `--dist-url=...` especifica
|
||||
dónde descargar las cabeceras. `--arch=x64` indica que el módulo será compilado para un sistema de 64bit.
|
||||
|
||||
### La forma npm
|
||||
|
||||
También puedes usar `npm` para instalar módulos, los pasos son exactamente igual a otros módulos Node,
|
||||
con la excepción de que necesitas establecer algunas variables de entorno primero:
|
||||
|
||||
```bash
|
||||
export npm_config_disturl=https://atom.io/download/atom-shell
|
||||
export npm_config_target=0.29.1
|
||||
export npm_config_arch=x64
|
||||
HOME=~/.electron-gyp npm install module-name
|
||||
```
|
58
docs/tutorial/using-pepper-flash-plugin-es.md
Normal file
58
docs/tutorial/using-pepper-flash-plugin-es.md
Normal file
|
@ -0,0 +1,58 @@
|
|||
# Utilizando el plugin Pepper Flash
|
||||
|
||||
El plugin Pepper Flash es soportado ahora. Para utilizar pepper flash en Electron, debes especificar la ubicación del plugin manualmente y activarlo en tu aplicación.
|
||||
|
||||
## Preparar una copia del plugin Flash
|
||||
|
||||
En OSX y Linux, el detalle del plugin puede encontrarse accediendo a `chrome://plugins` en el navegador. Su ubicación y versión son útiles para el soporte. También puedes copiarlo a otro lugar.
|
||||
|
||||
## Agrega la opción a Electron
|
||||
|
||||
Puedes agregar la opción `--ppapi-flash-path` y `ppapi-flash-version` o utilizar el método `app.commandLine.appendSwitch` antes del evento ready de la aplicación.
|
||||
También puedes agregar la opción `plugins` de `browser-window`. Por ejemplo,
|
||||
|
||||
```javascript
|
||||
var app = require('app');
|
||||
var BrowserWindow = require('browser-window');
|
||||
|
||||
// Report crashes to our server.
|
||||
require('crash-reporter').start();
|
||||
|
||||
// Keep a global reference of the window object, if you don't, the window will
|
||||
// be closed automatically when the javascript object is GCed.
|
||||
var mainWindow = null;
|
||||
|
||||
// Quit when all windows are closed.
|
||||
app.on('window-all-closed', function() {
|
||||
if (process.platform != 'darwin') {
|
||||
app.quit();
|
||||
}
|
||||
});
|
||||
|
||||
// Specify flash path.
|
||||
// On Windows, it might be /path/to/pepflashplayer.dll
|
||||
// On Mac, /path/to/PepperFlashPlayer.plugin
|
||||
// On Linux, /path/to/libpepflashplayer.so
|
||||
app.commandLine.appendSwitch('ppapi-flash-path', '/path/to/libpepflashplayer.so');
|
||||
|
||||
// Specify flash version, for example, v17.0.0.169
|
||||
app.commandLine.appendSwitch('ppapi-flash-version', '17.0.0.169');
|
||||
|
||||
app.on('ready', function() {
|
||||
mainWindow = new BrowserWindow({
|
||||
'width': 800,
|
||||
'height': 600,
|
||||
'web-preferences': {
|
||||
'plugins': true
|
||||
}
|
||||
});
|
||||
mainWindow.loadUrl('file://' + __dirname + '/index.html');
|
||||
// Something else
|
||||
});
|
||||
```
|
||||
|
||||
## Activar el plugin flash en una etiqueta `<webview>`
|
||||
Agrega el atributo `plugins`.
|
||||
```html
|
||||
<webview src="http://www.adobe.com/software/flash/about/" plugins></webview>
|
||||
```
|
72
docs/tutorial/using-selenium-and-webdriver-es.md
Normal file
72
docs/tutorial/using-selenium-and-webdriver-es.md
Normal file
|
@ -0,0 +1,72 @@
|
|||
# Utilizando Selenium y WebDriver
|
||||
|
||||
De [ChromeDriver - WebDriver for Chrome][chrome-driver]:
|
||||
|
||||
> WebDriver es una herramienta de código abierto para automatizar el testing de aplicaciones web
|
||||
> en varios navegadores. WebDriver provee funciones de navegación, entrada de usuario,
|
||||
> ejecución de JavaScript, y más. ChromeDriver es un servidor standalone que implementa
|
||||
> el protocolo de WebDriver para Chromium. Se encuentra en desarrollo por los miembros de
|
||||
> Chromium y WebDriver.
|
||||
|
||||
En la página de [lanzamientos](https://github.com/atom/electron/releases) de Electron encontrarás paquetes de `chromedriver`.
|
||||
|
||||
## Ajustando parámetros con WebDriverJs
|
||||
|
||||
[WebDriverJs](https://code.google.com/p/selenium/wiki/WebDriverJs) provee
|
||||
un paquete Node para realizar testing con web driver, lo usaremos como ejemplo.
|
||||
|
||||
### 1. Inicia chrome driver
|
||||
|
||||
Primero necesitas descargar el binario `chromedriver` y ejecutarlo:
|
||||
|
||||
```bash
|
||||
$ ./chromedriver
|
||||
Starting ChromeDriver (v2.10.291558) on port 9515
|
||||
Only local connections are allowed.
|
||||
```
|
||||
|
||||
Recuerda el puerto `9515`, lo utilizaremos después.
|
||||
|
||||
### 2. Instala WebDriverJS
|
||||
|
||||
```bash
|
||||
$ npm install selenium-webdriver
|
||||
```
|
||||
|
||||
### 3. Conecta chrome driver
|
||||
|
||||
El uso de `selenium-webdriver` junto con Electron es básicamente el mismo que el original,
|
||||
excepto que necesitas especificar manualmente cómo se conectará el chrome driver
|
||||
y dónde encontrará el binario de Electron:
|
||||
|
||||
```javascript
|
||||
var webdriver = require('selenium-webdriver');
|
||||
|
||||
var driver = new webdriver.Builder()
|
||||
// El puerto "9515" es que abre chrome driver.
|
||||
.usingServer('http://localhost:9515')
|
||||
.withCapabilities({chromeOptions: {
|
||||
// Aquí especificamos la ruta a Electron
|
||||
binary: '/Path-to-Your-App.app/Contents/MacOS/Atom'}})
|
||||
.forBrowser('electron')
|
||||
.build();
|
||||
|
||||
driver.get('http://www.google.com');
|
||||
driver.findElement(webdriver.By.name('q')).sendKeys('webdriver');
|
||||
driver.findElement(webdriver.By.name('btnG')).click();
|
||||
driver.wait(function() {
|
||||
return driver.getTitle().then(function(title) {
|
||||
return title === 'webdriver - Google Search';
|
||||
});
|
||||
}, 1000);
|
||||
|
||||
driver.quit();
|
||||
```
|
||||
|
||||
## Workflow
|
||||
|
||||
Para probar tu aplicación sin recompilar Electron, simplemente [copia](https://github.com/atom/electron/blob/master/docs/tutorial/application-distribution.md) las fuentes de tu aplicación en el directorio de recursos de Electron.
|
||||
|
||||
[chrome-driver]: https://sites.google.com/a/chromium.org/chromedriver/
|
||||
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue