
Security News
PodRocket Podcast: Inside the Recent npm Supply Chain Attacks
Socket CEO Feross Aboukhadijeh discusses the recent npm supply chain attacks on PodRocket, covering novel attack vectors and how developers can protect themselves.
@newswire/frames
Advanced tools
A minimalistic take on responsive iframes in the spirit of Pym.js.
@newswire/frames
is a minimalistic take on responsive iframes in the spirit of Pym.js.
amp-iframe
height
updates from Pym.js iframesBrowser | Supported |
---|---|
Safari | ✅ |
Mozilla Firefox | ✅ |
Google Chrome | ✅ |
Opera | ✅ |
Microsoft Edge | ✅ |
Internet Explorer 11 | ✅ |
Internet Explorer 10 and lower | ⛔️ |
@newswire/frames
is available via npm
.
npm install @newswire/frames
You can also use it directly via unpkg.com.
<script src="https://unpkg.com/@newswire/frames/dist/index.umd.js"></script>
<!-- Now available at `window.newswireFrames` -->
You can also import it as a module via unpkg!
<script type="module">
import * as frames from 'https://unpkg.com/@newswire/frames/dist/index.mjs';
frames.autoInitFrames();
</script>
The page that contains the embeds needs to use the Framer
class to set up instances for each embed.
Assume we have the following markup in our HTML:
<div id="embed-container">Loading...</div>
Then, in our script:
import { Framer } from '@newswire/frames';
const container = document.getElementById('embed-container');
const src = 'https://i-am-an-embed/';
const attributes = { sandbox: 'allow-scripts allow-same-origin' };
const framer = new Framer(container, { src, attributes });
// Now the iframe has been added to the page and is listening for height changes notifications from within the iframe
It is also possible to observe existing iframes on a page if the content of the frames are compatible with @newswire/frames
. This is handy if you already have your own method to dynamically add iframes to the page, or are using a custom method to lazy load them and don't need the heavy hand of Framer
.
import { observeIframe } from '@newswire/frames';
// grab a reference to an existing iframe
const iframe = document.getElementById('my-embed');
// returns a `unobserve()` function if you need to stop listening
const unobserve = observeIframe(iframe);
// later, if you need to disconnect from the iframe
unobserve();
Pym.js had the ability to automatically initialize embeds that had matching attibutes on their container elements — @newswire/frames
can do this as well.
Assume we have the following markup in our HTML:
<div data-frame-src="https://i-am-an-embed/"></div>
<div data-frame-src="https://i-am-an-embed-too/"></div>
<div data-frame-src="https://i-am-an-embed-three/"></div>
Then in our script, we can skip the fanfare of setting up a Framer
for each one and use the data-frame-src
attribute to find them.
import { autoInitFrames } from '@newswire/frames';
// looks for any elements with `data-frame-src` that haven't been initialized yet, and sets them up
autoInitFrames();
If you're needing to pass any of the other options to Framer
when you're automatically creating the embeds, you can add attributes that the initializer will pick up and pass along using the data-frame-attribute-*
prefix.
<div
data-frame-src="https://i-am-an-embed/"
data-frame-attribute-sandbox="allow-scripts allow-same-origin"
></div>
<!-- This creates... -->
<iframe src="https://i-am-an-embed/" sandbox="allow-scripts allow-same-origin">
</iframe>
While the code to setup the host page is similar to Pym's Parent
class, the methods for making the iframed page communicate with the host page are a little different.
Want to set it and forget it? You can import a function that sets up listeners and sends the initial height of the frame's content.
import { initFrame } from '@newswire/frames';
// 1. Sends the initial frame's content height
// 2. Sets up an one-time istener to send the height on load
// 3. Sets up a listener to send the height every time the frame resizes
// 4. Sets up an event listener that sends the height once the parent window begins watching
initFrame();
You can also automatically set up long polling for height changes as well.
import { initFrameAndPoll } from '@newswire/frames';
// 1. Sends the initial frame's content height
// 2. Sets up an one-time listener to send the height on load
// 3. Sets up a listener to send the height every time the frame resizes
// 4. Sets up an event listener that sends the height once the parent window begins watching
// 5. Sets up an interval to send a new height update every 300ms
initFrameAndPoll();
Alternatively, you can set and use function independently depending on the needs of your frame's content.
import {
sendFrameHeight,
sendHeightOnLoad,
sendHeightOnResize,
sendHeightOnPoll,
sendHeightOnFramerInit,
} from '@newswire/frames';
// 1. Sends the initial frame's content height
sendFrameHeight();
// 2. Sets up an one-time listener to send the height on load
sendHeightOnLoad();
// 3. Sets up a listener to send the height every time the frame resizes
sendHeightOnResize();
// 4. Sets up an event listener that sends the height once the parent window begins watching
sendHeightOnFramerInit();
// 5. Sets up an interval to send a new height update every 150ms
sendHeightOnPoll(150);
// 1-4 is identical to initFrame()! 1-5 is identical to initFrameAndPoll()!
Typically using initFrame()
will be enough, but if you have code that will potentially change the height of the frame's content (like with an <input>
or <button>
press) and would rather not use polling, you can use sendFrameHeight()
to manually recalculate and send an update to the parent page.
@newswire/frames
(1.0.0+
) can be a drop-in replacement for Pym.js
on host/parent pages, but it only understands height
events sent from Pym.js-powered child frames. All other events will be ignored. Unless you were doing something exotic or extremely bespoke with Pym.js odds are it will work!
Adds an event listener to an existing iframe for receiving height change
messages. Also tells the iframe that we're listening and requests the
initial height. Returns an unobserve()
function for later removing the
listener.
iframe
HTMLIFrameElement the iframe to observe// grab a reference to an existing iframe
const iframe = document.getElementById('my-embed');
// returns a `unobserve()` function if you need to stop listening
const unobserve = observeIframe(iframe);
// later, if you need to disconnect from the iframe
unobserve();
Type: object
src
(string | null)? the URL to set as the src
of the iframeattributes
Record<string, string>? any attributes to add to the iframe itselfThe Framer function to be called in the host page. A wrapper around
interactions with a created iframe. Returns a remove()
function for
disconnecting the event listener and removing the iframe from the DOM.
container
Element the containing DOM element for the iframe
options
FramerOptions (optional, default {}
)
options.attributes
options.src
Automatically initializes any frames that have not already been auto-activated.
// sets up all frames that have not been initialized yet
autoInitFrames();
Sends the current document's height or provided value to the host window using postMessage.
height
number? The height to pass to the host page, is determined automatically if not passed (optional, default getDocumentHeight()
)// Uses the document's height to tell the host page
sendFrameHeight();
// Pass a height you've determined in another way
sendFrameHeight(500);
Returns void
Sets up an event listener for the load event that sends the new frame height to the host. Automatically removes itself once fired.
// once the frame's load event is fired, tell the host page its new height
sendHeightOnLoad();
Returns void
Sets up an event listener for the resize event that sends the new frame height to the host.
// every time the frame is resized, tell the host page what its new height is
sendHeightOnResize();
Returns void
Sets up an event listener for a message from the parent window that it is now listening for messages from this iframe, and tells it the iframe's height at that time. This makes it possible to delay observing an iframe (e.g. when lazy loading) but trust the parent will get the current height ASAP.
// as soon as a Framer connects, tell the host page what the current height is
sendHeightOnFramerInit();
Returns void
Sends height updates to the host page on an interval.
delay
number? How long to set the interval (optional, default 300
)// will call sendFrameHeight every 300ms
sendHeightOnPoll();
// will call sendFrameHeight every 150ms
sendHeightOnPoll(150);
Returns void
A helper for running the standard functions for setting up a frame.
Automatically calls an sendFrameHeight
, sendHeightOnLoad
, sendHeightOnResize
and sendHeightOnFramerInit
.
initFrame();
Returns void
Calls initFrame
to setup a frame, then initializes a poller to continue to update on an interval.
delay
number? An optional custom delay to pass to sendHeightOnPoll// calls initFrame, then calls sendHeightOnPoll
initFrameAndPoll();
Returns void
MIT
[1.0.0] - 2022-01-04
Tests! Of everything!
The act of "observing" an iframe has been broken out of the Framer
class into its own function — observeIframe
! This makes it possible to observe @newswire/frames
compatible-iframes that have been created independent of this library. This means it is now possible to use your own code to create iframes (perhaps lazy load them with IntersectionObserver
!), have them added via your CMS/templating engine, etc.
It's important to remember however that this method does not add any attributes to the existing iframe. It just sets up the observer and stops there. This means it's on you to use CSS or other methods to style the iframe. (Set width to 100%
, etc.)
// grab a reference to an existing iframe, assuming there's already a "src" on this
const iframe = document.getElementById('my-embed');
// returns a `unobserve()` function if you need to stop listening
const unobserve = observeIframe(iframe);
// later, if you need to disconnect from the iframe
unobserve();
As the example shows above, you can also now disable the observer using the unobserve
function observeIframe
returns. Unlike the remove()
method on Framer
, this will not remove the iframe from the DOM.
Framer
of an embed's size - sendHeightOnFramerInit
. Once an iframe is observed (with either observeIframe
or Framer
), the parent page will notify the iframe it is now ready to receive height updates. In response, the iframe will send a message back to the parent Framer
with the initial height of the iframe. This should help get the correct iframe height to the parent page sooner.sendHeightOnFramerInit
has been added to both initFrame
and initFrameAndPoll
.
@newswire/frames
now has legacy support for Pym.js child frames. This means you can now use @newswire/frames
to resize iframes that have been built with Pym.js. However - @newswire/frames
only recognizes Pym.js' height
events. All other events will be ignored.Framer
still exists but its interface has changed. Because the container
was never optional it is now the first expected parameter when creating a new instance. The second parameter is now an object with two optional properties - src
and attributes
. src
does what you expect and sets the src
attribute on the iframe, but the attributes
object is the new way to configure any other attributes on the iframe
that's created. It's now just a convienient way to loop over an object and call setAttribute
.Why the change? The most common request to this library has been to add additional attributes that Framer
can apply to the iframe it creates. (Or the ability to not set one, like src
!) Instead of having to add support to Framer
for every attribute you want to set on the iframe, it's now just a matter of adding a new property to the attributes
object.
Framer
is no longer a class and instead just a function that returns an object. It was never really intended to be subclassed and this makes it a bit more compact when bundled, but it is still compatible with new
if you prefer that.
The auto loader now expects attributes to be set on containers using the data-frame-attribute-
prefix. This is to match the new way of passing attributes to Framer
.
<!-- NO LONGER WORKS -->
<div data-frame-src="embed.html" data-frame-sandbox="allow-scripts"></div>
<!-- THIS WORKS! -->
<div
data-frame-src="embed.html"
data-frame-attribute-sandbox="allow-scripts"
></div>
FAQs
A minimalistic take on responsive iframes in the spirit of Pym.js.
The npm package @newswire/frames receives a total of 201 weekly downloads. As such, @newswire/frames popularity was classified as not popular.
We found that @newswire/frames demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Socket CEO Feross Aboukhadijeh discusses the recent npm supply chain attacks on PodRocket, covering novel attack vectors and how developers can protect themselves.
Security News
Maintainers back GitHub’s npm security overhaul but raise concerns about CI/CD workflows, enterprise support, and token management.
Product
Socket Firewall is a free tool that blocks malicious packages at install time, giving developers proactive protection against rising supply chain attacks.