GithubHelp home page GithubHelp logo

orestbida / iframemanager Goto Github PK

View Code? Open in Web Editor NEW
225.0 8.0 25.0 370 KB

🍪 GDPR friendly iframe manager written in vanilla js

Home Page: https://orestbida.com/demo-projects/iframemanager/demo1/

License: MIT License

CSS 22.44% JavaScript 77.56%
gdpr iframe youtube vimeo gdpr-consent iframe-manager video

iframemanager's Introduction

IframeManager Logo

Demo   |   Features   |   Installation   

License: MIT Size Stable version

IframeMananger is a lightweight javascript plugin which helps you comply with GDPR by completely removing iframes initially and setting a notice relative to that service. Iframes are loaded only after consent.

The plugin was mainly developed to aid CookieConsent with iframe management.


Table of Contents

Features

  • Lightweight
  • Complies with GDPR
  • Multilanguage support
  • Automatic/custom thumbnail support *
  • Allows to integrate any service which uses iframes
  • Improves website performance:
    • lazy-load thumbnails
    • lazy-load iframes
  • Can be integrated with any consent solution

Installation

  1. Download the latest release or use via CDN/NPM:

    https://cdn.jsdelivr.net/gh/orestbida/[email protected]/dist/iframemanager.js
    https://cdn.jsdelivr.net/gh/orestbida/[email protected]/dist/iframemanager.css

    using npm:

    npm i @orestbida/iframemanager
  2. Import script + stylesheet:

    <html>
      <head>
        ...
        <link rel="stylesheet" href="iframemanager.css">
      </head>
      <body>
        ...
        <script defer src="iframemanager.js"></script>
      <body>
    </html>
  3. Configure and run:

    • As external script

      • Create a .js file (e.g. app.js) and import it in your html markup:

        <body>
            ...
            <script defer src="iframemanager.js"></script>
            <script defer src="app.js"></script>
        <body>
      • Configure iframemanager inside app.js:

        (function(){
        
            const im = iframemanager();
        
            // Example with youtube embed
            im.run({
                currLang: 'en',
                services : {
                    youtube : {
                        embedUrl: 'https://www.youtube-nocookie.com/embed/{data-id}',
                        thumbnailUrl: 'https://i3.ytimg.com/vi/{data-id}/hqdefault.jpg',
                        iframe : {
                            allow : 'accelerometer; encrypted-media; gyroscope; picture-in-picture; fullscreen;'
                        },
                        languages : {
                            en : {
                                notice: 'This content is hosted by a third party. By showing the external content you accept the <a rel="noreferrer noopener" href="https://www.youtube.com/t/terms" target="_blank">terms and conditions</a> of youtube.com.',
                                loadBtn: 'Load video',
                                loadAllBtn: "Don't ask again"
                            }
                        }
                    }
                }
            });
        })();

    • As inline script

      <body>
        ...
        <script defer src="iframemanager.js"></script>
      
        <!-- Inline script -->
        <script>
          window.addEventListener('load', function(){
      
              const im = iframemanager();
      
              // Example with youtube embed
              im.run({
                  currLang: 'en',
                  services : {
                      youtube : {
                          embedUrl: 'https://www.youtube-nocookie.com/embed/{data-id}',
                          thumbnailUrl: 'https://i3.ytimg.com/vi/{data-id}/hqdefault.jpg',
                          iframe : {
                              allow : 'accelerometer; encrypted-media; gyroscope; picture-in-picture; fullscreen;'
                          },
                          languages : {
                              en : {
                                  notice: 'This content is hosted by a third party. By showing the external content you accept the <a rel="noreferrer noopener" href="https://www.youtube.com/t/terms" target="_blank">terms and conditions</a> of youtube.com.',
                                  loadBtn: 'Load video',
                                  loadAllBtn: "Don't ask again"
                              }
                          }
                      }
                  }
              });
          });
        </script>
      <body>

  4. Create a div with data-service and data-id attributes:

    <div data-service="youtube" data-id="<video-id>"></div>

Configuration options

All available options for the <div> element:

