Показать сообщение отдельно
  #3 (permalink)  
Старый 22.01.2017, 22:03
Новичок на форуме
Отправить личное сообщение для LEV7n Посмотреть профиль Найти все сообщения от LEV7n
 
Регистрация: 21.03.2016
Сообщений: 2

#Решение проблемы динамического подключения js в chrome extensions
Столнулся с той же проблемой, единственным решением при поддержке динамической загрузки нужных скриптов стало написание некоторого функционала:

1. manifest.json
Код:
{
	"manifest_version": 2,
	"name": "Extension",
	"version": "1.0",
	"minimum_chrome_version": "46",

	"content_scripts": [
		{
			"matches": [ "http://*/*", "https://*/*" ],
			"js": [
				"assets/core.js",
				"assets/content.js"
			]
		}
	],

	"background": {
		"scripts": [
			"assets/core.js",
			"assets/background.js"
		]
	},

	"content_security_policy": "script-src 'unsafe-eval'; object-src 'self';"
}
2. background.js
function parseMessage(request, sender, sendResponse) {
	switch(request.type) {
		case 'ajax':
			ajax(request, sendResponse);
		break;
	}
}

chrome.extension.onMessage.addListener(function(request, sender, sendResponse) {
	parseMessage.call(this, request, sender, sendResponse);

	return true;
});


3. core.js
/*
	Здесь вставил содержимое файла jQuery v3.1.1
*/

/*
	Ajax function
	ajax({query: [{url: '/ajax'}, {url: '/ajax2'}]}, function(e) { ... });

	@args		request (object), sendResponse (function)
*/

/**
 * XmlHttpRequest's getAllResponseHeaders() method returns a string of response
 * headers according to the format described here:
 * [url]http://www.w3.org/TR/XMLHttpRequest/#the-getallresponseheaders-method[/url]
 * This method parses that string into a user-friendly key/value pair object.
 */
function parseResponseHeaders(r){var n={};if(!r)return n;for(var e=r.split("\r\n"),s=0;s<e.length;s++){var i=e[s],t=i.indexOf(": ");if(t>0){var a=i.substring(0,t),f=i.substring(t+2);n[a]=f}}return n};

function ajax(request, sendResponse) {
	if(!isBackground()) {
		return chrome.extension.sendMessage({
			type: 'ajax',
			query: request.query
		}, sendResponse || function() {});
	}

	if(request.query) {
		var responses = {},
			join = request.joinResults;

		function sendReq(n, req) {
			$.ajax($.extend({
				success: function(res, status, xhr) {
					var xhr = $.extend({
							headers: $.isFunction(parseResponseHeaders) ? parseResponseHeaders(xhr.getAllResponseHeaders()) : null
						}, xhr),
						data = {res: res, status: status, xhr: xhr};
					
					if(!n && !req) { sendResponse(data); }
					else {
						responses[n] = data;
						var arr = $.map(responses, function(v) { return [v]; });
						if(arr.length >= request.query.length) { !join ? sendResponse(arr) : sendResponse.apply(request, arr); }
					}
				},
				error: function(xhr, status, error) {
					var xhr = $.extend({}, xhr),
						data = {res: error, status: status, xhr: xhr};

					if(!n && !req) { sendResponse(data); }
					else {
						responses[n] = data;
						var arr = $.map(responses, function(v) { return [v]; });
						if(arr.length >= request.query.length) { !join ? sendResponse(arr) : sendResponse.apply(request, arr); }
					}
				}
			}, req || request.query));
		}

		if(!request.query.length) { sendReq(); }
		else { $.each(request.query, sendReq); }
	}
}

/*
	Include given file(s) to current document context (based on ajax)
	require('https://site.com/file');
	require({url: 'https://site.com/file', async: false}, function(f) { .. });
	require([
		{url: 'https://site.com/file', async: false},
		'https://site.com/file2'
	], function(f) { .. });

	@args		files (string/array/object), [callback (function)]
*/
function require(files, callback) {
	var timeout, content = [], loaded = 0;
	function req(file) {
		if(!file) return;
		
		ajax({
			query: ($.type(file) == 'object' ? file : {url: file})
		}, function(f) {
			if((file.url || file).indexOf('.js') > -1) {
				try {
					eval.call(window, f.res);
				} catch(e) {
					console.warn(f, e);
				}
			}

			content.push( $.extend(f, {file: file}) );
			loaded++;
		});
	}

	if($.type(files) == 'string') {
		req(files);
	} else if(files && $.type(files[0]) !== 'undefined') {
		$.map(files, req);
	}

	timeout = setInterval(function() {
		if(loaded == ($.type(files) == 'string' ? 1 : files.length) && $.isFunction(callback)) {
			clearInterval(timeout);
			callback(content);
		}
	}, 1000);
}

/*
	Check if current script instance of background or content
	isBackground()	// true

	@return		true (boolean) from background script
				false (boolean) from content script
*/
function isBackground() {
	return location.protocol == 'chrome-extension:';
}


4. options.js
/*Append module*/
require(chrome.extension.getURL('assets/script1.js'));

$(init);


поскольку модуль используется при нажатии на кнопку я не ожидаю его загрузки, если нужна инициализация после загрузки используйте коллбэк:

/*Append modules*/
require([
	chrome.extension.getURL('assets/script1.js'),
	chrome.extension.getURL('assets/script2.js')
], function(scripts) { /* Initialise */ });
Ответить с цитированием