Turbolinks 5.0 and Facebook SDK

Last week I upgraded to Rails 5, which uses Turbolinks 5.0. I used the following script to download the Facebook button as Turbolinks 3.0:

fb_root = null fb_events_bound = false $ -> loadFacebookSDK() bindFacebookEvents() unless fb_events_bound bindFacebookEvents = -> $(document) .on('page:fetch', saveFacebookRoot) .on('page:change', restoreFacebookRoot) .on('page:load', -> FB?.XFBML.parse() ) fb_events_bound = true saveFacebookRoot = -> fb_root = $('#fb-root').detach() restoreFacebookRoot = -> if $('#fb-root').length > 0 $('#fb-root').replaceWith fb_root else $('body').append fb_root loadFacebookSDK = -> window.fbAsyncInit = initializeFacebookSDK $.getScript("//connect.facebook.net/nl_NL/all.js#xfbml=1") initializeFacebookSDK = -> FB.init appId : 'YOUR_APP_ID' channelUrl: '//WWW.YOUR_DOMAIN.COM/channel.html' status : true cookie : true xfbml : true 

With Turbolinks 5.0, a similar button will only appear when the page reloads. When I do not reload the page and just click on the link, I get this error:

 Blocked a frame with origin "https://www.facebook.com" from accessing a frame with origin "http://localhost:3000". The frame requesting access has a protocol of "https", the frame being accessed has a protocol of "http". Protocols must match. 

Does anyone know how to fix this?

+1
source share
4 answers

The reason for this is that some of the events have been renamed Turbolinks 5 and are incompatible with Turbolinks 3 . my suggestion is trying to create a file in the javascripts/ folder named compatibility.coffee

compatibility.coffee

 {defer, dispatch} = Turbolinks handleEvent = (eventName, handler) -> document.addEventListener(eventName, handler, false) translateEvent = ({from, to}) -> handler = (event) -> event = dispatch(to, target: event.target, cancelable: event.cancelable, data: event.data) event.preventDefault() if event.defaultPrevented handleEvent(from, handler) translateEvent from: "turbolinks:click", to: "page:before-change" translateEvent from: "turbolinks:request-start", to: "page:fetch" translateEvent from: "turbolinks:request-end", to: "page:receive" translateEvent from: "turbolinks:before-cache", to: "page:before-unload" translateEvent from: "turbolinks:render", to: "page:update" translateEvent from: "turbolinks:load", to: "page:change" translateEvent from: "turbolinks:load", to: "page:update" loaded = false handleEvent "DOMContentLoaded", -> defer -> loaded = true handleEvent "turbolinks:load", -> if loaded dispatch("page:load") jQuery?(document).on "ajaxSuccess", (event, xhr, settings) -> if jQuery.trim(xhr.responseText).length > 0 dispatch("page:update") 
+1
source

If you prefer to use your own Turbolinks 5 events, you can add this script to your Rails resources:

 // FacebookSDK // https://developers.facebook.com/docs/plugins/page-plugin/ (function(d, s, id) { var js, fjs = d.getElementsByTagName(s)[0]; if (d.getElementById(id)) return; js = d.createElement(s); js.id = id; js.src = "//connect.facebook.net/en_US/sdk.js#xfbml=1&version=v2.8"; fjs.parentNode.insertBefore(js, fjs); }(document, 'script', 'facebook-jssdk')); // Replace 'facebook-jssdk' with your page id. // Compatibility with Turbolinks 5 (function($) { var fbRoot; function saveFacebookRoot() { if ($('#fb-root').length) { fbRoot = $('#fb-root').detach(); } }; function restoreFacebookRoot() { if (fbRoot != null) { if ($('#fb-root').length) { $('#fb-root').replaceWith(fbRoot); } else { $('body').append(fbRoot); } } if (typeof FB !== "undefined" && FB !== null) { // Instance of FacebookSDK FB.XFBML.parse(); } }; document.addEventListener('turbolinks:request-start', saveFacebookRoot) document.addEventListener('turbolinks:load', restoreFacebookRoot) }(jQuery)); 

From: https://gist.github.com/6temes/52648dc6b3adbbf05da3942794b97a00

+3
source

Here's a way to integrate Turbolinks 5 with the Facebook SDK.

In your layout template:

 // /source/layouts/layout.erb <body class="<%= page_classes %>"> <%= yield %> <div id='permanent' data-turbolinks-permanent></div> </body> 

Then in your javascript using jQuery here:

 function FBInit() { FB.init({ appId : 'YOUR_KEY', xfbml : true, version : 'v2.8' }); $('#permanent').append( $('#fb-root').detach() ); }; $(document).ready(function(){ $.getScript( "//connect.facebook.net/en_US/sdk.js#xfbml=1&version=v2.8", FBInit); }); $(document).on('turbolinks:load', function(event){ if (typeof FB !== "undefined" && FB !== null) { FB.XFBML.parse(); } }); $(document).on("turbolinks:before-cache", function() { $('[data-turbolinks-no-cache]').remove(); }); 

Then use any Facebook plugins using the data-turbolinks-no-cache attribute as follows:

 <div data-turbolinks-no-cache class="fb-like" data-href="#" data-layout="standard" data-action="like" data-size="small" data-show-faces="true" data-share="true"></div> 

Here is a gist and here is a post blog explaining how this works.

+3
source

I tried Alex solution to implement fb-customerchat. The plugin displays on every page, but when I navigate, js adds more of the same elements. Do you have any idea how to fix this?

0
source

Source: https://habr.com/ru/post/1492489/


All Articles