Развертывание расширения Google Chrome; Adobe Flash Player остановил потенциально опасную операцию
Мне интересно, как лучше всего решить проблему отсутствия достаточного разрешения внутри расширения Google Chrome. Я взаимодействую с API YouTube, но я не использую swfobject.js, просто использую am embededed div. Я не верю, что это представляет мою проблему безопасности, но, возможно, это так.
При разработке мне пришлось перейти на страницу безопасности Adobe Flash Player и указать папку для разработки как "безопасное" место. При развертывании у меня нет возможности сделать это. Я не хочу, чтобы мои пользователи нажимали кнопку "Разрешить все" в безопасности флэш-плеера, но я не вижу другого способа добиться своих результатов.
У кого-нибудь есть опыт работы с этим? Какие у меня варианты?
Кажется, что дубликат SWFobject в расширении Chrome - API недоступен, но остается без ответа.
Источник: https://github.com/MeoMix/YouPod
Для запуска: Вытащите из репозитория, загрузите Chrome, нажмите гаечный ключ, перейдите к расширению, выберите "Инструменты разработчика" -> Загрузить распакованное расширение и перейдите к папке.
2 ответа
Из-за ограничений происхождения вы не можете использовать <object>
элемент. Вместо этого вставьте <iframe>
и используйте API проигрывателя YouTube для связи с фреймом.
Замените свой function onYouTubePlayerReady
а также function Initialize(playlist)
со следующим (в background.js
):
function Initialize(playlist) {
port = chrome.extension.connect({ name: "statusPoller" });
if (!player) {
YT_ready(function() {
var frameID = getFrameID("MusicHolder");
if (frameID) {
player = new YT.Player(frameID, {
events: {
"onReady": function() {
player.cueVideoById(playlist[0].ID, 0);
},
"onStateChange": onPlayerStateChange
}
});
}
});
} else {
// Only reload if the player is not playing. Otherwise, the music
// stops when re-opening the popup.
if (player.getPlayerState && player.getPlayerState() != PLAYING) {
player.cueVideoById(playlist[0].ID, 0);
}
}
}
Чтобы предыдущий код заработал, вам нужно загрузить другой скрипт в background.htm
, Содержание youtube-player-api-helper.js
основаны на моем предыдущем ответе на Listening for Youtube Event в JavaScript или jQuery:
// @description Easier way to implement the YouTube JavaScript API
// @author Rob W
// @global getFrameID(id) Quick way to find the iframe object which corresponds to the given ID.
// @global YT_ready(Function:function [, Boolean:qeue_at_start])
// @global onYouTubePlayerAPIReady() - Used to trigger the qeued functions
// @website https://stackru.com/a/7988536/938089?listening-for-youtube-event-in-javascript-or-jquery
function getFrameID(id) {
var elem = document.getElementById(id);
if (elem) {
if(/^iframe$/i.test(elem.tagName)) return id; //Frame, OK
// else: Look for frame
var elems = elem.getElementsByTagName("iframe");
if (!elems.length) return null; //No iframe found, FAILURE
for (var i=0; i<elems.length; i++) {
if (/^https?:\/\/(?:www\.)?youtube(?:-nocookie)?\.com(\/|$)/i.test(elems[i].src)) break;
}
elem = elems[i]; //The only, or the best iFrame
if (elem.id) return elem.id; //Existing ID, return it
// else: Create a new ID
do { //Keep postfixing `-frame` until the ID is unique
id += "-frame";
} while (document.getElementById(id));
elem.id = id;
return id;
}
// If no element, return null.
return null;
}
// Define YT_ready function.
var YT_ready = (function() {
var onReady_funcs = [], api_isReady = false;
/* @param func function Function to execute on ready
* @param func Boolean If true, all qeued functions are executed
* @param b_before Boolean If true, the func will added to the first
position in the queue*/
return function(func, b_before) {
if (func === true) {
api_isReady = true;
for (var i=0; i<onReady_funcs.length; i++){
// Removes the first func from the array, and execute func
onReady_funcs.shift()();
}
}
else if(typeof func == "function") {
if (api_isReady) func();
else onReady_funcs[b_before?"unshift":"push"](func);
}
}
})();
// This function will be called when the API is fully loaded
function onYouTubePlayerAPIReady() {YT_ready(true);}
// Load YouTube Frame API
(function() { //Closure, to not leak to the scope
var s = document.createElement("script");
s.src = "http://www.youtube.com/player_api"; /* Load Player API*/
var before = document.getElementsByTagName("script")[0];
before.parentNode.insertBefore(s, before);
})();
Объяснение дополнительных изменений (бонус):
background.htm
:<!DOCTYPE html />
является недействительным. Так должно быть:<!DOCTYPE html>
,- Все
.htm
файлы:type
атрибут является необязательным на<script>
тег. Даже если вы хотите указать один, используйтеapplication/javascript
вместоtext/javascript
, Оба будут работать в расширении Chrome, но первый более правильный. popup.js
: Изменено определение ctrl + c. Вместо того, чтобы обнаруживать и запоминать,Ctrl
был нажат, используйтеe.ctrlKey
имущество.- И еще немного. Посмотри на
popup.js
и искатьRobW:
чтобы найти мои аннотации.
Модифицированные файлы
Сводка обновленных файлов (на основе вашего репозитория Github):
YouPod/background.htm
YouPod/popup.htm
(Исправление Doctype, прокомментированное предложение для фокуса заполнителя)YouPod/js/background.js
YouPod/js/popup.js
YouPad/js/youtube-player-api-helper.js
новый
Теперь я использую это как хедз-ап (задействован jQuery и requireJS, но более короткий)
//Provides an interface to the YouTube iFrame.
//Starts up Player/SongValidator object after receiving a ready response from the YouTube API.
define(['onYouTubePlayerAPIReady'],function(){
'use strict';
var events = {
onApiReady: 'onApiReady'
};
//This code will trigger onYouTubePlayerAPIReady
$(window).load(function(){
$('script:first').before($('<script/>', {
src: 'https://www.youtube.com/iframe_api'
}));
});
return {
ready: function(){
$(this).trigger(events.onApiReady);
},
onApiReady: function(event){
$(this).on(events.onApiReady, event);
}
};
});
//This function will be called when the API is fully loaded. Needs to be exposed globally so YouTube can call it.
var onYouTubePlayerAPIReady = function () {
'use strict';
require(['youtube-player-api-helper'], function(ytPlayerApiHelper){
ytPlayerApiHelper.ready();
});
}
Подпишитесь на событие, используя youtubePlayerApi.onApiReady.