- Sphere Engine overview
- Compilers
- Overview
- API
- Widgets
- Resources
- Problems
- Overview
- API
- Widgets
- Handbook
- Resources
- Containers
- Overview
- Glossary
- API
- Workspaces
- Handbook
- Resources
- RESOURCES
- Programming languages
- Modules comparison
- Webhooks
- Infrastructure management
- API changelog
- FAQ
Before the widget can be integrated, it is necessary to create and configure it. Please follow this quickstart tutorial to create and configure your Sphere Engine Compilers Widget.
Important: To successfully integrate Sphere Engine Compilers Widget you need to have a working Sphere Engine account. Register for a Sphere Engine account by filling in the sign-up form.
Standalone page
To embed the widget on a separate website located in the sphere-engine.com domain use the feature of presenting it as a "standalone page".
A link to a standalone page is generated in the Sphere Engine client panel when creating the widget: Menu
> Compilers
> Widgets
> WIDGET HASH
> Widget integration
. It has the following structure:
https://compilers.widgets.sphere-engine.com/lp?hash=<hash>
JavaScript integration
When using this method, you need to insert two snippets of HTML code responsible for the initialization and display of the widget.
Initializing the widget
The code responsible for widget initialization should be inserted only
once (regardless of the number of widgets you want to display on the page), immediately after the <body>
element.
A customized and ready-to-use widget initialization code can be found in Sphere Engine client panel: Menu
> Compilers
> Widgets
> WIDGET HASH
> Widget integration
:
<script>SEC_HTTPS = true;
SEC_BASE = "compilers.widgets.sphere-engine.com";
(function(d, s, id){ SEC = window.SEC || (window.SEC = []);
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) return; js = d.createElement(s); js.id = id;
js.src = (SEC_HTTPS ? "https" : "http") + "://" + SEC_BASE + "/static/sdk/sdk.min.js";
fjs.parentNode.insertBefore(js, fjs);
}(document, "script", "sphere-engine-compilers-jssdk"));
SEC.ready = function(f) {
if (document.readyState != "loading" && document.readyState != "interactive") f();
else window.addEventListener("load", f);
};
</script>
Displaying the widget
The following code should be inserted on the page in the spot where you want the widget to be displayed:
<div class="sec-widget" data-widget="<hash>"></div>
The hash
parameter which is the value of the data-widget
attribute is the
unique ID of the widget in the Sphere Engine system. It can be found under the
Unique hash
field in Sphere Engine client panel: Menu
> Compilers
> Widgets
> WIDGET HASH
> Widget settings
.
Displaying multiple widgets
Sphere Engine Compilers Widget allows you to embed multiple widgets on a single page.
If you need to manipulate widget's behavior using JavaScript (see
JavaScript SDK) it is necessary to identify it, which is done by means of a special identifier (marked as <id>
) denoted by the data-id
attribute of the div
element used to embed the widget. For example:
<div id="idInHTML" data-id="<id>" class="sec-widget" data-widget="<hash>"></div>
Note: The widget is initialized automatically after the page loads in the browser, even if it is not yet visible on the page. This makes performing operations on the widget possible (e.g., configuration) before displaying it.
Note: The process of loading (and displaying) the widget begins only when the widget becomes visible on the screen (i.e., when the user scrolls the page to the widget's position). Thanks to this, the loading of other elements on the page is not blocked. This allows for the page to load faster, which is especially useful when embedding multiple widgets.
Custom data
Custom data enables adding custom data to the Compilers Widget, which will be returned by webhooks and JavaScript SDK callbacks. You can use custom data to e.g., identify the context in which a specific widget has been used inside your application and/or to identify the user.
The format of the data is free but it has to fit the space of 256
bytes. In case of using selected special characters
(i.e., "
or #
) or characters outside of the ASCII
standard, the number of bytes increases because of encoding them
inside a URL. When validating data, the system limits the final encoded value to the first 256
bytes.
Example of proper formatting
course_id={course_id};user_id={user_id};another_param={value}
To add custom data, please add the data-custom-data
attribute to the div
element used to
embed the widget together with your custom data.
<div class="sec-widget" data-widget="<hash>" data-custom-data="course_id={course_id};user_id={user_id};another_param={value}"></div>
Themes
Themes allow you to customize the look and feel of a widget. To manage the themes go to the Themes section in the Sphere Engine client panel.
The following table lists built-in themes that can be used with both the Sphere Engine Problems and the Sphere Engine Compilers widgets:
Name | Description |
---|---|
Light | The default theme |
Dark | A dark theme |
To set a theme for a widget, add the data-theme
attribute to the widget's div
element:
<div class="sec-widget" data-widget="<hash>" data-theme="dark"></div>
JavaScript SDK
The Sphere Engine JavaScript SDK library for Compilers widget (or simply JavaScript SDK) is loaded asynchronously. For this reason, before using the functions provided by the library, we must be sure that it has been initialized.
<script>SEC_HTTPS = true;
SEC_BASE = "compilers.widgets.sphere-engine.com ";
(function(d, s, id){ SEC = window.SEC || (window.SEC = []);
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) return; js = d.createElement(s); js.id = id;
js.src = (SEC_HTTPS ? "https" : "http") + "://" + SEC_BASE + "/static/sdk/sdk.min.js";
fjs.parentNode.insertBefore(js, fjs);
}(document, "script", "sphere-engine-compilers-jssdk"));
SEC.ready = function(f) {
if (document.readyState != "loading" && document.readyState != "interactive") f();
else window.addEventListener("load", f);
};
</script>
The above code include the SEC.ready()
function which ensures that features utilizing JavaScript SDK will be used only after all the required components have been loaded.
All operations that use JavaScript SDK should be performed through the SEC.ready()
function, i.e., according to the
following scheme:
<script>
SEC.ready(function() {
// Sphere Engine JavaScript SDK usage
});
</script>
Using the SEC.ready()
function ensures that the library has been loaded, the
SEC
object has been initialized and no errors will occur while scripts are
being executed.
Access
We gain access to the widget by using the SEC.widget()
function, which (basing
on the given widget ID, previously defined by the data-id
attribute) returns
the object of SECWidget
class used to manage the widget. For example:
<script>SEC.ready(function() {
var widget = SEC.widget("widget");
// variable "widget" is ready to use
});
</script>
The SECWidget
class provides the following options for managing the widget:
- creating a widget,
- dedicated events for handling actions performed by the widget.
Methods
The global SEC
object provides public methods for managing widgets.
An object of class SECWidget
, which represents the widget, is created.
Parameters
Name | Type | Description |
---|---|---|
id * | string | widget's identifier placed in the HTML document ( |
Returned value
An object of class SECWidget
is returned.
Example
<div data-id="example-widget" data-widget="{widget_hash}"></div>
<script>
SEC.ready(function() {
var btnLoadWidget = document.getElementById("btn-load-widget");
btnLoadWidget.addEventListener("click", function(e) {
e.preventDefault();
var SECWidget = SEC.widget("example-widget");
});
});
</script>
<a href="#" id="btn-load-widget" class="btn btn-default">Load widget</a>
Destroys the widget.
Example
<div data-id="example-widget" data-widget="{widget_hash}"></div>
<script>
SEC.ready(function() {
var btnDestroyWidget = document.getElementById("btn-destroy-widget");
btnDestroyWidget.addEventListener("click", function(e) {
e.preventDefault();
var SECWidget = SEC.widget("example-widget");
SECWidget.destroy();
});
});
</script>
<a href="#" id="btn-destroy-widget" class="btn btn-default">Destroy widget</a>
Setting the widget's configuration data.
Parameters
Name | Type | Description |
---|---|---|
config.code.compiler | integer | programming language identifier (see. list of languages) |
config.code.source | string | program's source code |
config.code.input | string | input data |
config.compilers.list | array[int] | list of language identifiers (see. list of languages) |
Example
<div data-id="example-widget" data-widget="{widget_hash}"></div>
<script>
SEC.ready(function() {
var SECWidget = SEC.widget("example-widget");
SECWidget.config({
code: {
compiler: 28,
source: "#!/bin/bash\n\necho test",
input: "",
},
compilers: {
list: [11, 21, 28, 33]
}
});
});
</script>
Loading data (source code, programming language, input data) to the running editor.
Parameters
Name | Type | Description |
---|---|---|
compiler | integer | programming language identifier (see. list of languages) |
sourceCode | string | program's source code |
input | string | input data |
Example
<div data-id="example-widget" data-widget="{widget_hash}"></div>
<script>
SEC.ready(function() {
var sourceCode = "<?php \n\n$hi = fopen('php://stdin', \"r\");\nfscanf($hi, \"%d\", $n);\n\
fclose($hi);\n\necho 'number: ' . $n;";
var SECWidget = SEC.widget("example-widget");
SECWidget.loadSourceCode(29, sourceCode, "5");
});
</script>
Loading programming language to the running editor.
Parameters
Name | Type | Description |
---|---|---|
compiler | integer | programming language identifier (see. list of languages) |
Example
<div data-id="example-widget" data-widget="{widget_hash}"></div>
<script>
SEC.ready(function() {
var SECWidget = SEC.widget("example-widget");
SECWidget.setCompiler(10);
});
</script>
Loading source to the running editor.
Parameters
Name | Type | Description |
---|---|---|
sourceCode | string | program's source code |
Example
<div data-id="example-widget" data-widget="{widget_hash}"></div>
<script>
SEC.ready(function() {
var sourceCode = "print(\"hello world\")";
var SECWidget = SEC.widget("example-widget");
SECWidget.setSource(sourceCode);
});
</script>
Loading input to the running editor.
Parameters
Name | Type | Description |
---|---|---|
input | string | input data |
Example
<div data-id="example-widget" data-widget="{widget_hash}"></div>
<script>
SEC.ready(function() {
var SECWidget = SEC.widget("example-widget");
SECWidget.setInput("1 2 3");
});
</script>
Selection of programming languages available in the widget.
Parameters
Name | Type | Description |
---|---|---|
compilersList | array[int] | list of language identifiers (see. list of languages) |
Example
<div data-id="example-widget" data-widget="{widget_hash}"></div>
<script>
SEC.ready(function() {
var SECWidget = SEC.widget("example-widget");
SECWidget.setCompilers([1,2]);
});
</script>
Enables the ability to run code in the running editor.
Example
<div data-id="example-widget" data-widget="{widget_hash}"></div>
<script>
SEC.ready(function() {
var SECWidget = SEC.widget("example-widget");
var btnEnableRun = document.getElementById("btn-enable-run-sec-widget");
btnEnableRun.addEventListener("click", function(e) {
SECWidget.enableRun();
});
});
</script>
<a id="btn-enable-run-sec-widget" class="btn btn-secondary my-2">Enable Run</a>
Blocks the ability to execute code in the running editor.
Example
<script>
SEC.ready(function() {
var SECWidget = SEC.widget("example-widget");
var btnDisableRun = document.getElementById("btn-disable-run-sec-widget");
var btnEnableRun = document.getElementById("btn-enable-run-sec-widget");
btnDisableRun.addEventListener("click", function() {
SECWidget.disableRun();
});
btnEnableRun.addEventListener("click", function() {
SECWidget.enableRun();
});
});
</script>
<button id="btn-disable-run-sec-widget" class="btn btn-secondary my-2">Disable Run</button>
<button id="btn-enable-run-sec-widget" class="btn btn-secondary my-2">Enable Run</button>
Assigns a function to the event (see list of events).
Parameters
Name | Type | Description |
---|---|---|
event * | string | the name of the event to assign a function to |
callback * | function | function to be called on an event |
Example
<div data-id="example-widget" data-widget="{widget_hash}"></div>
<script>
SEC.ready(function() {
var callback = function(data) {
// Your code goes here
};
var SECWidget = SEC.widget("example-widget");
SECWidget.events.subscribe('{name_of_the_event}', callback);
});
</script>
Removes a function from the list of functions assigned to the event (see list of events).
Parameters
Name | Type | Description |
---|---|---|
event * | string | the name of the event to remove the function from |
callback * | function | function to be removed from the list of functions assigned to the event |
Example
<div data-id="example-widget" data-widget="{widget_hash}"></div>
<script>
SEC.ready(function() {
var callback = function(data) {
// Your code goes here
};
var SECWidget = SEC.widget("example-widget");
SECWidget.events.unsubscribe('{name_of_the_event}', callback);
});
</script>
Events
An object of the SECWidget
class has a collection of dedicated events called at specific moments of the widget's operation.
The event is invoked before sending a submission to the Sphere Engine system
(i.e. after pressing the Submit
button but before actually sending
the submission).
Data sent to the callback function
An object with the following fields is sent to the callback function
Name | Type | Description |
---|---|---|
|
string | the source code of the program sent in the submission |
|
string | the identifier of the programming language used to write the program |
|
string | input data sent in the submission |
|
string | your custom data added when initializing the widget, see custom data |
The value returned by the callback function
The value returned by the callback function allows modifying the submission data before it's sent to the Sphere Engine servers. It also allows canceling the submission altogether.
To modify the submission data before it's sent to the Sphere Engine servers, return an object with the following fields:
Name | Type | Description |
---|---|---|
submissionSource | string | the source code of the program |
submissionLanguage | integer | programming language identifier |
submissionInput | string | input data |
customData | string | custom data |
To leave the submission data unaltered, skip chosen fields in the object.
You can also return a boolean value instead of the object to determine whether the submission should be sent or not.
- true - the submission will continue,
- false - the submission will be cancelled.
Note: If the callback function returns an object, the submission will always continue.
Example
Submit submission to see the result
<div data-id="example-widget" data-widget="{widget_hash}" data-custom-data="course-id=1"></div>
<script>
SEC.ready(function() {
var beforeSendSubmission = function(data) {
var resultElement = document.getElementById('result');
if (resultElement) {
resultElement.innerHTML = '';
resultElement.innerHTML += '> submissionLanguage: ' + data.submissionLanguage + '<br><br>';
resultElement.innerHTML += '> submissionInput: <br>' + data.submissionInput + '<br><br>';
resultElement.innerHTML += '> submissionSource: <br>' + data.submissionSource + '<br><br>';
resultElement.innerHTML += '> customData: <br>' + data.customData + '<br><br>';
}
return {
customData: data.customData + ';timestamp=' + Math.floor(Date.now() / 1000), // is optional
// submissionSource: 'print(\'1 2 3\')', // is optional
// submissionInput: '1 2 3', // is optional
// submissionLanguage: 116, // is optional
};
// or just
// return true;
};
var SECWidget = SEC.widget('example-widget');
SECWidget.events.subscribe('beforeSendSubmission', beforeSendSubmission);
});
</script>
Data:
<pre id="result" style="height: 300px;">Submit submission to see the result</pre>
The event is invoked immediately after the submission has been sent to the Sphere Engine system.
Data sent to the callback function
An object with the following fields is sent to the callback function
Name | Type | Description |
---|---|---|
|
integer | submission identifier in the Sphere Engine system |
|
integer | submission identifier in the Sphere Engine system used to access submission using API; use getSubmission() API method to fetch all submission details |
|
string | your custom data added when initializing the widget, see custom data |
Example
Submit submission to see the result
<div data-id="example-widget" data-widget="{widget_hash}"></div>
<script>
SEC.ready(function() {
var afterSendSubmission = function(data) {
var resultElement = document.getElementById('result');
resultElement.innerHTML =
"> submissionId: " + data.submissionId + "<br>" +
"> apiSubmissionId: " + data.apiSubmissionId + "<br><br>";
};
var SECWidget = SEC.widget("example-widget");
SECWidget.events.subscribe('afterSendSubmission', afterSendSubmission);
});
</script>
Data:
<pre id="result" style="height: 100px;">Submit submission to see the result</pre>
The event is invoked repeatedly every time the JavaScript SDK library checks the status of the submission while it’s being executed.
Data sent to the callback function
An object with the following fields is sent to the callback function
Name | Type | Description |
---|---|---|
|
integer | submission identifier in the Sphere Engine system |
|
integer | submission identifier in the Sphere Engine system used to access submission using API; use getSubmission() API method to fetch all submission details |
|
integer | execution time in seconds (available after execution) |
|
integer | memory consumption in kilobytes (available after execution) |
|
integer | numeric value of the submission's status (see: list of statuses) |
|
string | description of the submission's status |
|
string | your custom data added when initializing the widget, see custom data |
Example
Submit submission to see the result
<div data-id="example-widget" data-widget="{widget_hash}"></div>
<script>
SEC.ready(function() {
var checkStatus = function(data) {
var resultElement = document.getElementById('result');
resultElement.innerHTML += "<br><br>";
resultElement.innerHTML += "> submissionId: " + data.submissionId + "<br>";
resultElement.innerHTML += "> apiSubmissionId: " + data.apiSubmissionId + "<br>";
resultElement.innerHTML += "> statusNumber: " + data.statusNumber + "<br>";
resultElement.innerHTML += "> statusDescription: " + data.statusDescription + "<br>";
resultElement.innerHTML += "> submissionMemory: " + data.submissionMemory + "<br>";
resultElement.innerHTML += "> submissionTime: " + data.submissionTime + "<br>";
resultElement.scrollTop = resultElement.scrollHeight;
};
var SECWidget = SEC.widget("example-widget");
SECWidget.events.subscribe('checkStatus', checkStatus);
});
</script>
Data:
<pre id="result" style="height: 300px;">Submit submission to see the result</pre>
The event is invoked when the programming language changes.
Data sent to the callback function
An object with the following fields is sent to the callback function
Name | Type | Description |
---|---|---|
|
integer | the identifier of the programming language |
Example
<div data-id="example-widget" data-widget="{widget_hash}"></div>
<script>
SEC.ready(function() {
var languageChanged = function(data) {
var result = document.getElementById('result');
result.innerHTML += '> language: ' + data.language + '<br />';
};
var SECWidget = SEC.widget('example-widget');
SECWidget.events.subscribe('languageChanged', languageChanged);
});
</script>
Data:
<pre id="result" style="height: 100px;"></pre>
The event is invoked when the widget is switched to a full-screen mode.
Example
<div data-id="example-widget" data-widget="{widget_hash}"></div>
<script>
SEC.ready(function() {
var enterFullScreen = function() {
alert('enter fullscreen');
};
var SECWidget = SEC.widget("example-widget");
SECWidget.events.subscribe('enterFullScreen', enterFullScreen);
});
</script>
The event is invoked when the widget exits a full-screen mode.
Example
<div data-id="example-widget" data-widget="{widget_hash}"></div>
<script>
SEC.ready(function() {
var exitFullScreen = function() {
alert('exit fullscreen');
};
var SECWidget = SEC.widget("example-widget");
SECWidget.events.subscribe('exitFullScreen', exitFullScreen);
});
</script>
The event is invoked when the source changes.
Example
<div data-id="example-widget" data-widget="{widget_hash}"></div>
<script>
SEC.ready(function() {
var callback = function() {
// Your code goes here
};
var SECWidget = SEC.widget("example-widget");
SECWidget.events.subscribe('sourceChanged', callback);
});
</script>
The event is invoked when the input code changes in "input" tab.
Example
<div data-id="example-widget" data-widget="{widget_hash}"></div>
<script>
SEC.ready(function() {
var callback = function() {
// Your code goes here
};
var SECWidget = SEC.widget("example-widget");
SECWidget.events.subscribe('inputChanged', callback);
});
</script>