mirror of
https://github.com/electron/electron.git
synced 2026-02-26 03:01:17 -05:00
Compare commits
34 Commits
refactor/U
...
v1.3.12
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0037af51f3 | ||
|
|
435162af17 | ||
|
|
64077277b1 | ||
|
|
acb95f4614 | ||
|
|
082b47fb85 | ||
|
|
650867772a | ||
|
|
13d2fc9c81 | ||
|
|
04a846a106 | ||
|
|
cb84d26d20 | ||
|
|
78cf807cf0 | ||
|
|
f3de3334cf | ||
|
|
a9d5a1d771 | ||
|
|
2356577614 | ||
|
|
94a5132b07 | ||
|
|
dca200d918 | ||
|
|
e86e7d699f | ||
|
|
922fcfb3da | ||
|
|
1d35151353 | ||
|
|
cb9fdc45e6 | ||
|
|
2dafd845b9 | ||
|
|
9017f90b57 | ||
|
|
b94638894e | ||
|
|
8a3288d791 | ||
|
|
6f5336c63f | ||
|
|
73c1fab423 | ||
|
|
1e36ee918e | ||
|
|
1f49da7a06 | ||
|
|
037a458e1d | ||
|
|
03a274ee27 | ||
|
|
c4bd516b77 | ||
|
|
4c914c1277 | ||
|
|
e3688a8e9d | ||
|
|
375534cf4a | ||
|
|
397e5ad0ac |
@@ -138,7 +138,7 @@ NativeWindowViews::NativeWindowViews(
|
|||||||
menu_bar_visible_(false),
|
menu_bar_visible_(false),
|
||||||
menu_bar_alt_pressed_(false),
|
menu_bar_alt_pressed_(false),
|
||||||
#if defined(OS_WIN)
|
#if defined(OS_WIN)
|
||||||
enabled_a11y_support_(false),
|
checked_for_a11y_support_(false),
|
||||||
thick_frame_(true),
|
thick_frame_(true),
|
||||||
#endif
|
#endif
|
||||||
keyboard_event_handler_(new views::UnhandledKeyboardEventHandler),
|
keyboard_event_handler_(new views::UnhandledKeyboardEventHandler),
|
||||||
|
|||||||
@@ -18,6 +18,8 @@
|
|||||||
#include "atom/browser/ui/win/message_handler_delegate.h"
|
#include "atom/browser/ui/win/message_handler_delegate.h"
|
||||||
#include "atom/browser/ui/win/taskbar_host.h"
|
#include "atom/browser/ui/win/taskbar_host.h"
|
||||||
#include "base/win/scoped_gdi_object.h"
|
#include "base/win/scoped_gdi_object.h"
|
||||||
|
#include "ui/base/win/accessibility_misc_utils.h"
|
||||||
|
#include <UIAutomationCoreApi.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace views {
|
namespace views {
|
||||||
@@ -228,8 +230,8 @@ class NativeWindowViews : public NativeWindow,
|
|||||||
// In charge of running taskbar related APIs.
|
// In charge of running taskbar related APIs.
|
||||||
TaskbarHost taskbar_host_;
|
TaskbarHost taskbar_host_;
|
||||||
|
|
||||||
// If true we have enabled a11y
|
// Memoized version of a11y check
|
||||||
bool enabled_a11y_support_;
|
bool checked_for_a11y_support_;
|
||||||
|
|
||||||
// Whether to show the WS_THICKFRAME style.
|
// Whether to show the WS_THICKFRAME style.
|
||||||
bool thick_frame_;
|
bool thick_frame_;
|
||||||
|
|||||||
@@ -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
|
} // namespace
|
||||||
|
|
||||||
bool NativeWindowViews::ExecuteWindowsCommand(int command_id) {
|
bool NativeWindowViews::ExecuteWindowsCommand(int command_id) {
|
||||||
@@ -91,16 +97,24 @@ bool NativeWindowViews::PreHandleMSG(
|
|||||||
// because we still want Chromium to handle returning the actual
|
// because we still want Chromium to handle returning the actual
|
||||||
// accessibility object.
|
// accessibility object.
|
||||||
case WM_GETOBJECT: {
|
case WM_GETOBJECT: {
|
||||||
const DWORD obj_id = static_cast<DWORD>(l_param);
|
if (checked_for_a11y_support_) return false;
|
||||||
if (enabled_a11y_support_) return false;
|
|
||||||
|
|
||||||
if (obj_id == OBJID_CLIENT) {
|
const DWORD obj_id = static_cast<DWORD>(l_param);
|
||||||
const auto axState = content::BrowserAccessibilityState::GetInstance();
|
|
||||||
if (axState && !axState->IsAccessibleBrowser()) {
|
if (obj_id != OBJID_CLIENT) {
|
||||||
axState->OnScreenReaderDetected();
|
return false;
|
||||||
enabled_a11y_support_ = true;
|
}
|
||||||
Browser::Get()->OnAccessibilitySupportChanged();
|
|
||||||
}
|
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;
|
return false;
|
||||||
|
|||||||
@@ -17,9 +17,9 @@
|
|||||||
<key>CFBundleIconFile</key>
|
<key>CFBundleIconFile</key>
|
||||||
<string>electron.icns</string>
|
<string>electron.icns</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>1.3.6</string>
|
<string>1.3.12</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>1.3.6</string>
|
<string>1.3.12</string>
|
||||||
<key>LSApplicationCategoryType</key>
|
<key>LSApplicationCategoryType</key>
|
||||||
<string>public.app-category.developer-tools</string>
|
<string>public.app-category.developer-tools</string>
|
||||||
<key>LSMinimumSystemVersion</key>
|
<key>LSMinimumSystemVersion</key>
|
||||||
|
|||||||
@@ -56,8 +56,8 @@ END
|
|||||||
//
|
//
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 1,3,6,0
|
FILEVERSION 1,3,12,0
|
||||||
PRODUCTVERSION 1,3,6,0
|
PRODUCTVERSION 1,3,12,0
|
||||||
FILEFLAGSMASK 0x3fL
|
FILEFLAGSMASK 0x3fL
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
@@ -74,12 +74,12 @@ BEGIN
|
|||||||
BEGIN
|
BEGIN
|
||||||
VALUE "CompanyName", "GitHub, Inc."
|
VALUE "CompanyName", "GitHub, Inc."
|
||||||
VALUE "FileDescription", "Electron"
|
VALUE "FileDescription", "Electron"
|
||||||
VALUE "FileVersion", "1.3.6"
|
VALUE "FileVersion", "1.3.12"
|
||||||
VALUE "InternalName", "electron.exe"
|
VALUE "InternalName", "electron.exe"
|
||||||
VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved."
|
VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved."
|
||||||
VALUE "OriginalFilename", "electron.exe"
|
VALUE "OriginalFilename", "electron.exe"
|
||||||
VALUE "ProductName", "Electron"
|
VALUE "ProductName", "Electron"
|
||||||
VALUE "ProductVersion", "1.3.6"
|
VALUE "ProductVersion", "1.3.12"
|
||||||
VALUE "SquirrelAwareVersion", "1"
|
VALUE "SquirrelAwareVersion", "1"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
|
|||||||
@@ -9,9 +9,11 @@
|
|||||||
#include "atom/common/api/remote_callback_freer.h"
|
#include "atom/common/api/remote_callback_freer.h"
|
||||||
#include "atom/common/api/remote_object_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/content_converter.h"
|
||||||
|
#include "atom/common/native_mate_converters/gurl_converter.h"
|
||||||
#include "atom/common/node_includes.h"
|
#include "atom/common/node_includes.h"
|
||||||
#include "base/hash.h"
|
#include "base/hash.h"
|
||||||
#include "native_mate/dictionary.h"
|
#include "native_mate/dictionary.h"
|
||||||
|
#include "url/origin.h"
|
||||||
#include "v8/include/v8-profiler.h"
|
#include "v8/include/v8-profiler.h"
|
||||||
|
|
||||||
namespace std {
|
namespace std {
|
||||||
@@ -92,6 +94,10 @@ void TakeHeapSnapshot(v8::Isolate* isolate) {
|
|||||||
isolate->GetHeapProfiler()->TakeHeapSnapshot();
|
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,
|
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
||||||
v8::Local<v8::Context> context, void* priv) {
|
v8::Local<v8::Context> context, void* priv) {
|
||||||
mate::Dictionary dict(context->GetIsolate(), exports);
|
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("createIDWeakMap", &atom::api::KeyWeakMap<int32_t>::Create);
|
||||||
dict.SetMethod("createDoubleIDWeakMap",
|
dict.SetMethod("createDoubleIDWeakMap",
|
||||||
&atom::api::KeyWeakMap<std::pair<int32_t, int32_t>>::Create);
|
&atom::api::KeyWeakMap<std::pair<int32_t, int32_t>>::Create);
|
||||||
|
dict.SetMethod("isSameOrigin", &IsSameOrigin);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
#define ATOM_MAJOR_VERSION 1
|
#define ATOM_MAJOR_VERSION 1
|
||||||
#define ATOM_MINOR_VERSION 3
|
#define ATOM_MINOR_VERSION 3
|
||||||
#define ATOM_PATCH_VERSION 6
|
#define ATOM_PATCH_VERSION 12
|
||||||
|
|
||||||
#define ATOM_VERSION_IS_RELEASE 1
|
#define ATOM_VERSION_IS_RELEASE 1
|
||||||
|
|
||||||
|
|||||||
@@ -88,10 +88,14 @@ double WebFrame::GetZoomFactor() const {
|
|||||||
return blink::WebView::zoomLevelToZoomFactor(GetZoomLevel());
|
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);
|
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(
|
v8::Local<v8::Value> WebFrame::RegisterEmbedderCustomElement(
|
||||||
const base::string16& name, v8::Local<v8::Object> options) {
|
const base::string16& name, v8::Local<v8::Object> options) {
|
||||||
blink::WebExceptionCode c = 0;
|
blink::WebExceptionCode c = 0;
|
||||||
@@ -196,7 +200,10 @@ void WebFrame::BuildPrototype(
|
|||||||
.SetMethod("getZoomLevel", &WebFrame::GetZoomLevel)
|
.SetMethod("getZoomLevel", &WebFrame::GetZoomLevel)
|
||||||
.SetMethod("setZoomFactor", &WebFrame::SetZoomFactor)
|
.SetMethod("setZoomFactor", &WebFrame::SetZoomFactor)
|
||||||
.SetMethod("getZoomFactor", &WebFrame::GetZoomFactor)
|
.SetMethod("getZoomFactor", &WebFrame::GetZoomFactor)
|
||||||
.SetMethod("setZoomLevelLimits", &WebFrame::SetZoomLevelLimits)
|
.SetMethod("setVisualZoomLevelLimits",
|
||||||
|
&WebFrame::SetVisualZoomLevelLimits)
|
||||||
|
.SetMethod("setLayoutZoomLevelLimits",
|
||||||
|
&WebFrame::SetLayoutZoomLevelLimits)
|
||||||
.SetMethod("registerEmbedderCustomElement",
|
.SetMethod("registerEmbedderCustomElement",
|
||||||
&WebFrame::RegisterEmbedderCustomElement)
|
&WebFrame::RegisterEmbedderCustomElement)
|
||||||
.SetMethod("registerElementResizeCallback",
|
.SetMethod("registerElementResizeCallback",
|
||||||
@@ -212,7 +219,9 @@ void WebFrame::BuildPrototype(
|
|||||||
.SetMethod("insertText", &WebFrame::InsertText)
|
.SetMethod("insertText", &WebFrame::InsertText)
|
||||||
.SetMethod("executeJavaScript", &WebFrame::ExecuteJavaScript)
|
.SetMethod("executeJavaScript", &WebFrame::ExecuteJavaScript)
|
||||||
.SetMethod("getResourceUsage", &WebFrame::GetResourceUsage)
|
.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
|
} // namespace api
|
||||||
|
|||||||
@@ -45,7 +45,8 @@ class WebFrame : public mate::Wrappable<WebFrame> {
|
|||||||
double SetZoomFactor(double factor);
|
double SetZoomFactor(double factor);
|
||||||
double GetZoomFactor() const;
|
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(
|
v8::Local<v8::Value> RegisterEmbedderCustomElement(
|
||||||
const base::string16& name, v8::Local<v8::Object> options);
|
const base::string16& name, v8::Local<v8::Object> options);
|
||||||
|
|||||||
@@ -36,6 +36,7 @@
|
|||||||
'node_use_perfctr': 'false',
|
'node_use_perfctr': 'false',
|
||||||
'node_use_v8_platform': 'false',
|
'node_use_v8_platform': 'false',
|
||||||
'node_use_bundled_v8': 'false',
|
'node_use_bundled_v8': 'false',
|
||||||
|
'node_enable_d8': 'false',
|
||||||
'uv_library': 'static_library',
|
'uv_library': 'static_library',
|
||||||
'uv_parent_path': 'vendor/node/deps/uv',
|
'uv_parent_path': 'vendor/node/deps/uv',
|
||||||
'uv_use_dtrace': 'false',
|
'uv_use_dtrace': 'false',
|
||||||
|
|||||||
@@ -684,7 +684,22 @@ Sends a request to get current zoom level, the `callback` will be called with
|
|||||||
* `minimumLevel` Number
|
* `minimumLevel` Number
|
||||||
* `maximumLevel` 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()`
|
#### `contents.undo()`
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,22 @@ Returns the current zoom level.
|
|||||||
* `minimumLevel` Number
|
* `minimumLevel` Number
|
||||||
* `maximumLevel` 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)`
|
### `webFrame.setSpellCheckProvider(language, autoCorrectWord, provider)`
|
||||||
|
|
||||||
|
|||||||
@@ -76,3 +76,28 @@ webContents.openDevTools({detach: true})
|
|||||||
// Replace with
|
// Replace with
|
||||||
webContents.openDevTools({mode: 'detach'})
|
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)
|
||||||
|
```
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
'product_name%': 'Electron',
|
'product_name%': 'Electron',
|
||||||
'company_name%': 'GitHub, Inc',
|
'company_name%': 'GitHub, Inc',
|
||||||
'company_abbr%': 'github',
|
'company_abbr%': 'github',
|
||||||
'version%': '1.3.6',
|
'version%': '1.3.12',
|
||||||
},
|
},
|
||||||
'includes': [
|
'includes': [
|
||||||
'filenames.gypi',
|
'filenames.gypi',
|
||||||
@@ -279,6 +279,7 @@
|
|||||||
'-lcomdlg32.lib',
|
'-lcomdlg32.lib',
|
||||||
'-lwininet.lib',
|
'-lwininet.lib',
|
||||||
'-lwinmm.lib',
|
'-lwinmm.lib',
|
||||||
|
'-luiautomationcore.lib',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
'dependencies': [
|
'dependencies': [
|
||||||
|
|||||||
@@ -100,8 +100,11 @@ WebContents.prototype.sendToAll = function (channel, ...args) {
|
|||||||
// Following methods are mapped to webFrame.
|
// Following methods are mapped to webFrame.
|
||||||
const webFrameMethods = [
|
const webFrameMethods = [
|
||||||
'insertText',
|
'insertText',
|
||||||
|
'setLayoutZoomLevelLimits',
|
||||||
|
'setVisualZoomLevelLimits',
|
||||||
'setZoomFactor',
|
'setZoomFactor',
|
||||||
'setZoomLevel',
|
'setZoomLevel',
|
||||||
|
// TODO(kevinsawicki): Remove in 2.0, deprecate before then with warnings
|
||||||
'setZoomLevelLimits'
|
'setZoomLevelLimits'
|
||||||
]
|
]
|
||||||
const webFrameMethodsWithResult = [
|
const webFrameMethodsWithResult = [
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
'use strict'
|
'use strict'
|
||||||
|
|
||||||
const {BrowserWindow, ipcMain, webContents} = require('electron')
|
const {BrowserWindow, ipcMain, webContents} = require('electron')
|
||||||
|
const {isSameOrigin} = process.atomBinding('v8_util')
|
||||||
|
|
||||||
const hasProp = {}.hasOwnProperty
|
const hasProp = {}.hasOwnProperty
|
||||||
const frameToGuest = {}
|
const frameToGuest = {}
|
||||||
@@ -86,10 +87,7 @@ const createGuest = function (embedder, url, frameName, options) {
|
|||||||
return guestId
|
return guestId
|
||||||
}
|
}
|
||||||
|
|
||||||
const getGuestWindow = function (guestId) {
|
const getGuestWindow = function (guestContents) {
|
||||||
const guestContents = webContents.fromId(guestId)
|
|
||||||
if (guestContents == null) return
|
|
||||||
|
|
||||||
let guestWindow = BrowserWindow.fromWebContents(guestContents)
|
let guestWindow = BrowserWindow.fromWebContents(guestContents)
|
||||||
if (guestWindow == null) {
|
if (guestWindow == null) {
|
||||||
const hostContents = guestContents.hostWebContents
|
const hostContents = guestContents.hostWebContents
|
||||||
@@ -100,6 +98,22 @@ const getGuestWindow = function (guestId) {
|
|||||||
return guestWindow
|
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.
|
// Routed window.open messages.
|
||||||
ipcMain.on('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_OPEN', function (event, url, frameName, disposition, options) {
|
ipcMain.on('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_OPEN', function (event, url, frameName, disposition, options) {
|
||||||
options = mergeBrowserWindowOptions(event.sender, 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) {
|
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()
|
if (guestWindow != null) guestWindow.destroy()
|
||||||
})
|
})
|
||||||
|
|
||||||
ipcMain.on('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_METHOD', function (event, guestId, method, ...args) {
|
ipcMain.on('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_METHOD', function (event, guestId, method, ...args) {
|
||||||
const guestWindow = getGuestWindow(guestId)
|
const guestContents = webContents.fromId(guestId)
|
||||||
event.returnValue = guestWindow != null ? guestWindow[method].apply(guestWindow, args) : null
|
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) {
|
ipcMain.on('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_POSTMESSAGE', function (event, guestId, message, targetOrigin, sourceOrigin) {
|
||||||
const guestContents = webContents.fromId(guestId)
|
const guestContents = webContents.fromId(guestId)
|
||||||
if (guestContents == null) return
|
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 === '*') {
|
if (guestContents.getURL().indexOf(targetOrigin) === 0 || targetOrigin === '*') {
|
||||||
const sourceId = event.sender.id
|
const sourceId = event.sender.id
|
||||||
guestContents.send('ELECTRON_GUEST_WINDOW_POSTMESSAGE', sourceId, message, sourceOrigin)
|
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) {
|
ipcMain.on('ELECTRON_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD', function (event, guestId, method, ...args) {
|
||||||
const guestContents = webContents.fromId(guestId)
|
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
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ var BrowserWindowProxy = (function () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
BrowserWindowProxy.remove = function (guestId) {
|
BrowserWindowProxy.remove = function (guestId) {
|
||||||
return delete this.proxies[guestId]
|
delete this.proxies[guestId]
|
||||||
}
|
}
|
||||||
|
|
||||||
function BrowserWindowProxy (guestId1) {
|
function BrowserWindowProxy (guestId1) {
|
||||||
@@ -40,28 +40,28 @@ var BrowserWindowProxy = (function () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
BrowserWindowProxy.prototype.close = 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 () {
|
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 () {
|
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 () {
|
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', {
|
Object.defineProperty(BrowserWindowProxy.prototype, 'location', {
|
||||||
get: function () {
|
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) {
|
set: function (url) {
|
||||||
url = resolveURL(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) {
|
if (targetOrigin == null) {
|
||||||
targetOrigin = '*'
|
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) {
|
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
|
return BrowserWindowProxy
|
||||||
@@ -205,7 +205,7 @@ ipcRenderer.on('ELECTRON_GUEST_WINDOW_POSTMESSAGE', function (event, sourceId, m
|
|||||||
|
|
||||||
// Forward history operations to browser.
|
// Forward history operations to browser.
|
||||||
var sendHistoryOperation = function (...args) {
|
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) {
|
var getHistoryOperation = function (...args) {
|
||||||
@@ -213,15 +213,15 @@ var getHistoryOperation = function (...args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
window.history.back = function () {
|
window.history.back = function () {
|
||||||
return sendHistoryOperation('goBack')
|
sendHistoryOperation('goBack')
|
||||||
}
|
}
|
||||||
|
|
||||||
window.history.forward = function () {
|
window.history.forward = function () {
|
||||||
return sendHistoryOperation('goForward')
|
sendHistoryOperation('goForward')
|
||||||
}
|
}
|
||||||
|
|
||||||
window.history.go = function (offset) {
|
window.history.go = function (offset) {
|
||||||
return sendHistoryOperation('goToOffset', offset)
|
sendHistoryOperation('goToOffset', offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
Object.defineProperty(window.history, 'length', {
|
Object.defineProperty(window.history, 'length', {
|
||||||
|
|||||||
@@ -394,8 +394,11 @@ var registerWebViewElement = function () {
|
|||||||
'insertText',
|
'insertText',
|
||||||
'send',
|
'send',
|
||||||
'sendInputEvent',
|
'sendInputEvent',
|
||||||
|
'setLayoutZoomLevelLimits',
|
||||||
|
'setVisualZoomLevelLimits',
|
||||||
'setZoomFactor',
|
'setZoomFactor',
|
||||||
'setZoomLevel',
|
'setZoomLevel',
|
||||||
|
// TODO(kevinsawicki): Remove in 2.0, deprecate before then with warnings
|
||||||
'setZoomLevelLimits'
|
'setZoomLevelLimits'
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "electron",
|
"name": "electron",
|
||||||
"version": "1.3.6",
|
"version": "1.3.12",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"asar": "^0.11.0",
|
"asar": "^0.11.0",
|
||||||
"electabul": "~0.0.4",
|
"electabul": "~0.0.4",
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ const {BrowserWindow, protocol, ipcMain} = remote
|
|||||||
|
|
||||||
describe('webFrame module', function () {
|
describe('webFrame module', function () {
|
||||||
var fixtures = path.resolve(__dirname, 'fixtures')
|
var fixtures = path.resolve(__dirname, 'fixtures')
|
||||||
|
|
||||||
describe('webFrame.registerURLSchemeAsPrivileged', function () {
|
describe('webFrame.registerURLSchemeAsPrivileged', function () {
|
||||||
it('supports fetch api', function (done) {
|
it('supports fetch api', function (done) {
|
||||||
webFrame.registerURLSchemeAsPrivileged('file')
|
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)
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ const ws = require('ws')
|
|||||||
const url = require('url')
|
const url = require('url')
|
||||||
const remote = require('electron').remote
|
const remote = require('electron').remote
|
||||||
|
|
||||||
const {BrowserWindow, session, webContents} = remote
|
const {BrowserWindow, protocol, session, webContents} = remote
|
||||||
|
|
||||||
const isCI = remote.getGlobal('isCi')
|
const isCI = remote.getGlobal('isCi')
|
||||||
|
|
||||||
@@ -283,11 +283,11 @@ describe('chromium feature', function () {
|
|||||||
describe('window.opener', function () {
|
describe('window.opener', function () {
|
||||||
this.timeout(10000)
|
this.timeout(10000)
|
||||||
|
|
||||||
var url = 'file://' + fixtures + '/pages/window-opener.html'
|
let url = 'file://' + fixtures + '/pages/window-opener.html'
|
||||||
var w = null
|
let w = null
|
||||||
|
|
||||||
afterEach(function () {
|
afterEach(function () {
|
||||||
w != null ? w.destroy() : void 0
|
if (w) w.destroy()
|
||||||
})
|
})
|
||||||
|
|
||||||
it('is null for main window', function (done) {
|
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) {
|
it('is not null for window opened by window.open', function (done) {
|
||||||
var b
|
let b
|
||||||
listener = function (event) {
|
listener = function (event) {
|
||||||
assert.equal(event.data, 'object')
|
assert.equal(event.data, 'object')
|
||||||
b.close()
|
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 () {
|
describe('window.postMessage', function () {
|
||||||
it('sets the source and origin correctly', function (done) {
|
it('sets the source and origin correctly', function (done) {
|
||||||
var b, sourceId
|
var b, sourceId
|
||||||
|
|||||||
7
spec/fixtures/pages/window-opener-location.html
vendored
Normal file
7
spec/fixtures/pages/window-opener-location.html
vendored
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
<script type="text/javascript" charset="utf-8">
|
||||||
|
window.opener.postMessage(window.opener.location, '*')
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -94,7 +94,8 @@ describe('Module._nodeModulePaths', function () {
|
|||||||
it('includes paths outside of the resources path', function () {
|
it('includes paths outside of the resources path', function () {
|
||||||
let modulePath = path.resolve('/foo')
|
let modulePath = path.resolve('/foo')
|
||||||
assert.deepEqual(Module._nodeModulePaths(modulePath), [
|
assert.deepEqual(Module._nodeModulePaths(modulePath), [
|
||||||
path.join(modulePath, 'node_modules')
|
path.join(modulePath, 'node_modules'),
|
||||||
|
path.resolve('/node_modules')
|
||||||
])
|
])
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
2
vendor/brightray
vendored
2
vendor/brightray
vendored
Submodule vendor/brightray updated: 554946c787...ee26c5218e
2
vendor/node
vendored
2
vendor/node
vendored
Submodule vendor/node updated: ee8c429dea...c47e9bf901
Reference in New Issue
Block a user