Merge pull request #3 from atom/master

Update from original
This commit is contained in:
Heilig Benedek 2015-11-14 21:11:26 +01:00
commit 9987082de5
155 changed files with 2588 additions and 753 deletions

View file

@ -16,6 +16,7 @@
#include "base/debug/stack_trace.h"
#include "base/environment.h"
#include "base/logging.h"
#include "chrome/common/chrome_paths.h"
#include "content/public/common/content_switches.h"
#include "ui/base/resource/resource_bundle.h"
@ -79,6 +80,8 @@ bool AtomMainDelegate::BasicStartupComplete(int* exit_code) {
if (enable_stack_dumping)
base::debug::EnableInProcessStackDumping();
chrome::RegisterPathProvider();
return brightray::MainDelegate::BasicStartupComplete(exit_code);
}

View file

@ -24,6 +24,7 @@
#include "base/files/file_path.h"
#include "base/path_service.h"
#include "brightray/browser/brightray_paths.h"
#include "chrome/common/chrome_paths.h"
#include "content/public/browser/client_certificate_delegate.h"
#include "content/public/browser/gpu_data_manager.h"
#include "content/public/common/content_switches.h"
@ -99,12 +100,22 @@ int GetPathConstant(const std::string& name) {
return base::DIR_HOME;
else if (name == "temp")
return base::DIR_TEMP;
else if (name == "userDesktop")
else if (name == "userDesktop" || name == "desktop")
return base::DIR_USER_DESKTOP;
else if (name == "exe")
return base::FILE_EXE;
else if (name == "module")
return base::FILE_MODULE;
else if (name == "documents")
return chrome::DIR_USER_DOCUMENTS;
else if (name == "downloads")
return chrome::DIR_DEFAULT_DOWNLOADS;
else if (name == "music")
return chrome::DIR_USER_MUSIC;
else if (name == "pictures")
return chrome::DIR_USER_PICTURES;
else if (name == "videos")
return chrome::DIR_USER_VIDEOS;
else
return -1;
}

View file