<div
    data-service="<service-name>"
    data-id="<resource-id>"
    data-params="<iframe-query-parameters>"
    data-thumbnail="<path-to-image>"
    data-autoscale
    data-ratio="<x:y>">
</div>
  • data-service : [String, Required] name of the service (must also be defined in the config. object)
  • data-id : [String, Required] unique id of the resource (example: video id)
  • data-title : [String] notice title
  • data-params : [String] iframe query parameters
  • data-thumbnail : [String] path to custom thumbnail
  • data-ratio : [String] custom aspect ratio (Available values.)[v1.1.0]
  • data-autoscale : specify for responsive iframe (fill parent width + scale proportionally)
  • data-widget : ignore the default aspect ratio; specify when implementing a custom widget with explicit width and height (twitter, facebook, instagram ...)[v1.2.0]

How to set attributes on the iframe element

You can set any attribute by using the following syntax:

  • data-iframe-<attribute> [String] note: replace <attribute> with a valid attribute name. [v1.1.0]

Example:

<div
    data-service="youtube"
    data-id="5b35haQV7tU"
    data-autoscale
    data-iframe-id="myYoutubeEmbed"
    data-iframe-loading="lazy"
    data-iframe-frameborder="0">
</div>

All available options for the config. object:

{
    currLang: 'en',     // current language of the notice (must also be defined in the "languages" object below)
    autoLang: false,    // if enabled => use current client's browser language
                        // instead of currLang [OPTIONAL]

    // callback fired when state changes (a new service is accepted/rejected)
    onChange: ({changedServices, eventSource}) => {
        // changedServices: string[]
        // eventSource.type: 'api' | 'click'
        // eventSource.service: string
        // eventSource.action: 'accept' | 'reject'
    },

    services : {
        myservice : {

            embedUrl: 'https://<myservice_embed_url>',

            // set valid url for automatic thumbnails   [OPTIONAL]
            thumbnailUrl: 'https://<myservice_embed_thumbnail_url>',

            // global iframe settings (apply to all iframes relative to current service) [OPTIONAL]
            iframe: {
                allow: 'fullscreen',           // iframe's allow attribute
                params: 'mute=1&start=21',     // iframe's url query parameters

                // function run for each iframe configured with current service
                onload: (dataId, setThumbnail) => {
                    console.log(`loaded iframe with data-id=${dataId}`);
                }
            },

            // cookie is set if the current service is accepted
            cookie: {
                name: 'cc_youtube',            // cookie name
                path: '/',                     // cookie path          [OPTIONAL]
                samesite: 'lax',               // cookie samesite      [OPTIONAL]
                domain: location.hostname      // cookie domain        [OPTIONAL]
            },

            languages: {
                en: {
                    notice: 'Html <b>notice</b> message',
                    loadBtn: 'Load video',          // Load only current iframe
                    loadAllBtn: "Don't ask again"   // Load all iframes configured with this service + set cookie
                }
            }
        },

        anotherservice: {
            // ...
        }
    }
}

Any other property specified inside the iframe object, will be set directly to the iframe element as attribute.

Example: add frameborder and style attributes:

{
    // ...

    services: {
        myservice: {
            // ...

            iframe: {
                // ...

                frameborder: '0',
                style: 'border: 4px solid red;'
            }
        }
    }
}

Note: thumbnailUrl can be static string, dynamic string or a function:

  • static string : "https://path_to_image/image.png"
  • dynamic string : "https://myservice_embed_url/{data-id}"
  • function :
    thumbnailUrl: (dataId, setThumbnail) => {
        // fetch thumbnail url here based on dataId of the current element ...
        let url = 'fetched_url';
    
        // pass obtained url to the setThumbnail function
        setThumbnail(url);
    }

Custom Widgets

Some services (e.g. twitter) have their own markup and API to generate the iframe.

