Compare commits

...

34 Commits

Author SHA1 Message Date
Kevin Sawicki
0037af51f3 Bump v1.3.12 2016-11-28 10:50:25 -08:00
Kevin Sawicki
435162af17 Remove unintended returns 2016-11-28 10:49:26 -08:00
Kevin Sawicki
64077277b1 Access URL through webContents directly 2016-11-28 10:48:52 -08:00
Kevin Sawicki
acb95f4614 Add more origin comparison specs 2016-11-28 10:48:41 -08:00
Kevin Sawicki
082b47fb85 window.opener location should be webview src URL 2016-11-28 10:48:31 -08:00
Kevin Sawicki
650867772a Bump v1.3.11 2016-11-23 13:20:57 -08:00
Kevin Sawicki
13d2fc9c81 Always use guest contents for canAccessWindow check 2016-11-23 11:45:05 -08:00
Kevin Sawicki
04a846a106 Add failing specs window.opener from <webview> opened window 2016-11-23 11:44:58 -08:00
Kevin Sawicki
cb84d26d20 Bump v1.3.10 2016-11-22 09:33:38 -08:00
Kevin Sawicki
78cf807cf0 Add initial spec for zoom level limits 2016-11-22 09:19:55 -08:00
Kevin Sawicki
f3de3334cf Add setZoomLevelLimits to planned breaking changes 2016-11-22 09:19:39 -08:00
Kevin Sawicki
a9d5a1d771 Add 2.0 comment about setZoomLevelLimits 2016-11-22 09:18:59 -08:00
Kevin Sawicki
2356577614 Expose setVisualZoomLevelLimits on webContents and <web-view> 2016-11-22 09:18:54 -08:00
Kevin Sawicki
94a5132b07 Document webFrame.setVisualZoomLevelLimits as public 2016-11-22 09:18:50 -08:00
Kevin Sawicki
dca200d918 Export a setVisualZoomLevelLimits method 2016-11-22 09:18:45 -08:00
Paul Betts
e86e7d699f 📝 2016-11-22 09:18:16 -08:00
Paul Betts
922fcfb3da Lint 2016-11-22 09:18:11 -08:00
Paul Betts
1d35151353 Add new method to set layout-based zoom level limit 2016-11-22 09:18:07 -08:00
Kevin Sawicki
cb9fdc45e6 Bump v1.3.9 2016-11-16 11:29:03 -08:00
Kevin Sawicki
2dafd845b9 Make scheme const 2016-11-16 11:29:03 -08:00
Kevin Sawicki
9017f90b57 Use sender.id instead of sender.webContents.id 2016-11-16 11:29:03 -08:00
Kevin Sawicki
b94638894e Don't log blocked messages when guestWindow is null 2016-11-16 11:29:03 -08:00
Kevin Sawicki
8a3288d791 Always call done callback in before block 2016-11-16 11:29:03 -08:00
Cheng Zhao
6f5336c63f Fix standard linting errors 2016-11-16 11:29:03 -08:00
Cheng Zhao
73c1fab423 Print error messages 2016-11-16 11:29:03 -08:00
Cheng Zhao
1e36ee918e Do permission check when calling guest window methods 2016-11-16 11:29:03 -08:00
Cheng Zhao
1f49da7a06 spec: Should check origin before accessing window.opener 2016-11-16 11:28:52 -08:00
Kevin Sawicki
037a458e1d Bump v1.3.8 2016-10-20 11:34:18 +09:00
Jacob Groundwater
03a274ee27 Fire a11y event on touch screens using screen readers 2016-10-18 13:52:05 +09:00
Paul Betts
c4bd516b77 Code Cleanup 2016-10-18 13:51:55 +09:00
Paul Betts
4c914c1277 Check harder before enabling Accessibility support 2016-10-18 13:51:34 +09:00
Cheng Zhao
e3688a8e9d Bump v1.3.7 2016-09-27 03:19:21 +00:00
Cheng Zhao
375534cf4a module search paths have changed 2016-09-27 03:00:08 +00:00
Cheng Zhao
397e5ad0ac Update to Node v6.5.0 2016-09-27 02:45:19 +00:00
25 changed files with 363 additions and 56 deletions

View File

