Editor extension URLs must now be registered in targetconfig.json
under packages.approvedEditorExtensionUrls
:
{
...
packages: {
...
approvedEditorExtensionUrls: [
"url to extension"
]
}
}
An editor extension may have an associated editor extension hosted in the Github Pages section of the repo.
The editor extension is configured in the pxt.json file by adding an extension
field:
{
...
extension: {
url: "url to extension"
}
}
The editor will automatically add an “Editor” button for the editor extension in the extensions category.
To debug a local extension, from the local dev server, add localeditorextensions=1
to the url
and add the a localUrl
field.
Urls must be registered in the targetconfig.json
package
configuration section under packages.approvedEditorExtensions
.
The editor and the editor extension <iframe> communicate using a protocol of IFrame messages.
id
to correlate responses to requests.response
message can be requested. The id
identifer can be used to correlate a receive response to the original query.extId
. This identifier is passed when loading the <iframe> (see Initialization).// sending message
var msg = {
id: Math.random().toString(),
type: "pxtpkgext",
action: "extinit",
extId: extId,
response: true
}
window.parent.postMessage(msg, "*");
// handle the response
function receivedResponse(resp) {
if (resp.action === "extinit")
console.log('initialized!')
}
window.addEventListener("message", function(ev) {
var resp = ev.data;
if (resp && resp.type === "pxtpkgext")
receivedResponse(resp);
}, false);
When the user presses the editor extension button:
extinit
message to the parent window.var msg = {
id: Math.random().toString(),
type: "pxtpkgext",
action: "extinit",
extId: extId
}
...
The editor sends a extshown
message when showing the editor frame, and a exthidden
message after hiding the editor.
The editor extension can read (extreadcode
) and write (extwritecode
) a dedicated TypeScript and JSON file in the project. The JSON file is designed to store rich metadata while the TypeScript is the “code behind” that gets executed. This feature does not require permissions.
var msg = {
id: Math.random().toString(),
type: "pxtpkgext",
action: "extwritecode",
extId: extId,
body: {
code: "// generated TypeScript code",
json: "serialized JSON here"
}
}
...
var id = Math.random().toString();
var msg = {
id: id,
type: "pxtpkgext",
action: "extreadcode",
extId: extId,
response: true
}
...
function receivedResponse(resp) {
if (resp.action === "extreadcode" && resp.id === id && resp.body) {
var ts = resp.body.code;
var json = JSON.parse(resp.body.json);
...
}
}
...
The extusercode
message requests to read the entire set of files in the project. If successfull, the response contains a resp
field with a map of the file names to file contents.
export interface UserCodeResponse extends ExtensionResponse {
/* A mapping of file names to their contents */
resp?: { [index: string]: string };
}
When available, the editor may stream data coming from the devices. The extdatastream
message requests to stream data. The following message sets a request for serial messages:
var msg {
...
action: "extdatastream",
body: {
serial: true
}
}
...
If successful, the editor will proxy serial messages to the editor <iframe>.