diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 5165877d1670..d67794a91aeb 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -269,9 +269,7 @@ WebContents::WebContents(v8::Isolate* isolate, managed_web_contents()->GetView()->SetDelegate(this); // Save the preferences in C++. - base::DictionaryValue web_preferences; - mate::ConvertFromV8(isolate, options.GetHandle(), &web_preferences); - new WebContentsPreferences(web_contents, &web_preferences); + new WebContentsPreferences(web_contents, options); web_contents->SetUserAgentOverride(GetBrowserContext()->GetUserAgent()); diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index 497b5a6930ff..048a8eff1df9 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -3,6 +3,7 @@ // found in the LICENSE file. #include "atom/browser/api/atom_api_window.h" +#include "atom/common/native_mate_converters/value_converter.h" #include "atom/browser/api/atom_api_menu.h" #include "atom/browser/api/atom_api_web_contents.h" @@ -60,7 +61,54 @@ void OnCapturePageDone( callback.Run(gfx::Image::CreateFrom1xBitmap(bitmap)); } +// Converts min-width to minWidth, returns false if no conversion is needed. +bool TranslateOldKey(const std::string& key, std::string* new_key) { + if (key.find('-') == std::string::npos) + return false; + new_key->reserve(key.size()); + bool next_upper_case = false; + for (char c : key) { + if (c == '-') { + next_upper_case = true; + } else if (next_upper_case) { + new_key->push_back(base::ToUpperASCII(c)); + next_upper_case = false; + } else { + new_key->push_back(c); + } + } + return true; +} + +// Converts min-width to minWidth recursively in the dictionary. +void TranslateOldOptions(v8::Isolate* isolate, v8::Local options) { + auto context = isolate->GetCurrentContext(); + auto maybe_keys = options->GetOwnPropertyNames(context); + if (maybe_keys.IsEmpty()) + return; + std::vector keys; + if (!mate::ConvertFromV8(isolate, maybe_keys.ToLocalChecked(), &keys)) + return; + mate::Dictionary dict(isolate, options); + for (const auto& key : keys) { + v8::Local value; + if (!dict.Get(key, &value)) // Shouldn't happen, but guard it anyway. + continue; + // Go recursively. + v8::Local sub_options; + if (mate::ConvertFromV8(isolate, value, &sub_options)) + TranslateOldOptions(isolate, sub_options); + // Translate key. + std::string new_key; + if (TranslateOldKey(key, &new_key)) { + dict.Set(new_key, value); + dict.Delete(key); + } + } +} + #if defined(OS_WIN) +// Converts binary data to Buffer. v8::Local ToBuffer(v8::Isolate* isolate, void* val, int size) { auto buffer = node::Buffer::New(isolate, static_cast(val), size); if (buffer.IsEmpty()) @@ -74,7 +122,10 @@ v8::Local ToBuffer(v8::Isolate* isolate, void* val, int size) { Window::Window(v8::Isolate* isolate, const mate::Dictionary& options) { - // Use options['web-preferences'] to create WebContents. + // Be compatible with old style field names like min-width. + TranslateOldOptions(isolate, options.GetHandle()); + + // Use options.webPreferences to create WebContents. mate::Dictionary web_preferences = mate::Dictionary::CreateEmpty(isolate); options.Get(switches::kWebPreferences, &web_preferences); diff --git a/atom/browser/default_app/default_app.js b/atom/browser/default_app/default_app.js index 2378902b44ec..de8b14d5f4d7 100644 --- a/atom/browser/default_app/default_app.js +++ b/atom/browser/default_app/default_app.js @@ -12,8 +12,8 @@ app.on('ready', function() { mainWindow = new BrowserWindow({ width: 800, height: 600, - 'auto-hide-menu-bar': true, - 'use-content-size': true, + autoHideMenuBar: true, + useContentSize: true, }); mainWindow.loadUrl('file://' + __dirname + '/index.html'); mainWindow.focus(); diff --git a/atom/browser/lib/guest-view-manager.coffee b/atom/browser/lib/guest-view-manager.coffee index c99b681498e4..8b2658a180cf 100644 --- a/atom/browser/lib/guest-view-manager.coffee +++ b/atom/browser/lib/guest-view-manager.coffee @@ -118,11 +118,11 @@ attachGuest = (embedder, elementInstanceId, guestInstanceId, params) -> destroyGuest embedder, oldGuestInstanceId webPreferences = - 'guest-instance-id': guestInstanceId - 'node-integration': params.nodeintegration ? false - 'plugins': params.plugins - 'web-security': !params.disablewebsecurity - webPreferences['preload-url'] = params.preload if params.preload + guestInstanceId: guestInstanceId + nodeIntegration: params.nodeintegration ? false + plugins: params.plugins + webSecurity: !params.disablewebsecurity + webPreferences.preloadUrl = params.preload if params.preload webViewManager.addGuest guestInstanceId, elementInstanceId, embedder, guest, webPreferences guest.attachParams = params diff --git a/atom/browser/lib/guest-window-manager.coffee b/atom/browser/lib/guest-window-manager.coffee index fe01c6fa771e..3ed8932d444c 100644 --- a/atom/browser/lib/guest-window-manager.coffee +++ b/atom/browser/lib/guest-window-manager.coffee @@ -4,15 +4,24 @@ BrowserWindow = require 'browser-window' frameToGuest = {} +# Copy attribute of |parent| to |child| if it is not defined in |child|. +mergeOptions = (child, parent) -> + for own key, value of parent when key not in child + if typeof value is 'object' + child[key] = mergeOptions {}, value + else + child[key] = value + child + # Merge |options| with the |embedder|'s window's options. mergeBrowserWindowOptions = (embedder, options) -> if embedder.browserWindowOptions? # Inherit the original options if it is a BrowserWindow. - options.__proto__ = embedder.browserWindowOptions + mergeOptions options, embedder.browserWindowOptions else # Or only inherit web-preferences if it is a webview. - options['web-preferences'] ?= {} - options['web-preferences'].__proto__ = embedder.getWebPreferences() + options.webPreferences ?= {} + mergeOptions options.webPreferences, embedder.getWebPreferences() options # Create a new guest created by |embedder| with |options|. diff --git a/atom/browser/web_contents_preferences.cc b/atom/browser/web_contents_preferences.cc index 14e32353af65..2adb77211b27 100644 --- a/atom/browser/web_contents_preferences.cc +++ b/atom/browser/web_contents_preferences.cc @@ -6,10 +6,12 @@ #include +#include "atom/common/native_mate_converters/value_converter.h" #include "atom/common/options_switches.h" #include "base/command_line.h" #include "base/strings/string_number_conversions.h" #include "content/public/common/web_preferences.h" +#include "native_mate/dictionary.h" #include "net/base/filename_util.h" #if defined(OS_WIN) @@ -36,12 +38,16 @@ const char* kWebRuntimeFeatures[] = { WebContentsPreferences::WebContentsPreferences( content::WebContents* web_contents, - base::DictionaryValue* web_preferences) { - web_preferences_.Swap(web_preferences); - web_contents->SetUserData(UserDataKey(), this); + const mate::Dictionary& web_preferences) { + v8::Isolate* isolate = web_preferences.isolate(); + mate::Dictionary copied(isolate, web_preferences.GetHandle()->Clone()); + // Following fields should not be stored. + copied.Delete("embedder"); + copied.Delete("isGuest"); + copied.Delete("session"); - // The "isGuest" is not a preferences field. - web_preferences_.Remove("isGuest", nullptr); + mate::ConvertFromV8(isolate, copied.GetHandle(), &web_preferences_); + web_contents->SetUserData(UserDataKey(), this); } WebContentsPreferences::~WebContentsPreferences() { @@ -135,21 +141,21 @@ void WebContentsPreferences::OverrideWebkitPrefs( prefs->images_enabled = b; if (self->web_preferences_.GetBoolean("java", &b)) prefs->java_enabled = b; - if (self->web_preferences_.GetBoolean("text-areas-are-resizable", &b)) + if (self->web_preferences_.GetBoolean("textAreasAreResizable", &b)) prefs->text_areas_are_resizable = b; if (self->web_preferences_.GetBoolean("webgl", &b)) prefs->experimental_webgl_enabled = b; if (self->web_preferences_.GetBoolean("webaudio", &b)) prefs->webaudio_enabled = b; - if (self->web_preferences_.GetBoolean("web-security", &b)) { + if (self->web_preferences_.GetBoolean("webSecurity", &b)) { prefs->web_security_enabled = b; prefs->allow_displaying_insecure_content = !b; prefs->allow_running_insecure_content = !b; } - if (self->web_preferences_.GetBoolean("allow-displaying-insecure-content", + if (self->web_preferences_.GetBoolean("allowDisplayingInsecureContent", &b)) prefs->allow_displaying_insecure_content = b; - if (self->web_preferences_.GetBoolean("allow-running-insecure-content", &b)) + if (self->web_preferences_.GetBoolean("allowRunningInsecureContent", &b)) prefs->allow_running_insecure_content = b; } diff --git a/atom/browser/web_contents_preferences.h b/atom/browser/web_contents_preferences.h index 3e36df021478..8b04f9ee24e6 100644 --- a/atom/browser/web_contents_preferences.h +++ b/atom/browser/web_contents_preferences.h @@ -16,6 +16,10 @@ namespace content { struct WebPreferences; } +namespace mate { +class Dictionary; +} + namespace atom { // Stores and applies the preferences of WebContents. @@ -31,7 +35,7 @@ class WebContentsPreferences content::WebContents* web_contents, content::WebPreferences* prefs); WebContentsPreferences(content::WebContents* web_contents, - base::DictionaryValue* web_preferences); + const mate::Dictionary& web_preferences); ~WebContentsPreferences() override; // $.extend(|web_preferences_|, |new_web_preferences|). diff --git a/atom/common/options_switches.cc b/atom/common/options_switches.cc index 903c15ee6dd1..9b3b50b4bf31 100644 --- a/atom/common/options_switches.cc +++ b/atom/common/options_switches.cc @@ -17,51 +17,80 @@ const char kX[] = "x"; const char kY[] = "y"; const char kWidth[] = "width"; const char kHeight[] = "height"; -const char kMinWidth[] = "min-width"; -const char kMinHeight[] = "min-height"; -const char kMaxWidth[] = "max-width"; -const char kMaxHeight[] = "max-height"; +const char kMinWidth[] = "minWidth"; +const char kMinHeight[] = "minHeight"; +const char kMaxWidth[] = "maxWidth"; +const char kMaxHeight[] = "maxHeight"; const char kResizable[] = "resizable"; const char kFullscreen[] = "fullscreen"; // Whether the window should show in taskbar. -const char kSkipTaskbar[] = "skip-taskbar"; +const char kSkipTaskbar[] = "skipTaskbar"; // Start with the kiosk mode, see Opera's page for description: // http://www.opera.com/support/mastering/kiosk/ const char kKiosk[] = "kiosk"; // Make windows stays on the top of all other windows. -const char kAlwaysOnTop[] = "always-on-top"; - -const char kNodeIntegration[] = "node-integration"; +const char kAlwaysOnTop[] = "alwaysOnTop"; // Enable the NSView to accept first mouse event. -const char kAcceptFirstMouse[] = "accept-first-mouse"; +const char kAcceptFirstMouse[] = "acceptFirstMouse"; // Whether window size should include window frame. -const char kUseContentSize[] = "use-content-size"; +const char kUseContentSize[] = "useContentSize"; // The requested title bar style for the window -const char kTitleBarStyle[] = "title-bar-style"; - -// The WebPreferences. -const char kWebPreferences[] = "web-preferences"; - -// The factor of which page should be zoomed. -const char kZoomFactor[] = "zoom-factor"; +const char kTitleBarStyle[] = "titleBarStyle"; // The menu bar is hidden unless "Alt" is pressed. -const char kAutoHideMenuBar[] = "auto-hide-menu-bar"; +const char kAutoHideMenuBar[] = "autoHideMenuBar"; // Enable window to be resized larger than screen. -const char kEnableLargerThanScreen[] = "enable-larger-than-screen"; +const char kEnableLargerThanScreen[] = "enableLargerThanScreen"; // Forces to use dark theme on Linux. -const char kDarkTheme[] = "dark-theme"; +const char kDarkTheme[] = "darkTheme"; -// Enable DirectWrite on Windows. -const char kDirectWrite[] = "direct-write"; +// Whether the window should be transparent. +const char kTransparent[] = "transparent"; + +// Window type hint. +const char kType[] = "type"; + +// Disable auto-hiding cursor. +const char kDisableAutoHideCursor[] = "disableAutoHideCursor"; + +// Use the OS X's standard window instead of the textured window. +const char kStandardWindow[] = "standardWindow"; + +// Default browser window background color. +const char kBackgroundColor[] = "backgroundColor"; + +// The WebPreferences. +const char kWebPreferences[] = "webPreferences"; + +// The factor of which page should be zoomed. +const char kZoomFactor[] = "zoomFactor"; + +// Script that will be loaded by guest WebContents before other scripts. +const char kPreloadScript[] = "preload"; + +// Like --preload, but the passed argument is an URL. +const char kPreloadUrl[] = "preloadUrl"; + +// Enable the node integration. +const char kNodeIntegration[] = "nodeIntegration"; + +// Instancd ID of guest WebContents. +const char kGuestInstanceID[] = "guestInstanceId"; + +// Web runtime features. +const char kExperimentalFeatures[] = "experimentalFeatures"; +const char kExperimentalCanvasFeatures[] = "experimentalCanvasFeatures"; +const char kOverlayScrollbars[] = "overlayScrollbars"; +const char kOverlayFullscreenVideo[] = "overlayFullscreenVideo"; +const char kSharedWorker[] = "sharedWorker"; // Enable plugins. const char kEnablePlugins[] = "enable-plugins"; @@ -72,43 +101,15 @@ const char kPpapiFlashPath[] = "ppapi-flash-path"; // Ppapi Flash version. const char kPpapiFlashVersion[] = "ppapi-flash-version"; -// Instancd ID of guest WebContents. -const char kGuestInstanceID[] = "guest-instance-id"; +// Set page visiblity to always visible. +const char kPageVisibility[] = "page-visibility"; -// Script that will be loaded by guest WebContents before other scripts. -const char kPreloadScript[] = "preload"; - -// Like --preload, but the passed argument is an URL. -const char kPreloadUrl[] = "preload-url"; - -// Whether the window should be transparent. -const char kTransparent[] = "transparent"; - -// Window type hint. -const char kType[] = "type"; - -// Disable auto-hiding cursor. -const char kDisableAutoHideCursor[] = "disable-auto-hide-cursor"; - -// Use the OS X's standard window instead of the textured window. -const char kStandardWindow[] = "standard-window"; - -// Default browser window background color. -const char kBackgroundColor[] = "background-color"; +// Enable DirectWrite on Windows. +const char kDirectWrite[] = "direct-write"; // Path to client certificate. const char kClientCertificate[] = "client-certificate"; -// Web runtime features. -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"; - -// Set page visiblity to always visible. -const char kPageVisibility[] = "page-visibility"; - // Disable HTTP cache. const char kDisableHttpCache[] = "disable-http-cache"; diff --git a/atom/common/options_switches.h b/atom/common/options_switches.h index 9887359a502b..9f171836f653 100644 --- a/atom/common/options_switches.h +++ b/atom/common/options_switches.h @@ -27,41 +27,42 @@ extern const char kFullscreen[]; extern const char kSkipTaskbar[]; extern const char kKiosk[]; extern const char kAlwaysOnTop[]; -extern const char kNodeIntegration[]; extern const char kAcceptFirstMouse[]; extern const char kUseContentSize[]; extern const char kTitleBarStyle[]; -extern const char kWebPreferences[]; -extern const char kZoomFactor[]; extern const char kAutoHideMenuBar[]; extern const char kEnableLargerThanScreen[]; extern const char kDarkTheme[]; -extern const char kDirectWrite[]; -extern const char kEnablePlugins[]; -extern const char kPpapiFlashPath[]; -extern const char kPpapiFlashVersion[]; -extern const char kGuestInstanceID[]; -extern const char kPreloadScript[]; -extern const char kPreloadUrl[]; extern const char kTransparent[]; extern const char kType[]; extern const char kDisableAutoHideCursor[]; extern const char kStandardWindow[]; extern const char kBackgroundColor[]; -extern const char kClientCertificate[]; +extern const char kWebPreferences[]; +// WebPreferences. +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[]; +extern const char kDirectWrite[]; +// Following are actually command line switches, should be moved to other files. +extern const char kEnablePlugins[]; +extern const char kPpapiFlashPath[]; +extern const char kPpapiFlashVersion[]; +extern const char kClientCertificate[]; extern const char kDisableHttpCache[]; extern const char kRegisterStandardSchemes[]; extern const char kSSLVersionFallbackMin[]; extern const char kCipherSuiteBlacklist[]; - extern const char kAppUserModelId[]; } // namespace switches diff --git a/atom/renderer/lib/init.coffee b/atom/renderer/lib/init.coffee index b7224b39aeed..ed3482fb972b 100644 --- a/atom/renderer/lib/init.coffee +++ b/atom/renderer/lib/init.coffee @@ -25,10 +25,10 @@ v8Util.setHiddenValue global, 'ipc', new events.EventEmitter # Process command line arguments. nodeIntegration = 'false' for arg in process.argv - if arg.indexOf('--guest-instance-id=') == 0 + if arg.indexOf('--guestInstanceId=') == 0 # This is a guest web view. process.guestInstanceId = parseInt arg.substr(arg.indexOf('=') + 1) - else if arg.indexOf('--node-integration=') == 0 + else if arg.indexOf('--nodeIntegration=') == 0 nodeIntegration = arg.substr arg.indexOf('=') + 1 else if arg.indexOf('--preload=') == 0 preloadScript = arg.substr arg.indexOf('=') + 1 diff --git a/atom/renderer/lib/override.coffee b/atom/renderer/lib/override.coffee index e54a0e9685c2..729de8ed64d2 100644 --- a/atom/renderer/lib/override.coffee +++ b/atom/renderer/lib/override.coffee @@ -60,12 +60,6 @@ window.open = (url, frameName='', features='') -> (options[name] = parseInt(options[name], 10) if options[name]?) for name in ints - # Inherit the node-integration option of current window. - unless options['node-integration']? - for arg in process.argv when arg.indexOf('--node-integration=') is 0 - options['node-integration'] = arg.substr(-4) is 'true' - break - guestId = ipc.sendSync 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_OPEN', url, frameName, options if guestId new BrowserWindowProxy(guestId) diff --git a/spec/api-browser-window-spec.coffee b/spec/api-browser-window-spec.coffee index 460a1c1ec17c..4528ab72b660 100644 --- a/spec/api-browser-window-spec.coffee +++ b/spec/api-browser-window-spec.coffee @@ -138,10 +138,10 @@ describe 'browser-window module', -> w.setResizable not w.isResizable() assert.deepEqual s, w.getSize() - describe '"use-content-size" option', -> + describe '"useContentSize" option', -> it 'make window created with content size when used', -> w.destroy() - w = new BrowserWindow(show: false, width: 400, height: 400, 'use-content-size': true) + w = new BrowserWindow(show: false, width: 400, height: 400, useContentSize: true) contentSize = w.getContentSize() assert.equal contentSize[0], 400 assert.equal contentSize[1], 400 @@ -153,7 +153,7 @@ describe 'browser-window module', -> it 'works for framless window', -> w.destroy() - w = new BrowserWindow(show: false, frame: false, width: 400, height: 400, 'use-content-size': true) + w = new BrowserWindow(show: false, frame: false, width: 400, height: 400, useContentSize: true) contentSize = w.getContentSize() assert.equal contentSize[0], 400 assert.equal contentSize[1], 400 @@ -167,22 +167,22 @@ describe 'browser-window module', -> it 'creates browser window with hidden title bar', -> w.destroy() - w = new BrowserWindow(show: false, width: 400, height: 400, 'title-bar-style': 'hidden') + w = new BrowserWindow(show: false, width: 400, height: 400, titleBarStyle: 'hidden') contentSize = w.getContentSize() assert.equal contentSize[1], 400 it 'creates browser window with hidden inset title bar', -> w.destroy() - w = new BrowserWindow(show: false, width: 400, height: 400, 'title-bar-style': 'hidden-inset') + w = new BrowserWindow(show: false, width: 400, height: 400, titleBarStyle: 'hidden-inset') contentSize = w.getContentSize() assert.equal contentSize[1], 400 - describe '"enable-larger-than-screen" option', -> + describe '"enableLargerThanScreen" option', -> return if process.platform is 'linux' beforeEach -> w.destroy() - w = new BrowserWindow(show: true, width: 400, height: 400, 'enable-larger-than-screen': true) + w = new BrowserWindow(show: true, width: 400, height: 400, enableLargerThanScreen: true) it 'can move the window out of screen', -> w.setPosition -10, -10 @@ -212,7 +212,7 @@ describe 'browser-window module', -> w.destroy() w = new BrowserWindow show: false - 'web-preferences': + webPreferences: preload: preload w.loadUrl 'file://' + path.join(fixtures, 'api', 'preload.html') @@ -225,9 +225,9 @@ describe 'browser-window module', -> w.destroy() w = new BrowserWindow show: false - 'web-preferences': + webPreferences: preload: preload - 'node-integration': false + nodeIntegration: false w.loadUrl 'file://' + path.join(fixtures, 'api', 'blank.html') describe 'beforeunload handler', -> diff --git a/spec/api-crash-reporter-spec.coffee b/spec/api-crash-reporter-spec.coffee index 5e06cade8cec..6232edfd3b6c 100644 --- a/spec/api-crash-reporter-spec.coffee +++ b/spec/api-crash-reporter-spec.coffee @@ -24,10 +24,15 @@ describe 'crash-reporter module', -> it 'should send minidump when renderer crashes', (done) -> @timeout 120000 + called = false server = http.createServer (req, res) -> server.close() form = new multiparty.Form() form.parse req, (error, fields, files) -> + # This callback can be called for twice sometimes. + return if called + called = true + assert.equal fields['prod'], 'Electron' assert.equal fields['ver'], process.versions['electron'] assert.equal fields['process_type'], 'renderer' diff --git a/spec/chromium-spec.coffee b/spec/chromium-spec.coffee index a034f9378235..09bae3d92e7e 100644 --- a/spec/chromium-spec.coffee +++ b/spec/chromium-spec.coffee @@ -70,7 +70,7 @@ describe 'chromium feature', -> b.close() done() window.addEventListener 'message', listener - b = window.open "file://#{fixtures}/pages/window-opener-node.html", '', 'node-integration=no,show=no' + b = window.open "file://#{fixtures}/pages/window-opener-node.html", '', 'nodeIntegration=no,show=no' it 'inherit options of parent window', (done) -> listener = (event) -> diff --git a/vendor/native_mate b/vendor/native_mate index 21cda4e7fcff..93984941005b 160000 --- a/vendor/native_mate +++ b/vendor/native_mate @@ -1 +1 @@ -Subproject commit 21cda4e7fcff592f33f989c1fea575658281711d +Subproject commit 93984941005bab194a2d47aff655d525c064efcb