@@ -138,7 +138,7 @@ NativeWindowViews::NativeWindowViews(
menu_bar_visible_(false),
menu_bar_alt_pressed_(false),
#if defined(OS_WIN)
enabled_a11y_support_(false),
checked_for_a11y_support_(false),
thick_frame_(true),
#endif
keyboard_event_handler_(new views::UnhandledKeyboardEventHandler),

View File

@@ -18,6 +18,8 @@
#include "atom/browser/ui/win/message_handler_delegate.h"
#include "atom/browser/ui/win/taskbar_host.h"
#include "base/win/scoped_gdi_object.h"
#include "ui/base/win/accessibility_misc_utils.h"
#include <UIAutomationCoreApi.h>
#endif
namespace views {
@@ -228,8 +230,8 @@ class NativeWindowViews : public NativeWindow,
// In charge of running taskbar related APIs.
TaskbarHost taskbar_host_;
// If true we have enabled a11y
bool enabled_a11y_support_;
// Memoized version of a11y check
bool checked_for_a11y_support_;
// Whether to show the WS_THICKFRAME style.
bool thick_frame_;

View File

@@ -72,6 +72,12 @@ const char* AppCommandToString(int command_id) {
}
}
bool IsScreenReaderActive() {
UINT screenReader = 0;
SystemParametersInfo(SPI_GETSCREENREADER, 0, &screenReader, 0);
return screenReader && UiaClientsAreListening();
}
} // namespace
bool NativeWindowViews::ExecuteWindowsCommand(int command_id) {
@@ -91,16 +97,24 @@ bool NativeWindowViews::PreHandleMSG(
// because we still want Chromium to handle returning the actual
// accessibility object.
case WM_GETOBJECT: {
const DWORD obj_id = static_cast<DWORD>(l_param);
if (enabled_a11y_support_) return false;
if (checked_for_a11y_support_) return false;
if (obj_id == OBJID_CLIENT) {
const auto axState = content::BrowserAccessibilityState::GetInstance();
if (axState && !axState->IsAccessibleBrowser()) {
axState->OnScreenReaderDetected();
enabled_a11y_support_ = true;
Browser::Get()->OnAccessibilitySupportChanged();
}
const DWORD obj_id = static_cast<DWORD>(l_param);
if (obj_id != OBJID_CLIENT) {
return false;
}
if (!IsScreenReaderActive()) {
return false;
}
checked_for_a11y_support_ = true;
const auto axState = content::BrowserAccessibilityState::GetInstance();
if (axState && !axState->IsAccessibleBrowser()) {
axState->OnScreenReaderDetected();
Browser::Get()->OnAccessibilitySupportChanged();
}
return false;

View File

@@ -17,9 +17,9 @@
<key>CFBundleIconFile</key>
<string>electron.icns</string>
<key>CFBundleVersion</key>
<string>1.3.6</string>
<string>1.3.12</string>
<key>CFBundleShortVersionString</key>
<string>1.3.6</string>
<string>1.3.12</string>
<key>LSApplicationCategoryType</key>
<string>public.app-category.developer-tools</string>
<key>LSMinimumSystemVersion</key>

View File

@@ -56,8 +56,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,3,6,0
PRODUCTVERSION 1,3,6,0
FILEVERSION 1,3,12,0
PRODUCTVERSION 1,3,12,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -74,12 +74,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "GitHub, Inc."
VALUE "FileDescription", "Electron"
VALUE "FileVersion", "1.3.6"
VALUE "FileVersion", "1.3.12"
VALUE "InternalName", "electron.exe"
VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved."
VALUE "OriginalFilename", "electron.exe"
VALUE "ProductName", "Electron"
VALUE "ProductVersion", "1.3.6"
VALUE "ProductVersion", "1.3.12"
VALUE "SquirrelAwareVersion", "1"
END
END

View File

@@ -9,9 +9,11 @@
#include "atom/common/api/remote_callback_freer.h"
#include "atom/common/api/remote_object_freer.h"
#include "atom/common/native_mate_converters/content_converter.h"
#include "atom/common/native_mate_converters/gurl_converter.h"
#include "atom/common/node_includes.h"
#include "base/hash.h"
#include "native_mate/dictionary.h"
#include "url/origin.h"
#include "v8/include/v8-profiler.h"
namespace std {
@@ -92,6 +94,10 @@ void TakeHeapSnapshot(v8::Isolate* isolate) {
isolate->GetHeapProfiler()->TakeHeapSnapshot();
}
bool IsSameOrigin(const GURL& l, const GURL& r) {
return url::Origin(l).IsSameOriginWith(url::Origin(r));
}
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
v8::Local<v8::Context> context, void* priv) {
mate::Dictionary dict(context->GetIsolate(), exports);
@@ -105,6 +111,7 @@ void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
dict.SetMethod("createIDWeakMap", &atom::api::KeyWeakMap<int32_t>::Create);
dict.SetMethod("createDoubleIDWeakMap",
&atom::api::KeyWeakMap<std::pair<int32_t, int32_t>>::Create);
dict.SetMethod("isSameOrigin", &IsSameOrigin);
}
} // namespace

View File

@@ -7,7 +7,7 @@
#define ATOM_MAJOR_VERSION 1
#define ATOM_MINOR_VERSION 3
#define ATOM_PATCH_VERSION 6
#define ATOM_PATCH_VERSION 12
#define ATOM_VERSION_IS_RELEASE 1

View File

@@ -88,10 +88,14 @@ double WebFrame::GetZoomFactor() const {
return blink::WebView::zoomLevelToZoomFactor(GetZoomLevel());
}
void WebFrame::SetZoomLevelLimits(double min_level, double max_level) {
void WebFrame::SetVisualZoomLevelLimits(double min_level, double max_level) {
web_frame_->view()->setDefaultPageScaleLimits(min_level, max_level);
}
void WebFrame::SetLayoutZoomLevelLimits(double min_level, double max_level) {
web_frame_->view()->zoomLimitsChanged(min_level, max_level);
}
v8::Local<v8::Value> WebFrame::RegisterEmbedderCustomElement(
const base::string16& name, v8::Local<v8::Object> options) {
blink::WebExceptionCode c = 0;
@@ -196,7 +200,10 @@ void WebFrame::BuildPrototype(
.SetMethod("getZoomLevel", &WebFrame::GetZoomLevel)
.SetMethod("setZoomFactor", &WebFrame::SetZoomFactor)
.SetMethod("getZoomFactor", &WebFrame::GetZoomFactor)
.SetMethod("setZoomLevelLimits", &WebFrame::SetZoomLevelLimits)
.SetMethod("setVisualZoomLevelLimits",
&WebFrame::SetVisualZoomLevelLimits)
.SetMethod("setLayoutZoomLevelLimits",
&WebFrame::SetLayoutZoomLevelLimits)
.SetMethod("registerEmbedderCustomElement",
&WebFrame::RegisterEmbedderCustomElement)
.SetMethod("registerElementResizeCallback",
@@ -212,7 +219,9 @@ void WebFrame::BuildPrototype(
.SetMethod("insertText", &WebFrame::InsertText)
.SetMethod("executeJavaScript", &WebFrame::ExecuteJavaScript)
.SetMethod("getResourceUsage", &WebFrame::GetResourceUsage)
.SetMethod("clearCache", &WebFrame::ClearCache);
.SetMethod("clearCache", &WebFrame::ClearCache)
// TODO(kevinsawicki): Remove in 2.0, deprecate before then with warnings
.SetMethod("setZoomLevelLimits", &WebFrame::SetVisualZoomLevelLimits);
}
} // namespace api

View File

@@ -45,7 +45,8 @@ class WebFrame : public mate::Wrappable<WebFrame> {
double SetZoomFactor(double factor);
double GetZoomFactor() const;
void SetZoomLevelLimits(double min_level, double max_level);
void SetVisualZoomLevelLimits(double min_level, double max_level);
void SetLayoutZoomLevelLimits(double min_level, double max_level);
v8::Local<v8::Value> RegisterEmbedderCustomElement(
const base::string16& name, v8::Local<v8::Object> options);

View File

@@ -36,6 +36,7 @@
'node_use_perfctr': 'false',
'node_use_v8_platform': 'false',
'node_use_bundled_v8': 'false',
'node_enable_d8': 'false',
'uv_library': 'static_library',
'uv_parent_path': 'vendor/node/deps/uv',
'uv_use_dtrace': 'false',

View File

@@ -684,7 +684,22 @@ Sends a request to get current zoom level, the `callback` will be called with
* `minimumLevel` Number
* `maximumLevel` Number
Sets the maximum and minimum zoom level.
**Deprecated:** Call `setVisualZoomLevelLimits` instead to set the visual zoom
level limits. This method will be removed in Electron 2.0.
#### `contents.setVisualZoomLevelLimits(minimumLevel, maximumLevel)`
* `minimumLevel` Number
* `maximumLevel` Number
Sets the maximum and minimum pinch-to-zoom level.
#### `contents.setLayoutZoomLevelLimits(minimumLevel, maximumLevel)`
* `minimumLevel` Number
* `maximumLevel` Number
Sets the maximum and minimum layout-based (i.e. non-visual) zoom level.
#### `contents.undo()`

View File

@@ -42,7 +42,22 @@ Returns the current zoom level.
* `minimumLevel` Number
* `maximumLevel` Number
Sets the maximum and minimum zoom level.
**Deprecated:** Call `setVisualZoomLevelLimits` instead to set the visual zoom
level limits. This method will be removed in Electron 2.0.
### `webFrame.setVisualZoomLevelLimits(minimumLevel, maximumLevel)`
* `minimumLevel` Number
* `maximumLevel` Number
Sets the maximum and minimum pinch-to-zoom level.
### `webFrame.setLayoutZoomLevelLimits(minimumLevel, maximumLevel)`
* `minimumLevel` Number
* `maximumLevel` Number
Sets the maximum and minimum layout-based (i.e. non-visual) zoom level.
### `webFrame.setSpellCheckProvider(language, autoCorrectWord, provider)`

View File

@@ -76,3 +76,28 @@ webContents.openDevTools({detach: true})
// Replace with
webContents.openDevTools({mode: 'detach'})
```
```js
// Deprecated
webContents.setZoomLevelLimits(1, 2)
// Replace with
webContents.setVisualZoomLevelLimits(1, 2)
```
## `webFrame`
```js
// Deprecated
webFrame.setZoomLevelLimits(1, 2)
// Replace with
webFrame.setVisualZoomLevelLimits(1, 2)
```
## `<webview>`
```js
// Deprecated
webview.setZoomLevelLimits(1, 2)
// Replace with
webview.setVisualZoomLevelLimits(1, 2)
```

View File

@@ -4,7 +4,7 @@
'product_name%': 'Electron',
'company_name%': 'GitHub, Inc',
'company_abbr%': 'github',
'version%': '1.3.6',
'version%': '1.3.12',
},
'includes': [
'filenames.gypi',
@@ -279,6 +279,7 @@
'-lcomdlg32.lib',
'-lwininet.lib',
'-lwinmm.lib',
'-luiautomationcore.lib',
],
},
'dependencies': [

View File

@@ -100,8 +100,11 @@ WebContents.prototype.sendToAll = function (channel, ...args) {
// Following methods are mapped to webFrame.
const webFrameMethods = [
'insertText',
'setLayoutZoomLevelLimits',
'setVisualZoomLevelLimits',
'setZoomFactor',
'setZoomLevel',
// TODO(kevinsawicki): Remove in 2.0, deprecate before then with warnings
'setZoomLevelLimits'
]
const webFrameMethodsWithResult = [

View File

@@ -1,6 +1,7 @@
'use strict'
const {BrowserWindow, ipcMain, webContents} = require('electron')
const {isSameOrigin} = process.atomBinding('v8_util')
const hasProp = {}.hasOwnProperty
const frameToGuest = {}
@@ -86,10 +87,7 @@ const createGuest = function (embedder, url, frameName, options) {
return guestId
}
const getGuestWindow = function (guestId) {
const guestContents = webContents.fromId(guestId)
if (guestContents == null) return
const getGuestWindow = function (guestContents) {
let guestWindow = BrowserWindow.fromWebContents(guestContents)
if (guestWindow == null) {
const hostContents = guestContents.hostWebContents
@@ -100,6 +98,22 @@ const getGuestWindow = function (guestId) {
return guestWindow
}
// Checks whether |sender| can access the |target|:
// 1. Check whether |sender| is the parent of |target|.
// 2. Check whether |sender| has node integration, if so it is allowed to
// do anything it wants.
// 3. Check whether the origins match.
//
// However it allows a child window without node integration but with same
// origin to do anything it wants, when its opener window has node integration.
// The W3C does not have anything on this, but from my understanding of the
// security model of |window.opener|, this should be fine.
const canAccessWindow = function (sender, target) {
return (target.getWebPreferences().openerId === sender.id) ||
(sender.getWebPreferences().nodeIntegration === true) ||
isSameOrigin(sender.getURL(), target.getURL())
}
// Routed window.open messages.
ipcMain.on('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_OPEN', function (event, url, frameName, disposition, options) {
options = mergeBrowserWindowOptions(event.sender, options)
@@ -112,19 +126,46 @@ ipcMain.on('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_OPEN', function (event, url, fr
})
ipcMain.on('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_CLOSE', function (event, guestId) {
const guestWindow = getGuestWindow(guestId)
const guestContents = webContents.fromId(guestId)
if (guestContents == null) return
if (!canAccessWindow(event.sender, guestContents)) {
console.error(`Blocked ${event.sender.getURL()} from closing its opener.`)
return
}
const guestWindow = getGuestWindow(guestContents)
if (guestWindow != null) guestWindow.destroy()
})
ipcMain.on('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_METHOD', function (event, guestId, method, ...args) {
const guestWindow = getGuestWindow(guestId)
event.returnValue = guestWindow != null ? guestWindow[method].apply(guestWindow, args) : null
const guestContents = webContents.fromId(guestId)
if (guestContents == null) {
event.returnValue = null
return
}
if (!canAccessWindow(event.sender, guestContents)) {
console.error(`Blocked ${event.sender.getURL()} from calling ${method} on its opener.`)
event.returnValue = null
return
}
const guestWindow = getGuestWindow(guestContents)
if (guestWindow != null) {
event.returnValue = guestWindow[method].apply(guestWindow, args)
} else {
event.returnValue = null
}
})
ipcMain.on('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_POSTMESSAGE', function (event, guestId, message, targetOrigin, sourceOrigin) {
const guestContents = webContents.fromId(guestId)
if (guestContents == null) return
// The W3C does not seem to have word on how postMessage should work when the
// origins do not match, so we do not do |canAccessWindow| check here since
// postMessage across origins is useful and not harmful.
if (guestContents.getURL().indexOf(targetOrigin) === 0 || targetOrigin === '*') {
const sourceId = event.sender.id
guestContents.send('ELECTRON_GUEST_WINDOW_POSTMESSAGE', sourceId, message, sourceOrigin)
@@ -133,5 +174,26 @@ ipcMain.on('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_POSTMESSAGE', function (event,
ipcMain.on('ELECTRON_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD', function (event, guestId, method, ...args) {
const guestContents = webContents.fromId(guestId)
if (guestContents != null) guestContents[method].apply(guestContents, args)
if (guestContents == null) return
if (canAccessWindow(event.sender, guestContents)) {
guestContents[method].apply(guestContents, args)
} else {
console.error(`Blocked ${event.sender.getURL()} from calling ${method} on its opener.`)
}
})
ipcMain.on('ELECTRON_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD_SYNC', function (event, guestId, method, ...args) {
const guestContents = webContents.fromId(guestId)
if (guestContents == null) {
event.returnValue = null
return
}
if (canAccessWindow(event.sender, guestContents)) {
event.returnValue = guestContents[method].apply(guestContents, args)
} else {
console.error(`Blocked ${event.sender.getURL()} from calling ${method} on its opener.`)
event.returnValue = null
}
})

View File

@@ -21,7 +21,7 @@ var BrowserWindowProxy = (function () {
}
BrowserWindowProxy.remove = function (guestId) {
return delete this.proxies[guestId]
delete this.proxies[guestId]
}
function BrowserWindowProxy (guestId1) {
@@ -40,28 +40,28 @@ var BrowserWindowProxy = (function () {
}
BrowserWindowProxy.prototype.close = function () {
return ipcRenderer.send('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_CLOSE', this.guestId)
ipcRenderer.send('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_CLOSE', this.guestId)
}
BrowserWindowProxy.prototype.focus = function () {
return ipcRenderer.send('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_METHOD', this.guestId, 'focus')
ipcRenderer.send('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_METHOD', this.guestId, 'focus')
}
BrowserWindowProxy.prototype.blur = function () {
return ipcRenderer.send('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_METHOD', this.guestId, 'blur')
ipcRenderer.send('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_METHOD', this.guestId, 'blur')
}
BrowserWindowProxy.prototype.print = function () {
return ipcRenderer.send('ELECTRON_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD', this.guestId, 'print')
ipcRenderer.send('ELECTRON_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD', this.guestId, 'print')
}
Object.defineProperty(BrowserWindowProxy.prototype, 'location', {
get: function () {
return ipcRenderer.sendSync('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_METHOD', this.guestId, 'getURL')
return ipcRenderer.sendSync('ELECTRON_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD_SYNC', this.guestId, 'getURL')
},
set: function (url) {
url = resolveURL(url)
return ipcRenderer.sendSync('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_METHOD', this.guestId, 'loadURL', url)
return ipcRenderer.sendSync('ELECTRON_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD_SYNC', this.guestId, 'loadURL', url)
}
})
@@ -69,11 +69,11 @@ var BrowserWindowProxy = (function () {
if (targetOrigin == null) {
targetOrigin = '*'
}
return ipcRenderer.send('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_POSTMESSAGE', this.guestId, message, targetOrigin, window.location.origin)
ipcRenderer.send('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_POSTMESSAGE', this.guestId, message, targetOrigin, window.location.origin)
}
BrowserWindowProxy.prototype['eval'] = function (...args) {
return ipcRenderer.send.apply(ipcRenderer, ['ELECTRON_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD', this.guestId, 'executeJavaScript'].concat(args))
ipcRenderer.send.apply(ipcRenderer, ['ELECTRON_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD', this.guestId, 'executeJavaScript'].concat(args))
}
return BrowserWindowProxy
@@ -205,7 +205,7 @@ ipcRenderer.on('ELECTRON_GUEST_WINDOW_POSTMESSAGE', function (event, sourceId, m
// Forward history operations to browser.
var sendHistoryOperation = function (...args) {
return ipcRenderer.send.apply(ipcRenderer, ['ELECTRON_NAVIGATION_CONTROLLER'].concat(args))
ipcRenderer.send.apply(ipcRenderer, ['ELECTRON_NAVIGATION_CONTROLLER'].concat(args))
}
var getHistoryOperation = function (...args) {
@@ -213,15 +213,15 @@ var getHistoryOperation = function (...args) {
}
window.history.back = function () {
return sendHistoryOperation('goBack')
sendHistoryOperation('goBack')
}
window.history.forward = function () {
return sendHistoryOperation('goForward')
sendHistoryOperation('goForward')
}
window.history.go = function (offset) {
return sendHistoryOperation('goToOffset', offset)
sendHistoryOperation('goToOffset', offset)
}
Object.defineProperty(window.history, 'length', {

View File

@@ -394,8 +394,11 @@ var registerWebViewElement = function () {
'insertText',
'send',
'sendInputEvent',
'setLayoutZoomLevelLimits',
'setVisualZoomLevelLimits',
'setZoomFactor',
'setZoomLevel',
// TODO(kevinsawicki): Remove in 2.0, deprecate before then with warnings
'setZoomLevelLimits'
]

View File

@@ -1,6 +1,6 @@
{
"name": "electron",
"version": "1.3.6",
"version": "1.3.12",
"devDependencies": {
"asar": "^0.11.0",
"electabul": "~0.0.4",

View File

@@ -6,6 +6,7 @@ const {BrowserWindow, protocol, ipcMain} = remote
describe('webFrame module', function () {
var fixtures = path.resolve(__dirname, 'fixtures')
describe('webFrame.registerURLSchemeAsPrivileged', function () {
it('supports fetch api', function (done) {
webFrame.registerURLSchemeAsPrivileged('file')
@@ -61,4 +62,12 @@ describe('webFrame module', function () {
})
})
})
it('supports setting the visual and layout zoom level limits', function () {
assert.doesNotThrow(function () {
webFrame.setZoomLevelLimits(1, 100)
webFrame.setVisualZoomLevelLimits(1, 50)
webFrame.setLayoutZoomLevelLimits(0, 25)
})
})
})

View File

@@ -5,7 +5,7 @@ const ws = require('ws')
const url = require('url')
const remote = require('electron').remote
const {BrowserWindow, session, webContents} = remote
const {BrowserWindow, protocol, session, webContents} = remote
const isCI = remote.getGlobal('isCi')
@@ -283,11 +283,11 @@ describe('chromium feature', function () {
describe('window.opener', function () {
this.timeout(10000)
var url = 'file://' + fixtures + '/pages/window-opener.html'
var w = null
let url = 'file://' + fixtures + '/pages/window-opener.html'
let w = null
afterEach(function () {
w != null ? w.destroy() : void 0
if (w) w.destroy()
})
it('is null for main window', function (done) {
@@ -302,7 +302,7 @@ describe('chromium feature', function () {
})
it('is not null for window opened by window.open', function (done) {
var b
let b
listener = function (event) {
assert.equal(event.data, 'object')
b.close()
@@ -313,6 +313,138 @@ describe('chromium feature', function () {
})
})
describe('window.opener access from BrowserWindow', function () {
this.timeout(10000)
const scheme = 'other'
let url = `${scheme}://${fixtures}/pages/window-opener-location.html`
let w = null
before(function (done) {
protocol.registerFileProtocol(scheme, function (request, callback) {
callback(`${fixtures}/pages/window-opener-location.html`)
}, function (error) {
done(error)
})
})
after(function () {
protocol.unregisterProtocol(scheme)
})
afterEach(function () {
w.close()
})
it('does nothing when origin of current window does not match opener', function (done) {
listener = function (event) {
assert.equal(event.data, undefined)
done()
}
window.addEventListener('message', listener)
w = window.open(url, '', 'show=no')
})
it('works when origin matches', function (done) {
listener = function (event) {
assert.equal(event.data, location.href)
done()
}
window.addEventListener('message', listener)
w = window.open(`file://${fixtures}/pages/window-opener-location.html`, '', 'show=no')
})
it('works when origin does not match opener but has node integration', function (done) {
listener = function (event) {
assert.equal(event.data, location.href)
done()
}
window.addEventListener('message', listener)
w = window.open(url, '', 'show=no,nodeIntegration=yes')
})
})
describe('window.opener access from <webview>', function () {
this.timeout(10000)
const scheme = 'other'
const srcPath = `${fixtures}/pages/webview-opener-postMessage.html`
const pageURL = `file://${fixtures}/pages/window-opener-location.html`
let webview = null
before(function (done) {
protocol.registerFileProtocol(scheme, function (request, callback) {
callback(srcPath)
}, function (error) {
done(error)
})
})
after(function () {
protocol.unregisterProtocol(scheme)
})
afterEach(function () {
if (webview != null) webview.remove()
})
it('does nothing when origin of webview src URL does not match opener', function (done) {
webview = new WebView()
webview.addEventListener('console-message', function (e) {
assert.equal(e.message, 'null')
done()
})
webview.setAttribute('allowpopups', 'on')
webview.src = url.format({
pathname: srcPath,
protocol: scheme,
query: {
p: pageURL
},
slashes: true
})
document.body.appendChild(webview)
})
it('works when origin matches', function (done) {
webview = new WebView()
webview.addEventListener('console-message', function (e) {
assert.equal(e.message, webview.src)
done()
})
webview.setAttribute('allowpopups', 'on')
webview.src = url.format({
pathname: srcPath,
protocol: 'file',
query: {
p: pageURL
},
slashes: true
})
document.body.appendChild(webview)
})
it('works when origin does not match opener but has node integration', function (done) {
webview = new WebView()
webview.addEventListener('console-message', function (e) {
webview.remove()
assert.equal(e.message, webview.src)
done()
})
webview.setAttribute('allowpopups', 'on')
webview.setAttribute('nodeintegration', 'on')
webview.src = url.format({
pathname: srcPath,
protocol: scheme,
query: {
p: pageURL
},
slashes: true
})
document.body.appendChild(webview)
})
})
describe('window.postMessage', function () {
it('sets the source and origin correctly', function (done) {
var b, sourceId

View File

@@ -0,0 +1,7 @@
<html>
<body>
<script type="text/javascript" charset="utf-8">
window.opener.postMessage(window.opener.location, '*')
</script>
</body>
</html>

View File

@@ -94,7 +94,8 @@ describe('Module._nodeModulePaths', function () {
it('includes paths outside of the resources path', function () {
let modulePath = path.resolve('/foo')
assert.deepEqual(Module._nodeModulePaths(modulePath), [
path.join(modulePath, 'node_modules')
path.join(modulePath, 'node_modules'),
path.resolve('/node_modules')
])
})
})

2
vendor/node vendored