@ -81,7 +81,7 @@ void AutoUpdater::OnWindowAllClosed() {
mate::ObjectTemplateBuilder AutoUpdater::GetObjectTemplateBuilder(
v8::Isolate* isolate) {
return mate::ObjectTemplateBuilder(isolate)
.SetMethod("setFeedUrl", &auto_updater::AutoUpdater::SetFeedURL)
.SetMethod("setFeedURL", &auto_updater::AutoUpdater::SetFeedURL)
.SetMethod("checkForUpdates", &auto_updater::AutoUpdater::CheckForUpdates)
.SetMethod("quitAndInstall", &AutoUpdater::QuitAndInstall);
}

View file

@ -204,7 +204,7 @@ void Cookies::GetCookiesOnIOThread(scoped_ptr<base::DictionaryValue> filter,
Passed(&filter), callback))) {
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
base::Bind(&RunGetCookiesCallbackOnUIThread, isolate(),
"Url is not valid", net::CookieList(), callback));
"URL is not valid", net::CookieList(), callback));
}
}
@ -229,7 +229,7 @@ void Cookies::Remove(const mate::Dictionary& details,
error_message = "Details(url, name) of removing cookie are required.";
}
if (error_message.empty() && !url.is_valid()) {
error_message = "Url is not valid.";
error_message = "URL is not valid.";
}
if (!error_message.empty()) {
RunRemoveCookiesCallbackOnUIThread(isolate(), error_message, callback);
@ -261,7 +261,7 @@ void Cookies::Set(const base::DictionaryValue& options,
GURL gurl(url);
if (error_message.empty() && !gurl.is_valid()) {
error_message = "Url is not valid.";
error_message = "URL is not valid.";
}
if (!error_message.empty()) {

View file

@ -103,7 +103,7 @@ int64 DownloadItem::GetTotalBytes() {
return download_item_->GetTotalBytes();
}
const GURL& DownloadItem::GetUrl() {
const GURL& DownloadItem::GetURL() {
return download_item_->GetURL();
}
@ -116,7 +116,7 @@ bool DownloadItem::HasUserGesture() {
}
std::string DownloadItem::GetFilename() {
return base::UTF16ToUTF8(net::GenerateFileName(GetUrl(),
return base::UTF16ToUTF8(net::GenerateFileName(GetURL(),
GetContentDisposition(),
std::string(),
download_item_->GetSuggestedFilename(),
@ -152,7 +152,7 @@ mate::ObjectTemplateBuilder DownloadItem::GetObjectTemplateBuilder(
.SetMethod("cancel", &DownloadItem::Cancel)
.SetMethod("getReceivedBytes", &DownloadItem::GetReceivedBytes)
.SetMethod("getTotalBytes", &DownloadItem::GetTotalBytes)
.SetMethod("getUrl", &DownloadItem::GetUrl)
.SetMethod("getURL", &DownloadItem::GetURL)
.SetMethod("getMimeType", &DownloadItem::GetMimeType)
.SetMethod("hasUserGesture", &DownloadItem::HasUserGesture)
.SetMethod("getFilename", &DownloadItem::GetFilename)

View file

@ -49,7 +49,7 @@ class DownloadItem : public mate::EventEmitter,
bool HasUserGesture();
std::string GetFilename();
std::string GetContentDisposition();
const GURL& GetUrl();
const GURL& GetURL();
void SetSavePath(const base::FilePath& path);
private:

View file

@ -37,7 +37,7 @@ mate::ObjectTemplateBuilder Protocol::GetObjectTemplateBuilder(
.SetMethod("registerBufferProtocol",
&Protocol::RegisterProtocol<URLRequestBufferJob>)
.SetMethod("registerFileProtocol",
&Protocol::RegisterProtocol<UrlRequestAsyncAsarJob>)
&Protocol::RegisterProtocol<URLRequestAsyncAsarJob>)
.SetMethod("registerHttpProtocol",
&Protocol::RegisterProtocol<URLRequestFetchJob>)
.SetMethod("unregisterProtocol", &Protocol::UnregisterProtocol)
@ -47,7 +47,7 @@ mate::ObjectTemplateBuilder Protocol::GetObjectTemplateBuilder(
.SetMethod("interceptBufferProtocol",
&Protocol::InterceptProtocol<URLRequestBufferJob>)
.SetMethod("interceptFileProtocol",
&Protocol::InterceptProtocol<UrlRequestAsyncAsarJob>)
&Protocol::InterceptProtocol<URLRequestAsyncAsarJob>)
.SetMethod("interceptHttpProtocol",
&Protocol::InterceptProtocol<URLRequestFetchJob>)
.SetMethod("uninterceptProtocol", &Protocol::UninterceptProtocol);

View file

@ -44,21 +44,21 @@ mate::Wrappable* Tray::New(v8::Isolate* isolate, const gfx::Image& image) {
void Tray::OnClicked(const gfx::Rect& bounds, int modifiers) {
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
EmitCustomEvent("clicked",
EmitCustomEvent("click",
ModifiersToObject(isolate(), modifiers), bounds);
}
void Tray::OnDoubleClicked(const gfx::Rect& bounds, int modifiers) {
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
EmitCustomEvent("double-clicked",
EmitCustomEvent("double-click",
ModifiersToObject(isolate(), modifiers), bounds);
}
void Tray::OnRightClicked(const gfx::Rect& bounds, int modifiers) {
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
EmitCustomEvent("right-clicked",
EmitCustomEvent("right-click",
ModifiersToObject(isolate(), modifiers), bounds);
}
@ -67,7 +67,7 @@ void Tray::OnBalloonShow() {
}
void Tray::OnBalloonClicked() {
Emit("balloon-clicked");
Emit("balloon-click");
}
void Tray::OnBalloonClosed() {

View file

@ -1003,8 +1003,8 @@ mate::ObjectTemplateBuilder WebContents::GetObjectTemplateBuilder(
.SetMethod("isAlive", &WebContents::IsAlive, true)
.SetMethod("getId", &WebContents::GetID)
.SetMethod("equal", &WebContents::Equal)
.SetMethod("_loadUrl", &WebContents::LoadURL)
.SetMethod("_getUrl", &WebContents::GetURL)
.SetMethod("_loadURL", &WebContents::LoadURL)
.SetMethod("_getURL", &WebContents::GetURL)
.SetMethod("getTitle", &WebContents::GetTitle)
.SetMethod("isLoading", &WebContents::IsLoading)
.SetMethod("isWaitingForResponse", &WebContents::IsWaitingForResponse)

View file

@ -127,16 +127,16 @@ Window::Window(v8::Isolate* isolate, const mate::Dictionary& options) {
// Use options.webPreferences to create WebContents.
mate::Dictionary web_preferences = mate::Dictionary::CreateEmpty(isolate);
options.Get(switches::kWebPreferences, &web_preferences);
options.Get(options::kWebPreferences, &web_preferences);
// Be compatible with old options which are now in web_preferences.
v8::Local<v8::Value> value;
if (options.Get(switches::kNodeIntegration, &value))
web_preferences.Set(switches::kNodeIntegration, value);
if (options.Get(switches::kPreloadScript, &value))
web_preferences.Set(switches::kPreloadScript, value);
if (options.Get(switches::kZoomFactor, &value))
web_preferences.Set(switches::kZoomFactor, value);
if (options.Get(options::kNodeIntegration, &value))
web_preferences.Set(options::kNodeIntegration, value);
if (options.Get(options::kPreloadScript, &value))
web_preferences.Set(options::kPreloadScript, value);
if (options.Get(options::kZoomFactor, &value))
web_preferences.Set(options::kZoomFactor, value);
// Creates the WebContents used by BrowserWindow.
auto web_contents = WebContents::Create(isolate, web_preferences);

View file

@ -1,5 +1,5 @@
deprecate = require 'deprecate'
EventEmitter = require('events').EventEmitter
electron = require 'electron'
{EventEmitter} = require 'events'
bindings = process.atomBinding 'app'
sessionBindings = process.atomBinding 'session'
@ -9,10 +9,10 @@ app = bindings.app
app.__proto__ = EventEmitter.prototype
app.setApplicationMenu = (menu) ->
require('menu').setApplicationMenu menu
electron.Menu.setApplicationMenu menu
app.getApplicationMenu = ->
require('menu').getApplicationMenu()
electron.Menu.getApplicationMenu()
app.commandLine =
appendSwitch: bindings.appendSwitch,
@ -39,6 +39,7 @@ app.getAppPath = ->
app.resolveProxy = (url, callback) -> @defaultSession.resolveProxy url, callback
# Deprecated.
{deprecate} = electron
app.getHomeDir = deprecate 'app.getHomeDir', 'app.getPath', ->
@getPath 'home'
app.getDataPath = deprecate 'app.getDataPath', 'app.getPath', ->
@ -62,10 +63,11 @@ wrapDownloadItem = (downloadItem) ->
# downloadItem is an EventEmitter.
downloadItem.__proto__ = EventEmitter.prototype
# Deprecated.
deprecate.property downloadItem, 'url', 'getUrl'
deprecate.property downloadItem, 'url', 'getURL'
deprecate.property downloadItem, 'filename', 'getFilename'
deprecate.property downloadItem, 'mimeType', 'getMimeType'
deprecate.property downloadItem, 'hasUserGesture', 'hasUserGesture'
deprecate.rename downloadItem, 'getUrl', 'getURL'
downloadItemBindings._setWrapDownloadItem wrapDownloadItem
# Only one App object pemitted.

View file

@ -1,7 +1,12 @@
switch process.platform
when 'win32'
module.exports = require './auto-updater/auto-updater-win'
when 'darwin'
module.exports = require './auto-updater/auto-updater-mac'
{deprecate} = require 'electron'
autoUpdater =
if process.platform is 'win32'
require './auto-updater/auto-updater-win'
else
throw new Error('auto-updater is not implemented on this platform')
require './auto-updater/auto-updater-native'
# Deprecated.
deprecate.rename autoUpdater, 'setFeedUrl', 'setFeedURL'
module.exports = autoUpdater

View file

@ -1,6 +1,6 @@
app = require 'app'
url = require 'url'
{app} = require 'electron'
{EventEmitter} = require 'events'
url = require 'url'
squirrelUpdate = require './squirrel-update-win'
@ -9,28 +9,28 @@ class AutoUpdater extends EventEmitter
squirrelUpdate.processStart()
app.quit()
setFeedUrl: (updateUrl) ->
@updateUrl = updateUrl
setFeedURL: (updateURL) ->
@updateURL = updateURL
checkForUpdates: ->
return @emitError 'Update URL is not set' unless @updateUrl
return @emitError 'Update URL is not set' unless @updateURL
return @emitError 'Can not find Squirrel' unless squirrelUpdate.supported()
@emit 'checking-for-update'
squirrelUpdate.download @updateUrl, (error, update) =>
squirrelUpdate.download @updateURL, (error, update) =>
return @emitError error if error?
return @emit 'update-not-available' unless update?
@emit 'update-available'
squirrelUpdate.update @updateUrl, (error) =>
squirrelUpdate.update @updateURL, (error) =>
return @emitError error if error?
{releaseNotes, version} = update
# Following information is not available on Windows, so fake them.
date = new Date
url = @updateUrl
url = @updateURL
@emit 'update-downloaded', {}, releaseNotes, version, date, url, => @quitAndInstall()

View file

@ -41,8 +41,8 @@ exports.processStart = (callback) ->
spawnUpdate ['--processStart', exeName], true, ->
# Download the releases specified by the URL and write new results to stdout.
exports.download = (updateUrl, callback) ->
spawnUpdate ['--download', updateUrl], false, (error, stdout) ->
exports.download = (updateURL, callback) ->
spawnUpdate ['--download', updateURL], false, (error, stdout) ->
return callback(error) if error?
try
@ -55,8 +55,8 @@ exports.download = (updateUrl, callback) ->
callback null, update
# Update the application to the latest remote version specified by URL.
exports.update = (updateUrl, callback) ->
spawnUpdate ['--update', updateUrl], false, callback
exports.update = (updateURL, callback) ->
spawnUpdate ['--update', updateURL], false, callback
# Is the Update.exe installed with the current application?
exports.supported = ->

View file

@ -1,9 +1,7 @@
EventEmitter = require('events').EventEmitter
app = require 'app'
ipc = require 'ipc-main'
deprecate = require 'deprecate'
{app, ipcMain, deprecate} = require 'electron'
{EventEmitter} = require 'events'
BrowserWindow = process.atomBinding('window').BrowserWindow
{BrowserWindow} = process.atomBinding 'window'
BrowserWindow::__proto__ = EventEmitter.prototype
BrowserWindow::_init = ->
@ -15,7 +13,7 @@ BrowserWindow::_init = ->
# Make new windows requested by links behave like "window.open"
@webContents.on '-new-window', (event, url, frameName) ->
options = show: true, width: 800, height: 600
ipc.emit 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_OPEN', event, url, frameName, options
ipcMain.emit 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_OPEN', event, url, frameName, options
# window.resizeTo(...)
# window.moveTo(...)
@ -71,7 +69,8 @@ BrowserWindow.fromDevToolsWebContents = (webContents) ->
return window for window in windows when window.devToolsWebContents?.equal webContents
# Helpers.
BrowserWindow::loadUrl = -> @webContents.loadUrl.apply @webContents, arguments
BrowserWindow::loadURL = -> @webContents.loadURL.apply @webContents, arguments
BrowserWindow::getURL = -> @webContents.getURL()
BrowserWindow::reload = -> @webContents.reload.apply @webContents, arguments
BrowserWindow::send = -> @webContents.send.apply @webContents, arguments
BrowserWindow::openDevTools = -> @webContents.openDevTools.apply @webContents, arguments
@ -82,14 +81,12 @@ BrowserWindow::inspectElement = -> @webContents.inspectElement.apply @webContent
BrowserWindow::inspectServiceWorker = -> @webContents.inspectServiceWorker()
# Deprecated.
deprecate.rename BrowserWindow, 'restart', 'reload'
deprecate.member BrowserWindow, 'undo', 'webContents'
deprecate.member BrowserWindow, 'redo', 'webContents'
deprecate.member BrowserWindow, 'cut', 'webContents'
deprecate.member BrowserWindow, 'copy', 'webContents'
deprecate.member BrowserWindow, 'paste', 'webContents'
deprecate.member BrowserWindow, 'selectAll', 'webContents'
deprecate.member BrowserWindow, 'getUrl', 'webContents'
deprecate.member BrowserWindow, 'reloadIgnoringCache', 'webContents'
deprecate.member BrowserWindow, 'getPageTitle', 'webContents'
deprecate.member BrowserWindow, 'isLoading', 'webContents'
@ -99,5 +96,8 @@ deprecate.member BrowserWindow, 'isCrashed', 'webContents'
deprecate.member BrowserWindow, 'executeJavaScriptInDevTools', 'webContents'
deprecate.member BrowserWindow, 'print', 'webContents'
deprecate.member BrowserWindow, 'printToPDF', 'webContents'
deprecate.rename BrowserWindow, 'restart', 'reload'
deprecate.rename BrowserWindow, 'loadUrl', 'loadURL'
deprecate.rename BrowserWindow, 'getUrl', 'getURL'
module.exports = BrowserWindow

View file

@ -1,7 +1,7 @@
{app, BrowserWindow} = require 'electron'
binding = process.atomBinding 'dialog'
v8Util = process.atomBinding 'v8_util'
app = require 'app'
BrowserWindow = require 'browser-window'
fileDialogProperties =
openFile: 1 << 0

View file

@ -0,0 +1,52 @@
# Import common modules.
module.exports = require '../../../../common/api/lib/exports/electron'
Object.defineProperties module.exports,
# Browser side modules, please sort with alphabet order.
app:
enumerable: true
get: -> require '../app'
autoUpdater:
enumerable: true
get: -> require '../auto-updater'
BrowserWindow:
enumerable: true
get: -> require '../browser-window'
contentTracing:
enumerable: true
get: -> require '../content-tracing'
dialog:
enumerable: true
get: -> require '../dialog'
ipcMain:
enumerable: true
get: -> require '../ipc-main'
globalShortcut:
enumerable: true
get: -> require '../global-shortcut'
Menu:
enumerable: true
get: -> require '../menu'
MenuItem:
enumerable: true
get: -> require '../menu-item'
powerMonitor:
enumerable: true
get: -> require '../power-monitor'
powerSaveBlocker:
enumerable: true
get: -> require '../power-save-blocker'
protocol:
enumerable: true
get: -> require '../protocol'
screen:
enumerable: true
get: -> require '../screen'
Tray:
enumerable: true
get: -> require '../tray'
# The internal modules, invisible unless you know their names.
NavigationController:
get: -> require '../navigation-controller'
webContents:
get: -> require '../web-contents'

View file

@ -1,5 +1,3 @@
bindings = process.atomBinding 'global_shortcut'
globalShortcut = bindings.globalShortcut
{globalShortcut} = process.atomBinding 'global_shortcut'
module.exports = globalShortcut

View file

@ -1,6 +1,6 @@
deprecate = require 'deprecate'
{deprecate, ipcMain} = require 'electron'
# This module is deprecated, we mirror everything from ipcMain.
deprecate.warn 'ipc module', 'ipcMain module'
module.exports = require 'ipc-main'
module.exports = ipcMain

View file

@ -1,4 +1,3 @@
BrowserWindow = require 'browser-window'
v8Util = process.atomBinding 'v8_util'
nextCommandId = 0
@ -18,7 +17,7 @@ class MenuItem
@types = ['normal', 'separator', 'submenu', 'checkbox', 'radio']
constructor: (options) ->
Menu = require 'menu'
{Menu} = require 'electron'
{click, @selector, @type, @role, @label, @sublabel, @accelerator, @icon, @enabled, @visible, @checked, @submenu} = options

View file

@ -1,8 +1,7 @@
BrowserWindow = require 'browser-window'
EventEmitter = require('events').EventEmitter
MenuItem = require 'menu-item'
v8Util = process.atomBinding 'v8_util'
{BrowserWindow, MenuItem} = require 'electron'
{EventEmitter} = require 'events'
v8Util = process.atomBinding 'v8_util'
bindings = process.atomBinding 'menu'
# Automatically generated radio menu item's group id.

View file

@ -1,15 +1,15 @@
ipc = require 'ipc-main'
{ipcMain} = require 'electron'
# The history operation in renderer is redirected to browser.
ipc.on 'ATOM_SHELL_NAVIGATION_CONTROLLER', (event, method, args...) ->
ipcMain.on 'ATOM_SHELL_NAVIGATION_CONTROLLER', (event, method, args...) ->
event.sender[method] args...
ipc.on 'ATOM_SHELL_SYNC_NAVIGATION_CONTROLLER', (event, method, args...) ->
ipcMain.on 'ATOM_SHELL_SYNC_NAVIGATION_CONTROLLER', (event, method, args...) ->
event.returnValue = event.sender[method] args...
# JavaScript implementation of Chromium's NavigationController.
# Instead of relying on Chromium for history control, we compeletely do history
# control on user land, and only rely on WebContents.loadUrl for navigation.
# control on user land, and only rely on WebContents.loadURL for navigation.
# This helps us avoid Chromium's various optimizations so we can ensure renderer
# process is restarted everytime.
class NavigationController
@ -17,9 +17,9 @@ class NavigationController
@clearHistory()
# webContents may have already navigated to a page.
if @webContents._getUrl()
if @webContents._getURL()
@currentIndex++
@history.push @webContents._getUrl()
@history.push @webContents._getURL()
@webContents.on 'navigation-entry-commited', (event, url, inPage, replaceEntry) =>
if @inPageIndex > -1 and not inPage
@ -42,12 +42,12 @@ class NavigationController
@currentIndex++
@history.push url
loadUrl: (url, options={}) ->
loadURL: (url, options={}) ->
@pendingIndex = -1
@webContents._loadUrl url, options
@webContents._loadURL url, options
@webContents.emit 'load-url', url, options
getUrl: ->
getURL: ->
if @currentIndex is -1
''
else
@ -59,7 +59,7 @@ class NavigationController
reload: ->
@pendingIndex = @currentIndex
@webContents._loadUrl @getUrl(), {}
@webContents._loadURL @getURL(), {}
reloadIgnoringCache: ->
@webContents._reloadIgnoringCache() # Rely on WebContents to clear cache.
@ -89,7 +89,7 @@ class NavigationController
if @inPageIndex > -1 and @pendingIndex >= @inPageIndex
@webContents._goBack()
else
@webContents._loadUrl @history[@pendingIndex], {}
@webContents._loadURL @history[@pendingIndex], {}
goForward: ->
return unless @canGoForward()
@ -97,12 +97,12 @@ class NavigationController
if @inPageIndex > -1 and @pendingIndex >= @inPageIndex
@webContents._goForward()
else
@webContents._loadUrl @history[@pendingIndex], {}
@webContents._loadURL @history[@pendingIndex], {}
goToIndex: (index) ->
return unless @canGoToIndex index
@pendingIndex = index
@webContents._loadUrl @history[@pendingIndex], {}
@webContents._loadURL @history[@pendingIndex], {}
goToOffset: (offset) ->
return unless @canGoToOffset offset

View file

@ -1,5 +1,6 @@
powerMonitor = process.atomBinding('power_monitor').powerMonitor
EventEmitter = require('events').EventEmitter
{EventEmitter} = require 'events'
{powerMonitor} = process.atomBinding 'power_monitor'
powerMonitor.__proto__ = EventEmitter.prototype

View file

@ -1,3 +1,3 @@
bindings = process.atomBinding 'power_save_blocker'
{powerSaveBlocker} = process.atomBinding 'power_save_blocker'
module.exports = bindings.powerSaveBlocker
module.exports = powerSaveBlocker

View file

@ -1,7 +1,8 @@
app = require 'app'
{app} = require 'electron'
throw new Error('Can not initialize protocol module before app is ready') unless app.isReady()
protocol = process.atomBinding('protocol').protocol
{protocol} = process.atomBinding 'protocol'
# Warn about removed APIs.
logAndThrow = (callback, message) ->

View file

@ -1,6 +1,6 @@
EventEmitter = require('events').EventEmitter
{EventEmitter} = require 'events'
{screen} = process.atomBinding 'screen'
screen = process.atomBinding('screen').screen
screen.__proto__ = EventEmitter.prototype
module.exports = screen

View file

@ -1,14 +1,19 @@
EventEmitter = require('events').EventEmitter
bindings = process.atomBinding 'tray'
{deprecate} = require 'electron'
{EventEmitter} = require 'events'
Tray = bindings.Tray
{Tray} = process.atomBinding 'tray'
Tray::__proto__ = EventEmitter.prototype
Tray::_init = ->
# Deprecated.
deprecate.rename this, 'popContextMenu', 'popUpContextMenu'
deprecate.event this, 'clicked', 'click'
deprecate.event this, 'double-clicked', 'double-click'
deprecate.event this, 'right-clicked', 'right-click'
deprecate.event this, 'balloon-clicked', 'balloon-click'
Tray::setContextMenu = (menu) ->
@_setContextMenu menu
@menu = menu # Keep a strong reference of menu.
# Keep compatibility with old APIs.
Tray::popContextMenu = Tray::popUpContextMenu
module.exports = Tray

View file

@ -1,8 +1,7 @@
EventEmitter = require('events').EventEmitter
Menu = require './menu'
NavigationController = require './navigation-controller'
{EventEmitter} = require 'events'
{deprecate, ipcMain, NavigationController, Menu} = require 'electron'
binding = process.atomBinding 'web_contents'
ipc = require 'ipc-main'
nextId = 0
getNextId = -> ++nextId
@ -46,7 +45,7 @@ wrapWebContents = (webContents) ->
# Make sure webContents.executeJavaScript would run the code only when the
# web contents has been loaded.
webContents.executeJavaScript = (code, hasUserGesture=false) ->
if @getUrl() and not @isLoading()
if @getURL() and not @isLoading()
@_executeJavaScript code, hasUserGesture
else
webContents.once 'did-finish-load', @_executeJavaScript.bind(this, code, hasUserGesture)
@ -60,17 +59,21 @@ wrapWebContents = (webContents) ->
# Dispatch IPC messages to the ipc module.
webContents.on 'ipc-message', (event, packed) ->
[channel, args...] = packed
ipc.emit channel, event, args...
ipcMain.emit channel, event, args...
webContents.on 'ipc-message-sync', (event, packed) ->
[channel, args...] = packed
Object.defineProperty event, 'returnValue', set: (value) -> event.sendReply JSON.stringify(value)
ipc.emit channel, event, args...
ipcMain.emit channel, event, args...
# Handle context menu action request from pepper plugin.
webContents.on 'pepper-context-menu', (event, params) ->
menu = Menu.buildFromTemplate params.menu
menu.popup params.x, params.y
# Deprecated.
deprecate.rename webContents, 'loadUrl', 'loadURL'
deprecate.rename webContents, 'getUrl', 'getURL'
webContents.printToPDF = (options, callback) ->
printingSetting =
pageRage: []

View file

@ -18,7 +18,7 @@ namespace {
// Notice that we just combined the api key with the url together here, because
// if we use the standard {url: key} format Chromium would override our key with
// the predefined one in common.gypi of libchromiumcontent, which is empty.
const char* kGeolocationProviderUrl =
const char* kGeolocationProviderURL =
"https://www.googleapis.com/geolocation/v1/geolocate?key="
GOOGLEAPIS_API_KEY;
@ -35,11 +35,11 @@ void AtomAccessTokenStore::LoadAccessTokens(
const LoadAccessTokensCallbackType& callback) {
AccessTokenSet access_token_set;
// Equivelent to access_token_set[kGeolocationProviderUrl].
// Equivelent to access_token_set[kGeolocationProviderURL].
// Somehow base::string16 is causing compilation errors when used in a pair
// of std::map on Linux, this can work around it.
std::pair<GURL, base::string16> token_pair;
token_pair.first = GURL(kGeolocationProviderUrl);
token_pair.first = GURL(kGeolocationProviderURL);
access_token_set.insert(token_pair);
auto browser_context = AtomBrowserMainParts::Get()->browser_context();

View file

@ -1,5 +1,6 @@
var app = require('app');
var BrowserWindow = require('browser-window');
const electron = require('electron');
const app = electron.app;
const BrowserWindow = electron.BrowserWindow;
var mainWindow = null;
@ -15,6 +16,6 @@ app.on('ready', function() {
autoHideMenuBar: true,
useContentSize: true,
});
mainWindow.loadUrl('file://' + __dirname + '/index.html');
mainWindow.loadURL('file://' + __dirname + '/index.html');
mainWindow.focus();
});

View file

@ -57,13 +57,17 @@
</head>
<body>
<script>
var execPath = require('remote').process.execPath;
const electron = require('electron');
const remote = electron.remote;
const shell = electron.shell;
var execPath = remote.process.execPath;
var command = execPath + ' path-to-your-app';
document.onclick = function(e) {
e.preventDefault();
if (e.target.tagName == 'A')
require('shell').openExternal(e.target.href);
shell.openExternal(e.target.href);
return false;
};
document.ondragover = document.ondrop = function(e) {

View file

@ -1,9 +1,11 @@
var app = require('app');
var dialog = require('dialog');
const electron = require('electron');
const app = electron.app;
const dialog = electron.dialog;
const shell = electron.shell;
const Menu = electron.Menu;
var fs = require('fs');
var path = require('path');
var Menu = require('menu');
var BrowserWindow = require('browser-window');
// Quit when all windows are closed and no other one is listening to this.
app.on('window-all-closed', function() {
@ -142,19 +144,19 @@ app.once('ready', function() {
submenu: [
{
label: 'Learn More',
click: function() { require('shell').openExternal('http://electron.atom.io') }
click: function() { shell.openExternal('http://electron.atom.io') }
},
{
label: 'Documentation',
click: function() { require('shell').openExternal('https://github.com/atom/electron/tree/master/docs#readme') }
click: function() { shell.openExternal('https://github.com/atom/electron/tree/master/docs#readme') }
},
{
label: 'Community Discussions',
click: function() { require('shell').openExternal('https://discuss.atom.io/c/electron') }
click: function() { shell.openExternal('https://discuss.atom.io/c/electron') }
},
{
label: 'Search Issues',
click: function() { require('shell').openExternal('https://github.com/atom/electron/issues') }
click: function() { shell.openExternal('https://github.com/atom/electron/issues') }
}
]
},
@ -269,5 +271,5 @@ if (option.file && !option.webdriver) {
console.log(helpMessage);
process.exit(0);
} else {
require('./default_app.js');
require('./default_app');
}

View file

@ -4,7 +4,10 @@
#include "atom/browser/javascript_environment.h"
#include <string>
#include "base/command_line.h"
#include "content/public/common/content_switches.h"
#include "gin/array_buffer.h"
#include "gin/v8_initializer.h"
@ -27,6 +30,12 @@ bool JavascriptEnvironment::Initialize() {
const char expose_debug_as[] = "--expose_debug_as=v8debug";
v8::V8::SetFlagsFromString(expose_debug_as, sizeof(expose_debug_as) - 1);
}
// --js-flags.
std::string js_flags = cmd->GetSwitchValueASCII(switches::kJavaScriptFlags);
if (!js_flags.empty())
v8::V8::SetFlagsFromString(js_flags.c_str(), js_flags.size());
gin::IsolateHolder::Initialize(gin::IsolateHolder::kNonStrictMode,
gin::ArrayBufferAllocator::SharedInstance());
return true;

View file

@ -1,4 +1,4 @@
app = require 'app'
electron = require 'electron'
fs = require 'fs'
path = require 'path'
url = require 'url'
@ -40,6 +40,7 @@ loadedExtensions = null
loadedExtensionsPath = null
# Persistent loaded extensions.
{app} = electron
app.on 'will-quit', ->
try
loadedExtensions = Object.keys(extensionInfoMap).map (key) -> extensionInfoMap[key].srcDirectory
@ -51,8 +52,7 @@ app.on 'will-quit', ->
# We can not use protocol or BrowserWindow until app is ready.
app.once 'ready', ->
protocol = require 'protocol'
BrowserWindow = require 'browser-window'
{protocol, BrowserWindow} = electron
# Load persistented extensions.
loadedExtensionsPath = path.join app.getPath('userData'), 'DevTools Extensions'

View file

@ -1,5 +1,5 @@
ipc = require 'ipc-main'
webContents = require 'web-contents'
{ipcMain, webContents} = require 'electron'
webViewManager = null # Doesn't exist in early initialization.
supportedWebViewEvents = [
@ -79,7 +79,7 @@ createGuest = (embedder, params) ->
opts = {}
opts.httpReferrer = params.httpreferrer if params.httpreferrer
opts.userAgent = params.useragent if params.useragent
@loadUrl params.src, opts
@loadURL params.src, opts
if params.allowtransparency?
@setAllowTransparency params.allowtransparency
@ -122,7 +122,7 @@ attachGuest = (embedder, elementInstanceId, guestInstanceId, params) ->
nodeIntegration: params.nodeintegration ? false
plugins: params.plugins
webSecurity: !params.disablewebsecurity
webPreferences.preloadUrl = params.preload if params.preload
webPreferences.preloadURL = params.preload if params.preload
webViewManager.addGuest guestInstanceId, elementInstanceId, embedder, guest, webPreferences
guest.attachParams = params
@ -140,19 +140,19 @@ destroyGuest = (embedder, id) ->
delete reverseEmbedderElementsMap[id]
delete embedderElementsMap[key]
ipc.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_CREATE_GUEST', (event, params, requestId) ->
ipcMain.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_CREATE_GUEST', (event, params, requestId) ->
event.sender.send "ATOM_SHELL_RESPONSE_#{requestId}", createGuest(event.sender, params)
ipc.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_ATTACH_GUEST', (event, elementInstanceId, guestInstanceId, params) ->
ipcMain.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_ATTACH_GUEST', (event, elementInstanceId, guestInstanceId, params) ->
attachGuest event.sender, elementInstanceId, guestInstanceId, params
ipc.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_DESTROY_GUEST', (event, id) ->
ipcMain.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_DESTROY_GUEST', (event, id) ->
destroyGuest event.sender, id
ipc.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_SET_SIZE', (event, id, params) ->
ipcMain.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_SET_SIZE', (event, id, params) ->
guestInstances[id]?.guest.setSize params
ipc.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_SET_ALLOW_TRANSPARENCY', (event, id, allowtransparency) ->
ipcMain.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_SET_ALLOW_TRANSPARENCY', (event, id, allowtransparency) ->
guestInstances[id]?.guest.setAllowTransparency allowtransparency
# Returns WebContents from its guest id.

View file

@ -1,6 +1,5 @@
ipc = require 'ipc-main'
{ipcMain, BrowserWindow} = require 'electron'
v8Util = process.atomBinding 'v8_util'
BrowserWindow = require 'browser-window'
frameToGuest = {}
@ -28,11 +27,11 @@ mergeBrowserWindowOptions = (embedder, options) ->
createGuest = (embedder, url, frameName, options) ->
guest = frameToGuest[frameName]
if frameName and guest?
guest.loadUrl url
guest.loadURL url
return guest.id
guest = new BrowserWindow(options)
guest.loadUrl url
guest.loadURL url
# Remember the embedder, will be used by window.opener methods.
v8Util.setHiddenValue guest.webContents, 'embedder', embedder
@ -58,7 +57,7 @@ createGuest = (embedder, url, frameName, options) ->
guest.id
# Routed window.open messages.
ipc.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_OPEN', (event, args...) ->
ipcMain.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_OPEN', (event, args...) ->
[url, frameName, options] = args
options = mergeBrowserWindowOptions event.sender, options
event.sender.emit 'new-window', event, url, frameName, 'new-window', options
@ -67,26 +66,26 @@ ipc.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_OPEN', (event, args...) ->
else
event.returnValue = createGuest event.sender, url, frameName, options
ipc.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_CLOSE', (event, guestId) ->
ipcMain.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_CLOSE', (event, guestId) ->
BrowserWindow.fromId(guestId)?.destroy()
ipc.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_METHOD', (event, guestId, method, args...) ->
ipcMain.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_METHOD', (event, guestId, method, args...) ->
BrowserWindow.fromId(guestId)?[method] args...
ipc.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_POSTMESSAGE', (event, guestId, message, targetOrigin) ->
ipcMain.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_POSTMESSAGE', (event, guestId, message, targetOrigin) ->
guestContents = BrowserWindow.fromId(guestId)?.webContents
if guestContents?.getUrl().indexOf(targetOrigin) is 0 or targetOrigin is '*'
if guestContents?.getURL().indexOf(targetOrigin) is 0 or targetOrigin is '*'
guestContents.send 'ATOM_SHELL_GUEST_WINDOW_POSTMESSAGE', guestId, message, targetOrigin
ipc.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_OPENER_POSTMESSAGE', (event, guestId, message, targetOrigin, sourceOrigin) ->
ipcMain.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_OPENER_POSTMESSAGE', (event, guestId, message, targetOrigin, sourceOrigin) ->
embedder = v8Util.getHiddenValue event.sender, 'embedder'
if embedder?.getUrl().indexOf(targetOrigin) is 0 or targetOrigin is '*'
if embedder?.getURL().indexOf(targetOrigin) is 0 or targetOrigin is '*'
embedder.send 'ATOM_SHELL_GUEST_WINDOW_POSTMESSAGE', guestId, message, sourceOrigin
ipc.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD', (event, guestId, method, args...) ->
ipcMain.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD', (event, guestId, method, args...) ->
BrowserWindow.fromId(guestId)?.webContents?[method] args...
ipc.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_GET_GUEST_ID', (event) ->
ipcMain.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_GET_GUEST_ID', (event) ->
embedder = v8Util.getHiddenValue event.sender, 'embedder'
if embedder?
guest = BrowserWindow.fromWebContents event.sender

View file

@ -13,10 +13,12 @@ require path.resolve(__dirname, '..', '..', 'common', 'lib', 'reset-search-paths
# Import common settings.
require path.resolve(__dirname, '..', '..', 'common', 'lib', 'init')
# Add browser/api/lib to module search paths, which contains javascript part of
# Electron's built-in libraries.
globalPaths = Module.globalPaths
globalPaths.push path.resolve(__dirname, '..', 'api', 'lib')
unless process.env.ELECTRON_HIDE_INTERNAL_MODULES
globalPaths.push path.resolve(__dirname, '..', 'api', 'lib')
# Expose public APIs.
globalPaths.push path.resolve(__dirname, '..', 'api', 'lib', 'exports')
if process.platform is 'win32'
# Redirect node's console to use our own implementations, since node can not
@ -44,12 +46,13 @@ process.on 'uncaughtException', (error) ->
return
# Show error in GUI.
{dialog} = require 'electron'
stack = error.stack ? "#{error.name}: #{error.message}"
message = "Uncaught Exception:\n#{stack}"
require('dialog').showErrorBox 'A JavaScript error occurred in the main process', message
dialog.showErrorBox 'A JavaScript error occurred in the main process', message
# Emit 'exit' event on quit.
app = require 'app'
{app} = require 'electron'
app.on 'quit', ->
process.emit 'exit'

View file

@ -1,4 +1,4 @@
EventEmitter = require('events').EventEmitter
{EventEmitter} = require 'events'
v8Util = process.atomBinding 'v8_util'
class ObjectsRegistry extends EventEmitter

View file

@ -1,8 +1,11 @@
ipc = require 'ipc-main'
path = require 'path'
objectsRegistry = require './objects-registry.js'
electron = require 'electron'
{ipcMain} = electron
objectsRegistry = require './objects-registry'
v8Util = process.atomBinding 'v8_util'
IDWeakMap = process.atomBinding('id_weak_map').IDWeakMap
{IDWeakMap} = process.atomBinding 'id_weak_map'
# Convert a real value into meta data.
valueToMeta = (sender, value, optimizeSimpleObject=false) ->
@ -13,7 +16,7 @@ valueToMeta = (sender, value, optimizeSimpleObject=false) ->
meta.type = 'array' if Array.isArray value
meta.type = 'error' if value instanceof Error
meta.type = 'date' if value instanceof Date
meta.type = 'promise' if value? and value.constructor.name is 'Promise'
meta.type = 'promise' if value?.constructor.name is 'Promise'
# Treat simple objects as value.
if optimizeSimpleObject and meta.type is 'object' and v8Util.getHiddenValue value, 'simple'
@ -115,28 +118,34 @@ callFunction = (event, func, caller, args) ->
process.on 'ATOM_BROWSER_RELEASE_RENDER_VIEW', (id) ->
objectsRegistry.clear id
ipc.on 'ATOM_BROWSER_REQUIRE', (event, module) ->
ipcMain.on 'ATOM_BROWSER_REQUIRE', (event, module) ->
try
event.returnValue = valueToMeta event.sender, process.mainModule.require(module)
catch e
event.returnValue = exceptionToMeta e
ipc.on 'ATOM_BROWSER_GLOBAL', (event, name) ->
ipcMain.on 'ATOM_BROWSER_GET_BUILTIN', (event, module) ->
try
event.returnValue = valueToMeta event.sender, electron[module]
catch e
event.returnValue = exceptionToMeta e
ipcMain.on 'ATOM_BROWSER_GLOBAL', (event, name) ->
try
event.returnValue = valueToMeta event.sender, global[name]
catch e
event.returnValue = exceptionToMeta e
ipc.on 'ATOM_BROWSER_CURRENT_WINDOW', (event) ->
ipcMain.on 'ATOM_BROWSER_CURRENT_WINDOW', (event) ->
try
event.returnValue = valueToMeta event.sender, event.sender.getOwnerBrowserWindow()
catch e
event.returnValue = exceptionToMeta e
ipc.on 'ATOM_BROWSER_CURRENT_WEB_CONTENTS', (event) ->
ipcMain.on 'ATOM_BROWSER_CURRENT_WEB_CONTENTS', (event) ->
event.returnValue = valueToMeta event.sender, event.sender
ipc.on 'ATOM_BROWSER_CONSTRUCTOR', (event, id, args) ->
ipcMain.on 'ATOM_BROWSER_CONSTRUCTOR', (event, id, args) ->
try
args = unwrapArgs event.sender, args
constructor = objectsRegistry.get id
@ -147,7 +156,7 @@ ipc.on 'ATOM_BROWSER_CONSTRUCTOR', (event, id, args) ->
catch e
event.returnValue = exceptionToMeta e
ipc.on 'ATOM_BROWSER_FUNCTION_CALL', (event, id, args) ->
ipcMain.on 'ATOM_BROWSER_FUNCTION_CALL', (event, id, args) ->
try
args = unwrapArgs event.sender, args
func = objectsRegistry.get id
@ -155,7 +164,7 @@ ipc.on 'ATOM_BROWSER_FUNCTION_CALL', (event, id, args) ->
catch e
event.returnValue = exceptionToMeta e
ipc.on 'ATOM_BROWSER_MEMBER_CONSTRUCTOR', (event, id, method, args) ->
ipcMain.on 'ATOM_BROWSER_MEMBER_CONSTRUCTOR', (event, id, method, args) ->
try
args = unwrapArgs event.sender, args
constructor = objectsRegistry.get(id)[method]
@ -165,7 +174,7 @@ ipc.on 'ATOM_BROWSER_MEMBER_CONSTRUCTOR', (event, id, method, args) ->
catch e
event.returnValue = exceptionToMeta e
ipc.on 'ATOM_BROWSER_MEMBER_CALL', (event, id, method, args) ->
ipcMain.on 'ATOM_BROWSER_MEMBER_CALL', (event, id, method, args) ->
try
args = unwrapArgs event.sender, args
obj = objectsRegistry.get id
@ -173,7 +182,7 @@ ipc.on 'ATOM_BROWSER_MEMBER_CALL', (event, id, method, args) ->
catch e
event.returnValue = exceptionToMeta e
ipc.on 'ATOM_BROWSER_MEMBER_SET', (event, id, name, value) ->
ipcMain.on 'ATOM_BROWSER_MEMBER_SET', (event, id, name, value) ->
try
obj = objectsRegistry.get id
obj[name] = value
@ -181,19 +190,22 @@ ipc.on 'ATOM_BROWSER_MEMBER_SET', (event, id, name, value) ->
catch e
event.returnValue = exceptionToMeta e
ipc.on 'ATOM_BROWSER_MEMBER_GET', (event, id, name) ->
ipcMain.on 'ATOM_BROWSER_MEMBER_GET', (event, id, name) ->
try
obj = objectsRegistry.get id
event.returnValue = valueToMeta event.sender, obj[name]
catch e
event.returnValue = exceptionToMeta e
ipc.on 'ATOM_BROWSER_DEREFERENCE', (event, id) ->
ipcMain.on 'ATOM_BROWSER_DEREFERENCE', (event, id) ->
objectsRegistry.remove event.sender.getId(), id
ipc.on 'ATOM_BROWSER_GUEST_WEB_CONTENTS', (event, guestInstanceId) ->
ipcMain.on 'ATOM_BROWSER_GUEST_WEB_CONTENTS', (event, guestInstanceId) ->
try
guestViewManager = require './guest-view-manager'
event.returnValue = valueToMeta event.sender, guestViewManager.getGuest(guestInstanceId)
catch e
event.returnValue = exceptionToMeta e
ipcMain.on 'ATOM_BROWSER_LIST_MODULES', (event) ->
event.returnValue = (name for name of electron)

View file

@ -56,16 +56,16 @@ NativeWindow::NativeWindow(
aspect_ratio_(0.0),
inspectable_web_contents_(inspectable_web_contents),
weak_factory_(this) {
options.Get(switches::kFrame, &has_frame_);
options.Get(switches::kTransparent, &transparent_);
options.Get(switches::kEnableLargerThanScreen, &enable_larger_than_screen_);
options.Get(options::kFrame, &has_frame_);
options.Get(options::kTransparent, &transparent_);
options.Get(options::kEnableLargerThanScreen, &enable_larger_than_screen_);
// Tell the content module to initialize renderer widget with transparent
// mode.
ui::GpuSwitchingManager::SetTransparent(transparent_);
// Read icon before window is created.
options.Get(switches::kIcon, &icon_);
options.Get(options::kIcon, &icon_);
WindowList::AddWindow(this);
}
@ -91,25 +91,25 @@ void NativeWindow::InitFromOptions(const mate::Dictionary& options) {
// Setup window from options.
int x = -1, y = -1;
bool center;
if (options.Get(switches::kX, &x) && options.Get(switches::kY, &y)) {
if (options.Get(options::kX, &x) && options.Get(options::kY, &y)) {
SetPosition(gfx::Point(x, y));
} else if (options.Get(switches::kCenter, &center) && center) {
} else if (options.Get(options::kCenter, &center) && center) {
Center();
}
// On Linux and Window we may already have maximum size defined.
extensions::SizeConstraints size_constraints(GetContentSizeConstraints());
int min_height = 0, min_width = 0;
if (options.Get(switches::kMinHeight, &min_height) |
options.Get(switches::kMinWidth, &min_width)) {
if (options.Get(options::kMinHeight, &min_height) |
options.Get(options::kMinWidth, &min_width)) {
size_constraints.set_minimum_size(gfx::Size(min_width, min_height));
}
int max_height = INT_MAX, max_width = INT_MAX;
if (options.Get(switches::kMaxHeight, &max_height) |
options.Get(switches::kMaxWidth, &max_width)) {
if (options.Get(options::kMaxHeight, &max_height) |
options.Get(options::kMaxWidth, &max_width)) {
size_constraints.set_maximum_size(gfx::Size(max_width, max_height));
}
bool use_content_size = false;
options.Get(switches::kUseContentSize, &use_content_size);
options.Get(options::kUseContentSize, &use_content_size);
if (use_content_size) {
SetContentSizeConstraints(size_constraints);
} else {
@ -117,39 +117,39 @@ void NativeWindow::InitFromOptions(const mate::Dictionary& options) {
}
#if defined(OS_WIN) || defined(USE_X11)
bool resizable;
if (options.Get(switches::kResizable, &resizable)) {
if (options.Get(options::kResizable, &resizable)) {
SetResizable(resizable);
}
#endif
bool top;
if (options.Get(switches::kAlwaysOnTop, &top) && top) {
if (options.Get(options::kAlwaysOnTop, &top) && top) {
SetAlwaysOnTop(true);
}
#if defined(OS_MACOSX) || defined(OS_WIN)
bool fullscreen;
if (options.Get(switches::kFullscreen, &fullscreen) && fullscreen) {
if (options.Get(options::kFullscreen, &fullscreen) && fullscreen) {
SetFullScreen(true);
}
#endif
bool skip;
if (options.Get(switches::kSkipTaskbar, &skip) && skip) {
if (options.Get(options::kSkipTaskbar, &skip) && skip) {
SetSkipTaskbar(skip);
}
bool kiosk;
if (options.Get(switches::kKiosk, &kiosk) && kiosk) {
if (options.Get(options::kKiosk, &kiosk) && kiosk) {
SetKiosk(kiosk);
}
std::string color;
if (options.Get(switches::kBackgroundColor, &color)) {
if (options.Get(options::kBackgroundColor, &color)) {
SetBackgroundColor(color);
}
std::string title("Electron");
options.Get(switches::kTitle, &title);
options.Get(options::kTitle, &title);
SetTitle(title);
// Then show it.
bool show = true;
options.Get(switches::kShow, &show);
options.Get(options::kShow, &show);
if (show)
Show();
}
@ -512,7 +512,7 @@ void NativeWindow::TitleWasSet(content::NavigationEntry* entry,
FOR_EACH_OBSERVER(NativeWindowObserver,
observers_,
OnPageTitleUpdated(&prevent_default, text));
if (!prevent_default)
if (!prevent_default && !is_closed_)
SetTitle(text);
}

View file

@ -320,8 +320,8 @@ NativeWindowMac::NativeWindowMac(
is_kiosk_(false),
attention_request_id_(0) {
int width = 800, height = 600;
options.Get(switches::kWidth, &width);
options.Get(switches::kHeight, &height);
options.Get(options::kWidth, &width);
options.Get(options::kHeight, &height);
NSRect main_screen_rect = [[[NSScreen screens] objectAtIndex:0] frame];
NSRect cocoa_bounds = NSMakeRect(
@ -331,14 +331,14 @@ NativeWindowMac::NativeWindowMac(
height);
bool useStandardWindow = true;
options.Get(switches::kStandardWindow, &useStandardWindow);
options.Get(options::kStandardWindow, &useStandardWindow);
bool resizable = true;
options.Get(switches::kResizable, &resizable);
options.Get(options::kResizable, &resizable);
// New title bar styles are available in Yosemite or newer
std::string titleBarStyle;
if (base::mac::IsOSYosemiteOrLater())
options.Get(switches::kTitleBarStyle, &titleBarStyle);
options.Get(options::kTitleBarStyle, &titleBarStyle);
NSUInteger styleMask = NSTitledWindowMask | NSClosableWindowMask |
NSMiniaturizableWindowMask;
@ -394,23 +394,23 @@ NativeWindowMac::NativeWindowMac(
// On OS X the initial window size doesn't include window frame.
bool use_content_size = false;
options.Get(switches::kUseContentSize, &use_content_size);
options.Get(options::kUseContentSize, &use_content_size);
if (!has_frame() || !use_content_size)
SetSize(gfx::Size(width, height));
// Enable the NSView to accept first mouse event.
bool acceptsFirstMouse = false;
options.Get(switches::kAcceptFirstMouse, &acceptsFirstMouse);
options.Get(options::kAcceptFirstMouse, &acceptsFirstMouse);
[window_ setAcceptsFirstMouse:acceptsFirstMouse];
// Disable auto-hiding cursor.
bool disableAutoHideCursor = false;
options.Get(switches::kDisableAutoHideCursor, &disableAutoHideCursor);
options.Get(options::kDisableAutoHideCursor, &disableAutoHideCursor);
[window_ setDisableAutoHideCursor:disableAutoHideCursor];
// Disable fullscreen button when 'fullscreen' is specified to false.
bool fullscreen;
if (!(options.Get(switches::kFullscreen, &fullscreen) &&
if (!(options.Get(options::kFullscreen, &fullscreen) &&
!fullscreen)) {
NSUInteger collectionBehavior = [window_ collectionBehavior];
collectionBehavior |= NSWindowCollectionBehaviorFullScreenPrimary;

View file

@ -132,13 +132,13 @@ NativeWindowViews::NativeWindowViews(
keyboard_event_handler_(new views::UnhandledKeyboardEventHandler),
use_content_size_(false),
resizable_(true) {
options.Get(switches::kTitle, &title_);
options.Get(switches::kAutoHideMenuBar, &menu_bar_autohide_);
options.Get(options::kTitle, &title_);
options.Get(options::kAutoHideMenuBar, &menu_bar_autohide_);
#if defined(OS_WIN)
// On Windows we rely on the CanResize() to indicate whether window can be
// resized, and it should be set before window is created.
options.Get(switches::kResizable, &resizable_);
options.Get(options::kResizable, &resizable_);
#endif
if (enable_larger_than_screen())
@ -150,8 +150,8 @@ NativeWindowViews::NativeWindowViews(
gfx::Size(), gfx::Size(INT_MAX / 10, INT_MAX / 10)));
int width = 800, height = 600;
options.Get(switches::kWidth, &width);
options.Get(switches::kHeight, &height);
options.Get(options::kWidth, &width);
options.Get(options::kHeight, &height);
gfx::Rect bounds(0, 0, width, height);
widget_size_ = bounds.size();
@ -187,7 +187,7 @@ NativeWindowViews::NativeWindowViews(
window_->Init(params);
bool fullscreen = false;
options.Get(switches::kFullscreen, &fullscreen);
options.Get(options::kFullscreen, &fullscreen);
#if defined(USE_X11)
// Start monitoring window states.
@ -195,7 +195,7 @@ NativeWindowViews::NativeWindowViews(
// Set _GTK_THEME_VARIANT to dark if we have "dark-theme" option set.
bool use_dark_theme = false;
if (options.Get(switches::kDarkTheme, &use_dark_theme) && use_dark_theme) {
if (options.Get(options::kDarkTheme, &use_dark_theme) && use_dark_theme) {
XDisplay* xdisplay = gfx::GetXDisplay();
XChangeProperty(xdisplay, GetAcceleratedWidget(),
XInternAtom(xdisplay, "_GTK_THEME_VARIANT", False),
@ -209,7 +209,7 @@ NativeWindowViews::NativeWindowViews(
// to manually set the _NET_WM_STATE.
std::vector<::Atom> state_atom_list;
bool skip_taskbar = false;
if (options.Get(switches::kSkipTaskbar, &skip_taskbar) && skip_taskbar) {
if (options.Get(options::kSkipTaskbar, &skip_taskbar) && skip_taskbar) {
state_atom_list.push_back(GetAtom("_NET_WM_STATE_SKIP_TASKBAR"));
}
@ -223,7 +223,7 @@ NativeWindowViews::NativeWindowViews(
// Set the _NET_WM_WINDOW_TYPE.
std::string window_type;
if (options.Get(switches::kType, &window_type))
if (options.Get(options::kType, &window_type))
SetWindowType(GetAcceleratedWidget(), window_type);
#endif
@ -274,7 +274,7 @@ NativeWindowViews::NativeWindowViews(
gfx::Size size = bounds.size();
if (has_frame() &&
options.Get(switches::kUseContentSize, &use_content_size_) &&
options.Get(options::kUseContentSize, &use_content_size_) &&
use_content_size_)
size = ContentSizeToWindowSize(size);

View file

@ -6,13 +6,13 @@
namespace atom {
UrlRequestAsyncAsarJob::UrlRequestAsyncAsarJob(
URLRequestAsyncAsarJob::URLRequestAsyncAsarJob(
net::URLRequest* request,
net::NetworkDelegate* network_delegate)
: JsAsker<asar::URLRequestAsarJob>(request, network_delegate) {
}
void UrlRequestAsyncAsarJob::StartAsync(scoped_ptr<base::Value> options) {
void URLRequestAsyncAsarJob::StartAsync(scoped_ptr<base::Value> options) {
base::FilePath::StringType file_path;
if (options->IsType(base::Value::TYPE_DICTIONARY)) {
static_cast<base::DictionaryValue*>(options.get())->GetString(

View file

@ -11,15 +11,15 @@
namespace atom {
// Like URLRequestAsarJob, but asks the JavaScript handler for file path.
class UrlRequestAsyncAsarJob : public JsAsker<asar::URLRequestAsarJob> {
class URLRequestAsyncAsarJob : public JsAsker<asar::URLRequestAsarJob> {
public:
UrlRequestAsyncAsarJob(net::URLRequest*, net::NetworkDelegate*);
URLRequestAsyncAsarJob(net::URLRequest*, net::NetworkDelegate*);
// JsAsker:
void StartAsync(scoped_ptr<base::Value> options) override;
private:
DISALLOW_COPY_AND_ASSIGN(UrlRequestAsyncAsarJob);
DISALLOW_COPY_AND_ASSIGN(URLRequestAsyncAsarJob);
};
} // namespace atom

View file

@ -25,13 +25,23 @@ namespace atom {
namespace {
// Array of available web runtime features.
const char* kWebRuntimeFeatures[] = {
switches::kExperimentalFeatures,
switches::kExperimentalCanvasFeatures,
switches::kOverlayScrollbars,
switches::kOverlayFullscreenVideo,
switches::kSharedWorker,
switches::kPageVisibility,
struct FeaturePair {
const char* name;
const char* cmd;
};
FeaturePair kWebRuntimeFeatures[] = {
{ options::kExperimentalFeatures,
switches::kExperimentalFeatures },
{ options::kExperimentalCanvasFeatures,
switches::kExperimentalCanvasFeatures },
{ options::kOverlayScrollbars,
switches::kOverlayScrollbars },
{ options::kOverlayFullscreenVideo,
switches::kOverlayFullscreenVideo },
{ options::kSharedWorker,
switches::kSharedWorker },
{ options::kPageVisibility,
switches::kPageVisibility },
};
} // namespace
@ -69,7 +79,7 @@ void WebContentsPreferences::AppendExtraCommandLineSwitches(
bool b;
#if defined(OS_WIN)
// Check if DirectWrite is disabled.
if (web_preferences.GetBoolean(switches::kDirectWrite, &b) && !b)
if (web_preferences.GetBoolean(options::kDirectWrite, &b) && !b)
command_line->AppendSwitch(::switches::kDisableDirectWrite);
#endif
@ -80,17 +90,17 @@ void WebContentsPreferences::AppendExtraCommandLineSwitches(
// This set of options are not availabe in WebPreferences, so we have to pass
// them via command line and enable them in renderer procss.
for (size_t i = 0; i < arraysize(kWebRuntimeFeatures); ++i) {
const char* feature = kWebRuntimeFeatures[i];
if (web_preferences.GetBoolean(feature, &b))
command_line->AppendSwitchASCII(feature, b ? "true" : "false");
const auto& feature = kWebRuntimeFeatures[i];
if (web_preferences.GetBoolean(feature.name, &b))
command_line->AppendSwitchASCII(feature.cmd, b ? "true" : "false");
}
// Check if we have node integration specified.
bool node_integration = true;
web_preferences.GetBoolean(switches::kNodeIntegration, &node_integration);
web_preferences.GetBoolean(options::kNodeIntegration, &node_integration);
// Be compatible with old API of "node-integration" option.
std::string old_token;
if (web_preferences.GetString(switches::kNodeIntegration, &old_token) &&
if (web_preferences.GetString(options::kNodeIntegration, &old_token) &&
old_token != "disable")
node_integration = true;
command_line->AppendSwitchASCII(switches::kNodeIntegration,
@ -98,12 +108,12 @@ void WebContentsPreferences::AppendExtraCommandLineSwitches(
// The preload script.
base::FilePath::StringType preload;
if (web_preferences.GetString(switches::kPreloadScript, &preload)) {
if (web_preferences.GetString(options::kPreloadScript, &preload)) {
if (base::FilePath(preload).IsAbsolute())
command_line->AppendSwitchNative(switches::kPreloadScript, preload);
else
LOG(ERROR) << "preload script must have absolute path.";
} else if (web_preferences.GetString(switches::kPreloadUrl, &preload)) {
} else if (web_preferences.GetString(options::kPreloadURL, &preload)) {
// Translate to file path if there is "preload-url" option.
base::FilePath preload_path;
if (net::FileURLToFilePath(GURL(preload), &preload_path))
@ -114,15 +124,14 @@ void WebContentsPreferences::AppendExtraCommandLineSwitches(
// The zoom factor.
double zoom_factor = 1.0;
if (web_preferences.GetDouble(switches::kZoomFactor, &zoom_factor) &&
if (web_preferences.GetDouble(options::kZoomFactor, &zoom_factor) &&
zoom_factor != 1.0)
command_line->AppendSwitchASCII(switches::kZoomFactor,
base::DoubleToString(zoom_factor));
// --guest-instance-id, which is used to identify guest WebContents.
int guest_instance_id;
if (web_preferences.GetInteger(switches::kGuestInstanceID,
&guest_instance_id))
if (web_preferences.GetInteger(options::kGuestInstanceID, &guest_instance_id))
command_line->AppendSwitchASCII(switches::kGuestInstanceID,
base::IntToString(guest_instance_id));
}
@ -152,8 +161,7 @@ void WebContentsPreferences::OverrideWebkitPrefs(
prefs->allow_displaying_insecure_content = !b;
prefs->allow_running_insecure_content = !b;
}
if (self->web_preferences_.GetBoolean("allowDisplayingInsecureContent",
&b))
if (self->web_preferences_.GetBoolean("allowDisplayingInsecureContent", &b))
prefs->allow_displaying_insecure_content = b;
if (self->web_preferences_.GetBoolean("allowRunningInsecureContent", &b))
prefs->allow_running_insecure_content = b;

View file

@ -168,7 +168,8 @@ mate::ObjectTemplateBuilder NativeImage::GetObjectTemplateBuilder(
template_.Reset(isolate, mate::ObjectTemplateBuilder(isolate)
.SetMethod("toPng", &NativeImage::ToPNG)
.SetMethod("toJpeg", &NativeImage::ToJPEG)
.SetMethod("toDataUrl", &NativeImage::ToDataURL)
.SetMethod("toDataURL", &NativeImage::ToDataURL)
.SetMethod("toDataUrl", &NativeImage::ToDataURL) // deprecated.
.SetMethod("isEmpty", &NativeImage::IsEmpty)
.SetMethod("getSize", &NativeImage::GetSize)
.SetMethod("setTemplateImage", &NativeImage::SetTemplateImage)
@ -309,7 +310,7 @@ void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
dict.SetMethod("createEmpty", &atom::api::NativeImage::CreateEmpty);
dict.SetMethod("createFromPath", &atom::api::NativeImage::CreateFromPath);
dict.SetMethod("createFromBuffer", &atom::api::NativeImage::CreateFromBuffer);
dict.SetMethod("createFromDataUrl",
dict.SetMethod("createFromDataURL",
&atom::api::NativeImage::CreateFromDataURL);
}

View file

@ -1,5 +1,5 @@
if process.platform is 'linux' and process.type is 'renderer'
# On Linux we could not access clipboard in renderer process.
module.exports = require('remote').require 'clipboard'
module.exports = require('electron').remote.clipboard
else
module.exports = process.atomBinding 'clipboard'

View file

@ -1,22 +1,26 @@
binding = process.atomBinding 'crash_reporter'
fs = require 'fs'
os = require 'os'
path = require 'path'
{spawn} = require 'child_process'
electron = require 'electron'
binding = process.atomBinding 'crash_reporter'
class CrashReporter
start: (options={}) ->
{@productName, companyName, submitUrl, autoSubmit, ignoreSystemCrashHandler, extra} = options
{@productName, companyName, submitURL, autoSubmit, ignoreSystemCrashHandler, extra} = options
app =
if process.type is 'browser'
require 'app'
else
require('remote').require 'app'
# Deprecated.
{deprecate} = electron
if options.submitUrl
submitURL ?= options.submitUrl
deprecate.warn 'submitUrl', 'submitURL'
{app} = if process.type is 'browser' then electron else electron.remote
@productName ?= app.getName()
companyName ?= 'GitHub, Inc'
submitUrl ?= 'http://54.249.141.255:1127/post'
submitURL ?= 'http://54.249.141.255:1127/post'
autoSubmit ?= true
ignoreSystemCrashHandler ?= false
extra ?= {}
@ -25,11 +29,11 @@ class CrashReporter
extra._companyName ?= companyName
extra._version ?= app.getVersion()
start = => binding.start @productName, companyName, submitUrl, autoSubmit, ignoreSystemCrashHandler, extra
start = => binding.start @productName, companyName, submitURL, autoSubmit, ignoreSystemCrashHandler, extra
if process.platform is 'win32'
args = [
"--reporter-url=#{submitUrl}"
"--reporter-url=#{submitURL}"
"--application-name=#{@productName}"
"--v=1"
]

View file

@ -42,12 +42,15 @@ deprecate.property = (object, property, method) ->
# Deprecate an event.
deprecate.event = (emitter, oldName, newName, fn) ->
warned = false
emitter.on newName, ->
emitter.on newName, (args...) ->
if @listenerCount(oldName) > 0 # there is listeners for old API.
unless warned or process.noDeprecation
warned = true
deprecate.warn "'#{oldName}' event", "'#{newName}' event"
fn.apply this, arguments
if fn?
fn.apply this, arguments
else
@emit oldName, args...
# Print deprecate warning.
deprecate.warn = (oldName, newName) ->

View file

@ -0,0 +1,27 @@
# Do not expose the internal modules to `require`.
exports.hideInternalModules = ->
{globalPaths} = require 'module'
if globalPaths.length is 3
# Remove the "common/api/lib" and "browser-or-renderer/api/lib".
globalPaths.splice 0, 2
Object.defineProperties exports,
# Common modules, please sort with alphabet order.
clipboard:
# Must be enumerable, otherwise it woulde be invisible to remote module.
enumerable: true
get: -> require '../clipboard'
crashReporter:
enumerable: true
get: -> require '../crash-reporter'
nativeImage:
enumerable: true
get: -> require '../native-image'
shell:
enumerable: true
get: -> require '../shell'
# The internal modules, invisible unless you know their names.
CallbacksRegistry:
get: -> require '../callbacks-registry'
deprecate:
get: -> require '../deprecate'

View file

@ -1 +1,7 @@
module.exports = process.atomBinding 'native_image'
{deprecate} = require 'electron'
nativeImage = process.atomBinding 'native_image'
# Deprecated.
deprecate.rename nativeImage, 'createFromDataUrl', 'createFromDataURL'
module.exports = nativeImage

View file

@ -9,8 +9,9 @@ process.atomBinding = (name) ->
catch e
process.binding "atom_common_#{name}" if /No such module/.test e.message
# Add common/api/lib to module search paths.
Module.globalPaths.push path.resolve(__dirname, '..', 'api', 'lib')
unless process.env.ELECTRON_HIDE_INTERNAL_MODULES
# Add common/api/lib to module search paths.
Module.globalPaths.push path.resolve(__dirname, '..', 'api', 'lib')
# setImmediate and process.nextTick makes use of uv_check and uv_prepare to
# run the callbacks, however since we only run uv loop on requests, the

View file

@ -21,6 +21,9 @@ struct Converter<base::FilePath> {
static bool FromV8(v8::Isolate* isolate,
v8::Local<v8::Value> val,
base::FilePath* out) {
if (val->IsNull())
return true;
base::FilePath::StringType path;
if (Converter<base::FilePath::StringType>::FromV8(isolate, val, &path)) {
*out = base::FilePath(path);

View file

@ -6,7 +6,7 @@
namespace atom {
namespace switches {
namespace options {
const char kTitle[] = "title";
const char kIcon[] = "icon";
@ -77,7 +77,7 @@ const char kZoomFactor[] = "zoomFactor";
const char kPreloadScript[] = "preload";
// Like --preload, but the passed argument is an URL.
const char kPreloadUrl[] = "preloadUrl";
const char kPreloadURL[] = "preloadURL";
// Enable the node integration.
const char kNodeIntegration[] = "nodeIntegration";
@ -85,6 +85,12 @@ const char kNodeIntegration[] = "nodeIntegration";
// Instancd ID of guest WebContents.
const char kGuestInstanceID[] = "guestInstanceId";
// Set page visiblity to always visible.
const char kPageVisibility[] = "pageVisibility";
// Enable DirectWrite on Windows.
const char kDirectWrite[] = "directWrite";
// Web runtime features.
const char kExperimentalFeatures[] = "experimentalFeatures";
const char kExperimentalCanvasFeatures[] = "experimentalCanvasFeatures";
@ -92,6 +98,10 @@ const char kOverlayScrollbars[] = "overlayScrollbars";
const char kOverlayFullscreenVideo[] = "overlayFullscreenVideo";
const char kSharedWorker[] = "sharedWorker";
} // namespace options
namespace switches {
// Enable plugins.
const char kEnablePlugins[] = "enable-plugins";
@ -101,12 +111,6 @@ const char kPpapiFlashPath[] = "ppapi-flash-path";
// Ppapi Flash version.
const char kPpapiFlashVersion[] = "ppapi-flash-version";
// Set page visiblity to always visible.
const char kPageVisibility[] = "page-visibility";
// Enable DirectWrite on Windows.
const char kDirectWrite[] = "direct-write";
// Path to client certificate.
const char kClientCertificate[] = "client-certificate";
@ -126,6 +130,19 @@ const char kCipherSuiteBlacklist[] = "cipher-suite-blacklist";
// The browser process app model ID
const char kAppUserModelId[] = "app-user-model-id";
// The command line switch versions of the options.
const char kZoomFactor[] = "zoom-factor";
const char kPreloadScript[] = "preload";
const char kPreloadURL[] = "preload-url";
const char kNodeIntegration[] = "node-integration";
const char kGuestInstanceID[] = "guest-instance-id";
const char kExperimentalFeatures[] = "experimental-features";
const char kExperimentalCanvasFeatures[] = "experimental-canvas-features";
const char kOverlayScrollbars[] = "overlay-scrollbars";
const char kOverlayFullscreenVideo[] = "overlay-fullscreen-video";
const char kSharedWorker[] = "shared-worker";
const char kPageVisibility[] = "page-visiblity";
} // namespace switches
} // namespace atom

View file

@ -7,7 +7,7 @@
namespace atom {
namespace switches {
namespace options {
extern const char kTitle[];
extern const char kIcon[];
@ -41,9 +41,10 @@ extern const char kBackgroundColor[];
extern const char kWebPreferences[];
// WebPreferences.
extern const char kDirectWrite[];
extern const char kZoomFactor[];
extern const char kPreloadScript[];
extern const char kPreloadUrl[];
extern const char kPreloadURL[];
extern const char kNodeIntegration[];
extern const char kGuestInstanceID[];
extern const char kExperimentalFeatures[];
@ -52,9 +53,14 @@ extern const char kOverlayScrollbars[];
extern const char kOverlayFullscreenVideo[];
extern const char kSharedWorker[];
extern const char kPageVisibility[];
extern const char kDirectWrite[];
} // namespace options
// Following are actually command line switches, should be moved to other files.
namespace switches {
extern const char kEnablePlugins[];
extern const char kPpapiFlashPath[];
extern const char kPpapiFlashVersion[];
@ -65,6 +71,18 @@ extern const char kSSLVersionFallbackMin[];
extern const char kCipherSuiteBlacklist[];
extern const char kAppUserModelId[];
extern const char kZoomFactor[];
extern const char kPreloadScript[];
extern const char kPreloadURL[];
extern const char kNodeIntegration[];
extern const char kGuestInstanceID[];
extern const char kExperimentalFeatures[];
extern const char kExperimentalCanvasFeatures[];
extern const char kOverlayScrollbars[];
extern const char kOverlayFullscreenVideo[];
extern const char kSharedWorker[];
extern const char kPageVisibility[];
} // namespace switches
} // namespace atom

View file

@ -307,8 +307,8 @@ bool OpenExternal(const GURL& url) {
// "Some versions of windows (Win2k before SP3, Win XP before SP1) crash in
// ShellExecute on long URLs (bug 161357 on bugzilla.mozilla.org). IE 5 and 6
// support URLS of 2083 chars in length, 2K is safe."
const size_t kMaxUrlLength = 2048;
if (escaped_url.length() > kMaxUrlLength) {
const size_t kMaxURLLength = 2048;
if (escaped_url.length() > kMaxURLLength) {
NOTREACHED();
return false;
}

View file

@ -98,7 +98,7 @@ void WebFrame::RegisterURLSchemeAsSecure(const std::string& scheme) {
blink::WebString::fromUTF8(scheme));
}
void WebFrame::RegisterURLSchemeAsBypassingCsp(const std::string& scheme) {
void WebFrame::RegisterURLSchemeAsBypassingCSP(const std::string& scheme) {
// Register scheme to bypass pages's Content Security Policy.
blink::WebSecurityPolicy::registerURLSchemeAsBypassingContentSecurityPolicy(
blink::WebString::fromUTF8(scheme));
@ -129,11 +129,11 @@ mate::ObjectTemplateBuilder WebFrame::GetObjectTemplateBuilder(
&WebFrame::RegisterElementResizeCallback)
.SetMethod("attachGuest", &WebFrame::AttachGuest)
.SetMethod("setSpellCheckProvider", &WebFrame::SetSpellCheckProvider)
.SetMethod("registerUrlSchemeAsSecure",
.SetMethod("registerURLSchemeAsSecure",
&WebFrame::RegisterURLSchemeAsSecure)
.SetMethod("registerUrlSchemeAsBypassingCsp",
&WebFrame::RegisterURLSchemeAsBypassingCsp)
.SetMethod("registerUrlSchemeAsPrivileged",
.SetMethod("registerURLSchemeAsBypassingCSP",
&WebFrame::RegisterURLSchemeAsBypassingCSP)
.SetMethod("registerURLSchemeAsPrivileged",
&WebFrame::RegisterURLSchemeAsPrivileged);
}

View file

@ -57,7 +57,7 @@ class WebFrame : public mate::Wrappable {
v8::Local<v8::Object> provider);
void RegisterURLSchemeAsSecure(const std::string& scheme);
void RegisterURLSchemeAsBypassingCsp(const std::string& scheme);
void RegisterURLSchemeAsBypassingCSP(const std::string& scheme);
void RegisterURLSchemeAsPrivileged(const std::string& scheme);
// mate::Wrappable:

View file

@ -0,0 +1,17 @@
# Import common modules.
module.exports = require '../../../../common/api/lib/exports/electron'
Object.defineProperties module.exports,
# Renderer side modules, please sort with alphabet order.
ipcRenderer:
enumerable: true
get: -> require '../ipc-renderer'
remote:
enumerable: true
get: -> require '../remote'
screen:
enumerable: true
get: -> require '../screen'
webFrame:
enumerable: true
get: -> require '../web-frame'

View file

@ -1,5 +1,4 @@
deprecate = require 'deprecate'
ipcRenderer = require 'ipc-renderer'
{ipcRenderer, deprecate} = require 'electron'
{EventEmitter} = require 'events'
# This module is deprecated, we mirror everything from ipcRenderer.

View file

@ -1,6 +1,5 @@
ipc = require 'ipc-renderer'
{ipcRenderer, CallbacksRegistry} = require 'electron'
v8Util = process.atomBinding 'v8_util'
CallbacksRegistry = require 'callbacks-registry'
callbacksRegistry = new CallbacksRegistry
@ -19,7 +18,7 @@ wrapArgs = (args, visited=[]) ->
type: 'array', value: wrapArgs(value, visited)
else if Buffer.isBuffer value
type: 'buffer', value: Array::slice.call(value, 0)
else if value? and value.constructor.name is 'Promise'
else if value?.constructor.name is 'Promise'
type: 'promise', then: valueToMeta(value.then.bind(value))
else if value? and typeof value is 'object' and v8Util.getHiddenValue value, 'atomId'
type: 'remote-object', id: v8Util.getHiddenValue value, 'atomId'
@ -58,7 +57,7 @@ metaToValue = (meta) ->
constructor: ->
if @constructor == RemoteFunction
# Constructor call.
obj = ipc.sendSync 'ATOM_BROWSER_CONSTRUCTOR', meta.id, wrapArgs(arguments)
obj = ipcRenderer.sendSync 'ATOM_BROWSER_CONSTRUCTOR', meta.id, wrapArgs(arguments)
# Returning object in constructor will replace constructed object
# with the returned object.
@ -66,7 +65,7 @@ metaToValue = (meta) ->
return metaToValue obj
else
# Function call.
ret = ipc.sendSync 'ATOM_BROWSER_FUNCTION_CALL', meta.id, wrapArgs(arguments)
ret = ipcRenderer.sendSync 'ATOM_BROWSER_FUNCTION_CALL', meta.id, wrapArgs(arguments)
return metaToValue ret
else
ret = v8Util.createObjectWithName meta.name
@ -80,11 +79,11 @@ metaToValue = (meta) ->
constructor: ->
if @constructor is RemoteMemberFunction
# Constructor call.
obj = ipc.sendSync 'ATOM_BROWSER_MEMBER_CONSTRUCTOR', meta.id, member.name, wrapArgs(arguments)
obj = ipcRenderer.sendSync 'ATOM_BROWSER_MEMBER_CONSTRUCTOR', meta.id, member.name, wrapArgs(arguments)
return metaToValue obj
else
# Call member function.
ret = ipc.sendSync 'ATOM_BROWSER_MEMBER_CALL', meta.id, member.name, wrapArgs(arguments)
ret = ipcRenderer.sendSync 'ATOM_BROWSER_MEMBER_CALL', meta.id, member.name, wrapArgs(arguments)
return metaToValue ret
else
Object.defineProperty ret, member.name,
@ -92,18 +91,18 @@ metaToValue = (meta) ->
configurable: false,
set: (value) ->
# Set member data.
ipc.sendSync 'ATOM_BROWSER_MEMBER_SET', meta.id, member.name, value
ipcRenderer.sendSync 'ATOM_BROWSER_MEMBER_SET', meta.id, member.name, value
value
get: ->
# Get member data.
ret = ipc.sendSync 'ATOM_BROWSER_MEMBER_GET', meta.id, member.name
ret = ipcRenderer.sendSync 'ATOM_BROWSER_MEMBER_GET', meta.id, member.name
metaToValue ret
# Track delegate object's life time, and tell the browser to clean up
# when the object is GCed.
v8Util.setDestructor ret, ->
ipc.send 'ATOM_BROWSER_DEREFERENCE', meta.id
ipcRenderer.send 'ATOM_BROWSER_DEREFERENCE', meta.id
# Remember object's id.
v8Util.setHiddenValue ret, 'atomId', meta.id
@ -119,13 +118,20 @@ metaToPlainObject = (meta) ->
obj
# Browser calls a callback in renderer.
ipc.on 'ATOM_RENDERER_CALLBACK', (event, id, args) ->
ipcRenderer.on 'ATOM_RENDERER_CALLBACK', (event, id, args) ->
callbacksRegistry.apply id, metaToValue(args)
# A callback in browser is released.
ipc.on 'ATOM_RENDERER_RELEASE_CALLBACK', (event, id) ->
ipcRenderer.on 'ATOM_RENDERER_RELEASE_CALLBACK', (event, id) ->
callbacksRegistry.remove id
# List all built-in modules in browser process.
browserModules = ipcRenderer.sendSync 'ATOM_BROWSER_LIST_MODULES'
# And add a helper receiver for each one.
for name in browserModules
do (name) ->
Object.defineProperty exports, name, get: -> exports.getBuiltin name
# Get remote module.
# (Just like node's require, the modules are cached permanently, note that this
# is safe leak since the object is not expected to get freed in browser)
@ -133,26 +139,37 @@ moduleCache = {}
exports.require = (module) ->
return moduleCache[module] if moduleCache[module]?
meta = ipc.sendSync 'ATOM_BROWSER_REQUIRE', module
meta = ipcRenderer.sendSync 'ATOM_BROWSER_REQUIRE', module
moduleCache[module] = metaToValue meta
# Optimize require('electron').
moduleCache.electron = exports
# Alias to remote.require('electron').xxx.
builtinCache = {}
exports.getBuiltin = (module) ->
return builtinCache[module] if builtinCache[module]?
meta = ipcRenderer.sendSync 'ATOM_BROWSER_GET_BUILTIN', module
builtinCache[module] = metaToValue meta
# Get current BrowserWindow object.
windowCache = null
exports.getCurrentWindow = ->
return windowCache if windowCache?
meta = ipc.sendSync 'ATOM_BROWSER_CURRENT_WINDOW'
meta = ipcRenderer.sendSync 'ATOM_BROWSER_CURRENT_WINDOW'
windowCache = metaToValue meta
# Get current WebContents object.
webContentsCache = null
exports.getCurrentWebContents = ->
return webContentsCache if webContentsCache?
meta = ipc.sendSync 'ATOM_BROWSER_CURRENT_WEB_CONTENTS'
meta = ipcRenderer.sendSync 'ATOM_BROWSER_CURRENT_WEB_CONTENTS'
webContentsCache = metaToValue meta
# Get a global object in browser.
exports.getGlobal = (name) ->
meta = ipc.sendSync 'ATOM_BROWSER_GLOBAL', name
meta = ipcRenderer.sendSync 'ATOM_BROWSER_GLOBAL', name
metaToValue meta
# Get the process object in browser.
@ -169,5 +186,5 @@ exports.createFunctionWithReturnValue = (returnValue) ->
# Get the guest WebContents from guestInstanceId.
exports.getGuestWebContents = (guestInstanceId) ->
meta = ipc.sendSync 'ATOM_BROWSER_GUEST_WEB_CONTENTS', guestInstanceId
meta = ipcRenderer.sendSync 'ATOM_BROWSER_GUEST_WEB_CONTENTS', guestInstanceId
metaToValue meta

View file

@ -1 +1 @@
module.exports = require('remote').require('screen')
module.exports = require('electron').remote.screen

View file

@ -1 +1,9 @@
module.exports = process.atomBinding('web_frame').webFrame
{deprecate} = require 'electron'
{webFrame} = process.atomBinding 'web_frame'
# Deprecated.
deprecate.rename webFrame, 'registerUrlSchemeAsSecure', 'registerURLSchemeAsSecure'
deprecate.rename webFrame, 'registerUrlSchemeAsBypassingCSP', 'registerURLSchemeAsBypassingCSP'
deprecate.rename webFrame, 'registerUrlSchemeAsPrivileged', 'registerURLSchemeAsPrivileged'
module.exports = webFrame

View file

@ -13,10 +13,12 @@ require path.resolve(__dirname, '..', '..', 'common', 'lib', 'reset-search-paths
# Import common settings.
require path.resolve(__dirname, '..', '..', 'common', 'lib', 'init')
# Add renderer/api/lib to require's search paths, which contains javascript part
# of Atom's built-in libraries.
globalPaths = Module.globalPaths
globalPaths.push path.resolve(__dirname, '..', 'api', 'lib')
unless process.env.ELECTRON_HIDE_INTERNAL_MODULES
globalPaths.push path.resolve(__dirname, '..', 'api', 'lib')
# Expose public APIs.
globalPaths.push path.resolve(__dirname, '..', 'api', 'lib', 'exports')
# The global variable will be used by ipc for event dispatching
v8Util = process.atomBinding 'v8_util'
@ -25,10 +27,10 @@ v8Util.setHiddenValue global, 'ipc', new events.EventEmitter
# Process command line arguments.
nodeIntegration = 'false'
for arg in process.argv
if arg.indexOf('--guestInstanceId=') == 0
if arg.indexOf('--guest-instance-id=') == 0
# This is a guest web view.
process.guestInstanceId = parseInt arg.substr(arg.indexOf('=') + 1)
else if arg.indexOf('--nodeIntegration=') == 0
else if arg.indexOf('--node-integration=') == 0
nodeIntegration = arg.substr arg.indexOf('=') + 1
else if arg.indexOf('--preload=') == 0
preloadScript = arg.substr arg.indexOf('=') + 1

View file

@ -32,8 +32,8 @@ convertToMenuTemplate = (items) ->
template
createMenu = (x, y, items, document) ->
remote = require 'remote'
Menu = remote.require 'menu'
{remote} = require 'electron'
{Menu} = remote
menu = Menu.buildFromTemplate convertToMenuTemplate(items)
# The menu is expected to show asynchronously.
@ -42,8 +42,8 @@ createMenu = (x, y, items, document) ->
DevToolsAPI.contextMenuCleared()
showFileChooserDialog = (callback) ->
remote = require 'remote'
dialog = remote.require 'dialog'
{remote} = require 'electron'
{dialog} = remote
files = dialog.showOpenDialog {}
callback pathToHtml5FileObject files[0] if files?

View file

@ -1,9 +1,8 @@
ipc = require 'ipc-renderer'
remote = require 'remote'
{ipcRenderer, remote} = require 'electron'
# Helper function to resolve relative url.
a = window.top.document.createElement 'a'
resolveUrl = (url) ->
resolveURL = (url) ->
a.href = url
a.href
@ -11,24 +10,24 @@ resolveUrl = (url) ->
class BrowserWindowProxy
constructor: (@guestId) ->
@closed = false
ipc.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_CLOSED', (event, guestId) =>
ipcRenderer.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_CLOSED', (event, guestId) =>
if guestId is @guestId
@closed = true
close: ->
ipc.send 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_CLOSE', @guestId
ipcRenderer.send 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_CLOSE', @guestId
focus: ->
ipc.send 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_METHOD', @guestId, 'focus'
ipcRenderer.send 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_METHOD', @guestId, 'focus'
blur: ->
ipc.send 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_METHOD', @guestId, 'blur'
ipcRenderer.send 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_METHOD', @guestId, 'blur'
postMessage: (message, targetOrigin='*') ->
ipc.send 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_POSTMESSAGE', @guestId, message, targetOrigin
ipcRenderer.send 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_POSTMESSAGE', @guestId, message, targetOrigin
eval: (args...) ->
ipc.send 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD', @guestId, 'executeJavaScript', args...
ipcRenderer.send 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD', @guestId, 'executeJavaScript', args...
unless process.guestInstanceId?
# Override default window.close.
@ -56,11 +55,11 @@ window.open = (url, frameName='', features='') ->
options.height ?= 600
# Resolve relative urls.
url = resolveUrl url
url = resolveURL url
(options[name] = parseInt(options[name], 10) if options[name]?) for name in ints
guestId = ipc.sendSync 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_OPEN', url, frameName, options
guestId = ipcRenderer.sendSync 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_OPEN', url, frameName, options
if guestId
new BrowserWindowProxy(guestId)
else
@ -68,32 +67,30 @@ window.open = (url, frameName='', features='') ->
# Use the dialog API to implement alert().
window.alert = (message, title='') ->
dialog = remote.require 'dialog'
buttons = ['OK']
message = message.toString()
dialog.showMessageBox remote.getCurrentWindow(), {message, title, buttons}
remote.dialog.showMessageBox remote.getCurrentWindow(), {message, title, buttons}
# Alert should always return undefined.
return
# And the confirm().
window.confirm = (message, title='') ->
dialog = remote.require 'dialog'
buttons = ['OK', 'Cancel']
cancelId = 1
not dialog.showMessageBox remote.getCurrentWindow(), {message, title, buttons, cancelId}
not remote.dialog.showMessageBox remote.getCurrentWindow(), {message, title, buttons, cancelId}
# But we do not support prompt().
window.prompt = ->
throw new Error('prompt() is and will not be supported.')
# Implement window.postMessage if current window is a guest window.
guestId = ipc.sendSync 'ATOM_SHELL_GUEST_WINDOW_MANAGER_GET_GUEST_ID'
guestId = ipcRenderer.sendSync 'ATOM_SHELL_GUEST_WINDOW_MANAGER_GET_GUEST_ID'
if guestId?
window.opener =
postMessage: (message, targetOrigin='*') ->
ipc.send 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_OPENER_POSTMESSAGE', guestId, message, targetOrigin, location.origin
ipcRenderer.send 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_OPENER_POSTMESSAGE', guestId, message, targetOrigin, location.origin
ipc.on 'ATOM_SHELL_GUEST_WINDOW_POSTMESSAGE', (event, guestId, message, sourceOrigin) ->
ipcRenderer.on 'ATOM_SHELL_GUEST_WINDOW_POSTMESSAGE', (event, guestId, message, sourceOrigin) ->
# Manually dispatch event instead of using postMessage because we also need to
# set event.source.
event = document.createEvent 'Event'
@ -105,10 +102,10 @@ ipc.on 'ATOM_SHELL_GUEST_WINDOW_POSTMESSAGE', (event, guestId, message, sourceOr
# Forward history operations to browser.
sendHistoryOperation = (args...) ->
ipc.send 'ATOM_SHELL_NAVIGATION_CONTROLLER', args...
ipcRenderer.send 'ATOM_SHELL_NAVIGATION_CONTROLLER', args...
getHistoryOperation = (args...) ->
ipc.sendSync 'ATOM_SHELL_SYNC_NAVIGATION_CONTROLLER', args...
ipcRenderer.sendSync 'ATOM_SHELL_SYNC_NAVIGATION_CONTROLLER', args...
window.history.back = -> sendHistoryOperation 'goBack'
window.history.forward = -> sendHistoryOperation 'goForward'

View file

@ -1,19 +1,18 @@
ipc = require 'ipc-renderer'
webFrame = require 'web-frame'
{ipcRenderer, webFrame} = require 'electron'
requestId = 0
WEB_VIEW_EVENTS =
'load-commit': ['url', 'isMainFrame']
'did-finish-load': []
'did-fail-load': ['errorCode', 'errorDescription', 'validatedUrl']
'did-fail-load': ['errorCode', 'errorDescription', 'validatedURL']
'did-frame-finish-load': ['isMainFrame']
'did-start-loading': []
'did-stop-loading': []
'did-get-response-details': ['status', 'newUrl', 'originalUrl',
'did-get-response-details': ['status', 'newURL', 'originalURL',
'httpResponseCode', 'requestMethod', 'referrer',
'headers']
'did-get-redirect-request': ['oldUrl', 'newUrl', 'isMainFrame']
'did-get-redirect-request': ['oldURL', 'newURL', 'isMainFrame']
'dom-ready': []
'console-message': ['level', 'message', 'line', 'sourceId']
'new-window': ['url', 'frameName', 'disposition', 'options']
@ -37,40 +36,40 @@ dispatchEvent = (webView, event, args...) ->
module.exports =
registerEvents: (webView, viewInstanceId) ->
ipc.on "ATOM_SHELL_GUEST_VIEW_INTERNAL_DISPATCH_EVENT-#{viewInstanceId}", (event, domEvent, args...) ->
ipcRenderer.on "ATOM_SHELL_GUEST_VIEW_INTERNAL_DISPATCH_EVENT-#{viewInstanceId}", (event, domEvent, args...) ->
dispatchEvent webView, domEvent, args...
ipc.on "ATOM_SHELL_GUEST_VIEW_INTERNAL_IPC_MESSAGE-#{viewInstanceId}", (event, channel, args...) ->
ipcRenderer.on "ATOM_SHELL_GUEST_VIEW_INTERNAL_IPC_MESSAGE-#{viewInstanceId}", (event, channel, args...) ->
domEvent = new Event('ipc-message')
domEvent.channel = channel
domEvent.args = [args...]
webView.dispatchEvent domEvent
ipc.on "ATOM_SHELL_GUEST_VIEW_INTERNAL_SIZE_CHANGED-#{viewInstanceId}", (event, args...) ->
ipcRenderer.on "ATOM_SHELL_GUEST_VIEW_INTERNAL_SIZE_CHANGED-#{viewInstanceId}", (event, args...) ->
domEvent = new Event('size-changed')
for f, i in ['oldWidth', 'oldHeight', 'newWidth', 'newHeight']
domEvent[f] = args[i]
webView.onSizeChanged domEvent
deregisterEvents: (viewInstanceId) ->
ipc.removeAllListeners "ATOM_SHELL_GUEST_VIEW_INTERNAL_DISPATCH_EVENT-#{viewInstanceId}"
ipc.removeAllListeners "ATOM_SHELL_GUEST_VIEW_INTERNAL_IPC_MESSAGE-#{viewInstanceId}"
ipc.removeAllListeners "ATOM_SHELL_GUEST_VIEW_INTERNAL_SIZE_CHANGED-#{viewInstanceId}"
ipcRenderer.removeAllListeners "ATOM_SHELL_GUEST_VIEW_INTERNAL_DISPATCH_EVENT-#{viewInstanceId}"
ipcRenderer.removeAllListeners "ATOM_SHELL_GUEST_VIEW_INTERNAL_IPC_MESSAGE-#{viewInstanceId}"
ipcRenderer.removeAllListeners "ATOM_SHELL_GUEST_VIEW_INTERNAL_SIZE_CHANGED-#{viewInstanceId}"
createGuest: (params, callback) ->
requestId++
ipc.send 'ATOM_SHELL_GUEST_VIEW_MANAGER_CREATE_GUEST', params, requestId
ipc.once "ATOM_SHELL_RESPONSE_#{requestId}", callback
ipcRenderer.send 'ATOM_SHELL_GUEST_VIEW_MANAGER_CREATE_GUEST', params, requestId
ipcRenderer.once "ATOM_SHELL_RESPONSE_#{requestId}", callback
attachGuest: (elementInstanceId, guestInstanceId, params) ->
ipc.send 'ATOM_SHELL_GUEST_VIEW_MANAGER_ATTACH_GUEST', elementInstanceId, guestInstanceId, params
ipcRenderer.send 'ATOM_SHELL_GUEST_VIEW_MANAGER_ATTACH_GUEST', elementInstanceId, guestInstanceId, params
webFrame.attachGuest elementInstanceId
destroyGuest: (guestInstanceId) ->
ipc.send 'ATOM_SHELL_GUEST_VIEW_MANAGER_DESTROY_GUEST', guestInstanceId
ipcRenderer.send 'ATOM_SHELL_GUEST_VIEW_MANAGER_DESTROY_GUEST', guestInstanceId
setSize: (guestInstanceId, params) ->
ipc.send 'ATOM_SHELL_GUEST_VIEW_MANAGER_SET_SIZE', guestInstanceId, params
ipcRenderer.send 'ATOM_SHELL_GUEST_VIEW_MANAGER_SET_SIZE', guestInstanceId, params
setAllowTransparency: (guestInstanceId, allowtransparency) ->
ipc.send 'ATOM_SHELL_GUEST_VIEW_MANAGER_SET_ALLOW_TRANSPARENCY', guestInstanceId, allowtransparency
ipcRenderer.send 'ATOM_SHELL_GUEST_VIEW_MANAGER_SET_ALLOW_TRANSPARENCY', guestInstanceId, allowtransparency

View file

@ -1,11 +1,12 @@
WebViewImpl = require './web-view'
guestViewInternal = require './guest-view-internal'
webViewConstants = require './web-view-constants'
remote = require 'remote'
{remote} = require 'electron'
# Helper function to resolve url set in attribute.
a = document.createElement 'a'
resolveUrl = (url) ->
resolveURL = (url) ->
a.href = url
a.href
@ -115,7 +116,7 @@ class SrcAttribute extends WebViewAttribute
getValue: ->
if @webViewImpl.webviewNode.hasAttribute @name
resolveUrl @webViewImpl.webviewNode.getAttribute(@name)
resolveURL @webViewImpl.webviewNode.getAttribute(@name)
else
''
@ -177,7 +178,7 @@ class SrcAttribute extends WebViewAttribute
if useragent then opts.userAgent = useragent
guestContents = remote.getGuestWebContents(@webViewImpl.guestInstanceId)
guestContents.loadUrl @getValue(), opts
guestContents.loadURL @getValue(), opts
# Attribute specifies HTTP referrer.
class HttpReferrerAttribute extends WebViewAttribute
@ -196,7 +197,7 @@ class PreloadAttribute extends WebViewAttribute
getValue: ->
return '' unless @webViewImpl.webviewNode.hasAttribute @name
preload = resolveUrl @webViewImpl.webviewNode.getAttribute(@name)
preload = resolveURL @webViewImpl.webviewNode.getAttribute(@name)
protocol = preload.substr 0, 5
unless protocol is 'file:'
console.error webViewConstants.ERROR_MSG_INVALID_PRELOAD_ATTRIBUTE

View file

@ -1,8 +1,8 @@
{deprecate, webFrame, remote} = require 'electron'
v8Util = process.atomBinding 'v8_util'
guestViewInternal = require './guest-view-internal'
webViewConstants = require './web-view-constants'
webFrame = require 'web-frame'
remote = require 'remote'
# ID generator.
nextId = 0
@ -252,49 +252,49 @@ registerWebViewElement = ->
# Public-facing API methods.
methods = [
"getUrl"
"getTitle"
"isLoading"
"isWaitingForResponse"
"stop"
"reload"
"reloadIgnoringCache"
"canGoBack"
"canGoForward"
"canGoToOffset"
"clearHistory"
"goBack"
"goForward"
"goToIndex"
"goToOffset"
"isCrashed"
"setUserAgent"
"getUserAgent"
"executeJavaScript"
"insertCSS"
"openDevTools"
"closeDevTools"
"isDevToolsOpened"
"inspectElement"
"setAudioMuted"
"isAudioMuted"
"undo"
"redo"
"cut"
"copy"
"paste"
"pasteAndMatchStyle"
"delete"
"selectAll"
"unselect"
"replace"
"replaceMisspelling"
"send"
"getId"
"inspectServiceWorker"
"print"
"printToPDF"
"sendInputEvent"
'getURL'
'getTitle'
'isLoading'
'isWaitingForResponse'
'stop'
'reload'
'reloadIgnoringCache'
'canGoBack'
'canGoForward'
'canGoToOffset'
'clearHistory'
'goBack'
'goForward'
'goToIndex'
'goToOffset'
'isCrashed'
'setUserAgent'
'getUserAgent'
'executeJavaScript'
'insertCSS'
'openDevTools'
'closeDevTools'
'isDevToolsOpened'
'inspectElement'
'setAudioMuted'
'isAudioMuted'
'undo'
'redo'
'cut'
'copy'
'paste'
'pasteAndMatchStyle'
'delete'
'selectAll'
'unselect'
'replace'
'replaceMisspelling'
'send'
'getId'
'inspectServiceWorker'
'print'
'printToPDF'
'sendInputEvent'
]
# Forward proto.foo* method calls to WebViewImpl.foo*.
@ -304,6 +304,9 @@ registerWebViewElement = ->
internal.webContents[m] args...
proto[m] = createHandler m for m in methods
# Deprecated.
deprecate.rename proto, 'getUrl', 'getURL'
window.WebView = webFrame.registerEmbedderCustomElement 'webview',
prototype: proto

View file

@ -0,0 +1,74 @@
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/common/chrome_constants.h"
#define FPL FILE_PATH_LITERAL
namespace chrome {
#if defined(OS_MACOSX)
const base::FilePath::CharType kFrameworkName[] =
FPL(ATOM_PRODUCT_NAME " Framework.framework");
#endif // OS_MACOSX
// filenames
const base::FilePath::CharType kCacheDirname[] = FPL("Cache");
const base::FilePath::CharType kChannelIDFilename[] = FPL("Origin Bound Certs");
const base::FilePath::CharType kCookieFilename[] = FPL("Cookies");
const base::FilePath::CharType kCRLSetFilename[] =
FPL("Certificate Revocation Lists");
const base::FilePath::CharType kCustomDictionaryFileName[] =
FPL("Custom Dictionary.txt");
const base::FilePath::CharType kExtensionActivityLogFilename[] =
FPL("Extension Activity");
const base::FilePath::CharType kExtensionsCookieFilename[] =
FPL("Extension Cookies");
const base::FilePath::CharType kFirstRunSentinel[] = FPL("First Run");
const base::FilePath::CharType kGCMStoreDirname[] = FPL("GCM Store");
const base::FilePath::CharType kLocalStateFilename[] = FPL("Local State");
const base::FilePath::CharType kLocalStorePoolName[] = FPL("LocalStorePool");
const base::FilePath::CharType kMediaCacheDirname[] = FPL("Media Cache");
const base::FilePath::CharType kNetworkPersistentStateFilename[] =
FPL("Network Persistent State");
const base::FilePath::CharType kOfflinePageArchviesDirname[] =
FPL("Offline Pages/archives");
const base::FilePath::CharType kOfflinePageMetadataDirname[] =
FPL("Offline Pages/metadata");
const base::FilePath::CharType kPreferencesFilename[] = FPL("Preferences");
const base::FilePath::CharType kProtectedPreferencesFilenameDeprecated[] =
FPL("Protected Preferences");
const base::FilePath::CharType kReadmeFilename[] = FPL("README");
const base::FilePath::CharType kResetPromptMementoFilename[] =
FPL("Reset Prompt Memento");
const base::FilePath::CharType kSafeBrowsingBaseFilename[] =
FPL("Safe Browsing");
const base::FilePath::CharType kSecurePreferencesFilename[] =
FPL("Secure Preferences");
const base::FilePath::CharType kServiceStateFileName[] = FPL("Service State");
const base::FilePath::CharType kSingletonCookieFilename[] =
FPL("SingletonCookie");
const base::FilePath::CharType kSingletonLockFilename[] = FPL("SingletonLock");
const base::FilePath::CharType kSingletonSocketFilename[] =
FPL("SingletonSocket");
const base::FilePath::CharType kSupervisedUserSettingsFilename[] =
FPL("Managed Mode Settings");
const base::FilePath::CharType kThemePackFilename[] = FPL("Cached Theme.pak");
const base::FilePath::CharType kThemePackMaterialDesignFilename[] =
FPL("Cached Theme Material Design.pak");
const base::FilePath::CharType kWebAppDirname[] = FPL("Web Applications");
// File name of the Pepper Flash plugin on different platforms.
const base::FilePath::CharType kPepperFlashPluginFilename[] =
#if defined(OS_MACOSX)
FPL("PepperFlashPlayer.plugin");
#elif defined(OS_WIN)
FPL("pepflashplayer.dll");
#else // OS_LINUX, etc.
FPL("libpepflashplayer.so");
#endif
} // namespace chrome
#undef FPL

View file

@ -0,0 +1,58 @@
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// A handful of resource-like constants related to the Chrome application.
#ifndef CHROME_COMMON_CHROME_CONSTANTS_H_
#define CHROME_COMMON_CHROME_CONSTANTS_H_
#include "base/files/file_path.h"
namespace chrome {
#if defined(OS_MACOSX)
// NOTE: if you change the value of kFrameworkName, please don't forget to
// update components/test/run_all_unittests.cc as well.
// TODO(tfarina): Remove the comment above, when you fix components to use plist
// on Mac.
extern const base::FilePath::CharType kFrameworkName[];
#endif // OS_MACOSX
// filenames
extern const base::FilePath::CharType kCacheDirname[];
extern const base::FilePath::CharType kChannelIDFilename[];
extern const base::FilePath::CharType kCookieFilename[];
extern const base::FilePath::CharType kCRLSetFilename[];
extern const base::FilePath::CharType kCustomDictionaryFileName[];
extern const base::FilePath::CharType kExtensionActivityLogFilename[];
extern const base::FilePath::CharType kExtensionsCookieFilename[];
extern const base::FilePath::CharType kFirstRunSentinel[];
extern const base::FilePath::CharType kGCMStoreDirname[];
extern const base::FilePath::CharType kLocalStateFilename[];
extern const base::FilePath::CharType kLocalStorePoolName[];
extern const base::FilePath::CharType kMediaCacheDirname[];
extern const base::FilePath::CharType kNetworkPersistentStateFilename[];
extern const base::FilePath::CharType kOfflinePageArchviesDirname[];
extern const base::FilePath::CharType kOfflinePageMetadataDirname[];
extern const base::FilePath::CharType kPreferencesFilename[];
extern const base::FilePath::CharType kProtectedPreferencesFilenameDeprecated[];
extern const base::FilePath::CharType kReadmeFilename[];
extern const base::FilePath::CharType kResetPromptMementoFilename[];
extern const base::FilePath::CharType kSafeBrowsingBaseFilename[];
extern const base::FilePath::CharType kSecurePreferencesFilename[];
extern const base::FilePath::CharType kServiceStateFileName[];
extern const base::FilePath::CharType kSingletonCookieFilename[];
extern const base::FilePath::CharType kSingletonLockFilename[];
extern const base::FilePath::CharType kSingletonSocketFilename[];
extern const base::FilePath::CharType kSupervisedUserSettingsFilename[];
extern const base::FilePath::CharType kThemePackFilename[];
extern const base::FilePath::CharType kThemePackMaterialDesignFilename[];
extern const base::FilePath::CharType kWebAppDirname[];
// File name of the Pepper Flash plugin on different platforms.
extern const base::FilePath::CharType kPepperFlashPluginFilename[];
} // namespace chrome
#endif // CHROME_COMMON_CHROME_CONSTANTS_H_

View file

@ -0,0 +1,610 @@
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/common/chrome_paths.h"
#include "base/files/file_util.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/mac/bundle_locations.h"
#include "base/path_service.h"
#include "base/strings/string_util.h"
#include "base/sys_info.h"
#include "base/threading/thread_restrictions.h"
#include "base/version.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths_internal.h"
#if defined(OS_ANDROID)
#include "base/android/path_utils.h"
#include "base/base_paths_android.h"
// ui/base must only be used on Android. See BUILD.gn for dependency info.
#include "ui/base/ui_base_paths.h" // nogncheck
#endif
#if defined(OS_MACOSX)
#include "base/mac/foundation_util.h"
#endif
#if defined(OS_WIN)
#include "base/win/registry.h"
#endif
namespace {
// The Pepper Flash plugins are in a directory with this name.
const base::FilePath::CharType kPepperFlashBaseDirectory[] =
FILE_PATH_LITERAL("PepperFlash");
#if defined(OS_MACOSX) && !defined(OS_IOS)
const base::FilePath::CharType kPepperFlashSystemBaseDirectory[] =
FILE_PATH_LITERAL("Internet Plug-Ins/PepperFlashPlayer");
const base::FilePath::CharType kFlashSystemBaseDirectory[] =
FILE_PATH_LITERAL("Internet Plug-Ins");
const base::FilePath::CharType kFlashSystemPluginName[] =
FILE_PATH_LITERAL("Flash Player.plugin");
#endif
const base::FilePath::CharType kInternalNaClPluginFileName[] =
FILE_PATH_LITERAL("internal-nacl-plugin");
#if defined(OS_LINUX)
// The path to the external extension <id>.json files.
// /usr/share seems like a good choice, see: http://www.pathname.com/fhs/
const base::FilePath::CharType kFilepathSinglePrefExtensions[] =
#if defined(GOOGLE_CHROME_BUILD)
FILE_PATH_LITERAL("/usr/share/google-chrome/extensions");
#else
FILE_PATH_LITERAL("/usr/share/chromium/extensions");
#endif // defined(GOOGLE_CHROME_BUILD)
// The path to the hint file that tells the pepper plugin loader
// where it can find the latest component updated flash.
const base::FilePath::CharType kComponentUpdatedFlashHint[] =
FILE_PATH_LITERAL("latest-component-updated-flash");
#endif // defined(OS_LINUX)
static base::LazyInstance<base::FilePath>
g_invalid_specified_user_data_dir = LAZY_INSTANCE_INITIALIZER;
// Gets the path for internal plugins.
bool GetInternalPluginsDirectory(base::FilePath* result) {
#if defined(OS_MACOSX) && !defined(OS_IOS)
// If called from Chrome, get internal plugins from a subdirectory of the
// framework.
if (base::mac::AmIBundled()) {
*result = chrome::GetFrameworkBundlePath();
DCHECK(!result->empty());
*result = result->Append("Internet Plug-Ins");
return true;
}
// In tests, just look in the module directory (below).
#endif
// The rest of the world expects plugins in the module directory.
return PathService::Get(base::DIR_MODULE, result);
}
#if defined(OS_WIN)
// Gets the Flash path if installed on the system. |is_npapi| determines whether
// to return the NPAPI of the PPAPI version of the system plugin.
bool GetSystemFlashFilename(base::FilePath* out_path, bool is_npapi) {
const wchar_t kNpapiFlashRegistryRoot[] =
L"SOFTWARE\\Macromedia\\FlashPlayerPlugin";
const wchar_t kPepperFlashRegistryRoot[] =
L"SOFTWARE\\Macromedia\\FlashPlayerPepper";
const wchar_t kFlashPlayerPathValueName[] = L"PlayerPath";
base::win::RegKey path_key(
HKEY_LOCAL_MACHINE,
is_npapi ? kNpapiFlashRegistryRoot : kPepperFlashRegistryRoot, KEY_READ);
base::string16 path_str;
if (FAILED(path_key.ReadValue(kFlashPlayerPathValueName, &path_str)))
return false;
*out_path = base::FilePath(path_str);
return true;
}
#endif
} // namespace
namespace chrome {
bool PathProvider(int key, base::FilePath* result) {
// Some keys are just aliases...
switch (key) {
case chrome::DIR_APP:
return PathService::Get(base::DIR_MODULE, result);
case chrome::DIR_LOGS:
#ifdef NDEBUG
// Release builds write to the data dir
return PathService::Get(chrome::DIR_USER_DATA, result);
#else
// Debug builds write next to the binary (in the build tree)
#if defined(OS_MACOSX)
if (!PathService::Get(base::DIR_EXE, result))
return false;
if (base::mac::AmIBundled()) {
// If we're called from chrome, dump it beside the app (outside the
// app bundle), if we're called from a unittest, we'll already
// outside the bundle so use the exe dir.
// exe_dir gave us .../Chromium.app/Contents/MacOS/Chromium.
*result = result->DirName();
*result = result->DirName();
*result = result->DirName();
}
return true;
#else
return PathService::Get(base::DIR_EXE, result);
#endif // defined(OS_MACOSX)
#endif // NDEBUG
case chrome::FILE_RESOURCE_MODULE:
return PathService::Get(base::FILE_MODULE, result);
}
// Assume that we will not need to create the directory if it does not exist.
// This flag can be set to true for the cases where we want to create it.
bool create_dir = false;
base::FilePath cur;
switch (key) {
case chrome::DIR_USER_DATA:
if (!GetDefaultUserDataDirectory(&cur)) {
NOTREACHED();
return false;
}
create_dir = true;
break;
case chrome::DIR_USER_DOCUMENTS:
if (!GetUserDocumentsDirectory(&cur))
return false;
create_dir = true;
break;
case chrome::DIR_USER_MUSIC:
if (!GetUserMusicDirectory(&cur))
return false;
break;
case chrome::DIR_USER_PICTURES:
if (!GetUserPicturesDirectory(&cur))
return false;
break;
case chrome::DIR_USER_VIDEOS:
if (!GetUserVideosDirectory(&cur))
return false;
break;
case chrome::DIR_DEFAULT_DOWNLOADS_SAFE:
#if defined(OS_WIN) || defined(OS_LINUX)
if (!GetUserDownloadsDirectorySafe(&cur))
return false;
break;
#else
// Fall through for all other platforms.
#endif
case chrome::DIR_DEFAULT_DOWNLOADS:
#if defined(OS_ANDROID)
if (!base::android::GetDownloadsDirectory(&cur))
return false;
#else
if (!GetUserDownloadsDirectory(&cur))
return false;
// Do not create the download directory here, we have done it twice now
// and annoyed a lot of users.
#endif
break;
case chrome::DIR_CRASH_DUMPS:
#if defined(OS_CHROMEOS)
// ChromeOS uses a separate directory. See http://crosbug.com/25089
cur = base::FilePath("/var/log/chrome");
#elif defined(OS_ANDROID)
if (!base::android::GetCacheDirectory(&cur))
return false;
#else
// The crash reports are always stored relative to the default user data
// directory. This avoids the problem of having to re-initialize the
// exception handler after parsing command line options, which may
// override the location of the app's profile directory.
if (!GetDefaultUserDataDirectory(&cur))
return false;
#endif
#if defined(OS_MACOSX)
cur = cur.Append(FILE_PATH_LITERAL("Crashpad"));
#else
cur = cur.Append(FILE_PATH_LITERAL("Crash Reports"));
#endif
create_dir = true;
break;
#if defined(OS_WIN)
case chrome::DIR_WATCHER_DATA:
// The watcher data is always stored relative to the default user data
// directory. This allows the watcher to be initialized before
// command-line options have been parsed.
if (!GetDefaultUserDataDirectory(&cur))
return false;
cur = cur.Append(FILE_PATH_LITERAL("Diagnostics"));
break;
#endif
case chrome::DIR_RESOURCES:
#if defined(OS_MACOSX)
cur = base::mac::FrameworkBundlePath();
cur = cur.Append(FILE_PATH_LITERAL("Resources"));
#else
if (!PathService::Get(chrome::DIR_APP, &cur))
return false;
cur = cur.Append(FILE_PATH_LITERAL("resources"));
#endif
break;
case chrome::DIR_INSPECTOR:
if (!PathService::Get(chrome::DIR_RESOURCES, &cur))
return false;
cur = cur.Append(FILE_PATH_LITERAL("inspector"));
break;
case chrome::DIR_APP_DICTIONARIES:
#if defined(OS_POSIX)
// We can't write into the EXE dir on Linux, so keep dictionaries
// alongside the safe browsing database in the user data dir.
// And we don't want to write into the bundle on the Mac, so push
// it to the user data dir there also.
if (!PathService::Get(chrome::DIR_USER_DATA, &cur))
return false;
#else
if (!PathService::Get(base::DIR_EXE, &cur))
return false;
#endif
cur = cur.Append(FILE_PATH_LITERAL("Dictionaries"));
create_dir = true;
break;
case chrome::DIR_INTERNAL_PLUGINS:
if (!GetInternalPluginsDirectory(&cur))
return false;
break;
case chrome::DIR_PEPPER_FLASH_PLUGIN:
if (!GetInternalPluginsDirectory(&cur))
return false;
cur = cur.Append(kPepperFlashBaseDirectory);
break;
case chrome::DIR_COMPONENT_UPDATED_PEPPER_FLASH_PLUGIN:
if (!PathService::Get(chrome::DIR_USER_DATA, &cur))
return false;
cur = cur.Append(kPepperFlashBaseDirectory);
break;
case chrome::FILE_PEPPER_FLASH_SYSTEM_PLUGIN:
#if defined(OS_WIN)
if (!GetSystemFlashFilename(&cur, false))
return false;
#elif defined(OS_MACOSX) && !defined(OS_IOS)
if (!GetLocalLibraryDirectory(&cur))
return false;
cur = cur.Append(kPepperFlashSystemBaseDirectory);
cur = cur.Append(chrome::kPepperFlashPluginFilename);
#else
// Chrome on iOS does not supports PPAPI binaries, return false.
// TODO(wfh): If Adobe release PPAPI binaries for Linux, add support here.
return false;
#endif
break;
case chrome::FILE_FLASH_SYSTEM_PLUGIN:
#if defined(OS_WIN)
if (!GetSystemFlashFilename(&cur, true))
return false;
#elif defined(OS_MACOSX) && !defined(OS_IOS)
if (!GetLocalLibraryDirectory(&cur))
return false;
cur = cur.Append(kFlashSystemBaseDirectory);
cur = cur.Append(kFlashSystemPluginName);
#else
// Chrome on other platforms does not supports system NPAPI binaries.
return false;
#endif
break;
case chrome::FILE_LOCAL_STATE:
if (!PathService::Get(chrome::DIR_USER_DATA, &cur))
return false;
cur = cur.Append(chrome::kLocalStateFilename);
break;
case chrome::FILE_RECORDED_SCRIPT:
if (!PathService::Get(chrome::DIR_USER_DATA, &cur))
return false;
cur = cur.Append(FILE_PATH_LITERAL("script.log"));
break;
case chrome::FILE_PEPPER_FLASH_PLUGIN:
if (!PathService::Get(chrome::DIR_PEPPER_FLASH_PLUGIN, &cur))
return false;
cur = cur.Append(chrome::kPepperFlashPluginFilename);
break;
// TODO(teravest): Remove this case once the internal NaCl plugin is gone.
// We currently need a path here to look up whether the plugin is disabled
// and what its permissions are.
case chrome::FILE_NACL_PLUGIN:
if (!GetInternalPluginsDirectory(&cur))
return false;
cur = cur.Append(kInternalNaClPluginFileName);
break;
// PNaCl is currenly installable via the component updater or by being
// simply built-in. DIR_PNACL_BASE is used as the base directory for
// installation via component updater. DIR_PNACL_COMPONENT will be
// the final location of pnacl, which is a subdir of DIR_PNACL_BASE.
case chrome::DIR_PNACL_BASE:
if (!PathService::Get(chrome::DIR_USER_DATA, &cur))
return false;
cur = cur.Append(FILE_PATH_LITERAL("pnacl"));
break;
// Where PNaCl files are ultimately located. The default finds the files
// inside the InternalPluginsDirectory / build directory, as if it
// was shipped along with chrome. The value can be overridden
// if it is installed via component updater.
case chrome::DIR_PNACL_COMPONENT:
#if defined(OS_MACOSX)
// PNaCl really belongs in the InternalPluginsDirectory but actually
// copying it there would result in the files also being shipped, which
// we don't want yet. So for now, just find them in the directory where
// they get built.
if (!PathService::Get(base::DIR_EXE, &cur))
return false;
if (base::mac::AmIBundled()) {
// If we're called from chrome, it's beside the app (outside the
// app bundle), if we're called from a unittest, we'll already be
// outside the bundle so use the exe dir.
// exe_dir gave us .../Chromium.app/Contents/MacOS/Chromium.
cur = cur.DirName();
cur = cur.DirName();
cur = cur.DirName();
}
#else
if (!GetInternalPluginsDirectory(&cur))
return false;
#endif
cur = cur.Append(FILE_PATH_LITERAL("pnacl"));
break;
#if defined(WIDEVINE_CDM_AVAILABLE) && defined(ENABLE_PEPPER_CDMS)
#if defined(WIDEVINE_CDM_IS_COMPONENT)
case chrome::DIR_COMPONENT_WIDEVINE_CDM:
if (!PathService::Get(chrome::DIR_USER_DATA, &cur))
return false;
cur = cur.Append(FILE_PATH_LITERAL("WidevineCDM"));
break;
#endif // defined(WIDEVINE_CDM_IS_COMPONENT)
// TODO(xhwang): FILE_WIDEVINE_CDM_ADAPTER has different meanings.
// In the component case, this is the source adapter. Otherwise, it is the
// actual Pepper module that gets loaded.
case chrome::FILE_WIDEVINE_CDM_ADAPTER:
if (!GetInternalPluginsDirectory(&cur))
return false;
cur = cur.AppendASCII(kWidevineCdmAdapterFileName);
break;
#endif // defined(WIDEVINE_CDM_AVAILABLE) && defined(ENABLE_PEPPER_CDMS)
case chrome::FILE_RESOURCES_PACK:
#if defined(OS_MACOSX) && !defined(OS_IOS)
if (base::mac::AmIBundled()) {
cur = base::mac::FrameworkBundlePath();
cur = cur.Append(FILE_PATH_LITERAL("Resources"))
.Append(FILE_PATH_LITERAL("resources.pak"));
break;
}
#elif defined(OS_ANDROID)
if (!PathService::Get(ui::DIR_RESOURCE_PAKS_ANDROID, &cur))
return false;
#else
// If we're not bundled on mac or Android, resources.pak should be next
// to the binary (e.g., for unit tests).
if (!PathService::Get(base::DIR_MODULE, &cur))
return false;
#endif
cur = cur.Append(FILE_PATH_LITERAL("resources.pak"));
break;
case chrome::DIR_RESOURCES_EXTENSION:
if (!PathService::Get(base::DIR_MODULE, &cur))
return false;
cur = cur.Append(FILE_PATH_LITERAL("resources"))
.Append(FILE_PATH_LITERAL("extension"));
break;
#if defined(OS_CHROMEOS)
case chrome::DIR_CHROMEOS_WALLPAPERS:
if (!PathService::Get(chrome::DIR_USER_DATA, &cur))
return false;
cur = cur.Append(FILE_PATH_LITERAL("wallpapers"));
break;
case chrome::DIR_CHROMEOS_WALLPAPER_THUMBNAILS:
if (!PathService::Get(chrome::DIR_USER_DATA, &cur))
return false;
cur = cur.Append(FILE_PATH_LITERAL("wallpaper_thumbnails"));
break;
case chrome::DIR_CHROMEOS_CUSTOM_WALLPAPERS:
if (!PathService::Get(chrome::DIR_USER_DATA, &cur))
return false;
cur = cur.Append(FILE_PATH_LITERAL("custom_wallpapers"));
break;
#endif
#if defined(ENABLE_SUPERVISED_USERS)
#if defined(OS_LINUX)
case chrome::DIR_SUPERVISED_USERS_DEFAULT_APPS:
if (!PathService::Get(chrome::DIR_STANDALONE_EXTERNAL_EXTENSIONS, &cur))
return false;
cur = cur.Append(FILE_PATH_LITERAL("managed_users"));
break;
#endif
case chrome::DIR_SUPERVISED_USER_INSTALLED_WHITELISTS:
if (!PathService::Get(chrome::DIR_USER_DATA, &cur))
return false;
cur = cur.Append(FILE_PATH_LITERAL("SupervisedUserInstalledWhitelists"));
break;
#endif
// The following are only valid in the development environment, and
// will fail if executed from an installed executable (because the
// generated path won't exist).
case chrome::DIR_GEN_TEST_DATA:
#if defined(OS_ANDROID)
// On Android, our tests don't have permission to write to DIR_MODULE.
// gtest/test_runner.py pushes data to external storage.
if (!PathService::Get(base::DIR_ANDROID_EXTERNAL_STORAGE, &cur))
return false;
#else
if (!PathService::Get(base::DIR_MODULE, &cur))
return false;
#endif
cur = cur.Append(FILE_PATH_LITERAL("test_data"));
if (!base::PathExists(cur)) // We don't want to create this.
return false;
break;
case chrome::DIR_TEST_DATA:
if (!PathService::Get(base::DIR_SOURCE_ROOT, &cur))
return false;
cur = cur.Append(FILE_PATH_LITERAL("chrome"));
cur = cur.Append(FILE_PATH_LITERAL("test"));
cur = cur.Append(FILE_PATH_LITERAL("data"));
if (!base::PathExists(cur)) // We don't want to create this.
return false;
break;
case chrome::DIR_TEST_TOOLS:
if (!PathService::Get(base::DIR_SOURCE_ROOT, &cur))
return false;
cur = cur.Append(FILE_PATH_LITERAL("chrome"));
cur = cur.Append(FILE_PATH_LITERAL("tools"));
cur = cur.Append(FILE_PATH_LITERAL("test"));
if (!base::PathExists(cur)) // We don't want to create this
return false;
break;
#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_OPENBSD)
case chrome::DIR_POLICY_FILES: {
#if defined(GOOGLE_CHROME_BUILD)
cur = base::FilePath(FILE_PATH_LITERAL("/etc/opt/chrome/policies"));
#else
cur = base::FilePath(FILE_PATH_LITERAL("/etc/chromium/policies"));
#endif
break;
}
#endif
#if defined(OS_MACOSX) && !defined(OS_IOS)
case chrome::DIR_USER_LIBRARY: {
if (!GetUserLibraryDirectory(&cur))
return false;
if (!base::PathExists(cur)) // We don't want to create this.
return false;
break;
}
case chrome::DIR_USER_APPLICATIONS: {
if (!GetUserApplicationsDirectory(&cur))
return false;
if (!base::PathExists(cur)) // We don't want to create this.
return false;
break;
}
#endif
#if defined(OS_CHROMEOS) || (defined(OS_LINUX) && defined(CHROMIUM_BUILD)) || \
(defined(OS_MACOSX) && !defined(OS_IOS))
case chrome::DIR_USER_EXTERNAL_EXTENSIONS: {
if (!PathService::Get(chrome::DIR_USER_DATA, &cur))
return false;
cur = cur.Append(FILE_PATH_LITERAL("External Extensions"));
break;
}
#endif
#if defined(OS_LINUX)
case chrome::DIR_STANDALONE_EXTERNAL_EXTENSIONS: {
cur = base::FilePath(kFilepathSinglePrefExtensions);
break;
}
#endif
case chrome::DIR_EXTERNAL_EXTENSIONS:
#if defined(OS_MACOSX) && !defined(OS_IOS)
if (!chrome::GetGlobalApplicationSupportDirectory(&cur))
return false;
cur = cur.Append(FILE_PATH_LITERAL("Google"))
.Append(FILE_PATH_LITERAL("Chrome"))
.Append(FILE_PATH_LITERAL("External Extensions"));
create_dir = false;
#else
if (!PathService::Get(base::DIR_MODULE, &cur))
return false;
cur = cur.Append(FILE_PATH_LITERAL("extensions"));
create_dir = true;
#endif
break;
case chrome::DIR_DEFAULT_APPS:
#if defined(OS_MACOSX)
cur = base::mac::FrameworkBundlePath();
cur = cur.Append(FILE_PATH_LITERAL("Default Apps"));
#else
if (!PathService::Get(chrome::DIR_APP, &cur))
return false;
cur = cur.Append(FILE_PATH_LITERAL("default_apps"));
#endif
break;
#if defined(OS_LINUX) || (defined(OS_MACOSX) && !defined(OS_IOS))
case chrome::DIR_NATIVE_MESSAGING:
#if defined(OS_MACOSX)
#if defined(GOOGLE_CHROME_BUILD)
cur = base::FilePath(FILE_PATH_LITERAL(
"/Library/Google/Chrome/NativeMessagingHosts"));
#else
cur = base::FilePath(FILE_PATH_LITERAL(
"/Library/Application Support/Chromium/NativeMessagingHosts"));
#endif
#else // defined(OS_MACOSX)
#if defined(GOOGLE_CHROME_BUILD)
cur = base::FilePath(FILE_PATH_LITERAL(
"/etc/opt/chrome/native-messaging-hosts"));
#else
cur = base::FilePath(FILE_PATH_LITERAL(
"/etc/chromium/native-messaging-hosts"));
#endif
#endif // !defined(OS_MACOSX)
break;
case chrome::DIR_USER_NATIVE_MESSAGING:
if (!PathService::Get(chrome::DIR_USER_DATA, &cur))
return false;
cur = cur.Append(FILE_PATH_LITERAL("NativeMessagingHosts"));
break;
#endif // defined(OS_LINUX) || (defined(OS_MACOSX) && !defined(OS_IOS))
#if !defined(OS_ANDROID)
case chrome::DIR_GLOBAL_GCM_STORE:
if (!PathService::Get(chrome::DIR_USER_DATA, &cur))
return false;
cur = cur.Append(kGCMStoreDirname);
break;
#endif // !defined(OS_ANDROID)
#if defined(OS_LINUX)
case chrome::FILE_COMPONENT_FLASH_HINT:
if (!PathService::Get(chrome::DIR_COMPONENT_UPDATED_PEPPER_FLASH_PLUGIN,
&cur)) {
return false;
}
cur = cur.Append(kComponentUpdatedFlashHint);
break;
#endif // defined(OS_LINUX)
default:
return false;
}
// TODO(bauerb): http://crbug.com/259796
base::ThreadRestrictions::ScopedAllowIO allow_io;
if (create_dir && !base::PathExists(cur) &&
!base::CreateDirectory(cur))
return false;
*result = cur;
return true;
}
// This cannot be done as a static initializer sadly since Visual Studio will
// eliminate this object file if there is no direct entry point into it.
void RegisterPathProvider() {
PathService::RegisterProvider(PathProvider, PATH_START, PATH_END);
}
void SetInvalidSpecifiedUserDataDir(const base::FilePath& user_data_dir) {
g_invalid_specified_user_data_dir.Get() = user_data_dir;
}
const base::FilePath& GetInvalidSpecifiedUserDataDir() {
return g_invalid_specified_user_data_dir.Get();
}
} // namespace chrome

View file

@ -0,0 +1,152 @@
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_COMMON_CHROME_PATHS_H__
#define CHROME_COMMON_CHROME_PATHS_H__
#include "build/build_config.h"
namespace base {
class FilePath;
}
// This file declares path keys for the chrome module. These can be used with
// the PathService to access various special directories and files.
namespace chrome {
enum {
PATH_START = 1000,
DIR_APP = PATH_START, // Directory where dlls and data reside.
DIR_LOGS, // Directory where logs should be written.
DIR_USER_DATA, // Directory where user data can be written.
DIR_CRASH_DUMPS, // Directory where crash dumps are written.
#if defined(OS_WIN)
DIR_WATCHER_DATA, // Directory where the Chrome watcher stores
// data.
#endif
DIR_RESOURCES, // Directory containing separate file resources
// used by Chrome at runtime.
DIR_INSPECTOR, // Directory where web inspector is located.
DIR_APP_DICTIONARIES, // Directory where the global dictionaries are.
DIR_USER_DOCUMENTS, // Directory for a user's "My Documents".
DIR_USER_MUSIC, // Directory for a user's music.
DIR_USER_PICTURES, // Directory for a user's pictures.
DIR_USER_VIDEOS, // Directory for a user's videos.
DIR_DEFAULT_DOWNLOADS_SAFE, // Directory for a user's
// "My Documents/Downloads", (Windows) or
// "Downloads". (Linux)
DIR_DEFAULT_DOWNLOADS, // Directory for a user's downloads.
DIR_INTERNAL_PLUGINS, // Directory where internal plugins reside.
#if defined(OS_POSIX) && !defined(OS_MACOSX)
DIR_POLICY_FILES, // Directory for system-wide read-only
// policy files that allow sys-admins
// to set policies for chrome. This directory
// contains subdirectories.
#endif
#if defined(OS_MACOSX) && !defined(OS_IOS)
DIR_USER_APPLICATIONS, // ~/Applications
DIR_USER_LIBRARY, // ~/Library
#endif
#if defined(OS_CHROMEOS) || (defined(OS_LINUX) && defined(CHROMIUM_BUILD)) || \
(defined(OS_MACOSX) && !defined(OS_IOS))
DIR_USER_EXTERNAL_EXTENSIONS, // Directory for per-user external extensions
// on Chrome Mac and Chromium Linux.
// On Chrome OS, this path is used for OEM
// customization. Getting this path does not
// create it.
#endif
#if defined(OS_LINUX)
DIR_STANDALONE_EXTERNAL_EXTENSIONS, // Directory for 'per-extension'
// definition manifest files that
// describe extensions which are to be
// installed when chrome is run.
#endif
DIR_EXTERNAL_EXTENSIONS, // Directory where installer places .crx files.
DIR_DEFAULT_APPS, // Directory where installer places .crx files
// to be installed when chrome is first run.
DIR_PEPPER_FLASH_PLUGIN, // Directory to the bundled Pepper Flash plugin,
// containing the plugin and the manifest.
DIR_COMPONENT_UPDATED_PEPPER_FLASH_PLUGIN, // Base directory of the Pepper
// Flash plugins downloaded by the
// component updater.
FILE_RESOURCE_MODULE, // Full path and filename of the module that
// contains embedded resources (version,
// strings, images, etc.).
FILE_LOCAL_STATE, // Path and filename to the file in which
// machine/installation-specific state is saved.
FILE_RECORDED_SCRIPT, // Full path to the script.log file that
// contains recorded browser events for
// playback.
FILE_PEPPER_FLASH_PLUGIN, // Full path to the bundled Pepper Flash plugin
// file.
FILE_PEPPER_FLASH_SYSTEM_PLUGIN, // Full path to the system version of the
// Pepper Flash plugin, downloadable from
// Adobe website. Querying this path might
// succeed no matter the file exists or not.
FILE_FLASH_SYSTEM_PLUGIN, // Full path to the system version of NPAPI
// Flash plugin, downloadable from Adobe
// website. Querying this path might succeed no
// matter the file exists or not.
FILE_NACL_PLUGIN, // Full path to the internal NaCl plugin file.
DIR_PNACL_BASE, // Full path to the base dir for PNaCl.
DIR_PNACL_COMPONENT, // Full path to the latest PNaCl version
// (subdir of DIR_PNACL_BASE).
DIR_COMPONENT_WIDEVINE_CDM, // Directory that contains component-updated
// Widevine CDM files.
FILE_WIDEVINE_CDM_ADAPTER, // Full path to the Widevine CDM adapter file.
FILE_RESOURCES_PACK, // Full path to the .pak file containing
// binary data (e.g., html files and images
// used by internal pages).
DIR_RESOURCES_EXTENSION, // Full path to extension resources.
#if defined(OS_CHROMEOS)
DIR_CHROMEOS_WALLPAPERS, // Directory where downloaded chromeos
// wallpapers reside.
DIR_CHROMEOS_WALLPAPER_THUMBNAILS, // Directory where downloaded chromeos
// wallpaper thumbnails reside.
DIR_CHROMEOS_CUSTOM_WALLPAPERS, // Directory where custom wallpapers
// reside.
#endif
DIR_SUPERVISED_USERS_DEFAULT_APPS, // Directory where installer places .crx
// files to be installed when managed user
// session starts.
DIR_SUPERVISED_USER_INSTALLED_WHITELISTS, // Directory where sanitized
// supervised user whitelists are
// installed.
#if defined(OS_LINUX) || (defined(OS_MACOSX) && !defined(OS_IOS))
DIR_NATIVE_MESSAGING, // System directory where native messaging host
// manifest files are stored.
DIR_USER_NATIVE_MESSAGING, // Directory with Native Messaging Hosts
// installed per-user.
#endif
#if !defined(OS_ANDROID)
DIR_GLOBAL_GCM_STORE, // Directory where the global GCM instance
// stores its data.
#endif
// Valid only in development environment; TODO(darin): move these
DIR_GEN_TEST_DATA, // Directory where generated test data resides.
DIR_TEST_DATA, // Directory where unit test data resides.
DIR_TEST_TOOLS, // Directory where unit test tools reside.
#if defined(OS_LINUX)
FILE_COMPONENT_FLASH_HINT, // A file in a known location that points to
// the component updated flash plugin.
#endif // defined(OS_LINUX)
PATH_END
};
// Call once to register the provider for the path keys defined above.
void RegisterPathProvider();
// Get or set the invalid user data dir that was originally specified.
void SetInvalidSpecifiedUserDataDir(const base::FilePath& user_data_dir);
const base::FilePath& GetInvalidSpecifiedUserDataDir();
} // namespace chrome
#endif // CHROME_COMMON_CHROME_PATHS_H__

View file

@ -0,0 +1,112 @@
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_COMMON_CHROME_PATHS_INTERNAL_H_
#define CHROME_COMMON_CHROME_PATHS_INTERNAL_H_
#include <string>
#include "build/build_config.h"
#if defined(OS_MACOSX)
#if defined(__OBJC__)
@class NSBundle;
#else
class NSBundle;
#endif
#endif
namespace base {
class FilePath;
}
namespace chrome {
// Get the path to the user's data directory, regardless of whether
// DIR_USER_DATA has been overridden by a command-line option.
bool GetDefaultUserDataDirectory(base::FilePath* result);
// Get the path to the user's cache directory. This is normally the
// same as the profile directory, but on Linux it can also be
// $XDG_CACHE_HOME and on Mac it can be under ~/Library/Caches.
// Note that the Chrome cache directories are actually subdirectories
// of this directory, with names like "Cache" and "Media Cache".
// This will always fill in |result| with a directory, sometimes
// just |profile_dir|.
void GetUserCacheDirectory(const base::FilePath& profile_dir, base::FilePath* result);
// Get the path to the user's documents directory.
bool GetUserDocumentsDirectory(base::FilePath* result);
#if defined(OS_WIN) || defined(OS_LINUX)
// Gets the path to a safe default download directory for a user.
bool GetUserDownloadsDirectorySafe(base::FilePath* result);
#endif
// Get the path to the user's downloads directory.
bool GetUserDownloadsDirectory(base::FilePath* result);
// Gets the path to the user's music directory.
bool GetUserMusicDirectory(base::FilePath* result);
// Gets the path to the user's pictures directory.
bool GetUserPicturesDirectory(base::FilePath* result);
// Gets the path to the user's videos directory.
bool GetUserVideosDirectory(base::FilePath* result);
#if defined(OS_MACOSX) && !defined(OS_IOS)
// The "versioned directory" is a directory in the browser .app bundle. It
// contains the bulk of the application, except for the things that the system
// requires be located at spepcific locations. The versioned directory is
// in the .app at Contents/Versions/w.x.y.z.
base::FilePath GetVersionedDirectory();
// This overrides the directory returned by |GetVersionedDirectory()|, to be
// used when |GetVersionedDirectory()| can't automatically determine the proper
// location. This is the case when the browser didn't load itself but by, e.g.,
// the app mode loader. This should be called before |ChromeMain()|. This takes
// ownership of the object |path| and the caller must not delete it.
void SetOverrideVersionedDirectory(const base::FilePath* path);
// Most of the application is further contained within the framework. The
// framework bundle is located within the versioned directory at a specific
// path. The only components in the versioned directory not included in the
// framework are things that also depend on the framework, such as the helper
// app bundle.
base::FilePath GetFrameworkBundlePath();
// Get the local library directory.
bool GetLocalLibraryDirectory(base::FilePath* result);
// Get the user library directory.
bool GetUserLibraryDirectory(base::FilePath* result);
// Get the user applications directory.
bool GetUserApplicationsDirectory(base::FilePath* result);
// Get the global Application Support directory (under /Library/).
bool GetGlobalApplicationSupportDirectory(base::FilePath* result);
// Returns the NSBundle for the outer browser application, even when running
// inside the helper. In unbundled applications, such as tests, returns nil.
NSBundle* OuterAppBundle();
// Get the user data directory for the Chrome browser bundle at |bundle|.
// |bundle| should be the same value that would be returned from +[NSBundle
// mainBundle] if Chrome were launched normaly. This is used by app shims,
// which run from a bundle which isn't Chrome itself, but which need access to
// the user data directory to connect to a UNIX-domain socket therein.
// Returns false if there was a problem fetching the app data directory.
bool GetUserDataDirectoryForBrowserBundle(NSBundle* bundle,
base::FilePath* result);
#endif // OS_MACOSX && !OS_IOS
// Checks if the |process_type| has the rights to access the profile.
bool ProcessNeedsProfileDir(const std::string& process_type);
} // namespace chrome
#endif // CHROME_COMMON_CHROME_PATHS_INTERNAL_H_

View file

@ -0,0 +1,145 @@
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/common/chrome_paths_internal.h"
#include "base/base_paths.h"
#include "base/environment.h"
#include "base/files/file_util.h"
#include "base/memory/scoped_ptr.h"
#include "base/nix/xdg_util.h"
#include "base/path_service.h"
#include "chrome/common/chrome_paths.h"
namespace chrome {
using base::nix::GetXDGDirectory;
using base::nix::GetXDGUserDirectory;
using base::nix::kDotConfigDir;
using base::nix::kXdgConfigHomeEnvVar;
namespace {
const char kDownloadsDir[] = "Downloads";
const char kMusicDir[] = "Music";
const char kPicturesDir[] = "Pictures";
const char kVideosDir[] = "Videos";
// Generic function for GetUser{Music,Pictures,Video}Directory.
bool GetUserMediaDirectory(const std::string& xdg_name,
const std::string& fallback_name,
base::FilePath* result) {
#if defined(OS_CHROMEOS)
// No local media directories on CrOS.
return false;
#else
*result = GetXDGUserDirectory(xdg_name.c_str(), fallback_name.c_str());
base::FilePath home;
PathService::Get(base::DIR_HOME, &home);
if (*result != home) {
base::FilePath desktop;
if (!PathService::Get(base::DIR_USER_DESKTOP, &desktop))
return false;
if (*result != desktop) {
return true;
}
}
*result = home.Append(fallback_name);
return true;
#endif
}
} // namespace
// See http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
// for a spec on where config files go. The net effect for most
// systems is we use ~/.config/chromium/ for Chromium and
// ~/.config/google-chrome/ for official builds.
// (This also helps us sidestep issues with other apps grabbing ~/.chromium .)
bool GetDefaultUserDataDirectory(base::FilePath* result) {
scoped_ptr<base::Environment> env(base::Environment::Create());
base::FilePath config_dir(GetXDGDirectory(env.get(),
kXdgConfigHomeEnvVar,
kDotConfigDir));
#if defined(GOOGLE_CHROME_BUILD)
*result = config_dir.Append("google-chrome");
#else
*result = config_dir.Append("chromium");
#endif
return true;
}
void GetUserCacheDirectory(const base::FilePath& profile_dir,
base::FilePath* result) {
// See http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
// for a spec on where cache files go. Our rule is:
// - if the user-data-dir in the standard place,
// use same subdirectory of the cache directory.
// (this maps ~/.config/google-chrome to ~/.cache/google-chrome as well
// as the same thing for ~/.config/chromium)
// - otherwise, use the profile dir directly.
// Default value in cases where any of the following fails.
*result = profile_dir;
scoped_ptr<base::Environment> env(base::Environment::Create());
base::FilePath cache_dir;
if (!PathService::Get(base::DIR_CACHE, &cache_dir))
return;
base::FilePath config_dir(GetXDGDirectory(env.get(),
kXdgConfigHomeEnvVar,
kDotConfigDir));
if (!config_dir.AppendRelativePath(profile_dir, &cache_dir))
return;
*result = cache_dir;
}
bool GetUserDocumentsDirectory(base::FilePath* result) {
*result = GetXDGUserDirectory("DOCUMENTS", "Documents");
return true;
}
bool GetUserDownloadsDirectorySafe(base::FilePath* result) {
base::FilePath home;
PathService::Get(base::DIR_HOME, &home);
*result = home.Append(kDownloadsDir);
return true;
}
bool GetUserDownloadsDirectory(base::FilePath* result) {
*result = GetXDGUserDirectory("DOWNLOAD", kDownloadsDir);
return true;
}
// We respect the user's preferred pictures location, unless it is
// ~ or their desktop directory, in which case we default to ~/Music.
bool GetUserMusicDirectory(base::FilePath* result) {
return GetUserMediaDirectory("MUSIC", kMusicDir, result);
}
// We respect the user's preferred pictures location, unless it is
// ~ or their desktop directory, in which case we default to ~/Pictures.
bool GetUserPicturesDirectory(base::FilePath* result) {
return GetUserMediaDirectory("PICTURES", kPicturesDir, result);
}
// We respect the user's preferred pictures location, unless it is
// ~ or their desktop directory, in which case we default to ~/Videos.
bool GetUserVideosDirectory(base::FilePath* result) {
return GetUserMediaDirectory("VIDEOS", kVideosDir, result);
}
bool ProcessNeedsProfileDir(const std::string& process_type) {
// For now we have no reason to forbid this on Linux as we don't
// have the roaming profile troubles there. Moreover the Linux breakpad needs
// profile dir access in all process if enabled on Linux.
return true;
}
} // namespace chrome

View file

@ -0,0 +1,251 @@
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/common/chrome_paths_internal.h"
#import <Foundation/Foundation.h>
#include <string.h>
#include <string>
#include "base/base_paths.h"
#include "base/logging.h"
#import "base/mac/foundation_util.h"
#import "base/mac/scoped_nsautorelease_pool.h"
#include "base/memory/scoped_ptr.h"
#include "base/path_service.h"
#include "chrome/common/chrome_constants.h"
namespace {
#if !defined(OS_IOS)
const base::FilePath* g_override_versioned_directory = NULL;
// Return a retained (NOT autoreleased) NSBundle* as the internal
// implementation of chrome::OuterAppBundle(), which should be the only
// caller.
NSBundle* OuterAppBundleInternal() {
base::mac::ScopedNSAutoreleasePool pool;
if (!base::mac::AmIBundled()) {
// If unbundled (as in a test), there's no app bundle.
return nil;
}
if (!base::mac::IsBackgroundOnlyProcess()) {
// Shortcut: in the browser process, just return the main app bundle.
return [[NSBundle mainBundle] retain];
}
// From C.app/Contents/Versions/1.2.3.4, go up three steps to get to C.app.
base::FilePath versioned_dir = chrome::GetVersionedDirectory();
base::FilePath outer_app_dir = versioned_dir.DirName().DirName().DirName();
const char* outer_app_dir_c = outer_app_dir.value().c_str();
NSString* outer_app_dir_ns = [NSString stringWithUTF8String:outer_app_dir_c];
return [[NSBundle bundleWithPath:outer_app_dir_ns] retain];
}
#endif // !defined(OS_IOS)
char* ProductDirNameForBundle(NSBundle* chrome_bundle) {
const char* product_dir_name = NULL;
#if !defined(OS_IOS)
base::mac::ScopedNSAutoreleasePool pool;
NSString* product_dir_name_ns =
[chrome_bundle objectForInfoDictionaryKey:@"CrProductDirName"];
product_dir_name = [product_dir_name_ns fileSystemRepresentation];
#else
DCHECK(!chrome_bundle);
#endif
if (!product_dir_name) {
#if defined(GOOGLE_CHROME_BUILD)
product_dir_name = "Google/Chrome";
#else
product_dir_name = "Chromium";
#endif
}
// Leaked, but the only caller initializes a static with this result, so it
// only happens once, and that's OK.
return strdup(product_dir_name);
}
// ProductDirName returns the name of the directory inside
// ~/Library/Application Support that should hold the product application
// data. This can be overridden by setting the CrProductDirName key in the
// outer browser .app's Info.plist. The default is "Google/Chrome" for
// officially-branded builds, and "Chromium" for unbranded builds. For the
// official canary channel, the Info.plist will have CrProductDirName set
// to "Google/Chrome Canary".
std::string ProductDirName() {
#if defined(OS_IOS)
static const char* product_dir_name = ProductDirNameForBundle(nil);
#else
// Use OuterAppBundle() to get the main app's bundle. This key needs to live
// in the main app's bundle because it will be set differently on the canary
// channel, and the autoupdate system dictates that there can be no
// differences between channels within the versioned directory. This would
// normally use base::mac::FrameworkBundle(), but that references the
// framework bundle within the versioned directory. Ordinarily, the profile
// should not be accessed from non-browser processes, but those processes do
// attempt to get the profile directory, so direct them to look in the outer
// browser .app's Info.plist for the CrProductDirName key.
static const char* product_dir_name =
ProductDirNameForBundle(chrome::OuterAppBundle());
#endif
return std::string(product_dir_name);
}
bool GetDefaultUserDataDirectoryForProduct(const std::string& product_dir,
base::FilePath* result) {
bool success = false;
if (result && PathService::Get(base::DIR_APP_DATA, result)) {
*result = result->Append(product_dir);
success = true;
}
return success;
}
} // namespace
namespace chrome {
bool GetDefaultUserDataDirectory(base::FilePath* result) {
return GetDefaultUserDataDirectoryForProduct(ProductDirName(), result);
}
bool GetUserDocumentsDirectory(base::FilePath* result) {
return base::mac::GetUserDirectory(NSDocumentDirectory, result);
}
void GetUserCacheDirectory(const base::FilePath& profile_dir,
base::FilePath* result) {
// If the profile directory is under ~/Library/Application Support,
// use a suitable cache directory under ~/Library/Caches. For
// example, a profile directory of ~/Library/Application
// Support/Google/Chrome/MyProfileName would use the cache directory
// ~/Library/Caches/Google/Chrome/MyProfileName.
// Default value in cases where any of the following fails.
*result = profile_dir;
base::FilePath app_data_dir;
if (!PathService::Get(base::DIR_APP_DATA, &app_data_dir))
return;
base::FilePath cache_dir;
if (!PathService::Get(base::DIR_CACHE, &cache_dir))
return;
if (!app_data_dir.AppendRelativePath(profile_dir, &cache_dir))
return;
*result = cache_dir;
}
bool GetUserDownloadsDirectory(base::FilePath* result) {
return base::mac::GetUserDirectory(NSDownloadsDirectory, result);
}
bool GetUserMusicDirectory(base::FilePath* result) {
return base::mac::GetUserDirectory(NSMusicDirectory, result);
}
bool GetUserPicturesDirectory(base::FilePath* result) {
return base::mac::GetUserDirectory(NSPicturesDirectory, result);
}
bool GetUserVideosDirectory(base::FilePath* result) {
return base::mac::GetUserDirectory(NSMoviesDirectory, result);
}
#if !defined(OS_IOS)
base::FilePath GetVersionedDirectory() {
if (g_override_versioned_directory)
return *g_override_versioned_directory;
// Start out with the path to the running executable.
base::FilePath path;
PathService::Get(base::FILE_EXE, &path);
// One step up to MacOS, another to Contents.
path = path.DirName().DirName();
DCHECK_EQ(path.BaseName().value(), "Contents");
if (base::mac::IsBackgroundOnlyProcess()) {
// path identifies the helper .app's Contents directory in the browser
// .app's versioned directory. Go up two steps to get to the browser
// .app's versioned directory.
path = path.DirName().DirName();
} else {
// Go into the versioned directory.
path = path.Append("Frameworks");
}
return path;
}
void SetOverrideVersionedDirectory(const base::FilePath* path) {
if (path != g_override_versioned_directory) {
delete g_override_versioned_directory;
g_override_versioned_directory = path;
}
}
base::FilePath GetFrameworkBundlePath() {
// It's tempting to use +[NSBundle bundleWithIdentifier:], but it's really
// slow (about 30ms on 10.5 and 10.6), despite Apple's documentation stating
// that it may be more efficient than +bundleForClass:. +bundleForClass:
// itself takes 1-2ms. Getting an NSBundle from a path, on the other hand,
// essentially takes no time at all, at least when the bundle has already
// been loaded as it will have been in this case. The FilePath operations
// needed to compute the framework's path are also effectively free, so that
// is the approach that is used here. NSBundle is also documented as being
// not thread-safe, and thread safety may be a concern here.
// The framework bundle is at a known path and name from the browser .app's
// versioned directory.
return GetVersionedDirectory().Append(kFrameworkName);
}
bool GetLocalLibraryDirectory(base::FilePath* result) {
return base::mac::GetLocalDirectory(NSLibraryDirectory, result);
}
bool GetUserLibraryDirectory(base::FilePath* result) {
return base::mac::GetUserDirectory(NSLibraryDirectory, result);
}
bool GetUserApplicationsDirectory(base::FilePath* result) {
return base::mac::GetUserDirectory(NSApplicationDirectory, result);
}
bool GetGlobalApplicationSupportDirectory(base::FilePath* result) {
return base::mac::GetLocalDirectory(NSApplicationSupportDirectory, result);
}
NSBundle* OuterAppBundle() {
// Cache this. Foundation leaks it anyway, and this should be the only call
// to OuterAppBundleInternal().
static NSBundle* bundle = OuterAppBundleInternal();
return bundle;
}
bool GetUserDataDirectoryForBrowserBundle(NSBundle* bundle,
base::FilePath* result) {
scoped_ptr<char, base::FreeDeleter>
product_dir_name(ProductDirNameForBundle(bundle));
return GetDefaultUserDataDirectoryForProduct(product_dir_name.get(), result);
}
#endif // !defined(OS_IOS)
bool ProcessNeedsProfileDir(const std::string& process_type) {
// For now we have no reason to forbid this on other MacOS as we don't
// have the roaming profile troubles there.
return true;
}
} // namespace chrome

View file

@ -0,0 +1,107 @@
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/common/chrome_paths_internal.h"
#include <windows.h>
#include <knownfolders.h>
#include <shellapi.h>
#include <shlobj.h>
#include <shobjidl.h>
#include "base/files/file_path.h"
#include "base/path_service.h"
#include "base/win/metro.h"
#include "base/win/scoped_co_mem.h"
#include "chrome/common/chrome_constants.h"
namespace chrome {
namespace {
// Generic function to call SHGetFolderPath().
bool GetUserDirectory(int csidl_folder, base::FilePath* result) {
// We need to go compute the value. It would be nice to support paths
// with names longer than MAX_PATH, but the system functions don't seem
// to be designed for it either, with the exception of GetTempPath
// (but other things will surely break if the temp path is too long,
// so we don't bother handling it.
wchar_t path_buf[MAX_PATH];
path_buf[0] = 0;
if (FAILED(SHGetFolderPath(NULL, csidl_folder, NULL,
SHGFP_TYPE_CURRENT, path_buf))) {
return false;
}
*result = base::FilePath(path_buf);
return true;
}
} // namespace
bool GetDefaultUserDataDirectory(base::FilePath* result) {
return PathService::Get(base::DIR_LOCAL_APP_DATA, result);
}
void GetUserCacheDirectory(const base::FilePath& profile_dir,
base::FilePath* result) {
// This function does more complicated things on Mac/Linux.
*result = profile_dir;
}
bool GetUserDocumentsDirectory(base::FilePath* result) {
return GetUserDirectory(CSIDL_MYDOCUMENTS, result);
}
// Return a default path for downloads that is safe.
// We just use 'Downloads' under DIR_USER_DOCUMENTS. Localizing
// 'downloads' is not a good idea because Chrome's UI language
// can be changed.
bool GetUserDownloadsDirectorySafe(base::FilePath* result) {
if (!GetUserDocumentsDirectory(result))
return false;
*result = result->Append(L"Downloads");
return true;
}
// On Vista and higher, use the downloads known folder. Since it can be
// relocated to point to a "dangerous" folder, callers should validate that the
// returned path is not dangerous before using it.
bool GetUserDownloadsDirectory(base::FilePath* result) {
typedef HRESULT (WINAPI *GetKnownFolderPath)(
REFKNOWNFOLDERID, DWORD, HANDLE, PWSTR*);
GetKnownFolderPath f = reinterpret_cast<GetKnownFolderPath>(
GetProcAddress(GetModuleHandle(L"shell32.dll"), "SHGetKnownFolderPath"));
base::win::ScopedCoMem<wchar_t> path_buf;
if (f && SUCCEEDED(f(FOLDERID_Downloads, 0, NULL, &path_buf))) {
*result = base::FilePath(std::wstring(path_buf));
return true;
}
return GetUserDownloadsDirectorySafe(result);
}
bool GetUserMusicDirectory(base::FilePath* result) {
return GetUserDirectory(CSIDL_MYMUSIC, result);
}
bool GetUserPicturesDirectory(base::FilePath* result) {
return GetUserDirectory(CSIDL_MYPICTURES, result);
}
bool GetUserVideosDirectory(base::FilePath* result) {
return GetUserDirectory(CSIDL_MYVIDEO, result);
}
bool ProcessNeedsProfileDir(const std::string& process_type) {
// On windows we don't want subprocesses other than the browser process and
// service processes to be able to use the profile directory because if it
// lies on a network share the sandbox will prevent us from accessing it.
if (process_type.empty())
return true;
return false;
}
} // namespace chrome

View file

@ -34,6 +34,10 @@ HTTP 요청 캐시를 비활성화 합니다.
시스템 설정의 프록시 서버를 무시하고 지정한 서버로 연결합니다. HTTP와 HTTPS 요청에만 적용됩니다.
시스템 프록시 서버 설정을 무시하고 지정한 서버로 연결합니다.
이 스위치는 HTTP와 HTTPS 그리고 WebSocket 요청에만 적용됩니다.
그리고 모든 프록시 서버가 HTTPS가 WebSocket 요청을 지원하지 않고 있을 수 있으므로 사용시 주의해야 합니다.
## --proxy-pac-url=`url`
지정한 `url`의 PAC 스크립트를 사용합니다.

View file

@ -107,6 +107,10 @@ __주의:__ `bounds`는 OS X 와 Windows에서만 작동합니다.
알림풍선이 시간이 지나 사라지거나 유저가 클릭하여 닫을 때 발생하는 이벤트입니다.
### Event: 'drop' _OS X_
드래그 가능한 아이템이 트레이 아이콘에 드롭되면 발생하는 이벤트입니다.
### Event: 'drop-files' _OS X_
* `event`
@ -114,6 +118,18 @@ __주의:__ `bounds`는 OS X 와 Windows에서만 작동합니다.
트레이 아이콘에 파일이 드롭되면 발생하는 이벤트입니다.
### Event: 'drag-enter' _OS X_
트레이 아이콘에 드래그 작업이 시작될 때 발생하는 이벤트입니다.
### Event: 'drag-leave' _OS X_
트레이 아이콘에 드래그 작업이 종료될 때 발생하는 이벤트입니다.
### Event: 'drag-end' _OS X_
트레이 아이콘에 드래그 작업이 종료되거나 다른 위치에서 종료될 때 발생하는 이벤트입니다.
## Methods
`Tray` 모듈은 다음과 같은 메서드를 가지고 있습니다:

View file

@ -44,9 +44,12 @@ var webdriver = require('selenium-webdriver');
var driver = new webdriver.Builder()
// 작동하고 있는 크롬 드라이버의 포트 "9515"를 사용합니다.
.usingServer('http://localhost:9515')
.withCapabilities({chromeOptions: {
// 여기에 사용중인 Electron 바이너리의 경로를 지정하세요.
binary: '/Path-to-Your-App.app/Contents/MacOS/Atom'}})
.withCapabilities({
chromeOptions: {
// 여기에 사용중인 Electron 바이너리의 경로를 지정하세요.
binary: '/Path-to-Your-App.app/Contents/MacOS/Atom',
}
})
.forBrowser('electron')
.build();
@ -92,7 +95,10 @@ var options = {
port: 9515, // 연결할 크롬 드라이버 서버의 포트를 설정합니다.
desiredCapabilities: {
browserName: 'chrome',
chromeOptions: {binary: '/Path-to-Your-App.app/Electron'} // Electron 바이너리의 위치
chromeOptions: {
binary: '/Path-to-Your-App/electron', // Electron 바이너리 경로
args: [/* cli arguments */] // 선택 사항, 'app=' + /path/to/your/app/
}
}
};
@ -109,9 +115,12 @@ client
.end();
```
## 작업환경
## 작업 환경
따로 Electron을 다시 빌드하지 않는 경우 간단히 어플리케이션을 Electron의 리소스 디렉터리에
[배치](application-distribution.md)하여 바로 테스트 할 수 있습니다.
또한, Electron 바이너리의 명령줄 인수에 어플리케이션 폴더를 지정하는 방법으로 실행할 수도 있습니다.
이 방법을 사용하면 어플리케이션 폴더를 Electron의 `resource` 디렉터리로 복사하는 불필요한 과정을 생략할 수 있습니다.
[chrome-driver]: https://sites.google.com/a/chromium.org/chromedriver/

View file

@ -31,32 +31,32 @@
### Modules for the Main Process:
* [app](api/app.md)
* [auto-updater](api/auto-updater.md)
* [browser-window](api/browser-window.md)
* [content-tracing](api/content-tracing.md)
* [autoUpdater](api/auto-updater.md)
* [BrowserWindow](api/browser-window.md)
* [contentTracing](api/content-tracing.md)
* [dialog](api/dialog.md)
* [global-shortcut](api/global-shortcut.md)
* [ipc-main](api/ipc-main.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)
* [globalShortcut](api/global-shortcut.md)
* [ipcMain](api/ipc-main.md)
* [Menu](api/menu.md)
* [MenuItem](api/menu-item.md)
* [powerMonitor](api/power-monitor.md)
* [powerSaveBlocker](api/power-save-blocker.md)
* [protocol](api/protocol.md)
* [session](api/session.md)
* [web-contents](api/web-contents.md)
* [tray](api/tray.md)
* [webContents](api/web-contents.md)
* [Tray](api/tray.md)
### Modules for the Renderer Process (Web Page):
* [ipc-renderer](api/ipc-renderer.md)
* [ipcRenderer](api/ipc-renderer.md)
* [remote](api/remote.md)
* [web-frame](api/web-frame.md)
* [webFrame](api/web-frame.md)
### Modules for Both Processes:
* [clipboard](api/clipboard.md)
* [crash-reporter](api/crash-reporter.md)
* [native-image](api/native-image.md)
* [crashReporter](api/crash-reporter.md)
* [nativeImage](api/native-image.md)
* [screen](api/screen.md)
* [shell](api/shell.md)

View file

@ -6,7 +6,7 @@ The following example shows how to quit the application when the last window is
closed:
```javascript
var app = require('app');
const app = require('electron').app;
app.on('window-all-closed', function() {
app.quit();
});
@ -238,9 +238,14 @@ You can request the following paths by the name:
* `userData` The directory for storing your app's configuration files, which by
default it is the `appData` directory appended with your app's name.
* `temp` Temporary directory.
* `userDesktop` The current user's Desktop directory.
* `exe` The current executable file.
* `module` The `libchromiumcontent` library.
* `desktop` The current user's Desktop directory.
* `documents` Directory for a user's "My Documents".
* `downloads` Directory for a user's downloads.
* `music` Directory for a user's music.
* `pictures` Directory for a user's pictures.
* `videos` Directory for a user's videos.
### `app.setPath(name, path)`

View file

@ -67,7 +67,7 @@ Returns:
* `releaseNotes` String
* `releaseName` String
* `releaseDate` Date
* `updateUrl` String
* `updateURL` String
Emitted when an update has been downloaded.
@ -77,7 +77,7 @@ On Windows only `releaseName` is available.
The `autoUpdater` object has the following methods:
### `autoUpdater.setFeedUrl(url)`
### `autoUpdater.setFeedURL(url)`
* `url` String
@ -86,7 +86,7 @@ once it is set.
### `autoUpdater.checkForUpdates()`
Asks the server whether there is an update. You must call `setFeedUrl` before
Asks the server whether there is an update. You must call `setFeedURL` before
using this API.
### `autoUpdater.quitAndInstall()`

View file

@ -4,14 +4,14 @@ The `BrowserWindow` class gives you the ability to create a browser window. For
example:
```javascript
var BrowserWindow = require('browser-window');
const BrowserWindow = require('electron').BrowserWindow;
var win = new BrowserWindow({ width: 800, height: 600, show: false });
win.on('closed', function() {
win = null;
});
win.loadUrl('https://github.com');
win.loadURL('https://github.com');
win.show();
```
@ -291,11 +291,8 @@ Remove the DevTools extension whose name is `name`.
Objects created with `new BrowserWindow` have the following properties:
```javascript
var BrowserWindow = require('browser-window');
// In this example `win` is our instance
var win = new BrowserWindow({ width: 800, height: 600 });
```
### `win.webContents`
@ -316,14 +313,6 @@ Objects created with `new BrowserWindow` have the following instance methods:
**Note:** Some methods are only available on specific operating systems and are labeled as such.
```javascript
var BrowserWindow = require('browser-window');
// In this example `win` is our instance
var win = new BrowserWindow({ width: 800, height: 600 });
```
### `win.destroy()`
Force closing the window, the `unload` and `beforeunload` event won't be emitted
@ -624,9 +613,9 @@ Same as `webContents.print([options])`
Same as `webContents.printToPDF(options, callback)`
### `win.loadUrl(url[, options])`
### `win.loadURL(url[, options])`
Same as `webContents.loadUrl(url[, options])`.
Same as `webContents.loadURL(url[, options])`.
### `win.reload()`

View file

@ -6,7 +6,7 @@ them in your app's main script before the [ready][ready] event of [app][app]
module is emitted:
```javascript
var app = require('app');
const app = require('electron').app;
app.commandLine.appendSwitch('remote-debugging-port', '8315');
app.commandLine.appendSwitch('host-rules', 'MAP * 127.0.0.1');
@ -31,6 +31,15 @@ Disables the disk cache for HTTP requests.
Enables remote debugging over HTTP on the specified `port`.
## --js-flags=`flags`
Specifies the flags passed to JS engine. It has to be passed when starting
Electron if you want to enable the `flags` in the main process.
```bash
$ electron --js-flags="--harmony_proxies --harmony_collections" your-app
```
## --proxy-server=`address:port`
Use a specified proxy server, which overrides the system setting. This switch

View file

@ -4,7 +4,7 @@ The `clipboard` module 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');
const clipboard = require('electron').clipboard;
clipboard.writeText('Example String');
```
@ -12,7 +12,6 @@ On X Window systems, there is also a selection clipboard. To manipulate it
you need to pass `selection` to each method:
```javascript
var clipboard = require('clipboard');
clipboard.writeText('Example String', 'selection');
console.log(clipboard.readText('selection'));
```
@ -82,7 +81,6 @@ Returns an array of supported formats for the clipboard `type`.
Returns whether the clipboard supports the format of specified `data`.
```javascript
var clipboard = require('clipboard');
console.log(clipboard.has('<p>selection</p>'));
```
@ -102,7 +100,6 @@ Reads `data` from the clipboard.
* `type` String (optional)
```javascript
var clipboard = require('clipboard');
clipboard.write({text: 'test', html: "<b>test</b>"});
```
Writes `data` to the clipboard.

View file

@ -6,9 +6,14 @@ so you need to open `chrome://tracing/` in a Chrome browser and load the
generated file to view the result.
```javascript
var contentTracing = require('content-tracing');
const contentTracing = require('electron').contentTracing;
contentTracing.startRecording('*', contentTracing.DEFAULT_OPTIONS, function() {
const options = {
categoryFilter: '*',
traceOptions: 'record-until-full,enable-sampling'
}
contentTracing.startRecording(options, function() {
console.log('Tracing started');
setTimeout(function() {

View file

@ -6,12 +6,12 @@ The following is an example of automatically submitting a crash report to a
remote server:
```javascript
var crashReporter = require('crash-reporter');
const crashReporter = require('electron').crashReporter;
crashReporter.start({
productName: 'YourName',
companyName: 'YourCompany',
submitUrl: 'https://your-domain.com/url-to-submit',
submitURL: 'https://your-domain.com/url-to-submit',
autoSubmit: true
});
```
@ -26,7 +26,7 @@ The `crash-reporter` module has the following methods:
* `productName` String, default: Electron.
* `companyName` String, default: GitHub, Inc.
* `submitUrl` String, default: http://54.249.141.255:1127/post.
* `submitURL` String, default: http://54.249.141.255:1127/post.
* URL that crash reports will be sent to as POST.
* `autoSubmit` Boolean, default: `true`.
* Send the crash report without user interaction.
@ -57,12 +57,12 @@ ID.
## crash-reporter Payload
The crash reporter will send the following data to the `submitUrl` as `POST`:
The crash reporter will send the following data to the `submitURL` as `POST`:
* `ver` String - The version of Electron.
* `platform` String - e.g. 'win32'.
* `process_type` String - e.g. 'renderer'.
* `guid` String - e.g. '5e1286fc-da97-479e-918b-6bfb0c3d1c72'
* `guid` String - e.g. '5e1286fc-da97-479e-918b-6bfb0c3d1c72'
* `_version` String - The version in `package.json`.
* `_productName` String - The product name in the `crashReporter` `options`
object.

View file

@ -8,7 +8,7 @@ An example of showing a dialog to select multiple files and directories:
```javascript
var win = ...; // BrowserWindow in which to show the dialog
var dialog = require('dialog');
const dialog = require('electron').dialog;
console.log(dialog.showOpenDialog({ properties: [ 'openFile', 'openDirectory', 'multiSelections' ]}));
```
@ -114,6 +114,6 @@ will be passed via `callback(response)`.
Displays a modal dialog that shows an error message.
This API can be called safely before the `ready` event the `app` module emits,
it is usually used to report errors in early stage of startup. If called
before the app `ready`event on Linux, the message will be emitted to stderr,
it is usually used to report errors in early stage of startup. If called
before the app `ready`event on Linux, the message will be emitted to stderr,
and no GUI dialog will appear.

View file

@ -66,7 +66,7 @@ Resumes the download that has been paused.
Cancels the download operation.
### `downloadItem.getUrl()`
### `downloadItem.getURL()`
Returns a `String` represents the origin url where the item is downloaded from.

View file

@ -9,7 +9,7 @@ To create a frameless window, you need to set `frame` to `false` in
```javascript
var BrowserWindow = require('browser-window');
const BrowserWindow = require('electron').BrowserWindow;
var win = new BrowserWindow({ width: 800, height: 600, frame: false });
```
@ -23,8 +23,7 @@ the window controls ("traffic lights") for standard window actions.
You can do so by specifying the new `title-bar-style` option:
```javascript
var BrowserWindow = require('browser-window');
var win = new BrowserWindow({ width: 800, height: 600, 'title-bar-style': 'hidden' });
var win = new BrowserWindow({ 'title-bar-style': 'hidden' });
```
## Transparent window

View file

@ -9,8 +9,9 @@ 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');
var globalShortcut = require('global-shortcut');
const electron = require('electron');
const app = electron.app;
const globalShortcut = electron.globalShortcut;
app.on('ready', function() {
// Register a 'ctrl+x' shortcut listener.

View file

@ -19,7 +19,7 @@ processes:
```javascript
// In main process.
var ipcMain = require('ipc-main');
const ipcMain = require('electron').ipcMain;
ipcMain.on('asynchronous-message', function(event, arg) {
console.log(arg); // prints "ping"
event.sender.send('asynchronous-reply', 'pong');
@ -33,7 +33,7 @@ ipcMain.on('synchronous-message', function(event, arg) {
```javascript
// In renderer process (web page).
var ipcRenderer = require('ipc-renderer');
const ipcRenderer = require('electron').ipcRenderer;
console.log(ipcRenderer.sendSync('synchronous-message', 'ping')); // prints "pong"
ipcRenderer.on('asynchronous-reply', function(event, arg) {

View file

@ -16,9 +16,9 @@ the user right clicks the page:
```html
<!-- index.html -->
<script>
var remote = require('remote');
var Menu = remote.require('menu');
var MenuItem = remote.require('menu-item');
const remote = require('electron').remote;
const Menu = remote.Menu;
const MenuItem = remote.MenuItem;
var menu = new Menu();
menu.append(new MenuItem({ label: 'MenuItem1', click: function() { console.log('item 1 clicked'); } }));
@ -136,14 +136,14 @@ var template = [
submenu: [
{
label: 'Learn More',
click: function() { require('shell').openExternal('http://electron.atom.io') }
click: function() { require('electron').shell.openExternal('http://electron.atom.io') }
},
]
},
];
if (process.platform == 'darwin') {
var name = require('app').getName();
var name = require('electron').app.getName();
template.unshift({
label: name,
submenu: [

View file

@ -1,7 +1,7 @@
# NativeImage
# nativeImage
In Electron, for the APIs that take images, you can pass either file paths or
`NativeImage` instances. An empty image will be used when `null` is passed.
`nativeImage` instances. An empty image will be used when `null` is passed.
For example, when creating a tray or setting a window's icon, you can pass an
image file path as a `String`:
@ -11,10 +11,9 @@ var appIcon = new Tray('/Users/somebody/images/icon.png');
var window = new BrowserWindow({icon: '/Users/somebody/images/window.png'});
```
Or read the image from the clipboard which returns a `NativeImage`:
Or read the image from the clipboard which returns a `nativeImage`:
```javascript
var clipboard = require('clipboard');
var image = clipboard.readImage();
var appIcon = new Tray(image);
```
@ -84,40 +83,40 @@ To mark an image as a template image, its filename should end with the word
## Methods
The `NativeImage` class has the following methods:
The `nativeImage` class has the following methods:
### `NativeImage.createEmpty()`
### `nativeImage.createEmpty()`
Creates an empty `NativeImage` instance.
Creates an empty `nativeImage` instance.
### `NativeImage.createFromPath(path)`
### `nativeImage.createFromPath(path)`
* `path` String
Creates a new `NativeImage` instance from a file located at `path`.
Creates a new `nativeImage` instance from a file located at `path`.
### `NativeImage.createFromBuffer(buffer[, scaleFactor])`
### `nativeImage.createFromBuffer(buffer[, scaleFactor])`
* `buffer` [Buffer][buffer]
* `scaleFactor` Double (optional)
Creates a new `NativeImage` instance from `buffer`. The default `scaleFactor` is
Creates a new `nativeImage` instance from `buffer`. The default `scaleFactor` is
1.0.
### `NativeImage.createFromDataUrl(dataUrl)`
### `nativeImage.createFromDataURL(dataURL)`
* `dataUrl` String
* `dataURL` String
Creates a new `NativeImage` instance from `dataUrl`.
Creates a new `nativeImage` instance from `dataURL`.
## Instance Methods
The following methods are available on instances of `nativeImage`:
```javascript
var NativeImage = require('native-image');
const nativeImage = require('electron').nativeImage;
var image = NativeImage.createFromPath('/Users/somebody/images/icon.png');
var image = nativeImage.createFromPath('/Users/somebody/images/icon.png');
```
### `image.toPng()`
@ -130,7 +129,7 @@ Returns a [Buffer][buffer] that contains the image's `PNG` encoded data.
Returns a [Buffer][buffer] that contains the image's `JPEG` encoded data.
### `image.toDataUrl()`
### `image.toDataURL()`
Returns the data URL of the image.

View file

@ -1,4 +1,4 @@
# power-monitor
# powerMonitor
The `power-monitor` module is used to monitor power state changes. You can
only use it in the main process. You should not use this module until the `ready`
@ -7,10 +7,8 @@ event of the `app` module is emitted.
For example:
```javascript
var app = require('app');
app.on('ready', function() {
require('power-monitor').on('suspend', function() {
require('electron').powerMonitor.on('suspend', function() {
console.log('The system is going to sleep');
});
});

View file

@ -1,13 +1,13 @@
# powerSaveBlocker
The `power-save-blocker` module is used to block the system from entering
The `powerSaveBlocker` module is used to block the system from entering
low-power (sleep) mode and thus allowing the app to keep the system and screen
active.
For example:
```javascript
var powerSaveBlocker = require('power-save-blocker');
const powerSaveBlocker = require('electron').powerSaveBlocker;
var id = powerSaveBlocker.start('prevent-display-sleep');
console.log(powerSaveBlocker.isStarted(id));

View file

@ -7,11 +7,12 @@ An example of implementing a protocol that has the same effect as the
`file://` protocol:
```javascript
var app = require('app');
var path = require('path');
const electron = require('electron');
const app = electron.app;
const path = require('path');
app.on('ready', function() {
var protocol = require('protocol');
var protocol = electron.protocol;
protocol.registerFileProtocol('atom', function(request, callback) {
var url = request.url.substr(7);
callback({path: path.normalize(__dirname + '/' + url)});

View file

@ -3,16 +3,20 @@
The `remote` module provides a simple way to do inter-process communication
(IPC) between the renderer process (web page) and the main process.
In Electron, GUI-related modules (such as `dialog`, `menu` etc.) are only available in the main process, not in the renderer process. In order to use them from the renderer process, the `ipc` module is necessary to send inter-process messages to the main process. With the `remote` module, you can invoke methods of the main process object without explicitly sending inter-process messages, similar to Java's [RMI](http://en.wikipedia.org/wiki/Java_remote_method_invocation).
An example of creating a browser window from a renderer process:
In Electron, GUI-related modules (such as `dialog`, `menu` etc.) are only
available in the main process, not in the renderer process. In order to use them
from the renderer process, the `ipc` module is necessary to send inter-process
messages to the main process. With the `remote` module, you can invoke methods
of the main process object without explicitly sending inter-process messages,
similar to Java's [RMI][rmi]. An example of creating a browser window from a
renderer process:
```javascript
var remote = require('remote');
var BrowserWindow = remote.require('browser-window');
const remote = require('electron').remote;
const BrowserWindow = remote.BrowserWindow;
var win = new BrowserWindow({ width: 800, height: 600 });
win.loadUrl('https://github.com');
win.loadURL('https://github.com');
```
**Note:** for the reverse (access the renderer process from the main process),
@ -96,8 +100,6 @@ For example, the following code seems innocent at first glance. It installs a
callback for the `close` event on a remote object:
```javascript
var remote = require('remote');
remote.getCurrentWindow().on('close', function() {
// blabla...
});
@ -116,6 +118,15 @@ passed to the main process. This involves cleaning up event handlers, or
ensuring the main process is explicitly told to deference callbacks that came
from a renderer process that is exiting.
## Accessing built-in modules in the main process
The built-in modules in the main process are added as getters in the `remote`
module, so you can use them directly like the `electron` module.
```javascript
const app = remote.app;
```
## Methods
The `remote` module has the following methods:
@ -146,3 +157,5 @@ process.
Returns the `process` object in the main process. This is the same as
`remote.getGlobal('process')` but is cached.
[rmi]: http://en.wikipedia.org/wiki/Java_remote_method_invocation

Some files were not shown because too many files have changed in this diff Show more