Note: this is an example with twitter's widget. Each widget/service will have a slightly different implementation.

  1. Place the markup inside a special data-placeholder div. Remove any script tag that comes with the markup. Example:

    <div
        data-service="twitter"
        data-widget
        style="width: 300px; height: 501px"
    >
    
        <div data-placeholder>
            <blockquote class="twitter-tweet"><p lang="en" dir="ltr">Sunsets don&#39;t get much better than this one over <a href="https://twitter.com/GrandTetonNPS?ref_src=twsrc%5Etfw">@GrandTetonNPS</a>. <a href="https://twitter.com/hashtag/nature?src=hash&amp;ref_src=twsrc%5Etfw">#nature</a> <a href="https://twitter.com/hashtag/sunset?src=hash&amp;ref_src=twsrc%5Etfw">#sunset</a> <a href="http://t.co/YuKy2rcjyU">pic.twitter.com/YuKy2rcjyU</a></p>&mdash; US Department of the Interior (@Interior) <a href="https://twitter.com/Interior/status/463440424141459456?ref_src=twsrc%5Etfw">May 5, 2014</a></blockquote>
        </div>
    
    </div>
  2. Create a new service and dynamically load and initialize the widget inside the onAccept callback:

    im.run({
        services: {
            twitter: {
                onAccept: async (div, setIframe) => {
                    // Using cookieconsent v3
                    await CookieConsent.loadScript('https://platform.twitter.com/widgets.js');
    
                    // Make sure the "window.twttr" property exists
                    await im.childExists({childProperty: 'twttr'}) && await twttr.widgets.load(div);
    
                    // Make sure the "iframe" element exists
                    await im.childExists({parent: div}) && setIframe(div.querySelector('iframe'));
                },
    
                onReject: (iframe) => {
                    iframe && iframe.parentElement.remove();
                }
            }
        }
    })

It is highly recommended to set a fixed width and height to the main data-service div, to avoid the (awful) content jump effect when the iframe is loaded.

Placeholder for non-js browsers

You can set a placeholder visible only if javascript is disabled via a special div:

<div data-placeholder data-visible></div>

Example:

<div
    data-service="youtube"
    data-id="5b35haQV7tU"
    data-autoscale>

    <div data-placeholder data-visible>
        <p>I'm visible only if js is disabled</p>
    </div>

</div>

APIs

The plugin exposes the following methods:

  • .run(<config_object>)
  • .acceptService(<service_name>)
  • .rejectService(<service_name>)
  • .getState() [v1.2.0+]
  • .getConfig() [v1.2.0+]

Example usage:

// accept specific service only
im.acceptService('youtube');

// accept all services (for example if user has given full consent to cookies)
im.acceptService('all');

// reject specific service
im.rejectService('youtube');

// reject all services (for example when user opts out of cookies)
im.rejectService('all');

// get entire config object
const config = im.getConfig();

// get current state (enabled/disabled services)
const state = im.getState();

// state.services: Map<string, boolean>
// state.acceptedServices: string[]

Both acceptService and rejectService work the same way:

  1. set/erase cookie
  2. create/remove iframes

