├── LICENSE ├── README-DE.md ├── README.md ├── dist └── 2ClickIframePrivacy.min.js └── src └── 2ClickIframePrivacy.js /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Michael Lorer - https://www.01-scripts.de/ 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README-DE.md: -------------------------------------------------------------------------------- 1 | # 2Click-Iframe-Privacy 2 | Einfaches JavaScript, um eine 2-Klick-Lösung für beliebige per IFrame eingebettete Inhalte zu aktivieren (z.B. Youtube, Google-Maps, Google Kalender etc.) - Kein Framework nötig! 3 | [Demo](https://01-scripts.github.io/2Click-Iframe-Privacy/) 4 | 5 | ___ 6 | 7 | ## Setup 8 | 9 | JavaScript aus dem `dist` Verzeichnis in die Webseite einfügen. 10 | 11 | ```html 12 | 13 | ``` 14 | 15 | Folgende CSS-Klasse in eine existierende CSS-Datei einfügen oder den Code direkt in die Webseite kopieren: 16 | 17 | ```html 18 | 34 | ``` 35 | 36 | Abschließend muss die Funktion initialisiert werden: 37 | 38 | ```html 39 | 42 | ``` 43 | 44 | # Benutzen 45 | 46 | ## Für Videos 47 | 48 | `src=` mit `data-src=` ersetzen und ein leeres Attribut `src=""` hinzufügen; `data-2click-type="video"` als weiteres Attribut dem IFrame hinzufügen: 49 | 50 | ```html 51 | 52 | ``` 53 | 54 | ## Für Google Maps 55 | 56 | `src=` mit `data-src=` ersetzen und ein leeres Attribut `src=""` hinzufügen; `data-2click-type="map"` als weiteres Attribut dem IFrame hinzufügen: 57 | 58 | ```html 59 | 60 | ``` 61 | 62 | ## Für Google Kalender 63 | 64 | `src=` mit `data-src=` ersetzen und ein leeres Attribut `src=""` hinzufügen; `data-2click-type="calendar"` als weiteres Attribut dem IFrame hinzufügen: 65 | 66 | ```html 67 | 68 | ``` 69 | 70 | # Demo 71 | 72 | [Demo hier ausprobieren](https://01-scripts.github.io/2Click-Iframe-Privacy/demo.html) 73 | 74 | # Weitere Optionen 75 | 76 | Der nachfolgende Code zeigt alle verfügbaren Optionen zur einfachen Anpassung des Scritps: 77 | 78 | ```html 79 | 99 | ``` 100 | 101 | ## Optionen 102 | 103 | | Konfigurationsvariable | Beschreibung | Standard | 104 | |-------------------------|--------------|----------| 105 | | `enableCookies` | Auf `false` setzen um die Nutzung von Cookies abzuschalten. Das Nachladen von eingebettetem Inhalt muss dann auf jeder Seite erneut bestätigt werden. | `true` | 106 | | `useSessionCookie` | Einstellung auf `false` um dauerhafte Cookies statt Session-Cookies zu verwernden. Session-Cookies werden beim Schließen des Browsers gelöscht. | `true` | 107 | | `cookieNamespace` | Definition eines eigenen Namenbereichs zum Anlegen der Cookies | `_2ClickIPEnable-` | 108 | | `showContentLabel` | Bezeichnung des Links der angezeigt wird um den eingebetteten Inhalt nachzuladen. | `Inhalt anzeigen` | 109 | | `rememberChoiceLabel` | Bezeichnung der Checkbox um die Besucher-Auswahl zu merken (es wird dazu ein Cookie gesetzt). | `Auswahl merken` | 110 | | `privacyPolicyLabel` | Bezeichnung des Links der zu einer eigenen Datenschutzerklärung führt. | `Datenschutzerklärung` | 111 | | `privacyPolicyUrl` | Link zu einer eigenen Datenschutzerklärung. Wird nur angezeigt, wenn eine URL angegeben wird. | `false` | 112 | | `CustomTypes` | Details zur Nutzung wie nachfolgend beschrieben. | | 113 | 114 | ## Benutzerdefinierte Inhaltstypen definieren 115 | 116 | Neben den drei Vordefinierten Inhaltstypen (`video`, `map`, `calendar`) ist es auch möglich eigene, benutzerdefinierte Inhaltstypen zu definieren 117 | sowie JavaScript Callback-Funktionen zu erstellen, die immer dann ausgelöst werden, wenn ein Besucher den `showContentLabel`-Link anklickt. 118 | Eigene Inhaltstypen können wie im obigen Code-Beispiel zu sehen definiert werden. Dazu können folgende Optionen genutzt werden: 119 | 120 | | Variable | Beschreibung | 121 | |------------------|--------------| 122 | | `type` | Definiere einen eindeutigen Namen für den neu definierten Inhaltstypen. Dieser Name muss in folgendem Attribut für jedes entsprechende IFrame verwendet werden: `data-2click-type="ownvideo"`. | 123 | | `callback` | Name einer gültigen JavaScript-Function. Diese Funktion wird als Callback immer aufgerufen wenn ein Besucher auf den `showContentLabel`-Link klickt. | 124 | | `description` | Beschreibung (kann HTML enthalten) die in einem `div` innerhalb des IFrame angezeigt wird, bevor der eigentliche Inhalt nachgeladen wird. | 125 | 126 | ### Callback example 127 | 128 | ```html 129 | 134 | ``` -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 2Click-Iframe-Privacy 2 | Easy way to implement a 2-click solution for every IFrame embedded content (like Youtube videos, Google maps, Google calendar and more) using vanilla JavaScript. 3 | [Demo](https://01-scripts.github.io/2Click-Iframe-Privacy/) 4 | 5 | ## Setup 6 | 7 | First, include the script located in the `dist` folder. 8 | 9 | ```html 10 | 11 | ``` 12 | 13 | Add some CSS into one of your CSS files or include it directly: 14 | 15 | ```html 16 | 32 | ``` 33 | 34 | Now, you need to instantiate it: 35 | 36 | ```html 37 | 40 | ``` 41 | 42 | # Usage 43 | 44 | ## For Videos 45 | 46 | Replace `src=` with `data-src=` and add an empty attribute `src=""`, add the attribute `data-2click-type="video"` to the IFrame: 47 | 48 | ```html 49 | 50 | ``` 51 | 52 | ## For Google Maps 53 | 54 | Replace `src=` with `data-src=` and add an empty attribute `src=""`, add the attribute `data-2click-type="map"` to the IFrame: 55 | 56 | ```html 57 | 58 | ``` 59 | 60 | ## For Google Calendar 61 | 62 | Replace `src=` with `data-src=` and add an empty attribute `src=""`, add the attribute `data-2click-type="calendar"` to the IFrame: 63 | 64 | ```html 65 | 66 | ``` 67 | 68 | # Demo 69 | 70 | Have a [look here](https://01-scripts.github.io/2Click-Iframe-Privacy/demo.html). 71 | 72 | # More options 73 | 74 | The following code shows all available options described in detail below: 75 | 76 | ```html 77 | 97 | ``` 98 | 99 | ## Options 100 | 101 | | Config-Variable | Description | Default | 102 | |-------------------------|-------------|---------| 103 | | `enableCookies` | Set to `false` will disable the usage of cookies. Loading of embedded content must be accepted at each page load. | `true` | 104 | | `useSessionCookie` | Change this setting to `false` to use a persistent cookie instead of a session cookie. Session cookies are cleared when the browser is closed. | `true` | 105 | | `cookieNamespace` | Define a name for the namespace in which cookies should be created. | `_2ClickIPEnable-` | 106 | | `showContentLabel` | Change the naming of the link that is shown to enable and load the embedded content. | `Inhalt anzeigen` | 107 | | `rememberChoiceLabel` | Change the naming of the checkbox that is shown to remember the user-choice (by setting a cookie). | `Auswahl merken` | 108 | | `privacyPolicyLabel` | Change the naming of the link to your privacy statement. | `Datenschutzerklärung` | 109 | | `privacyPolicyUrl` | Define a link to the privacy statement of your web page. Link is only shown if a URL is provided. | `false` | 110 | | `CustomTypes` | See detailed description of options below. | | 111 | 112 | ## Define custom types 113 | 114 | Besides the three pre-defined content types (`video`, `map`, `calendar`) it's also possible to define your own custom types and also define 115 | JavaScript callback-functions that are triggered each time a user is clicking on the `showContentLabel`-link. 116 | You may define your own `CustomTypes` as shown in the code-snipped above and can use the following options within: 117 | 118 | | Variable | Description | 119 | |------------------|-------------| 120 | | `type` | Define a unique name for your custom content type. Use this type-name in the follwing attribute of each iframe: `data-2click-type="ownvideo"`. | 121 | | `callback` | Set the name of a valid JavaScript function. This function is called as a callback everytime a user clicks on the `showContentLabel`-link. | 122 | | `description` | Define a description (may contain HTML) that is shown in a `div` within the iframe of this type before loading the embedded content. | 123 | 124 | ### Callback example 125 | 126 | ```html 127 | 132 | ``` -------------------------------------------------------------------------------- /dist/2ClickIframePrivacy.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * 2Click-Iframe-Privacy v0.3.1 3 | * https://github.com/01-Scripts/2Click-Iframe-Privacy 4 | * 5 | * Licensed MIT © 2018-2023 Michael Lorer - https://www.01-scripts.de/ 6 | */ 7 | var _2ClickIframePrivacy=new function(){function e(e,n,i){var t=new Date;t.setTime(t.getTime()+864e5*i),document.cookie=e+"="+n+";path=/;expires="+t.toGMTString()}function n(e,n){document.cookie=e+"="+n+";path=/"}function t(e){var n=document.cookie.match("(^|;) ?"+e+"=([^;]*)(;|$)");return n?n[2]:null}function r(e,n,i,t){e.parentNode.insertBefore(n,e),n.className="privacy-msg privacy-"+i+"-msg",n.style.width=e.clientWidth+"px",n.style.height=e.clientHeight+"px",n.innerHTML=t+'"+o.showContentLabel+"",o.enableCookies&&(n.innerHTML=n.innerHTML+'
"),o.privacyPolicyUrl&&(n.innerHTML=n.innerHTML+'
'+o.privacyPolicyLabel+""),n.innerHTML="

