Skip to content

Commit

Permalink
Fix: scroll methods can scroll uncontrolled parent iframe #868
Browse files Browse the repository at this point in the history
  • Loading branch information
davidjbradshaw committed Sep 11, 2024
1 parent e53c329 commit a6c4fd3
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 51 deletions.
42 changes: 42 additions & 0 deletions example/html/uncontrolledParent.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>Iframe-Resizer Examples</title>
<meta name="description" content="iFrame message passing test" />
<meta name="viewport" content="width=device-width" />
<style>
a.toggle {
float: right;
margin-left: 8px;
}
#callback {
margin: -5px 0 5px 24px;
}

iframe {
width: 100%;
height: 300px;
/* border-width: 0; */
}

</style>
</head>

<body>
<a href="#" id="toggle" class="toggle">Toggle iFrame</a>
<h2>iFrame Wrapper</h2>
<p>
Resize window or click one of the links in the iFrame to watch it resize.
Or try with <a name="anchorParentTest" href="two.html">two iFrames</a>.
</p>

<div id="iframeContainer" style="margin: 20px">
<iframe
src="index.html"
scrolling="auto"
></iframe>
</div>

</body>
</html>
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"test:all": "time npm run rollup:test && npm run test && npm run test:int",
"test:ci": "time npm run rollup:test:ci && npm run test && npm run test:int",
"test:int": "karma start --single-run --browsers ChromeHeadless karma.conf.cjs",
"test:int:watch": "karma start --browsers Chrome karma.conf.cjs",
"upgrade": "time npm-check-updates -i && npm run build"
},
"description": "Keep iFrames sized to their content.",
Expand Down Expand Up @@ -159,4 +160,4 @@
"CrossDomain",
"responsive"
]
}
}
85 changes: 37 additions & 48 deletions packages/core/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ function iframeListener(event) {
const top = compStyle.borderTopWidth
? parseInt(compStyle.borderTopWidth, 10)
: 0

const bot = compStyle.borderBottomWidth
? parseInt(compStyle.borderBottomWidth, 10)
: 0
Expand Down Expand Up @@ -122,12 +123,9 @@ function iframeListener(event) {
return true
}

function isMessageForUs() {
return (
msgId === `${msg}`.slice(0, msgIdLen) &&
msg.slice(msgIdLen).split(':')[0] in settings
) // ''+Protects against non-string msg
}
const isMessageForUs = () =>
msgId === `${msg}`.slice(0, msgIdLen) &&
msg.slice(msgIdLen).split(':')[0] in settings

function isMessageFromMetaParent() {
// Test if this message is from a parent above us. This is an ugly test, however, updating
Expand All @@ -141,9 +139,8 @@ function iframeListener(event) {
return retCode
}

function getMsgBody(offset) {
return msg.slice(msg.indexOf(':') + msgHeaderLen + offset)
}
const getMsgBody = (offset) =>
msg.slice(msg.indexOf(':') + msgHeaderLen + offset)

function forwardMsgFromIFrame(msgBody) {
log(
Expand Down Expand Up @@ -310,14 +307,12 @@ function iframeListener(event) {
const stopParentInfoMonitor = stopInfoMonitor('stopParentInfo')

function checkIFrameExists() {
let retBool = true

if (messageData.iframe === null) {
warn(iframeId, `The iframe (${messageData.id}) was not found.`)
retBool = false
return false
}

return retBool
return true
}

function getElementPosition(target) {
Expand Down Expand Up @@ -347,21 +342,14 @@ function iframeListener(event) {
function reposition() {
page.position = newPosition
scrollTo(iframeId)
log(iframeId, '--')
log(iframeId, '---')
}

function scrollParent() {
if (window.parentIFrame) {
window.parentIFrame[`scrollTo${addOffset ? 'Offset' : ''}`](
newPosition.x,
newPosition.y,
)
} else {
warn(
iframeId,
'Unable to scroll to requested position, window.parentIFrame not found',
)
}
function scrollParent(target) {
target[`scrollTo${addOffset ? 'Offset' : ''}`](
newPosition.x,
newPosition.y,
)
}

const calcOffset = (messageData, offset) => ({
Expand All @@ -373,27 +361,33 @@ function iframeListener(event) {
? getElementPosition(messageData.iframe)
: { x: 0, y: 0 }

const target = window.parentIframe || window.parentIFrame

let newPosition = calcOffset(messageData, offset)

log(
iframeId,
`Reposition requested from iFrame (offset x:${offset.x} y:${offset.y})`,
)

if (window.top === window.self) {
reposition()
} else {
scrollParent()
// Check for V4 as well
if (target) {
scrollParent(target)
return
}

reposition()
}

function scrollTo(iframeId) {
const { x, y } = page.position
const iframe = settings[iframeId]?.iframe

if (on('onScroll', { iframe, top: y, left: x, x, y }) === false) {
unsetPagePosition()
return
}

setPagePosition(iframeId)
}

Expand Down Expand Up @@ -720,25 +714,23 @@ function closeIFrame(iframe) {
}

function getPagePosition(iframeId) {
if (page.position === null) {
page.position = {
x: window.scrollX,
y: window.scrollY,
}
log(iframeId, `Get page position: ${page.position.x}, ${page.position.y}`)
if (page.position !== null) return
page.position = {
x: window.scrollX,
y: window.scrollY,
}
log(iframeId, `Get page position: ${page.position.x}, ${page.position.y}`)
}

function unsetPagePosition() {
page.position = null
}

function setPagePosition(iframeId) {
if (page.position !== null) {
window.scrollTo(page.position.x, page.position.y)
log(iframeId, `Set page position: ${page.position.x}, ${page.position.y}`)
unsetPagePosition()
}
if (page.position === null) return
window.scrollTo(page.position.x, page.position.y)
log(iframeId, `Set page position: ${page.position.x}, ${page.position.y}`)
unsetPagePosition()
}

function resetIFrame(messageData) {
Expand Down Expand Up @@ -1084,12 +1076,11 @@ The <b>sizeWidth</>, <b>sizeHeight</> and <b>autoResize</> options have been rep
}
}

function getTargetOrigin(remoteHost) {
return remoteHost === '' ||
remoteHost.match(/^(about:blank|javascript:|file:\/\/)/) !== null
const getTargetOrigin = (remoteHost) =>
remoteHost === '' ||
remoteHost.match(/^(about:blank|javascript:|file:\/\/)/) !== null
? '*'
: remoteHost
}

function getPostMessageTarget() {
if (settings[iframeId].postMessageTarget === null)
Expand Down Expand Up @@ -1130,9 +1121,7 @@ The <b>sizeWidth</>, <b>sizeHeight</> and <b>autoResize</> options have been rep
: '*'
}

function beenHere() {
return iframeId in settings && 'iFrameResizer' in iframe
}
const beenHere = () => iframeId in settings && 'iFrameResizer' in iframe

const iframeId = ensureHasId(iframe.id)

Expand Down
6 changes: 4 additions & 2 deletions spec/scrollSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,12 @@ define(['iframeResizerParent'], (iframeResize) => {
it('mock incoming message (scrollTo)', (done) => {
iframe = iframeResize({ license: 'GPLv3', log: true, id: 'scroll1' })[0]

window.parentIFrame = {
window.parentIframe = {
scrollTo: (x, y) => {
expect(x).toBe(0)
expect(y).toBe(0)
done()
return false
},
}

Expand All @@ -27,11 +28,12 @@ define(['iframeResizerParent'], (iframeResize) => {
it('mock incoming message (scrollToOffset)', (done) => {
iframe = iframeResize({ license: 'GPLv3', log: true, id: 'scroll2' })[0]

window.parentIFrame = {
window.parentIframe = {
scrollToOffset: (x, y) => {
expect(x).toBe(8)
expect(y).toBe(8)
done()
return false
},
}

Expand Down

0 comments on commit a6c4fd3

Please sign in to comment.