Configuration examples

  • Youtube

    im.run({
        currLang: 'en',
        services: {
            youtube: {
                embedUrl: 'https://www.youtube-nocookie.com/embed/{data-id}',
    
                thumbnailUrl: 'https://i3.ytimg.com/vi/{data-id}/hqdefault.jpg',
    
                iframe: {
                    allow: 'accelerometer; encrypted-media; gyroscope; picture-in-picture; fullscreen;',
                },
    
                languages: {
                    en: {
                        notice: 'This content is hosted by a third party. By showing the external content you accept the <a rel="noreferrer noopener" href="https://www.youtube.com/t/terms" target="_blank">terms and conditions</a> of youtube.com.',
                        loadBtn: 'Load video',
                        loadAllBtn: "Don't ask again"
                    }
                }
            }
        }
    });

    Example:

    <!-- https://www.youtube.com/watch?v=5b35haQV7tU -->
    <div
        data-service="youtube"
        data-id="5b35haQV7tU"
    ></div>

  • Dailymotion

    im.run({
        currLang: 'en',
        services: {
            dailymotion: {
                embedUrl: 'https://www.dailymotion.com/embed/video/{data-id}',
    
                thumbnailUrl: async (dataId, setThumbnail) => {
                    // Use dailymotion's API to fetch the thumbnail
                    const url = `https://api.dailymotion.com/video/${dataId}?fields=thumbnail_large_url`;
                    const response = await (await fetch(url)).json();
                    const thumbnailUlr = response?.thumbnail_large_url;
                    thumbnailUlr && setThumbnail(thumbnailUlr);
                },
    
                iframe: {
                    allow: 'accelerometer; encrypted-media; gyroscope; picture-in-picture; fullscreen;',
                },
    
                languages: {
                    en: {
                        notice: 'This content is hosted by a third party. By showing the external content you accept the <a rel="noreferrer noopener" href="https://www.dailymotion.com/legal/privacy?localization=en" target="_blank">terms and conditions</a> of dailymotion.com.',
                        loadBtn: 'Load video',
                        loadAllBtn: "Don't ask again"
                    }
                }
            }
        }
    });

  • Vimeo

    im.run({
        currLang: 'en',
        services: {
            vimeo: {
                embedUrl: 'https://player.vimeo.com/video/{data-id}',
    
                iframe: {
                    allow : 'fullscreen; picture-in-picture, allowfullscreen;',
                },
    
                thumbnailUrl: async (dataId, setThumbnail) => {
                    const url = `https://vimeo.com/api/v2/video/${dataId}.json`;
                    const response = await (await fetch(url)).json();
                    const thumbnailUrl = response[0]?.thumbnail_large;
                    thumbnailUrl && setThumbnail(thumbnailUrl);
                },
    
                languages: {
                    en: {
                        notice: 'This content is hosted by a third party. By showing the external content you accept the <a rel="noreferrer noopener" href="https://vimeo.com/terms" target="_blank">terms and conditions</a> of vimeo.com.',
                        loadBtn: 'Load video',
                        loadAllBtn: "Don't ask again"
                    }
                }
            }
        }
    });

  • Twitch

    im.run({
        currLang: 'en',
        services: {
            twitch: {
                embedUrl: `https://player.twitch.tv/?{data-id}&parent=${location.hostname}`,
    
                iframe: {
                    allow: 'accelerometer; encrypted-media; gyroscope; picture-in-picture; fullscreen;',
                },
    
                languages: {
                    en: {
                        notice: 'This content is hosted by a third party. By showing the external content you accept the <a rel="noreferrer noopener" href="https://www.twitch.tv/p/en/legal/terms-of-service/" target="_blank">terms and conditions</a> of twitch.com.',
                        loadBtn: 'Load stream',
                        loadAllBtn: "Don't ask again"
                    }
                }
            }
        }
    });

  • Google Maps

    • With API key

      im.run({
          currLang: 'en',
          services: {
              googlemaps: {
                  embedUrl: 'https://www.google.com/maps/embed/v1/place?key=API_KEY&q={data-id}',
      
                  iframe: {
                      allow: 'picture-in-picture; fullscreen;'
                  },
      
                  languages: {
                      en: {
                          notice: 'This content is hosted by a third party. By showing the external content you accept the <a rel="noreferrer noopener" href="https://cloud.google.com/maps-platform/terms" target="_blank">terms and conditions</a> of Google Maps.',
                          loadBtn: 'Load map',
                          loadAllBtn: "Don't ask again"
                      }
                  }
              }
          }
      });

      Example:

      <div
          data-service="GoogleMaps"
          data-id="Space+Needle,Seattle+WA"
          data-autoscale
      ></div>

    • Without API key

      im.run({
          currLang: 'en',
          services : {
              googlemaps : {
                  embedUrl: 'https://www.google.com/maps/embed?pb={data-id}',
      
                  iframe: {
                      allow : 'picture-in-picture; fullscreen;'
                  },
      
                  languages : {
                      en : {
                          notice: 'This content is hosted by a third party. By showing the external content you accept the <a rel="noreferrer noopener" href="https://cloud.google.com/maps-platform/terms" target="_blank">terms and conditions</a> of Google Maps.',
                          loadBtn: 'Load map',
                          loadAllBtn: "Don't ask again"
                      }
                  }
              }
          }
      });

      Example usage:

      <div
          data-service="googlemaps"
          data-id="!1m18!1m12!1m3!1d2659.4482749804133!2d11.644969316034478!3d48.19798087922823!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x479e7499e2d4c67f%3A0x32f7f02c5e77043a!2sM%C3%BCnchner+Str.+123%2C+85774+Unterf%C3%B6hring%2C+Germany!5e0!3m2!1sen!2sin!4v1565347252768!5m2!1sen!2sin"
          data-autoscale
      ></div>

