Merge pull request #8693 from electron/zoom_specs
webContents: add basic zoom specs
This commit is contained in:
commit
1f75df0253
12 changed files with 372 additions and 26 deletions
|
@ -1672,9 +1672,9 @@ void WebContents::BuildPrototype(v8::Isolate* isolate,
|
|||
.SetMethod("getFrameRate", &WebContents::GetFrameRate)
|
||||
.SetMethod("invalidate", &WebContents::Invalidate)
|
||||
.SetMethod("setZoomLevel", &WebContents::SetZoomLevel)
|
||||
.SetMethod("getZoomLevel", &WebContents::GetZoomLevel)
|
||||
.SetMethod("_getZoomLevel", &WebContents::GetZoomLevel)
|
||||
.SetMethod("setZoomFactor", &WebContents::SetZoomFactor)
|
||||
.SetMethod("getZoomFactor", &WebContents::GetZoomFactor)
|
||||
.SetMethod("_getZoomFactor", &WebContents::GetZoomFactor)
|
||||
.SetMethod("getType", &WebContents::GetType)
|
||||
.SetMethod("getWebPreferences", &WebContents::GetWebPreferences)
|
||||
.SetMethod("getOwnerBrowserWindow", &WebContents::GetOwnerBrowserWindow)
|
||||
|
|
|
@ -112,8 +112,7 @@ void WebContentsZoomController::DidFinishNavigation(
|
|||
return;
|
||||
}
|
||||
|
||||
if (!navigation_handle->IsSamePage())
|
||||
SetZoomFactorOnNavigationIfNeeded(navigation_handle->GetURL());
|
||||
SetZoomFactorOnNavigationIfNeeded(navigation_handle->GetURL());
|
||||
}
|
||||
|
||||
void WebContentsZoomController::WebContentsDestroyed() {
|
||||
|
|
|
@ -206,6 +206,26 @@ WebContents.prototype.printToPDF = function (options, callback) {
|
|||
this._printToPDF(printingSetting, callback)
|
||||
}
|
||||
|
||||
WebContents.prototype.getZoomLevel = function (callback) {
|
||||
if (typeof callback !== 'function') {
|
||||
throw new Error('Must pass function as an argument')
|
||||
}
|
||||
process.nextTick(() => {
|
||||
const zoomLevel = this._getZoomLevel()
|
||||
callback(zoomLevel)
|
||||
})
|
||||
}
|
||||
|
||||
WebContents.prototype.getZoomFactor = function (callback) {
|
||||
if (typeof callback !== 'function') {
|
||||
throw new Error('Must pass function as an argument')
|
||||
}
|
||||
process.nextTick(() => {
|
||||
const zoomFactor = this._getZoomFactor()
|
||||
callback(zoomFactor)
|
||||
})
|
||||
}
|
||||
|
||||
// Add JavaScript wrappers for WebContents class.
|
||||
WebContents.prototype._init = function () {
|
||||
// The navigation controller.
|
||||
|
|
|
@ -184,7 +184,7 @@ const attachGuest = function (event, elementInstanceId, guestInstanceId, params)
|
|||
guestInstanceId: guestInstanceId,
|
||||
nodeIntegration: params.nodeintegration != null ? params.nodeintegration : false,
|
||||
plugins: params.plugins,
|
||||
zoomFactor: embedder.getZoomFactor(),
|
||||
zoomFactor: embedder._getZoomFactor(),
|
||||
webSecurity: !params.disablewebsecurity,
|
||||
blinkFeatures: params.blinkfeatures,
|
||||
disableBlinkFeatures: params.disableblinkfeatures
|
||||
|
|
|
@ -374,7 +374,11 @@ var registerWebViewElement = function () {
|
|||
'print',
|
||||
'printToPDF',
|
||||
'showDefinitionForSelection',
|
||||
'capturePage'
|
||||
'capturePage',
|
||||
'setZoomFactor',
|
||||
'setZoomLevel',
|
||||
'getZoomLevel',
|
||||
'getZoomFactor'
|
||||
]
|
||||
const nonblockMethods = [
|
||||
'insertCSS',
|
||||
|
@ -383,8 +387,6 @@ var registerWebViewElement = function () {
|
|||
'sendInputEvent',
|
||||
'setLayoutZoomLevelLimits',
|
||||
'setVisualZoomLevelLimits',
|
||||
'setZoomFactor',
|
||||
'setZoomLevel',
|
||||
// TODO(kevinsawicki): Remove in 2.0, deprecate before then with warnings
|
||||
'setZoomLevelLimits'
|
||||
]
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
'use strict'
|
||||
|
||||
const assert = require('assert')
|
||||
const http = require('http')
|
||||
const path = require('path')
|
||||
const {closeWindow} = require('./window-helpers')
|
||||
|
||||
const {ipcRenderer, remote} = require('electron')
|
||||
const {BrowserWindow, webContents, ipcMain} = remote
|
||||
const {BrowserWindow, webContents, ipcMain, session} = remote
|
||||
|
||||
const isCi = remote.getGlobal('isCi')
|
||||
|
||||
|
@ -322,4 +323,208 @@ describe('webContents module', function () {
|
|||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('zoom api', () => {
|
||||
const zoomScheme = remote.getGlobal('zoomScheme')
|
||||
const hostZoomMap = {
|
||||
host1: 0.3,
|
||||
host2: 0.7,
|
||||
host3: 0.2
|
||||
}
|
||||
|
||||
before((done) => {
|
||||
const protocol = session.defaultSession.protocol
|
||||
protocol.registerStringProtocol(zoomScheme, (request, callback) => {
|
||||
const response = `<script>
|
||||
const {ipcRenderer, remote} = require('electron')
|
||||
ipcRenderer.send('set-zoom', window.location.hostname)
|
||||
ipcRenderer.on(window.location.hostname + '-zoom-set', () => {
|
||||
remote.getCurrentWebContents().getZoomLevel((zoomLevel) => {
|
||||
ipcRenderer.send(window.location.hostname + '-zoom-level', zoomLevel)
|
||||
})
|
||||
})
|
||||
</script>`
|
||||
callback({data: response, mimeType: 'text/html'})
|
||||
}, (error) => done(error))
|
||||
})
|
||||
|
||||
after((done) => {
|
||||
const protocol = session.defaultSession.protocol
|
||||
protocol.unregisterProtocol(zoomScheme, (error) => done(error))
|
||||
})
|
||||
|
||||
it('can set the correct zoom level', (done) => {
|
||||
w.loadURL('about:blank')
|
||||
w.webContents.on('did-finish-load', () => {
|
||||
w.webContents.getZoomLevel((zoomLevel) => {
|
||||
assert.equal(zoomLevel, 0.0)
|
||||
w.webContents.setZoomLevel(0.5)
|
||||
w.webContents.getZoomLevel((zoomLevel) => {
|
||||
assert.equal(zoomLevel, 0.5)
|
||||
w.webContents.setZoomLevel(0)
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('can persist zoom level across navigation', (done) => {
|
||||
let finalNavigation = false
|
||||
ipcMain.on('set-zoom', (e, host) => {
|
||||
const zoomLevel = hostZoomMap[host]
|
||||
if (!finalNavigation) {
|
||||
w.webContents.setZoomLevel(zoomLevel)
|
||||
}
|
||||
e.sender.send(`${host}-zoom-set`)
|
||||
})
|
||||
ipcMain.on('host1-zoom-level', (e, zoomLevel) => {
|
||||
const expectedZoomLevel = hostZoomMap.host1
|
||||
assert.equal(zoomLevel, expectedZoomLevel)
|
||||
if (finalNavigation) {
|
||||
done()
|
||||
} else {
|
||||
w.loadURL(`${zoomScheme}://host2`)
|
||||
}
|
||||
})
|
||||
ipcMain.once('host2-zoom-level', (e, zoomLevel) => {
|
||||
const expectedZoomLevel = hostZoomMap.host2
|
||||
assert.equal(zoomLevel, expectedZoomLevel)
|
||||
finalNavigation = true
|
||||
w.webContents.goBack()
|
||||
})
|
||||
w.loadURL(`${zoomScheme}://host1`)
|
||||
})
|
||||
|
||||
it('can propagate zoom level across same session', (done) => {
|
||||
const w2 = new BrowserWindow({
|
||||
show: false
|
||||
})
|
||||
w2.webContents.on('did-finish-load', () => {
|
||||
w.webContents.getZoomLevel((zoomLevel1) => {
|
||||
assert.equal(zoomLevel1, hostZoomMap.host3)
|
||||
w2.webContents.getZoomLevel((zoomLevel2) => {
|
||||
assert.equal(zoomLevel1, zoomLevel2)
|
||||
w2.setClosable(true)
|
||||
w2.close()
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
w.webContents.on('did-finish-load', () => {
|
||||
w.webContents.setZoomLevel(hostZoomMap.host3)
|
||||
w2.loadURL(`${zoomScheme}://host3`)
|
||||
})
|
||||
w.loadURL(`${zoomScheme}://host3`)
|
||||
})
|
||||
|
||||
it('cannot propagate zoom level across different session', (done) => {
|
||||
const w2 = new BrowserWindow({
|
||||
show: false,
|
||||
webPreferences: {
|
||||
partition: 'temp'
|
||||
}
|
||||
})
|
||||
const protocol = w2.webContents.session.protocol
|
||||
protocol.registerStringProtocol(zoomScheme, (request, callback) => {
|
||||
callback('hello')
|
||||
}, (error) => {
|
||||
if (error) return done(error)
|
||||
w2.webContents.on('did-finish-load', () => {
|
||||
w.webContents.getZoomLevel((zoomLevel1) => {
|
||||
assert.equal(zoomLevel1, hostZoomMap.host3)
|
||||
w2.webContents.getZoomLevel((zoomLevel2) => {
|
||||
assert.equal(zoomLevel2, 0)
|
||||
assert.notEqual(zoomLevel1, zoomLevel2)
|
||||
protocol.unregisterProtocol(zoomScheme, (error) => {
|
||||
if (error) return done(error)
|
||||
w2.setClosable(true)
|
||||
w2.close()
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
w.webContents.on('did-finish-load', () => {
|
||||
w.webContents.setZoomLevel(hostZoomMap.host3)
|
||||
w2.loadURL(`${zoomScheme}://host3`)
|
||||
})
|
||||
w.loadURL(`${zoomScheme}://host3`)
|
||||
})
|
||||
})
|
||||
|
||||
it('can persist when it contains iframe', (done) => {
|
||||
const server = http.createServer(function (req, res) {
|
||||
setTimeout(() => {
|
||||
res.end()
|
||||
}, 200)
|
||||
})
|
||||
server.listen(0, '127.0.0.1', function () {
|
||||
const url = 'http://127.0.0.1:' + server.address().port
|
||||
const content = `<iframe src=${url}></iframe>`
|
||||
w.webContents.on('did-frame-finish-load', (e, isMainFrame) => {
|
||||
if (!isMainFrame) {
|
||||
w.webContents.getZoomLevel((zoomLevel) => {
|
||||
assert.equal(zoomLevel, 2.0)
|
||||
w.webContents.setZoomLevel(0)
|
||||
server.close()
|
||||
done()
|
||||
})
|
||||
}
|
||||
})
|
||||
w.webContents.on('dom-ready', () => {
|
||||
w.webContents.setZoomLevel(2.0)
|
||||
})
|
||||
w.loadURL(`data:text/html,${content}`)
|
||||
})
|
||||
})
|
||||
|
||||
it('cannot propagate when used with webframe', (done) => {
|
||||
let finalZoomLevel = 0
|
||||
const w2 = new BrowserWindow({
|
||||
show: false
|
||||
})
|
||||
w2.webContents.on('did-finish-load', () => {
|
||||
w.webContents.getZoomLevel((zoomLevel1) => {
|
||||
assert.equal(zoomLevel1, finalZoomLevel)
|
||||
w2.webContents.getZoomLevel((zoomLevel2) => {
|
||||
assert.equal(zoomLevel2, 0)
|
||||
assert.notEqual(zoomLevel1, zoomLevel2)
|
||||
w2.setClosable(true)
|
||||
w2.close()
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
ipcMain.once('temporary-zoom-set', (e, zoomLevel) => {
|
||||
w2.loadURL(`file://${fixtures}/pages/c.html`)
|
||||
finalZoomLevel = zoomLevel
|
||||
})
|
||||
w.loadURL(`file://${fixtures}/pages/webframe-zoom.html`)
|
||||
})
|
||||
|
||||
it('cannot persist zoom level after navigation with webFrame', (done) => {
|
||||
let initialNavigation = true
|
||||
const source = `
|
||||
const {ipcRenderer, webFrame} = require('electron')
|
||||
webFrame.setZoomLevel(0.6)
|
||||
ipcRenderer.send('zoom-level-set', webFrame.getZoomLevel())
|
||||
`
|
||||
w.webContents.on('did-finish-load', () => {
|
||||
if (initialNavigation) {
|
||||
w.webContents.executeJavaScript(source, () => {})
|
||||
} else {
|
||||
w.webContents.getZoomLevel((zoomLevel) => {
|
||||
assert.equal(zoomLevel, 0)
|
||||
done()
|
||||
})
|
||||
}
|
||||
})
|
||||
ipcMain.once('zoom-level-set', (e, zoomLevel) => {
|
||||
assert.equal(zoomLevel, 0.6)
|
||||
w.loadURL(`file://${fixtures}/pages/d.html`)
|
||||
initialNavigation = false
|
||||
})
|
||||
w.loadURL(`file://${fixtures}/pages/c.html`)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
9
spec/fixtures/pages/webframe-zoom.html
vendored
Normal file
9
spec/fixtures/pages/webframe-zoom.html
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
<html>
|
||||
<body>
|
||||
<script type="text/javascript" charset="utf-8">
|
||||
const {ipcRenderer, webFrame} = require('electron')
|
||||
webFrame.setZoomLevel(1.0)
|
||||
ipcRenderer.send('temporary-zoom-set', webFrame.getZoomLevel())
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
26
spec/fixtures/pages/webview-custom-zoom-level.html
vendored
Normal file
26
spec/fixtures/pages/webview-custom-zoom-level.html
vendored
Normal file
|
@ -0,0 +1,26 @@
|
|||
<html>
|
||||
<body>
|
||||
<webview nodeintegration src="zoom://host1" id="view" partition="webview-temp"/>
|
||||
</body>
|
||||
<script>
|
||||
const {ipcRenderer, webFrame} = require('electron')
|
||||
const view = document.getElementById('view')
|
||||
let finalNavigation = false
|
||||
view.addEventListener('dom-ready', () => {
|
||||
if (!finalNavigation && !view.canGoBack()) {
|
||||
view.setZoomLevel(2.0)
|
||||
}
|
||||
view.getZoomLevel((zoomLevel) => {
|
||||
view.getZoomFactor((zoomFactor) => {
|
||||
ipcRenderer.send('webview-zoom-level', zoomLevel, zoomFactor, view.canGoBack(), finalNavigation)
|
||||
if (!view.canGoBack() && !finalNavigation) {
|
||||
view.src = 'zoom://host2'
|
||||
} else if (!finalNavigation) {
|
||||
finalNavigation = true
|
||||
view.goBack()
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
</script>
|
||||
</html>
|
32
spec/fixtures/pages/webview-in-page-navigate.html
vendored
Normal file
32
spec/fixtures/pages/webview-in-page-navigate.html
vendored
Normal file
|
@ -0,0 +1,32 @@
|
|||
<html>
|
||||
<body>
|
||||
<webview nodeintegration src="zoom://host1" id="view" partition="webview-temp"/>
|
||||
</body>
|
||||
<script>
|
||||
const {ipcRenderer, webFrame} = require('electron')
|
||||
const view = document.getElementById('view')
|
||||
let finalNavigation = false
|
||||
function SendZoomLevel() {
|
||||
return new Promise((resolve, reject) => {
|
||||
view.getZoomLevel((zoomLevel) => {
|
||||
view.getZoomFactor((zoomFactor) => {
|
||||
ipcRenderer.send('webview-zoom-in-page', zoomLevel, zoomFactor, finalNavigation)
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
view.addEventListener('dom-ready', () => {
|
||||
view.setZoomLevel(2.0)
|
||||
SendZoomLevel().then(() => {
|
||||
if (!finalNavigation) {
|
||||
finalNavigation = true
|
||||
view.executeJavaScript('window.location.hash=123', () => {})
|
||||
}
|
||||
})
|
||||
})
|
||||
view.addEventListener('did-navigate-in-page', () => {
|
||||
SendZoomLevel()
|
||||
})
|
||||
</script>
|
||||
</html>
|
2
spec/fixtures/pages/zoom-factor.html
vendored
2
spec/fixtures/pages/zoom-factor.html
vendored
|
@ -2,7 +2,7 @@
|
|||
<body>
|
||||
<script type="text/javascript" charset="utf-8">
|
||||
const {ipcRenderer, webFrame} = require('electron')
|
||||
ipcRenderer.send('pong', webFrame.getZoomFactor(), webFrame.getZoomLevel())
|
||||
ipcRenderer.send('webview-parent-zoom-level', webFrame.getZoomFactor(), webFrame.getZoomLevel())
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -93,7 +93,8 @@ if (global.isCi) {
|
|||
|
||||
// Register app as standard scheme.
|
||||
global.standardScheme = 'app'
|
||||
protocol.registerStandardSchemes([global.standardScheme], { secure: true })
|
||||
global.zoomScheme = 'zoom'
|
||||
protocol.registerStandardSchemes([global.standardScheme, global.zoomScheme], { secure: true })
|
||||
|
||||
app.on('window-all-closed', function () {
|
||||
app.quit()
|
||||
|
|
|
@ -1067,21 +1067,6 @@ describe('<webview> tag', function () {
|
|||
})
|
||||
})
|
||||
|
||||
it('inherits the zoomFactor of the parent window', function (done) {
|
||||
w = new BrowserWindow({
|
||||
show: false,
|
||||
webPreferences: {
|
||||
zoomFactor: 1.2
|
||||
}
|
||||
})
|
||||
ipcMain.once('pong', function (event, zoomFactor, zoomLevel) {
|
||||
assert.equal(zoomFactor, 1.2)
|
||||
assert.equal(zoomLevel, 1)
|
||||
done()
|
||||
})
|
||||
w.loadURL('file://' + fixtures + '/pages/webview-zoom-factor.html')
|
||||
})
|
||||
|
||||
it('inherits the parent window visibility state and receives visibilitychange events', function (done) {
|
||||
w = new BrowserWindow({
|
||||
show: false
|
||||
|
@ -1540,4 +1525,71 @@ describe('<webview> tag', function () {
|
|||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('zoom behavior', () => {
|
||||
const zoomScheme = remote.getGlobal('zoomScheme')
|
||||
const webviewSession = session.fromPartition('webview-temp')
|
||||
|
||||
before((done) => {
|
||||
const protocol = webviewSession.protocol
|
||||
protocol.registerStringProtocol(zoomScheme, (request, callback) => {
|
||||
callback('hello')
|
||||
}, (error) => done(error))
|
||||
})
|
||||
|
||||
after((done) => {
|
||||
const protocol = webviewSession.protocol
|
||||
protocol.unregisterProtocol(zoomScheme, (error) => done(error))
|
||||
})
|
||||
|
||||
it('inherits the zoomFactor of the parent window', (done) => {
|
||||
w = new BrowserWindow({
|
||||
show: false,
|
||||
webPreferences: {
|
||||
zoomFactor: 1.2
|
||||
}
|
||||
})
|
||||
ipcMain.once('webview-parent-zoom-level', (event, zoomFactor, zoomLevel) => {
|
||||
assert.equal(zoomFactor, 1.2)
|
||||
assert.equal(zoomLevel, 1)
|
||||
done()
|
||||
})
|
||||
w.loadURL(`file://${fixtures}/pages/webview-zoom-factor.html`)
|
||||
})
|
||||
|
||||
it('maintains zoom level on navigation', (done) => {
|
||||
w = new BrowserWindow({
|
||||
show: false,
|
||||
webPreferences: {
|
||||
zoomFactor: 1.2
|
||||
}
|
||||
})
|
||||
ipcMain.on('webview-zoom-level', (event, zoomLevel, zoomFactor, newHost, final) => {
|
||||
if (!newHost) {
|
||||
assert.equal(zoomFactor, 1.44)
|
||||
assert.equal(zoomLevel, 2.0)
|
||||
} else {
|
||||
assert.equal(zoomFactor, 1.2)
|
||||
assert.equal(zoomLevel, 1)
|
||||
}
|
||||
if (final) done()
|
||||
})
|
||||
w.loadURL(`file://${fixtures}/pages/webview-custom-zoom-level.html`)
|
||||
})
|
||||
|
||||
it('maintains zoom level when navigating within same page', (done) => {
|
||||
w = new BrowserWindow({
|
||||
show: false,
|
||||
webPreferences: {
|
||||
zoomFactor: 1.2
|
||||
}
|
||||
})
|
||||
ipcMain.on('webview-zoom-in-page', (event, zoomLevel, zoomFactor, final) => {
|
||||
assert.equal(zoomFactor, 1.44)
|
||||
assert.equal(zoomLevel, 2.0)
|
||||
if (final) done()
|
||||
})
|
||||
w.loadURL(`file://${fixtures}/pages/webview-in-page-navigate.html`)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
Loading…
Reference in a new issue