1
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
2
|
|
3
|
"""
|
4
|
Making temporary WebExtensions for use in the test suite
|
5
|
"""
|
6
|
|
7
|
# This file is part of Haketilo.
|
8
|
#
|
9
|
# Copyright (C) 2021 Wojtek Kosior <koszko@koszko.org>
|
10
|
#
|
11
|
# This program is free software: you can redistribute it and/or modify
|
12
|
# it under the terms of the GNU General Public License as published by
|
13
|
# the Free Software Foundation, either version 3 of the License, or
|
14
|
# (at your option) any later version.
|
15
|
#
|
16
|
# This program is distributed in the hope that it will be useful,
|
17
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
18
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
19
|
# GNU General Public License for more details.
|
20
|
#
|
21
|
# You should have received a copy of the GNU General Public License
|
22
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
23
|
#
|
24
|
# I, Wojtek Kosior, thereby promise not to sue for violation of this file's
|
25
|
# license. Although I request that you do not make use this code in a
|
26
|
# proprietary program, I am not going to enforce this in court.
|
27
|
|
28
|
import json
|
29
|
import zipfile
|
30
|
from pathlib import Path
|
31
|
from uuid import uuid4
|
32
|
|
33
|
from .misc_constants import *
|
34
|
|
35
|
class ManifestTemplateValueToFill:
|
36
|
pass
|
37
|
|
38
|
def manifest_template():
|
39
|
return {
|
40
|
'manifest_version': 2,
|
41
|
'name': 'Haketilo test extension',
|
42
|
'version': '1.0',
|
43
|
'applications': {
|
44
|
'gecko': {
|
45
|
'id': ManifestTemplateValueToFill(),
|
46
|
'strict_min_version': '60.0'
|
47
|
}
|
48
|
},
|
49
|
'permissions': [
|
50
|
'contextMenus',
|
51
|
'webRequest',
|
52
|
'webRequestBlocking',
|
53
|
'activeTab',
|
54
|
'notifications',
|
55
|
'sessions',
|
56
|
'storage',
|
57
|
'tabs',
|
58
|
'<all_urls>',
|
59
|
'unlimitedStorage'
|
60
|
],
|
61
|
'web_accessible_resources': ['testpage.html'],
|
62
|
'background': {
|
63
|
'persistent': True,
|
64
|
'scripts': ['__open_test_page.js', 'background.js']
|
65
|
},
|
66
|
'content_scripts': [
|
67
|
{
|
68
|
'run_at': 'document_start',
|
69
|
'matches': ['<all_urls>'],
|
70
|
'match_about_blank': True,
|
71
|
'all_frames': True,
|
72
|
'js': ['content.js']
|
73
|
}
|
74
|
]
|
75
|
}
|
76
|
|
77
|
default_background_script = ''
|
78
|
default_content_script = ''
|
79
|
default_test_page = '''
|
80
|
<!DOCTYPE html>
|
81
|
<html>
|
82
|
<head>
|
83
|
<title>Extension's options page for testing</title>
|
84
|
</head>
|
85
|
<body>
|
86
|
<h1>Extension's options page for testing</h1>
|
87
|
</body>
|
88
|
</html>
|
89
|
'''
|
90
|
|
91
|
open_test_page_script = '''(() => {
|
92
|
const page_url = browser.runtime.getURL("testpage.html");
|
93
|
const execute_details = {
|
94
|
code: `window.location.href=${JSON.stringify(page_url)};`
|
95
|
};
|
96
|
browser.tabs.query({currentWindow: true, active: true})
|
97
|
.then(t => browser.tabs.executeScript(t.id, execute_details));
|
98
|
})();'''
|
99
|
|
100
|
def make_extension(destination_dir,
|
101
|
background_script=default_background_script,
|
102
|
content_script=default_content_script,
|
103
|
test_page=default_test_page,
|
104
|
extra_files={}):
|
105
|
manifest = manifest_template()
|
106
|
extension_id = '{%s}' % uuid4()
|
107
|
manifest['applications']['gecko']['id'] = extension_id
|
108
|
files = {
|
109
|
'manifest.json' : json.dumps(manifest),
|
110
|
'__open_test_page.js': open_test_page_script,
|
111
|
'background.js' : background_script,
|
112
|
'content.js' : content_script,
|
113
|
'testpage.html' : test_page,
|
114
|
**extra_files
|
115
|
}
|
116
|
destination_path = destination_dir / f'{extension_id}.xpi'
|
117
|
with zipfile.ZipFile(destination_path, 'x') as xpi:
|
118
|
for filename, contents in files.items():
|
119
|
xpi.writestr(filename, contents)
|
120
|
|
121
|
return destination_path
|