Usage with CookieConsent [v1.2.0+]

You can use the onChange callback to detect when an iframe is loaded by the loadAllBtn button click event and notify CookieConsent to also update its state.

Example:

im.run({
    currLang: 'en',

    onChange: ({changedServices, eventSource}) => {

        if(eventSource.type === 'click') {
            // Retrieve all accepted services:
            // const allAcceptedServices = im.getState().acceptedServices;

            /**
             * Retrieve array of already accepted services
             * and add the new service
             */
            const servicesToAccept = [
                ...CookieConsent.getUserPreferences().acceptedServices['analytics'], //cookieconsent v3
                ...changedServices
            ];

            CookieConsent.acceptService(servicesToAccept, 'analytics');
        }
    },

    services: {
        // ...
    }
});

Note: the above example assumes that all services belong to the analytics category.

Available data-ratio

Horizontal aspect ratio:

  • 1:1, 2:1, 3:2, 5:2, 4:3, 16:9, 16:10, 20:9, 21:9

Vertical aspect ratio:

  • 9:16, 9:20

License

Distributed under the MIT License. See LICENSE for more information.


Note

Not all services (example: twitch) allow automatic/easy thumbnail fetch.

iframemanager's People

Contributors

iammeds avatar orestbida avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

iframemanager's Issues

Merge cookies + automatically generate <div> around

Hi there,

Two questions:

Is it be possible to merge all the active services cookies into only one json cookie? (a bit like the cookieconsent script does!).
A unified cookie would be also easier to be specified within the cookieconsent modal cookie_table

I've read about some questions from last year about dynamically generated iframes and the idea of creating automatically the

around them deducing its properties through regex. Is there any progress about that?
It would be extremely helpful to integrate iframemanager within a CMS!

Thanks!

Ist there a way to re-run?

Hi,

i am loading some video portfolios via ajax on an wordpress theme. Is there a way to re-run the script to detect the that are new to the dom?

Thanks for your help!

Cheers
Tobias

Use {data-id} on notice

In one use case, it was necessary to pass the {data-id} variable within the printed message, and this variable was not rewritten by the token.
After analyzing the code, this update was possible by changing one line of code (line 568) to this:
notice && notice_text.insertAdjacentHTML('beforeend', noticeText.replaceAll(DATA_ID_PLACEHOLDER, serviceProp._id) || '');
Right now the code is working.

How to size the div?

I am embedding a google map, but using the iframemanager the resulting maps is very small. I tried to set the width and height manually in the div, but it does not change size?

<div class="map-area" data-service="googleMaps" data-id="map1" width="100%" height="450px"></div>

Support for Slideshare.net

I am looking into support for Slideshare.net

Is there a way to sponsor this feature (with a small budget)?

Parameters defined in the configuration are also added to the iframe as an attribute

When setting parameters using the iframe configuration, those params are added to the embed URL, but the <iframe> also gets an param attribute with the specified string:

vimeo: {
    embedUrl: 'https://player.vimeo.com/video/{data-id}',
    iframe: {
        allow: 'fullscreen; picture-in-picture, allowfullscreen',
        params: 'title=0&byline=0&portrait=0',
    },
},

Results in this HTML:

<iframe allow="fullscreen; picture-in-picture, allowfullscreen" params="title=0&byline=0&portrait=0" lazy="" title="Vimeo" src="https://player.vimeo.com/video/252417024?title=0&byline=0&portrait=0"></iframe>

The params attribute should not be there.

Some ideas how to solve this:

  • Is the params configuration even required? The parameters can just be added to the embedUrl.
  • The params configuration value should be handled specially and not added as an attribute.
  • More generically, maybe it makes sense to split the iframe configuration and attributes into separate configs?

Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'name')

