`script-src 'self'; object-src 'self'
by default `script-src 'self'; object-src 'self'
`script-src 'self'; object-src 'self'
. This is essentially the most important update. About him a little later.chrome-extension://[PACKAGE ID]/[PATH]
URL chrome-extension://[PACKAGE ID]/[PATH]
. Those. You can not connect a script or image from an extension from other pages except the extension itself. But to get around this drawback, the web_accessible_resources
property web_accessible_resources
, in which you can specify an array with the paths to the necessary resources.background_page
property (which was a string), we now write background
, which should contain an object with the scripts
or page
property.browser_actions
field has browser_actions
replaced with browser_action
, and the chrome.browserActions
API has been chrome.browserActions
with chrome.browserAction
.icons
property from browser_action
. Instead, use default_icon
or chrome.browserAction.setIcon
.name
property from browser_action
. Instead, use default_title
or chrome.browserAction.setTitle
.popup
property from browser_action
. Instead, use default_popup
or chrome.browserAction.setPopup
.default_popup
property in browser_action
should be a string, not an objectpage_actions
field page_actions
replaced by page_action
, and the chrome.pageActions
API is chrome.pageActions
by chrome.pageAction
.icons
from page_action
. Instead, use default_icon
or chrome.pageAction.setIcon
.name
property from page_action
. Instead, use default_title
or chrome.pageAction.setTitle
.popup
property from page_action
. Instead, use default_popup
or chrome.pageAction.setPopup
.default_popup
property in page_action
should be a string, not an object.chrome.self
from the API, now you need to use chrome.extension
.chrome.extension.getTabContentses
and chrome.extension.getExtensionTabs
. Instead, you need to use chrome.extension.getViews({ "type": "tab" })
.Port.tab
use Port.sender
.content_security_policy
in manifest.json
.manifest_version
), then by default there is no content security policy. But for the second version of the manifest, it is installed by default with the value script-src 'self'; object-src 'self'
script-src 'self'; object-src 'self'
. Therefore, there are some limitations. For example, the eval
function will fail. Also, inline (). - setTimeout setInterval
, .
, ( CDN, ), .
. (, https). content_security_policy
, :
{ ..., "content_security_policy": "script-src 'self' https://example.com; object-src 'self'", ... }
β eval?β β ?β
- eval? (, new Function()
). ( sandbox ).
, (, eval) ( CSP ).
postMessage()
.
underscore
sandboxed/template-renderer.html
template-renderer.html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Sandboxed Template Renderer</title> <script src="/js/libs/underscore/underscore-min.js"></script> </head> <body> <script> var templates = {}; window.addEventListener('message', function (event) { var template; if (typeof templates[event.data.templateName] == 'undefined') { template = _.template(event.data.template); templates[event.data.templateName] = template; } else { template = templates[event.data.templateName]; } event.source.postMessage({ id: event.data.id, result: template(event.data.context) }, event.origin); }); </script> </html>
html
{ ..., "sandbox": { "pages": ["sandboxed/template-renderer.html"] }, ... }
function getTemplate var getTemplate = (function(){ var iframe = document.createElement('iframe'), callbacks = []; iframe.src = 'sandboxed/template-renderer.html'; iframe.style.display = 'none'; document.body.appendChild(iframe); window.addEventListener('message', function (event) { callbacks.forEach(function (item, idx) { if (item && item.id == event.data.id) { item.callback(event.data.result); delete callbacks[idx]; } }); }); return function (templateName, template) { return function (context, callback) { var id = Math.random(); callbacks.push({ id: id, callback: callback }); iframe.contentWindow.postMessage({ id: id, templateName: templateName, template: template, context: context }, '*'); }; }; }());
// , var template = getTemplate('templateId', templateContent); // - template({text: 'Hello world'}, function (html) { // html // $('body').html , // $('body').html(html); });
- . (). .
, manifest.json
:
manifest.json { "name": "Twittext", "description": "A lightweight Google Chrome extension for Twitter", "background": { "page": "background.html" }, "manifest_version": 2, "browser_action": { "default_icon": "img/icon_19.png", "default_title": "Twittext", "default_popup": "popup.html" }, "icons": { "128": "img/icon_128.png", "19": "img/icon_19.png", "48": "img/icon_48.png" }, "options_page": "options.html", "version": "1.6.1", "permissions": [ "tabs", "background", "https://api.twitter.com/", "https://userstream.twitter.com/" ], "sandbox": { "pages": ["sandboxed/template-renderer.html"] } }
will not be executed (). - setTimeout setInterval
, .
, ( CDN, ), .
. (, https). content_security_policy
, :
{ ..., "content_security_policy": "script-src 'self' https://example.com; object-src 'self'", ... }
β eval?β β ?β
- eval? (, new Function()
). ( sandbox ).
, (, eval) ( CSP ).
postMessage()
.
underscore
sandboxed/template-renderer.html
template-renderer.html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Sandboxed Template Renderer</title> <script src="/js/libs/underscore/underscore-min.js"></script> </head> <body> <script> var templates = {}; window.addEventListener('message', function (event) { var template; if (typeof templates[event.data.templateName] == 'undefined') { template = _.template(event.data.template); templates[event.data.templateName] = template; } else { template = templates[event.data.templateName]; } event.source.postMessage({ id: event.data.id, result: template(event.data.context) }, event.origin); }); </script> </html>
html
{ ..., "sandbox": { "pages": ["sandboxed/template-renderer.html"] }, ... }
function getTemplate var getTemplate = (function(){ var iframe = document.createElement('iframe'), callbacks = []; iframe.src = 'sandboxed/template-renderer.html'; iframe.style.display = 'none'; document.body.appendChild(iframe); window.addEventListener('message', function (event) { callbacks.forEach(function (item, idx) { if (item && item.id == event.data.id) { item.callback(event.data.result); delete callbacks[idx]; } }); }); return function (templateName, template) { return function (context, callback) { var id = Math.random(); callbacks.push({ id: id, callback: callback }); iframe.contentWindow.postMessage({ id: id, templateName: templateName, template: template, context: context }, '*'); }; }; }());
// , var template = getTemplate('templateId', templateContent); // - template({text: 'Hello world'}, function (html) { // html // $('body').html , // $('body').html(html); });
- . (). .
, manifest.json
:
manifest.json { "name": "Twittext", "description": "A lightweight Google Chrome extension for Twitter", "background": { "page": "background.html" }, "manifest_version": 2, "browser_action": { "default_icon": "img/icon_19.png", "default_title": "Twittext", "default_popup": "popup.html" }, "icons": { "128": "img/icon_128.png", "19": "img/icon_19.png", "48": "img/icon_48.png" }, "options_page": "options.html", "version": "1.6.1", "permissions": [ "tabs", "background", "https://api.twitter.com/", "https://userstream.twitter.com/" ], "sandbox": { "pages": ["sandboxed/template-renderer.html"] } }
(). - setTimeout
setInterval
, .
, ( CDN, ), .
. (, https). content_security_policy
, :
{ ..., "content_security_policy": "script-src 'self' https://example.com; object-src 'self'", ... }
β eval?β β ?β
- eval? (, new Function()
). ( sandbox ).
, (, eval) ( CSP ).
postMessage()
.
underscore
sandboxed/template-renderer.html
template-renderer.html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Sandboxed Template Renderer</title> <script src="/js/libs/underscore/underscore-min.js"></script> </head> <body> <script> var templates = {}; window.addEventListener('message', function (event) { var template; if (typeof templates[event.data.templateName] == 'undefined') { template = _.template(event.data.template); templates[event.data.templateName] = template; } else { template = templates[event.data.templateName]; } event.source.postMessage({ id: event.data.id, result: template(event.data.context) }, event.origin); }); </script> </html>
html
{ ..., "sandbox": { "pages": ["sandboxed/template-renderer.html"] }, ... }
function getTemplate var getTemplate = (function(){ var iframe = document.createElement('iframe'), callbacks = []; iframe.src = 'sandboxed/template-renderer.html'; iframe.style.display = 'none'; document.body.appendChild(iframe); window.addEventListener('message', function (event) { callbacks.forEach(function (item, idx) { if (item && item.id == event.data.id) { item.callback(event.data.result); delete callbacks[idx]; } }); }); return function (templateName, template) { return function (context, callback) { var id = Math.random(); callbacks.push({ id: id, callback: callback }); iframe.contentWindow.postMessage({ id: id, templateName: templateName, template: template, context: context }, '*'); }; }; }());
// , var template = getTemplate('templateId', templateContent); // - template({text: 'Hello world'}, function (html) { // html // $('body').html , // $('body').html(html); });
- . (). .
, manifest.json
:
manifest.json { "name": "Twittext", "description": "A lightweight Google Chrome extension for Twitter", "background": { "page": "background.html" }, "manifest_version": 2, "browser_action": { "default_icon": "img/icon_19.png", "default_title": "Twittext", "default_popup": "popup.html" }, "icons": { "128": "img/icon_128.png", "19": "img/icon_19.png", "48": "img/icon_48.png" }, "options_page": "options.html", "version": "1.6.1", "permissions": [ "tabs", "background", "https://api.twitter.com/", "https://userstream.twitter.com/" ], "sandbox": { "pages": ["sandboxed/template-renderer.html"] } }
(). - setTimeout
setInterval
, .
, ( CDN, ), .
. (, https). content_security_policy
, :
{ ..., "content_security_policy": "script-src 'self' https://example.com; object-src 'self'", ... }
β eval?β β ?β
- eval? (, new Function()
). ( sandbox ).
, (, eval) ( CSP ).
postMessage()
.
underscore
sandboxed/template-renderer.html
template-renderer.html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Sandboxed Template Renderer</title> <script src="/js/libs/underscore/underscore-min.js"></script> </head> <body> <script> var templates = {}; window.addEventListener('message', function (event) { var template; if (typeof templates[event.data.templateName] == 'undefined') { template = _.template(event.data.template); templates[event.data.templateName] = template; } else { template = templates[event.data.templateName]; } event.source.postMessage({ id: event.data.id, result: template(event.data.context) }, event.origin); }); </script> </html>
html
{ ..., "sandbox": { "pages": ["sandboxed/template-renderer.html"] }, ... }
function getTemplate var getTemplate = (function(){ var iframe = document.createElement('iframe'), callbacks = []; iframe.src = 'sandboxed/template-renderer.html'; iframe.style.display = 'none'; document.body.appendChild(iframe); window.addEventListener('message', function (event) { callbacks.forEach(function (item, idx) { if (item && item.id == event.data.id) { item.callback(event.data.result); delete callbacks[idx]; } }); }); return function (templateName, template) { return function (context, callback) { var id = Math.random(); callbacks.push({ id: id, callback: callback }); iframe.contentWindow.postMessage({ id: id, templateName: templateName, template: template, context: context }, '*'); }; }; }());
// , var template = getTemplate('templateId', templateContent); // - template({text: 'Hello world'}, function (html) { // html // $('body').html , // $('body').html(html); });
- . (). .
, manifest.json
:
manifest.json { "name": "Twittext", "description": "A lightweight Google Chrome extension for Twitter", "background": { "page": "background.html" }, "manifest_version": 2, "browser_action": { "default_icon": "img/icon_19.png", "default_title": "Twittext", "default_popup": "popup.html" }, "icons": { "128": "img/icon_128.png", "19": "img/icon_19.png", "48": "img/icon_48.png" }, "options_page": "options.html", "version": "1.6.1", "permissions": [ "tabs", "background", "https://api.twitter.com/", "https://userstream.twitter.com/" ], "sandbox": { "pages": ["sandboxed/template-renderer.html"] } }
(). - setTimeout
setInterval
, .
, ( CDN, ), .
. (, https). content_security_policy
, :
{ ..., "content_security_policy": "script-src 'self' https://example.com; object-src 'self'", ... }
β eval?β β ?β
- eval? (, new Function()
). ( sandbox ).
, (, eval) ( CSP ).
postMessage()
.
underscore
sandboxed/template-renderer.html
template-renderer.html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Sandboxed Template Renderer</title> <script src="/js/libs/underscore/underscore-min.js"></script> </head> <body> <script> var templates = {}; window.addEventListener('message', function (event) { var template; if (typeof templates[event.data.templateName] == 'undefined') { template = _.template(event.data.template); templates[event.data.templateName] = template; } else { template = templates[event.data.templateName]; } event.source.postMessage({ id: event.data.id, result: template(event.data.context) }, event.origin); }); </script> </html>
html
{ ..., "sandbox": { "pages": ["sandboxed/template-renderer.html"] }, ... }
function getTemplate var getTemplate = (function(){ var iframe = document.createElement('iframe'), callbacks = []; iframe.src = 'sandboxed/template-renderer.html'; iframe.style.display = 'none'; document.body.appendChild(iframe); window.addEventListener('message', function (event) { callbacks.forEach(function (item, idx) { if (item && item.id == event.data.id) { item.callback(event.data.result); delete callbacks[idx]; } }); }); return function (templateName, template) { return function (context, callback) { var id = Math.random(); callbacks.push({ id: id, callback: callback }); iframe.contentWindow.postMessage({ id: id, templateName: templateName, template: template, context: context }, '*'); }; }; }());
// , var template = getTemplate('templateId', templateContent); // - template({text: 'Hello world'}, function (html) { // html // $('body').html , // $('body').html(html); });
- . (). .
, manifest.json
:
manifest.json { "name": "Twittext", "description": "A lightweight Google Chrome extension for Twitter", "background": { "page": "background.html" }, "manifest_version": 2, "browser_action": { "default_icon": "img/icon_19.png", "default_title": "Twittext", "default_popup": "popup.html" }, "icons": { "128": "img/icon_128.png", "19": "img/icon_19.png", "48": "img/icon_48.png" }, "options_page": "options.html", "version": "1.6.1", "permissions": [ "tabs", "background", "https://api.twitter.com/", "https://userstream.twitter.com/" ], "sandbox": { "pages": ["sandboxed/template-renderer.html"] } }
(). - setTimeout
setInterval
, .
, ( CDN, ), .
. (, https). content_security_policy
, :
{ ..., "content_security_policy": "script-src 'self' https://example.com; object-src 'self'", ... }
β eval?β β ?β
- eval? (, new Function()
). ( sandbox ).
, (, eval) ( CSP ).
postMessage()
.
underscore
sandboxed/template-renderer.html
template-renderer.html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Sandboxed Template Renderer</title> <script src="/js/libs/underscore/underscore-min.js"></script> </head> <body> <script> var templates = {}; window.addEventListener('message', function (event) { var template; if (typeof templates[event.data.templateName] == 'undefined') { template = _.template(event.data.template); templates[event.data.templateName] = template; } else { template = templates[event.data.templateName]; } event.source.postMessage({ id: event.data.id, result: template(event.data.context) }, event.origin); }); </script> </html>
html
{ ..., "sandbox": { "pages": ["sandboxed/template-renderer.html"] }, ... }
function getTemplate var getTemplate = (function(){ var iframe = document.createElement('iframe'), callbacks = []; iframe.src = 'sandboxed/template-renderer.html'; iframe.style.display = 'none'; document.body.appendChild(iframe); window.addEventListener('message', function (event) { callbacks.forEach(function (item, idx) { if (item && item.id == event.data.id) { item.callback(event.data.result); delete callbacks[idx]; } }); }); return function (templateName, template) { return function (context, callback) { var id = Math.random(); callbacks.push({ id: id, callback: callback }); iframe.contentWindow.postMessage({ id: id, templateName: templateName, template: template, context: context }, '*'); }; }; }());
// , var template = getTemplate('templateId', templateContent); // - template({text: 'Hello world'}, function (html) { // html // $('body').html , // $('body').html(html); });
- . (). .
, manifest.json
:
manifest.json { "name": "Twittext", "description": "A lightweight Google Chrome extension for Twitter", "background": { "page": "background.html" }, "manifest_version": 2, "browser_action": { "default_icon": "img/icon_19.png", "default_title": "Twittext", "default_popup": "popup.html" }, "icons": { "128": "img/icon_128.png", "19": "img/icon_19.png", "48": "img/icon_48.png" }, "options_page": "options.html", "version": "1.6.1", "permissions": [ "tabs", "background", "https://api.twitter.com/", "https://userstream.twitter.com/" ], "sandbox": { "pages": ["sandboxed/template-renderer.html"] } }
(). - setTimeout
setInterval
, .
, ( CDN, ), .
. (, https). content_security_policy
, :
{ ..., "content_security_policy": "script-src 'self' https://example.com; object-src 'self'", ... }
β eval?β β ?β
- eval? (, new Function()
). ( sandbox ).
, (, eval) ( CSP ).
postMessage()
.
underscore
sandboxed/template-renderer.html
template-renderer.html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Sandboxed Template Renderer</title> <script src="/js/libs/underscore/underscore-min.js"></script> </head> <body> <script> var templates = {}; window.addEventListener('message', function (event) { var template; if (typeof templates[event.data.templateName] == 'undefined') { template = _.template(event.data.template); templates[event.data.templateName] = template; } else { template = templates[event.data.templateName]; } event.source.postMessage({ id: event.data.id, result: template(event.data.context) }, event.origin); }); </script> </html>
html
{ ..., "sandbox": { "pages": ["sandboxed/template-renderer.html"] }, ... }
function getTemplate var getTemplate = (function(){ var iframe = document.createElement('iframe'), callbacks = []; iframe.src = 'sandboxed/template-renderer.html'; iframe.style.display = 'none'; document.body.appendChild(iframe); window.addEventListener('message', function (event) { callbacks.forEach(function (item, idx) { if (item && item.id == event.data.id) { item.callback(event.data.result); delete callbacks[idx]; } }); }); return function (templateName, template) { return function (context, callback) { var id = Math.random(); callbacks.push({ id: id, callback: callback }); iframe.contentWindow.postMessage({ id: id, templateName: templateName, template: template, context: context }, '*'); }; }; }());
// , var template = getTemplate('templateId', templateContent); // - template({text: 'Hello world'}, function (html) { // html // $('body').html , // $('body').html(html); });
- . (). .
, manifest.json
:
manifest.json { "name": "Twittext", "description": "A lightweight Google Chrome extension for Twitter", "background": { "page": "background.html" }, "manifest_version": 2, "browser_action": { "default_icon": "img/icon_19.png", "default_title": "Twittext", "default_popup": "popup.html" }, "icons": { "128": "img/icon_128.png", "19": "img/icon_19.png", "48": "img/icon_48.png" }, "options_page": "options.html", "version": "1.6.1", "permissions": [ "tabs", "background", "https://api.twitter.com/", "https://userstream.twitter.com/" ], "sandbox": { "pages": ["sandboxed/template-renderer.html"] } }
(). - setTimeout
setInterval
, .
, ( CDN, ), .
. (, https). content_security_policy
, :
{ ..., "content_security_policy": "script-src 'self' https://example.com; object-src 'self'", ... }
β eval?β β ?β
- eval? (, new Function()
). ( sandbox ).
, (, eval) ( CSP ).
postMessage()
.
underscore
sandboxed/template-renderer.html
template-renderer.html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Sandboxed Template Renderer</title> <script src="/js/libs/underscore/underscore-min.js"></script> </head> <body> <script> var templates = {}; window.addEventListener('message', function (event) { var template; if (typeof templates[event.data.templateName] == 'undefined') { template = _.template(event.data.template); templates[event.data.templateName] = template; } else { template = templates[event.data.templateName]; } event.source.postMessage({ id: event.data.id, result: template(event.data.context) }, event.origin); }); </script> </html>
html
{ ..., "sandbox": { "pages": ["sandboxed/template-renderer.html"] }, ... }
function getTemplate var getTemplate = (function(){ var iframe = document.createElement('iframe'), callbacks = []; iframe.src = 'sandboxed/template-renderer.html'; iframe.style.display = 'none'; document.body.appendChild(iframe); window.addEventListener('message', function (event) { callbacks.forEach(function (item, idx) { if (item && item.id == event.data.id) { item.callback(event.data.result); delete callbacks[idx]; } }); }); return function (templateName, template) { return function (context, callback) { var id = Math.random(); callbacks.push({ id: id, callback: callback }); iframe.contentWindow.postMessage({ id: id, templateName: templateName, template: template, context: context }, '*'); }; }; }());
// , var template = getTemplate('templateId', templateContent); // - template({text: 'Hello world'}, function (html) { // html // $('body').html , // $('body').html(html); });
- . (). .
, manifest.json
:
manifest.json { "name": "Twittext", "description": "A lightweight Google Chrome extension for Twitter", "background": { "page": "background.html" }, "manifest_version": 2, "browser_action": { "default_icon": "img/icon_19.png", "default_title": "Twittext", "default_popup": "popup.html" }, "icons": { "128": "img/icon_128.png", "19": "img/icon_19.png", "48": "img/icon_48.png" }, "options_page": "options.html", "version": "1.6.1", "permissions": [ "tabs", "background", "https://api.twitter.com/", "https://userstream.twitter.com/" ], "sandbox": { "pages": ["sandboxed/template-renderer.html"] } }
(). - setTimeout
setInterval
, .
, ( CDN, ), .
. (, https). content_security_policy
, :
{ ..., "content_security_policy": "script-src 'self' https://example.com; object-src 'self'", ... }
β eval?β β ?β
- eval? (, new Function()
). ( sandbox ).
, (, eval) ( CSP ).
postMessage()
.
underscore
sandboxed/template-renderer.html
template-renderer.html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Sandboxed Template Renderer</title> <script src="/js/libs/underscore/underscore-min.js"></script> </head> <body> <script> var templates = {}; window.addEventListener('message', function (event) { var template; if (typeof templates[event.data.templateName] == 'undefined') { template = _.template(event.data.template); templates[event.data.templateName] = template; } else { template = templates[event.data.templateName]; } event.source.postMessage({ id: event.data.id, result: template(event.data.context) }, event.origin); }); </script> </html>
html
{ ..., "sandbox": { "pages": ["sandboxed/template-renderer.html"] }, ... }
function getTemplate var getTemplate = (function(){ var iframe = document.createElement('iframe'), callbacks = []; iframe.src = 'sandboxed/template-renderer.html'; iframe.style.display = 'none'; document.body.appendChild(iframe); window.addEventListener('message', function (event) { callbacks.forEach(function (item, idx) { if (item && item.id == event.data.id) { item.callback(event.data.result); delete callbacks[idx]; } }); }); return function (templateName, template) { return function (context, callback) { var id = Math.random(); callbacks.push({ id: id, callback: callback }); iframe.contentWindow.postMessage({ id: id, templateName: templateName, template: template, context: context }, '*'); }; }; }());
// , var template = getTemplate('templateId', templateContent); // - template({text: 'Hello world'}, function (html) { // html // $('body').html , // $('body').html(html); });
- . (). .
, manifest.json
:
manifest.json { "name": "Twittext", "description": "A lightweight Google Chrome extension for Twitter", "background": { "page": "background.html" }, "manifest_version": 2, "browser_action": { "default_icon": "img/icon_19.png", "default_title": "Twittext", "default_popup": "popup.html" }, "icons": { "128": "img/icon_128.png", "19": "img/icon_19.png", "48": "img/icon_48.png" }, "options_page": "options.html", "version": "1.6.1", "permissions": [ "tabs", "background", "https://api.twitter.com/", "https://userstream.twitter.com/" ], "sandbox": { "pages": ["sandboxed/template-renderer.html"] } }
(). - setTimeout
setInterval
, .
, ( CDN, ), .
. (, https). content_security_policy
, :
{ ..., "content_security_policy": "script-src 'self' https://example.com; object-src 'self'", ... }
β eval?β β ?β
- eval? (, new Function()
). ( sandbox ).
, (, eval) ( CSP ).
postMessage()
.
underscore
sandboxed/template-renderer.html
template-renderer.html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Sandboxed Template Renderer</title> <script src="/js/libs/underscore/underscore-min.js"></script> </head> <body> <script> var templates = {}; window.addEventListener('message', function (event) { var template; if (typeof templates[event.data.templateName] == 'undefined') { template = _.template(event.data.template); templates[event.data.templateName] = template; } else { template = templates[event.data.templateName]; } event.source.postMessage({ id: event.data.id, result: template(event.data.context) }, event.origin); }); </script> </html>
html
{ ..., "sandbox": { "pages": ["sandboxed/template-renderer.html"] }, ... }
function getTemplate var getTemplate = (function(){ var iframe = document.createElement('iframe'), callbacks = []; iframe.src = 'sandboxed/template-renderer.html'; iframe.style.display = 'none'; document.body.appendChild(iframe); window.addEventListener('message', function (event) { callbacks.forEach(function (item, idx) { if (item && item.id == event.data.id) { item.callback(event.data.result); delete callbacks[idx]; } }); }); return function (templateName, template) { return function (context, callback) { var id = Math.random(); callbacks.push({ id: id, callback: callback }); iframe.contentWindow.postMessage({ id: id, templateName: templateName, template: template, context: context }, '*'); }; }; }());
// , var template = getTemplate('templateId', templateContent); // - template({text: 'Hello world'}, function (html) { // html // $('body').html , // $('body').html(html); });
- . (). .
, manifest.json
:
manifest.json { "name": "Twittext", "description": "A lightweight Google Chrome extension for Twitter", "background": { "page": "background.html" }, "manifest_version": 2, "browser_action": { "default_icon": "img/icon_19.png", "default_title": "Twittext", "default_popup": "popup.html" }, "icons": { "128": "img/icon_128.png", "19": "img/icon_19.png", "48": "img/icon_48.png" }, "options_page": "options.html", "version": "1.6.1", "permissions": [ "tabs", "background", "https://api.twitter.com/", "https://userstream.twitter.com/" ], "sandbox": { "pages": ["sandboxed/template-renderer.html"] } }
(). - setTimeout
setInterval
, .
, ( CDN, ), .
. (, https). content_security_policy
, :
{ ..., "content_security_policy": "script-src 'self' https://example.com; object-src 'self'", ... }
β eval?β β ?β
- eval? (, new Function()
). ( sandbox ).
, (, eval) ( CSP ).
postMessage()
.
underscore
sandboxed/template-renderer.html
template-renderer.html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Sandboxed Template Renderer</title> <script src="/js/libs/underscore/underscore-min.js"></script> </head> <body> <script> var templates = {}; window.addEventListener('message', function (event) { var template; if (typeof templates[event.data.templateName] == 'undefined') { template = _.template(event.data.template); templates[event.data.templateName] = template; } else { template = templates[event.data.templateName]; } event.source.postMessage({ id: event.data.id, result: template(event.data.context) }, event.origin); }); </script> </html>
html
{ ..., "sandbox": { "pages": ["sandboxed/template-renderer.html"] }, ... }
function getTemplate var getTemplate = (function(){ var iframe = document.createElement('iframe'), callbacks = []; iframe.src = 'sandboxed/template-renderer.html'; iframe.style.display = 'none'; document.body.appendChild(iframe); window.addEventListener('message', function (event) { callbacks.forEach(function (item, idx) { if (item && item.id == event.data.id) { item.callback(event.data.result); delete callbacks[idx]; } }); }); return function (templateName, template) { return function (context, callback) { var id = Math.random(); callbacks.push({ id: id, callback: callback }); iframe.contentWindow.postMessage({ id: id, templateName: templateName, template: template, context: context }, '*'); }; }; }());
// , var template = getTemplate('templateId', templateContent); // - template({text: 'Hello world'}, function (html) { // html // $('body').html , // $('body').html(html); });
- . (). .
, manifest.json
:
manifest.json { "name": "Twittext", "description": "A lightweight Google Chrome extension for Twitter", "background": { "page": "background.html" }, "manifest_version": 2, "browser_action": { "default_icon": "img/icon_19.png", "default_title": "Twittext", "default_popup": "popup.html" }, "icons": { "128": "img/icon_128.png", "19": "img/icon_19.png", "48": "img/icon_48.png" }, "options_page": "options.html", "version": "1.6.1", "permissions": [ "tabs", "background", "https://api.twitter.com/", "https://userstream.twitter.com/" ], "sandbox": { "pages": ["sandboxed/template-renderer.html"] } }
(). - setTimeout
setInterval
, .
, ( CDN, ), .
. (, https). content_security_policy
, :
{ ..., "content_security_policy": "script-src 'self' https://example.com; object-src 'self'", ... }
β eval?β β ?β
- eval? (, new Function()
). ( sandbox ).
, (, eval) ( CSP ).
postMessage()
.
underscore
sandboxed/template-renderer.html
template-renderer.html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Sandboxed Template Renderer</title> <script src="/js/libs/underscore/underscore-min.js"></script> </head> <body> <script> var templates = {}; window.addEventListener('message', function (event) { var template; if (typeof templates[event.data.templateName] == 'undefined') { template = _.template(event.data.template); templates[event.data.templateName] = template; } else { template = templates[event.data.templateName]; } event.source.postMessage({ id: event.data.id, result: template(event.data.context) }, event.origin); }); </script> </html>
html
{ ..., "sandbox": { "pages": ["sandboxed/template-renderer.html"] }, ... }
function getTemplate var getTemplate = (function(){ var iframe = document.createElement('iframe'), callbacks = []; iframe.src = 'sandboxed/template-renderer.html'; iframe.style.display = 'none'; document.body.appendChild(iframe); window.addEventListener('message', function (event) { callbacks.forEach(function (item, idx) { if (item && item.id == event.data.id) { item.callback(event.data.result); delete callbacks[idx]; } }); }); return function (templateName, template) { return function (context, callback) { var id = Math.random(); callbacks.push({ id: id, callback: callback }); iframe.contentWindow.postMessage({ id: id, templateName: templateName, template: template, context: context }, '*'); }; }; }());
// , var template = getTemplate('templateId', templateContent); // - template({text: 'Hello world'}, function (html) { // html // $('body').html , // $('body').html(html); });
- . (). .
, manifest.json
:
manifest.json { "name": "Twittext", "description": "A lightweight Google Chrome extension for Twitter", "background": { "page": "background.html" }, "manifest_version": 2, "browser_action": { "default_icon": "img/icon_19.png", "default_title": "Twittext", "default_popup": "popup.html" }, "icons": { "128": "img/icon_128.png", "19": "img/icon_19.png", "48": "img/icon_48.png" }, "options_page": "options.html", "version": "1.6.1", "permissions": [ "tabs", "background", "https://api.twitter.com/", "https://userstream.twitter.com/" ], "sandbox": { "pages": ["sandboxed/template-renderer.html"] } }
(). - setTimeout
setInterval
, .
, ( CDN, ), .
. (, https). content_security_policy
, :
{ ..., "content_security_policy": "script-src 'self' https://example.com; object-src 'self'", ... }
β eval?β β ?β
- eval? (, new Function()
). ( sandbox ).
, (, eval) ( CSP ).
postMessage()
.
underscore
sandboxed/template-renderer.html
template-renderer.html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Sandboxed Template Renderer</title> <script src="/js/libs/underscore/underscore-min.js"></script> </head> <body> <script> var templates = {}; window.addEventListener('message', function (event) { var template; if (typeof templates[event.data.templateName] == 'undefined') { template = _.template(event.data.template); templates[event.data.templateName] = template; } else { template = templates[event.data.templateName]; } event.source.postMessage({ id: event.data.id, result: template(event.data.context) }, event.origin); }); </script> </html>
html
{ ..., "sandbox": { "pages": ["sandboxed/template-renderer.html"] }, ... }
function getTemplate var getTemplate = (function(){ var iframe = document.createElement('iframe'), callbacks = []; iframe.src = 'sandboxed/template-renderer.html'; iframe.style.display = 'none'; document.body.appendChild(iframe); window.addEventListener('message', function (event) { callbacks.forEach(function (item, idx) { if (item && item.id == event.data.id) { item.callback(event.data.result); delete callbacks[idx]; } }); }); return function (templateName, template) { return function (context, callback) { var id = Math.random(); callbacks.push({ id: id, callback: callback }); iframe.contentWindow.postMessage({ id: id, templateName: templateName, template: template, context: context }, '*'); }; }; }());
// , var template = getTemplate('templateId', templateContent); // - template({text: 'Hello world'}, function (html) { // html // $('body').html , // $('body').html(html); });
- . (). .
, manifest.json
:
manifest.json { "name": "Twittext", "description": "A lightweight Google Chrome extension for Twitter", "background": { "page": "background.html" }, "manifest_version": 2, "browser_action": { "default_icon": "img/icon_19.png", "default_title": "Twittext", "default_popup": "popup.html" }, "icons": { "128": "img/icon_128.png", "19": "img/icon_19.png", "48": "img/icon_48.png" }, "options_page": "options.html", "version": "1.6.1", "permissions": [ "tabs", "background", "https://api.twitter.com/", "https://userstream.twitter.com/" ], "sandbox": { "pages": ["sandboxed/template-renderer.html"] } }
(). - setTimeout
setInterval
, .
, ( CDN, ), .
. (, https). content_security_policy
, :
{ ..., "content_security_policy": "script-src 'self' https://example.com; object-src 'self'", ... }
β eval?β β ?β
- eval? (, new Function()
). ( sandbox ).
, (, eval) ( CSP ).
postMessage()
.
underscore
sandboxed/template-renderer.html
template-renderer.html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Sandboxed Template Renderer</title> <script src="/js/libs/underscore/underscore-min.js"></script> </head> <body> <script> var templates = {}; window.addEventListener('message', function (event) { var template; if (typeof templates[event.data.templateName] == 'undefined') { template = _.template(event.data.template); templates[event.data.templateName] = template; } else { template = templates[event.data.templateName]; } event.source.postMessage({ id: event.data.id, result: template(event.data.context) }, event.origin); }); </script> </html>
html
{ ..., "sandbox": { "pages": ["sandboxed/template-renderer.html"] }, ... }
function getTemplate var getTemplate = (function(){ var iframe = document.createElement('iframe'), callbacks = []; iframe.src = 'sandboxed/template-renderer.html'; iframe.style.display = 'none'; document.body.appendChild(iframe); window.addEventListener('message', function (event) { callbacks.forEach(function (item, idx) { if (item && item.id == event.data.id) { item.callback(event.data.result); delete callbacks[idx]; } }); }); return function (templateName, template) { return function (context, callback) { var id = Math.random(); callbacks.push({ id: id, callback: callback }); iframe.contentWindow.postMessage({ id: id, templateName: templateName, template: template, context: context }, '*'); }; }; }());
// , var template = getTemplate('templateId', templateContent); // - template({text: 'Hello world'}, function (html) { // html // $('body').html , // $('body').html(html); });
- . (). .
, manifest.json
:
manifest.json { "name": "Twittext", "description": "A lightweight Google Chrome extension for Twitter", "background": { "page": "background.html" }, "manifest_version": 2, "browser_action": { "default_icon": "img/icon_19.png", "default_title": "Twittext", "default_popup": "popup.html" }, "icons": { "128": "img/icon_128.png", "19": "img/icon_19.png", "48": "img/icon_48.png" }, "options_page": "options.html", "version": "1.6.1", "permissions": [ "tabs", "background", "https://api.twitter.com/", "https://userstream.twitter.com/" ], "sandbox": { "pages": ["sandboxed/template-renderer.html"] } }
(). - setTimeout
setInterval
, .
, ( CDN, ), .
. (, https). content_security_policy
, :
{ ..., "content_security_policy": "script-src 'self' https://example.com; object-src 'self'", ... }
β eval?β β ?β
- eval? (, new Function()
). ( sandbox ).
, (, eval) ( CSP ).
postMessage()
.
underscore
sandboxed/template-renderer.html
template-renderer.html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Sandboxed Template Renderer</title> <script src="/js/libs/underscore/underscore-min.js"></script> </head> <body> <script> var templates = {}; window.addEventListener('message', function (event) { var template; if (typeof templates[event.data.templateName] == 'undefined') { template = _.template(event.data.template); templates[event.data.templateName] = template; } else { template = templates[event.data.templateName]; } event.source.postMessage({ id: event.data.id, result: template(event.data.context) }, event.origin); }); </script> </html>
html
{ ..., "sandbox": { "pages": ["sandboxed/template-renderer.html"] }, ... }
function getTemplate var getTemplate = (function(){ var iframe = document.createElement('iframe'), callbacks = []; iframe.src = 'sandboxed/template-renderer.html'; iframe.style.display = 'none'; document.body.appendChild(iframe); window.addEventListener('message', function (event) { callbacks.forEach(function (item, idx) { if (item && item.id == event.data.id) { item.callback(event.data.result); delete callbacks[idx]; } }); }); return function (templateName, template) { return function (context, callback) { var id = Math.random(); callbacks.push({ id: id, callback: callback }); iframe.contentWindow.postMessage({ id: id, templateName: templateName, template: template, context: context }, '*'); }; }; }());
// , var template = getTemplate('templateId', templateContent); // - template({text: 'Hello world'}, function (html) { // html // $('body').html , // $('body').html(html); });
- . (). .
, manifest.json
:
manifest.json { "name": "Twittext", "description": "A lightweight Google Chrome extension for Twitter", "background": { "page": "background.html" }, "manifest_version": 2, "browser_action": { "default_icon": "img/icon_19.png", "default_title": "Twittext", "default_popup": "popup.html" }, "icons": { "128": "img/icon_128.png", "19": "img/icon_19.png", "48": "img/icon_48.png" }, "options_page": "options.html", "version": "1.6.1", "permissions": [ "tabs", "background", "https://api.twitter.com/", "https://userstream.twitter.com/" ], "sandbox": { "pages": ["sandboxed/template-renderer.html"] } }
(). - setTimeout
setInterval
, .
, ( CDN, ), .
. (, https). content_security_policy
, :
{ ..., "content_security_policy": "script-src 'self' https://example.com; object-src 'self'", ... }
β eval?β β ?β
- eval? (, new Function()
). ( sandbox ).
, (, eval) ( CSP ).
postMessage()
.
underscore
sandboxed/template-renderer.html
template-renderer.html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Sandboxed Template Renderer</title> <script src="/js/libs/underscore/underscore-min.js"></script> </head> <body> <script> var templates = {}; window.addEventListener('message', function (event) { var template; if (typeof templates[event.data.templateName] == 'undefined') { template = _.template(event.data.template); templates[event.data.templateName] = template; } else { template = templates[event.data.templateName]; } event.source.postMessage({ id: event.data.id, result: template(event.data.context) }, event.origin); }); </script> </html>
html
{ ..., "sandbox": { "pages": ["sandboxed/template-renderer.html"] }, ... }
function getTemplate var getTemplate = (function(){ var iframe = document.createElement('iframe'), callbacks = []; iframe.src = 'sandboxed/template-renderer.html'; iframe.style.display = 'none'; document.body.appendChild(iframe); window.addEventListener('message', function (event) { callbacks.forEach(function (item, idx) { if (item && item.id == event.data.id) { item.callback(event.data.result); delete callbacks[idx]; } }); }); return function (templateName, template) { return function (context, callback) { var id = Math.random(); callbacks.push({ id: id, callback: callback }); iframe.contentWindow.postMessage({ id: id, templateName: templateName, template: template, context: context }, '*'); }; }; }());
// , var template = getTemplate('templateId', templateContent); // - template({text: 'Hello world'}, function (html) { // html // $('body').html , // $('body').html(html); });
- . (). .
, manifest.json
:
manifest.json { "name": "Twittext", "description": "A lightweight Google Chrome extension for Twitter", "background": { "page": "background.html" }, "manifest_version": 2, "browser_action": { "default_icon": "img/icon_19.png", "default_title": "Twittext", "default_popup": "popup.html" }, "icons": { "128": "img/icon_128.png", "19": "img/icon_19.png", "48": "img/icon_48.png" }, "options_page": "options.html", "version": "1.6.1", "permissions": [ "tabs", "background", "https://api.twitter.com/", "https://userstream.twitter.com/" ], "sandbox": { "pages": ["sandboxed/template-renderer.html"] } }
(). - setTimeout
setInterval
, .
, ( CDN, ), .
. (, https). content_security_policy
, :
{ ..., "content_security_policy": "script-src 'self' https://example.com; object-src 'self'", ... }
β eval?β β ?β
- eval? (, new Function()
). ( sandbox ).
, (, eval) ( CSP ).
postMessage()
.
underscore
sandboxed/template-renderer.html
template-renderer.html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Sandboxed Template Renderer</title> <script src="/js/libs/underscore/underscore-min.js"></script> </head> <body> <script> var templates = {}; window.addEventListener('message', function (event) { var template; if (typeof templates[event.data.templateName] == 'undefined') { template = _.template(event.data.template); templates[event.data.templateName] = template; } else { template = templates[event.data.templateName]; } event.source.postMessage({ id: event.data.id, result: template(event.data.context) }, event.origin); }); </script> </html>
html
{ ..., "sandbox": { "pages": ["sandboxed/template-renderer.html"] }, ... }
function getTemplate var getTemplate = (function(){ var iframe = document.createElement('iframe'), callbacks = []; iframe.src = 'sandboxed/template-renderer.html'; iframe.style.display = 'none'; document.body.appendChild(iframe); window.addEventListener('message', function (event) { callbacks.forEach(function (item, idx) { if (item && item.id == event.data.id) { item.callback(event.data.result); delete callbacks[idx]; } }); }); return function (templateName, template) { return function (context, callback) { var id = Math.random(); callbacks.push({ id: id, callback: callback }); iframe.contentWindow.postMessage({ id: id, templateName: templateName, template: template, context: context }, '*'); }; }; }());
// , var template = getTemplate('templateId', templateContent); // - template({text: 'Hello world'}, function (html) { // html // $('body').html , // $('body').html(html); });
- . (). .
, manifest.json
:
manifest.json { "name": "Twittext", "description": "A lightweight Google Chrome extension for Twitter", "background": { "page": "background.html" }, "manifest_version": 2, "browser_action": { "default_icon": "img/icon_19.png", "default_title": "Twittext", "default_popup": "popup.html" }, "icons": { "128": "img/icon_128.png", "19": "img/icon_19.png", "48": "img/icon_48.png" }, "options_page": "options.html", "version": "1.6.1", "permissions": [ "tabs", "background", "https://api.twitter.com/", "https://userstream.twitter.com/" ], "sandbox": { "pages": ["sandboxed/template-renderer.html"] } }
(). - setTimeout
setInterval
, .
, ( CDN, ), .
. (, https). content_security_policy
, :
{ ..., "content_security_policy": "script-src 'self' https://example.com; object-src 'self'", ... }
β eval?β β ?β
- eval? (, new Function()
). ( sandbox ).
, (, eval) ( CSP ).
postMessage()
.
underscore
sandboxed/template-renderer.html
template-renderer.html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Sandboxed Template Renderer</title> <script src="/js/libs/underscore/underscore-min.js"></script> </head> <body> <script> var templates = {}; window.addEventListener('message', function (event) { var template; if (typeof templates[event.data.templateName] == 'undefined') { template = _.template(event.data.template); templates[event.data.templateName] = template; } else { template = templates[event.data.templateName]; } event.source.postMessage({ id: event.data.id, result: template(event.data.context) }, event.origin); }); </script> </html>
html
{ ..., "sandbox": { "pages": ["sandboxed/template-renderer.html"] }, ... }
function getTemplate var getTemplate = (function(){ var iframe = document.createElement('iframe'), callbacks = []; iframe.src = 'sandboxed/template-renderer.html'; iframe.style.display = 'none'; document.body.appendChild(iframe); window.addEventListener('message', function (event) { callbacks.forEach(function (item, idx) { if (item && item.id == event.data.id) { item.callback(event.data.result); delete callbacks[idx]; } }); }); return function (templateName, template) { return function (context, callback) { var id = Math.random(); callbacks.push({ id: id, callback: callback }); iframe.contentWindow.postMessage({ id: id, templateName: templateName, template: template, context: context }, '*'); }; }; }());
// , var template = getTemplate('templateId', templateContent); // - template({text: 'Hello world'}, function (html) { // html // $('body').html , // $('body').html(html); });
- . (). .
, manifest.json
:
manifest.json { "name": "Twittext", "description": "A lightweight Google Chrome extension for Twitter", "background": { "page": "background.html" }, "manifest_version": 2, "browser_action": { "default_icon": "img/icon_19.png", "default_title": "Twittext", "default_popup": "popup.html" }, "icons": { "128": "img/icon_128.png", "19": "img/icon_19.png", "48": "img/icon_48.png" }, "options_page": "options.html", "version": "1.6.1", "permissions": [ "tabs", "background", "https://api.twitter.com/", "https://userstream.twitter.com/" ], "sandbox": { "pages": ["sandboxed/template-renderer.html"] } }
(). - setTimeout
setInterval
, .
, ( CDN, ), .
. (, https). content_security_policy
, :
{ ..., "content_security_policy": "script-src 'self' https://example.com; object-src 'self'", ... }
β eval?β β ?β
- eval? (, new Function()
). ( sandbox ).
, (, eval) ( CSP ).
postMessage()
.
underscore
sandboxed/template-renderer.html
template-renderer.html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Sandboxed Template Renderer</title> <script src="/js/libs/underscore/underscore-min.js"></script> </head> <body> <script> var templates = {}; window.addEventListener('message', function (event) { var template; if (typeof templates[event.data.templateName] == 'undefined') { template = _.template(event.data.template); templates[event.data.templateName] = template; } else { template = templates[event.data.templateName]; } event.source.postMessage({ id: event.data.id, result: template(event.data.context) }, event.origin); }); </script> </html>
html
{ ..., "sandbox": { "pages": ["sandboxed/template-renderer.html"] }, ... }
function getTemplate var getTemplate = (function(){ var iframe = document.createElement('iframe'), callbacks = []; iframe.src = 'sandboxed/template-renderer.html'; iframe.style.display = 'none'; document.body.appendChild(iframe); window.addEventListener('message', function (event) { callbacks.forEach(function (item, idx) { if (item && item.id == event.data.id) { item.callback(event.data.result); delete callbacks[idx]; } }); }); return function (templateName, template) { return function (context, callback) { var id = Math.random(); callbacks.push({ id: id, callback: callback }); iframe.contentWindow.postMessage({ id: id, templateName: templateName, template: template, context: context }, '*'); }; }; }());
// , var template = getTemplate('templateId', templateContent); // - template({text: 'Hello world'}, function (html) { // html // $('body').html , // $('body').html(html); });
- . (). .
, manifest.json
:
manifest.json { "name": "Twittext", "description": "A lightweight Google Chrome extension for Twitter", "background": { "page": "background.html" }, "manifest_version": 2, "browser_action": { "default_icon": "img/icon_19.png", "default_title": "Twittext", "default_popup": "popup.html" }, "icons": { "128": "img/icon_128.png", "19": "img/icon_19.png", "48": "img/icon_48.png" }, "options_page": "options.html", "version": "1.6.1", "permissions": [ "tabs", "background", "https://api.twitter.com/", "https://userstream.twitter.com/" ], "sandbox": { "pages": ["sandboxed/template-renderer.html"] } }
(). - setTimeout
setInterval
, .
, ( CDN, ), .
. (, https). content_security_policy
, :
{ ..., "content_security_policy": "script-src 'self' https://example.com; object-src 'self'", ... }
β eval?β β ?β
- eval? (, new Function()
). ( sandbox ).
, (, eval) ( CSP ).
postMessage()
.
underscore
sandboxed/template-renderer.html
template-renderer.html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Sandboxed Template Renderer</title> <script src="/js/libs/underscore/underscore-min.js"></script> </head> <body> <script> var templates = {}; window.addEventListener('message', function (event) { var template; if (typeof templates[event.data.templateName] == 'undefined') { template = _.template(event.data.template); templates[event.data.templateName] = template; } else { template = templates[event.data.templateName]; } event.source.postMessage({ id: event.data.id, result: template(event.data.context) }, event.origin); }); </script> </html>
html
{ ..., "sandbox": { "pages": ["sandboxed/template-renderer.html"] }, ... }
function getTemplate var getTemplate = (function(){ var iframe = document.createElement('iframe'), callbacks = []; iframe.src = 'sandboxed/template-renderer.html'; iframe.style.display = 'none'; document.body.appendChild(iframe); window.addEventListener('message', function (event) { callbacks.forEach(function (item, idx) { if (item && item.id == event.data.id) { item.callback(event.data.result); delete callbacks[idx]; } }); }); return function (templateName, template) { return function (context, callback) { var id = Math.random(); callbacks.push({ id: id, callback: callback }); iframe.contentWindow.postMessage({ id: id, templateName: templateName, template: template, context: context }, '*'); }; }; }());
// , var template = getTemplate('templateId', templateContent); // - template({text: 'Hello world'}, function (html) { // html // $('body').html , // $('body').html(html); });
- . (). .
, manifest.json
:
manifest.json { "name": "Twittext", "description": "A lightweight Google Chrome extension for Twitter", "background": { "page": "background.html" }, "manifest_version": 2, "browser_action": { "default_icon": "img/icon_19.png", "default_title": "Twittext", "default_popup": "popup.html" }, "icons": { "128": "img/icon_128.png", "19": "img/icon_19.png", "48": "img/icon_48.png" }, "options_page": "options.html", "version": "1.6.1", "permissions": [ "tabs", "background", "https://api.twitter.com/", "https://userstream.twitter.com/" ], "sandbox": { "pages": ["sandboxed/template-renderer.html"] } }
(). - setTimeout
setInterval
, .
, ( CDN, ), .
. (, https). content_security_policy
, :
{ ..., "content_security_policy": "script-src 'self' https://example.com; object-src 'self'", ... }
β eval?β β ?β
- eval? (, new Function()
). ( sandbox ).
, (, eval) ( CSP ).
postMessage()
.
underscore
sandboxed/template-renderer.html
template-renderer.html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Sandboxed Template Renderer</title> <script src="/js/libs/underscore/underscore-min.js"></script> </head> <body> <script> var templates = {}; window.addEventListener('message', function (event) { var template; if (typeof templates[event.data.templateName] == 'undefined') { template = _.template(event.data.template); templates[event.data.templateName] = template; } else { template = templates[event.data.templateName]; } event.source.postMessage({ id: event.data.id, result: template(event.data.context) }, event.origin); }); </script> </html>
html
{ ..., "sandbox": { "pages": ["sandboxed/template-renderer.html"] }, ... }
function getTemplate var getTemplate = (function(){ var iframe = document.createElement('iframe'), callbacks = []; iframe.src = 'sandboxed/template-renderer.html'; iframe.style.display = 'none'; document.body.appendChild(iframe); window.addEventListener('message', function (event) { callbacks.forEach(function (item, idx) { if (item && item.id == event.data.id) { item.callback(event.data.result); delete callbacks[idx]; } }); }); return function (templateName, template) { return function (context, callback) { var id = Math.random(); callbacks.push({ id: id, callback: callback }); iframe.contentWindow.postMessage({ id: id, templateName: templateName, template: template, context: context }, '*'); }; }; }());
// , var template = getTemplate('templateId', templateContent); // - template({text: 'Hello world'}, function (html) { // html // $('body').html , // $('body').html(html); });
- . (). .
, manifest.json
:
manifest.json { "name": "Twittext", "description": "A lightweight Google Chrome extension for Twitter", "background": { "page": "background.html" }, "manifest_version": 2, "browser_action": { "default_icon": "img/icon_19.png", "default_title": "Twittext", "default_popup": "popup.html" }, "icons": { "128": "img/icon_128.png", "19": "img/icon_19.png", "48": "img/icon_48.png" }, "options_page": "options.html", "version": "1.6.1", "permissions": [ "tabs", "background", "https://api.twitter.com/", "https://userstream.twitter.com/" ], "sandbox": { "pages": ["sandboxed/template-renderer.html"] } }
(). - setTimeout
setInterval
, .
, ( CDN, ), .
. (, https). content_security_policy
, :
{ ..., "content_security_policy": "script-src 'self' https://example.com; object-src 'self'", ... }
β eval?β β ?β
- eval? (, new Function()
). ( sandbox ).
, (, eval) ( CSP ).
postMessage()
.
underscore
sandboxed/template-renderer.html
template-renderer.html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Sandboxed Template Renderer</title> <script src="/js/libs/underscore/underscore-min.js"></script> </head> <body> <script> var templates = {}; window.addEventListener('message', function (event) { var template; if (typeof templates[event.data.templateName] == 'undefined') { template = _.template(event.data.template); templates[event.data.templateName] = template; } else { template = templates[event.data.templateName]; } event.source.postMessage({ id: event.data.id, result: template(event.data.context) }, event.origin); }); </script> </html>
html
{ ..., "sandbox": { "pages": ["sandboxed/template-renderer.html"] }, ... }
function getTemplate var getTemplate = (function(){ var iframe = document.createElement('iframe'), callbacks = []; iframe.src = 'sandboxed/template-renderer.html'; iframe.style.display = 'none'; document.body.appendChild(iframe); window.addEventListener('message', function (event) { callbacks.forEach(function (item, idx) { if (item && item.id == event.data.id) { item.callback(event.data.result); delete callbacks[idx]; } }); }); return function (templateName, template) { return function (context, callback) { var id = Math.random(); callbacks.push({ id: id, callback: callback }); iframe.contentWindow.postMessage({ id: id, templateName: templateName, template: template, context: context }, '*'); }; }; }());
// , var template = getTemplate('templateId', templateContent); // - template({text: 'Hello world'}, function (html) { // html // $('body').html , // $('body').html(html); });
- . (). .
, manifest.json
:
manifest.json { "name": "Twittext", "description": "A lightweight Google Chrome extension for Twitter", "background": { "page": "background.html" }, "manifest_version": 2, "browser_action": { "default_icon": "img/icon_19.png", "default_title": "Twittext", "default_popup": "popup.html" }, "icons": { "128": "img/icon_128.png", "19": "img/icon_19.png", "48": "img/icon_48.png" }, "options_page": "options.html", "version": "1.6.1", "permissions": [ "tabs", "background", "https://api.twitter.com/", "https://userstream.twitter.com/" ], "sandbox": { "pages": ["sandboxed/template-renderer.html"] } }
(). - setTimeout
setInterval
, .
, ( CDN, ), .
. (, https). content_security_policy
, :
{ ..., "content_security_policy": "script-src 'self' https://example.com; object-src 'self'", ... }
β eval?β β ?β
- eval? (, new Function()
). ( sandbox ).
, (, eval) ( CSP ).
postMessage()
.
underscore
sandboxed/template-renderer.html
template-renderer.html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Sandboxed Template Renderer</title> <script src="/js/libs/underscore/underscore-min.js"></script> </head> <body> <script> var templates = {}; window.addEventListener('message', function (event) { var template; if (typeof templates[event.data.templateName] == 'undefined') { template = _.template(event.data.template); templates[event.data.templateName] = template; } else { template = templates[event.data.templateName]; } event.source.postMessage({ id: event.data.id, result: template(event.data.context) }, event.origin); }); </script> </html>
html
{ ..., "sandbox": { "pages": ["sandboxed/template-renderer.html"] }, ... }
function getTemplate var getTemplate = (function(){ var iframe = document.createElement('iframe'), callbacks = []; iframe.src = 'sandboxed/template-renderer.html'; iframe.style.display = 'none'; document.body.appendChild(iframe); window.addEventListener('message', function (event) { callbacks.forEach(function (item, idx) { if (item && item.id == event.data.id) { item.callback(event.data.result); delete callbacks[idx]; } }); }); return function (templateName, template) { return function (context, callback) { var id = Math.random(); callbacks.push({ id: id, callback: callback }); iframe.contentWindow.postMessage({ id: id, templateName: templateName, template: template, context: context }, '*'); }; }; }());
// , var template = getTemplate('templateId', templateContent); // - template({text: 'Hello world'}, function (html) { // html // $('body').html , // $('body').html(html); });
- . (). .
, manifest.json
:
manifest.json { "name": "Twittext", "description": "A lightweight Google Chrome extension for Twitter", "background": { "page": "background.html" }, "manifest_version": 2, "browser_action": { "default_icon": "img/icon_19.png", "default_title": "Twittext", "default_popup": "popup.html" }, "icons": { "128": "img/icon_128.png", "19": "img/icon_19.png", "48": "img/icon_48.png" }, "options_page": "options.html", "version": "1.6.1", "permissions": [ "tabs", "background", "https://api.twitter.com/", "https://userstream.twitter.com/" ], "sandbox": { "pages": ["sandboxed/template-renderer.html"] } }
(). - setTimeout
setInterval
, .
, ( CDN, ), .
. (, https). content_security_policy
, :
{ ..., "content_security_policy": "script-src 'self' https://example.com; object-src 'self'", ... }
β eval?β β ?β
- eval? (, new Function()
). ( sandbox ).
, (, eval) ( CSP ).
postMessage()
.
underscore
sandboxed/template-renderer.html
template-renderer.html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Sandboxed Template Renderer</title> <script src="/js/libs/underscore/underscore-min.js"></script> </head> <body> <script> var templates = {}; window.addEventListener('message', function (event) { var template; if (typeof templates[event.data.templateName] == 'undefined') { template = _.template(event.data.template); templates[event.data.templateName] = template; } else { template = templates[event.data.templateName]; } event.source.postMessage({ id: event.data.id, result: template(event.data.context) }, event.origin); }); </script> </html>
html
{ ..., "sandbox": { "pages": ["sandboxed/template-renderer.html"] }, ... }
function getTemplate var getTemplate = (function(){ var iframe = document.createElement('iframe'), callbacks = []; iframe.src = 'sandboxed/template-renderer.html'; iframe.style.display = 'none'; document.body.appendChild(iframe); window.addEventListener('message', function (event) { callbacks.forEach(function (item, idx) { if (item && item.id == event.data.id) { item.callback(event.data.result); delete callbacks[idx]; } }); }); return function (templateName, template) { return function (context, callback) { var id = Math.random(); callbacks.push({ id: id, callback: callback }); iframe.contentWindow.postMessage({ id: id, templateName: templateName, template: template, context: context }, '*'); }; }; }());
// , var template = getTemplate('templateId', templateContent); // - template({text: 'Hello world'}, function (html) { // html // $('body').html , // $('body').html(html); });
- . (). .
, manifest.json
:
manifest.json { "name": "Twittext", "description": "A lightweight Google Chrome extension for Twitter", "background": { "page": "background.html" }, "manifest_version": 2, "browser_action": { "default_icon": "img/icon_19.png", "default_title": "Twittext", "default_popup": "popup.html" }, "icons": { "128": "img/icon_128.png", "19": "img/icon_19.png", "48": "img/icon_48.png" }, "options_page": "options.html", "version": "1.6.1", "permissions": [ "tabs", "background", "https://api.twitter.com/", "https://userstream.twitter.com/" ], "sandbox": { "pages": ["sandboxed/template-renderer.html"] } }
(). - setTimeout
setInterval
, .
, ( CDN, ), .
. (, https). content_security_policy
, :
{ ..., "content_security_policy": "script-src 'self' https://example.com; object-src 'self'", ... }
β eval?β β ?β
- eval? (, new Function()
). ( sandbox ).
, (, eval) ( CSP ).
postMessage()
.
underscore
sandboxed/template-renderer.html
template-renderer.html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Sandboxed Template Renderer</title> <script src="/js/libs/underscore/underscore-min.js"></script> </head> <body> <script> var templates = {}; window.addEventListener('message', function (event) { var template; if (typeof templates[event.data.templateName] == 'undefined') { template = _.template(event.data.template); templates[event.data.templateName] = template; } else { template = templates[event.data.templateName]; } event.source.postMessage({ id: event.data.id, result: template(event.data.context) }, event.origin); }); </script> </html>
html
{ ..., "sandbox": { "pages": ["sandboxed/template-renderer.html"] }, ... }
function getTemplate var getTemplate = (function(){ var iframe = document.createElement('iframe'), callbacks = []; iframe.src = 'sandboxed/template-renderer.html'; iframe.style.display = 'none'; document.body.appendChild(iframe); window.addEventListener('message', function (event) { callbacks.forEach(function (item, idx) { if (item && item.id == event.data.id) { item.callback(event.data.result); delete callbacks[idx]; } }); }); return function (templateName, template) { return function (context, callback) { var id = Math.random(); callbacks.push({ id: id, callback: callback }); iframe.contentWindow.postMessage({ id: id, templateName: templateName, template: template, context: context }, '*'); }; }; }());
// , var template = getTemplate('templateId', templateContent); // - template({text: 'Hello world'}, function (html) { // html // $('body').html , // $('body').html(html); });
- . (). .
, manifest.json
:
manifest.json { "name": "Twittext", "description": "A lightweight Google Chrome extension for Twitter", "background": { "page": "background.html" }, "manifest_version": 2, "browser_action": { "default_icon": "img/icon_19.png", "default_title": "Twittext", "default_popup": "popup.html" }, "icons": { "128": "img/icon_128.png", "19": "img/icon_19.png", "48": "img/icon_48.png" }, "options_page": "options.html", "version": "1.6.1", "permissions": [ "tabs", "background", "https://api.twitter.com/", "https://userstream.twitter.com/" ], "sandbox": { "pages": ["sandboxed/template-renderer.html"] } }
(). - setTimeout
setInterval
, .
, ( CDN, ), .
. (, https). content_security_policy
, :
{ ..., "content_security_policy": "script-src 'self' https://example.com; object-src 'self'", ... }
β eval?β β ?β
- eval? (, new Function()
). ( sandbox ).
, (, eval) ( CSP ).
postMessage()
.
underscore
sandboxed/template-renderer.html
template-renderer.html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Sandboxed Template Renderer</title> <script src="/js/libs/underscore/underscore-min.js"></script> </head> <body> <script> var templates = {}; window.addEventListener('message', function (event) { var template; if (typeof templates[event.data.templateName] == 'undefined') { template = _.template(event.data.template); templates[event.data.templateName] = template; } else { template = templates[event.data.templateName]; } event.source.postMessage({ id: event.data.id, result: template(event.data.context) }, event.origin); }); </script> </html>
html
{ ..., "sandbox": { "pages": ["sandboxed/template-renderer.html"] }, ... }
function getTemplate var getTemplate = (function(){ var iframe = document.createElement('iframe'), callbacks = []; iframe.src = 'sandboxed/template-renderer.html'; iframe.style.display = 'none'; document.body.appendChild(iframe); window.addEventListener('message', function (event) { callbacks.forEach(function (item, idx) { if (item && item.id == event.data.id) { item.callback(event.data.result); delete callbacks[idx]; } }); }); return function (templateName, template) { return function (context, callback) { var id = Math.random(); callbacks.push({ id: id, callback: callback }); iframe.contentWindow.postMessage({ id: id, templateName: templateName, template: template, context: context }, '*'); }; }; }());
// , var template = getTemplate('templateId', templateContent); // - template({text: 'Hello world'}, function (html) { // html // $('body').html , // $('body').html(html); });
- . (). .
, manifest.json
:
manifest.json { "name": "Twittext", "description": "A lightweight Google Chrome extension for Twitter", "background": { "page": "background.html" }, "manifest_version": 2, "browser_action": { "default_icon": "img/icon_19.png", "default_title": "Twittext", "default_popup": "popup.html" }, "icons": { "128": "img/icon_128.png", "19": "img/icon_19.png", "48": "img/icon_48.png" }, "options_page": "options.html", "version": "1.6.1", "permissions": [ "tabs", "background", "https://api.twitter.com/", "https://userstream.twitter.com/" ], "sandbox": { "pages": ["sandboxed/template-renderer.html"] } }
(). - setTimeout
setInterval
, .
, ( CDN, ), .
. (, https). content_security_policy
, :
{ ..., "content_security_policy": "script-src 'self' https://example.com; object-src 'self'", ... }
β eval?β β ?β
- eval? (, new Function()
). ( sandbox ).
, (, eval) ( CSP ).
postMessage()
.
underscore
sandboxed/template-renderer.html
template-renderer.html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Sandboxed Template Renderer</title> <script src="/js/libs/underscore/underscore-min.js"></script> </head> <body> <script> var templates = {}; window.addEventListener('message', function (event) { var template; if (typeof templates[event.data.templateName] == 'undefined') { template = _.template(event.data.template); templates[event.data.templateName] = template; } else { template = templates[event.data.templateName]; } event.source.postMessage({ id: event.data.id, result: template(event.data.context) }, event.origin); }); </script> </html>
html
{ ..., "sandbox": { "pages": ["sandboxed/template-renderer.html"] }, ... }
function getTemplate var getTemplate = (function(){ var iframe = document.createElement('iframe'), callbacks = []; iframe.src = 'sandboxed/template-renderer.html'; iframe.style.display = 'none'; document.body.appendChild(iframe); window.addEventListener('message', function (event) { callbacks.forEach(function (item, idx) { if (item && item.id == event.data.id) { item.callback(event.data.result); delete callbacks[idx]; } }); }); return function (templateName, template) { return function (context, callback) { var id = Math.random(); callbacks.push({ id: id, callback: callback }); iframe.contentWindow.postMessage({ id: id, templateName: templateName, template: template, context: context }, '*'); }; }; }());
// , var template = getTemplate('templateId', templateContent); // - template({text: 'Hello world'}, function (html) { // html // $('body').html , // $('body').html(html); });
- . (). .
, manifest.json
:
manifest.json { "name": "Twittext", "description": "A lightweight Google Chrome extension for Twitter", "background": { "page": "background.html" }, "manifest_version": 2, "browser_action": { "default_icon": "img/icon_19.png", "default_title": "Twittext", "default_popup": "popup.html" }, "icons": { "128": "img/icon_128.png", "19": "img/icon_19.png", "48": "img/icon_48.png" }, "options_page": "options.html", "version": "1.6.1", "permissions": [ "tabs", "background", "https://api.twitter.com/", "https://userstream.twitter.com/" ], "sandbox": { "pages": ["sandboxed/template-renderer.html"] } }
Source: https://habr.com/ru/post/149948/
All Articles