"+n.innerHTML+"

",n.appendChild(e)}var o={enableCookies:!0,useSessionCookie:!0,cookieNamespace:"_2ClickIPEnable-",showContentLabel:"Inhalt anzeigen",rememberChoiceLabel:"Auswahl merken",privacyPolicyLabel:"Datenschutzerklärung",privacyPolicyUrl:!1};this.types=new Array({type:"video",description:"Zum Aktivieren des Videos bitte auf den Link klicken. Durch das Aktivieren von eingebetteten Videos werden Daten an den jeweiligen Anbieter übermittelt. Weitere Informationen können unserer Datenschutzerklärung entnommen werden.
"},{type:"map",description:"Zum Aktivieren der eingebetteten Karte bitte auf den Link klicken. Durch das Aktivieren werden Daten an den jeweiligen Anbieter übermittelt. Weitere Informationen können unserer Datenschutzerklärung entnommen werden.
"},{type:"calendar",description:"Zum Aktivieren des eingebetteten Kalenders bitte auf den Link klicken. Durch das Aktivieren werden Daten an den jeweiligen Anbieter übermittelt. Weitere Informationen können unserer Datenschutzerklärung entnommen werden.
"}),this.EnableContent=function(i){var t;if(o.enableCookies){var r=!1,a=document.querySelectorAll("div.privacy-"+i+"-msg p input");for(t=0;t' 24 | }, 25 | { 26 | type: 'map', 27 | description: 'Zum Aktivieren der eingebetteten Karte bitte auf den Link klicken. Durch das Aktivieren werden Daten an den jeweiligen Anbieter übermittelt. Weitere Informationen können unserer Datenschutzerklärung entnommen werden.
' 28 | }, 29 | { 30 | type: 'calendar', 31 | description: 'Zum Aktivieren des eingebetteten Kalenders bitte auf den Link klicken. Durch das Aktivieren werden Daten an den jeweiligen Anbieter übermittelt. Weitere Informationen können unserer Datenschutzerklärung entnommen werden.
' 32 | } 33 | ); 34 | 35 | function setCookie(name, value, days) { 36 | var d = new Date; 37 | d.setTime(d.getTime() + 24*60*60*1000*days); 38 | document.cookie = name + "=" + value + ";path=/;expires=" + d.toGMTString(); 39 | } 40 | 41 | function setSessionCookie(name, value) { 42 | document.cookie = name + "=" + value + ";path=/"; 43 | } 44 | 45 | function getCookie(name) { 46 | var v = document.cookie.match('(^|;) ?' + name + '=([^;]*)(;|$)'); 47 | return v ? v[2] : null; 48 | } 49 | 50 | // Create
-element within the respective iframe to display the defined data-security message and get consent for loading the iframe content. 51 | function wrap(el, wrapper, type, text) { 52 | el.parentNode.insertBefore(wrapper, el); 53 | wrapper.className = 'privacy-msg privacy-'+type+'-msg'; 54 | wrapper.style.width = el.clientWidth+'px'; 55 | wrapper.style.height = el.clientHeight+'px'; 56 | wrapper.innerHTML = text +''+config.showContentLabel+''; 57 | if(config.enableCookies){ 58 | wrapper.innerHTML = wrapper.innerHTML + '
'; 59 | } 60 | if(config.privacyPolicyUrl){ 61 | wrapper.innerHTML = wrapper.innerHTML + '
'+config.privacyPolicyLabel+''; 62 | } 63 | wrapper.innerHTML = '

' + wrapper.innerHTML + '

'; 64 | wrapper.appendChild(el); 65 | } 66 | 67 | this.EnableContent = function (type){ 68 | var i; 69 | 70 | // Cookies globally enabled by config? 71 | if(config.enableCookies){ 72 | var remind = false; 73 | var x = document.querySelectorAll('div.privacy-'+type+'-msg p input'); 74 | // Check if any checkbox for the selected class was checked. If so a cookie will be set 75 | for (i = 0; i < x.length; i++) { 76 | if(x[i].checked == true){ 77 | remind = true; 78 | } 79 | } 80 | 81 | if(remind){ 82 | if(config.useSessionCookie){ 83 | setSessionCookie(config.cookieNamespace+type, '1'); 84 | } 85 | else{ 86 | setCookie(config.cookieNamespace+type, '1', 30); 87 | } 88 | } 89 | } 90 | 91 | var x = document.querySelectorAll('div.privacy-'+type+'-msg p'); 92 | for (i = 0; i < x.length; i++) { 93 | x[i].parentNode.removeChild(x[i]); 94 | } 95 | 96 | x = document.querySelectorAll('div.privacy-'+type+'-msg'); 97 | for (i = 0; i < x.length; i++) { 98 | var parent = x[i].parentNode; 99 | 100 | // Move all children out of the element 101 | while (x[i].firstChild) parent.insertBefore(x[i].firstChild, x[i]); 102 | 103 | // Remove the empty element 104 | parent.removeChild(x[i]); 105 | } 106 | 107 | x = document.querySelectorAll('iframe[data-2click-type="'+type+'"]'); 108 | for (i = 0; i < x.length; i++) { 109 | x[i].src = x[i].getAttribute("data-src"); 110 | } 111 | 112 | // If available, execute the callback that is defined for the currently active type 113 | for (i = 0; i < this.types.length; i++) { 114 | if(this.types[i].type == type && this.types[i].callback) { 115 | window[this.types[i].callback](); 116 | } 117 | } 118 | } 119 | 120 | this.init = function (Userconfig) { 121 | // Read UserConfiguration: 122 | if (typeof Userconfig.enableCookies !== 'undefined') { 123 | config.enableCookies = Userconfig.enableCookies; 124 | } 125 | if (typeof Userconfig.useSessionCookie !== 'undefined') { 126 | config.useSessionCookie = Userconfig.useSessionCookie; 127 | } 128 | if (typeof Userconfig.cookieNamespace !== 'undefined') { 129 | config.cookieNamespace = Userconfig.cookieNamespace; 130 | } 131 | if (typeof Userconfig.privacyPolicyUrl !== 'undefined') { 132 | config.privacyPolicyUrl = Userconfig.privacyPolicyUrl; 133 | } 134 | if (typeof Userconfig.showContentLabel !== 'undefined') { 135 | config.showContentLabel = Userconfig.showContentLabel; 136 | } 137 | if (typeof Userconfig.rememberChoiceLabel !== 'undefined') { 138 | config.rememberChoiceLabel = Userconfig.rememberChoiceLabel; 139 | } 140 | if (typeof Userconfig.privacyPolicyLabel !== 'undefined') { 141 | config.privacyPolicyLabel = Userconfig.privacyPolicyLabel; 142 | } 143 | 144 | if (Array.isArray(Userconfig.CustomTypes)) { 145 | this.types = Userconfig.CustomTypes; 146 | } 147 | 148 | for (i = 0; i < this.types.length; i++) { 149 | var selector = document.querySelectorAll('iframe[data-2click-type="'+this.types[i].type+'"]'); 150 | 151 | var x; 152 | if(!getCookie(config.cookieNamespace+this.types[i].type)){ 153 | for (x = 0; x < selector.length; x++) { 154 | wrap(selector[x], document.createElement('div'), this.types[i].type, this.types[i].description); 155 | } 156 | }else{ 157 | for (x = 0; x < selector.length; x++) { 158 | selector[x].src = selector[x].getAttribute("data-src"); 159 | } 160 | } 161 | } 162 | 163 | }; 164 | } --------------------------------------------------------------------------------