Hi, I'm using the latest RC of CookieConsent 3 but I can't reassemble this example https://stackblitz.com/edit/web-platform-mwccsc?file=index.js - I always get this kind of error and I can't explain myself why:

Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'name')
    at H (iframemanager.js:6:3380)
    at Object.acceptService (iframemanager.js:6:4372)
    at onAccept ((Index):172:43)
    at W (cookieconsent.js:7:3657)
    at e.run (cookieconsent.js:7:20793)
H @ iframemanager.js:6
acceptService @ iframemanager.js:6
onAccept @ (Index):172
W @ cookieconsent.js:7
e.run @ cookieconsent.js:7
await in e.run (asynchron)
(anonym) @ (Index):127

Twitter/X "Read More" not clickable

Apparently Tweets or other name "posts" on X get either rendered as images now or theres a bug
with the links now: Clicking "Read more on X" has no effect.
But last time I checked this and it worked X was still called Twitter.
So not sure if it is the iframemanager or on Xs site thats causing the issue.

Is it possible to read the accepted/rejected cookies from iframemanager and show them in cookieconsent?

I got it to work so I can accept a cookie category in cookieconsent and have it also accept/deny the appropriate ones for iframemanager. Is it possible the other way round? So someone rejects the "external" category in CC, but then clicks on "Don't ask again" on an embedded YT iframe. This will not show up in CCs settings, since I cannot read it the other way round - or did I miss something?
Cheers!

How to iframe with arguments?

Hi, love the project!

However, can I add iframe arguments like width etc.?

For example, this one:

<script src="https://static.airtable.com/js/embed/embed_snippet_v1.js"></script><iframe class="airtable-embed airtable-dynamic-height" src="https://airtable.com/embed/shr5EBHUmHzStubDx?backgroundColor=orange" frameborder="0" onmousewheel="" width="100%" height="1541" style="background: transparent; border: 1px solid #ccc;" loading="lazy"></iframe>

Add build tools

Set up rollup or vite.

Terser + postcss are enough for now.

Google maps embed marker not showing

Hi,

I'm trying to get this to work with the normal embed iframe (not through the embed api) e.g. <iframe src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d40299.30426384719!2d4.340397959224176!3d50.85511876045215!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x47c3a4ed73c76867%3A0xc18b3a66787302a7!2sBrussel!5e0!3m2!1snl!2sbe!4v1666528240497!5m2!1snl!2sbe" width="600" height="450" style="border:0;" allowfullscreen="" loading="lazy" referrerpolicy="no-referrer-when-downgrade"></iframe>. When loading the iframe, the src string is encoded (video.iframe.src = encodeURI(src);), which prevents the marker from being rendered. When removing the encodeURI() function, the marker is render correctly.

Could you add a flag to disable the encoding?

Kind regards,
Tom

Example for leaflet map with open street map layer?

Could/should I use iframemanager to embed a leaflet map in a gdpr complient way? Is there some example? Or can you recommend a different solution?

I would like to define the leaflet map and its layers on the same web page but defer the loading of background layers from external servers until a user explicitly confirms it.

=> Instead of an embed url, can I also specify some html content (containing the map definition) directly?

Related: #9

Integration with cookieconsent

Discussed in #22

Originally posted by jelen07 August 24, 2022
Hi, is there any way how to integrate those two tools together?

UC

  1. User add positive consent with category, which include YouTube videos.
  2. There is no need to requride additional consent for iframemanager, because it was already given by cookieconsent.

and vice versa.

SvelteKit

I have a hard time getting this to work with SvelteKit.

The div stays black and I get the following error in console:
Bildschirm­foto 2024-03-10 um 10 13 03

Outside a Svelte component, it works fine. The strange thing is, it worked a few times within a Svelte component. But after another reload it was gone (nothing changed). Now I can't reproduce the working state ... Could you provide a SvelteKit example in StackBlitz?

Currently, I have the css and js part via CDN in app.html and also tried to load them with svelte:head inside the component.

Support for iframe-video-area with a preview image first

What we want for video-iframes is this:

Editor set up an area that shall contain an embedded video and may also specify an (internal) preview-image.

Visitor sees initially: (both those that not has accepted and those who has accepted that category)
Preview-image and a play button on top of it.
If editor did not specify a preview-image a default is used.
(I.e. it only load data from us, never the external service)

When visitor presses image or play-button:

If visitor has accepted that service, the video with the iframe is displayed. (loading data from external service)

If visitor not (yet) has accepted it displays a text and buttons on top of the image (white-faded). Just as iframemanager looks like when you not yet have accepted the service.
"Accept this", and ( "Accept all of type X" or "Open cookie settings" ). The first one only loads the iframe of that vidoe and the second one calls cookieconsent to accept all of that type or open dialog.

NOTE: Currently I have set this up myself with cookieconsent, and are not (yet?) using iframemanager.

Add an option to hide the overlay if consent has already been given

Follow-up to the discussion in #10

Some external content may require external resources to load before it can be displayed, some will be visible almost immediately. In the first case, showing the overlay and then fading it out (the current behaviour) makes sense. But if the external content will be displayed immediately, having the overlay just show up very briefly and then fade out immediately doesn't look great, it looks more like a bug to the users.

As a solution, I suggest an optional option (either for the entire library or for individual services) to adjust this behaviour. If activated, the option should change the behaviour as followed:

  • If no consent has been given for the service, the overlay should be displayed normally and fade out as it currently does.
  • If consent has already been given for the service when the library is initialized, the library should skip showing the overlay and immediately reveal the external content (and call the onAccept callback).

Turn off cookies

I have a website that doesn't currently store any user data, and I'd like to use this plugin to require consent to load in embedded video. I'd rather not have to add a GDPR cookie disclosure just to save GDPR consent information, so is there a way to turn off cookies on this script and just require the user to consent every time they want to load in a video?

[Bug]: loaded iframes outside viewport are not reset

If a specific service is accepted, and there is at least one iframe not visible in the viewport, calling .rejectService('<specific_service>') does not reset the iframe. Instead, as soon as you scroll to that iframe, it will load as if the rejectService method was never called.

This occurs with specific services only:

  • .rejectService('all') ok
  • .rejectService('youtube') fail

Support all configurations in the div

Hi! We are using your Cookie Consent javascript plugin (😍) and the IframeManager looks like a very interesting companion for that!

For simplicity of the use, could you consider a possibility of supporting the service configurations fully straight in the div and using the same languages object for all iframes?

That would make using this plugin a much more versatile in situations when the client can update their content through some CMS and add new embeds as they wish. The current way of defining each embed separately on config is hard to achieve, when embeds change dynamically. With the approach of supporting all configs in the div, it would become much more easier just to do some regexp and replace the iframe embed with the div.

Load iframes when a category from Cookie Consent is accepted

Is there a way to allow load iframes when a category gets accepted from CookieConsent per default but allow the single-service management when not authorized?

I mean, one with allowed marketing cookies will get iframes loaded. The others could agree only to YouTube service on iframe. If they'll later eventually agree and disagree with marketing, the consent will be removed as well for YT.

I load the IframeManager only when the iframe is used in the WordPress Content (created a super simple plugin), and CookieConsent is running on all pages. Maybe a parameter will check the specified category before using cc_youtube or cc_vimeo? Or did I miss something?

P.S. Thanks for a great tool, hope you enjoy your ☕

When integrating with CookieConsent it still sets cookies

It would be great if IframeManager could have an option to disable cookies. If using CookieConsent integration it's all handled there. It just makes documenting the cookies a bit easier as with the current setup you end up documenting every cookie for every service setup when really you could cover it all under a single cookie (CookieConsent's)

Help for using with Docusaurus

Hello,

Thanks for this neat proposition !

I am trying to get this working with Docusaurus.

While I get it working when I load the page where the iframe is embedded (for example https://opencomp.github.io/docv2/saisir-les-resultats/utiliser-opencomp-genie/detecter-les-resultats/#en-savoir-plus-sur-les-diff%C3%A9rents-statuts-de-traitement-possibles), if  I load another page then browse to a page where the div element is inserted, the javascript is not triggered. This is due to the Single Page Application architecture used by Docusaurus v2 / react but I have no idea how to get this working on page change ?

Any idea / guidance to get this working ?

Thanks 🙂

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.