|
|
@@ -2,59 +2,153 @@
|
|
|
import editor from "./editor/editor";
|
|
|
import * as editorConfig from "./editor/editorConfig";
|
|
|
|
|
|
-export function saveCode() {
|
|
|
+/**
|
|
|
+ * Port to attach Chrome Dev Tools to
|
|
|
+ * @type {Number}
|
|
|
+ */
|
|
|
+const DEBUG_PORT = 3335;
|
|
|
|
|
|
- const data = {
|
|
|
- message: "saveCode",
|
|
|
- payload: editor.session.getValue()
|
|
|
- };
|
|
|
+/**
|
|
|
+ * Display "Attach dev tools now" alert on startup if this is set to true
|
|
|
+ * @type {Boolean}
|
|
|
+ */
|
|
|
+const DEBUG_ALERT = false;
|
|
|
|
|
|
- window.atomicQuery({
|
|
|
- request: JSON.stringify(data),
|
|
|
- persistent: false,
|
|
|
- onSuccess: function(response) {/**/ },
|
|
|
- onFailure: function(error_code, error_message) {
|
|
|
- console.log("Error getting code");
|
|
|
- }
|
|
|
- });
|
|
|
-}
|
|
|
+/**
|
|
|
+ * Promise version of atomic query
|
|
|
+ * @param {string} message the query to use to pass to atomicQuery. If there is no payload, this will be passed directly, otherwise it will be passed in a data object
|
|
|
+ * @param {any} payload optional data to send
|
|
|
+ * @return {Promise}
|
|
|
+ */
|
|
|
+function atomicQueryPromise(message: any): Promise<{}> {
|
|
|
+ return new Promise(function(resolve, reject) {
|
|
|
+ let queryMessage = message;
|
|
|
+
|
|
|
+ // if message is coming in as an object then let's stringify it
|
|
|
+ if (typeof (message) != "string") {
|
|
|
+ queryMessage = JSON.stringify(message);
|
|
|
+ }
|
|
|
|
|
|
-export function codeLoaded(value: string, fileExt: string) {
|
|
|
- editor.session.setValue(value);
|
|
|
- editor.gotoLine(0);
|
|
|
-
|
|
|
- editor.getSession().on("change", function(e) {
|
|
|
- window.atomicQuery({
|
|
|
- request: "change",
|
|
|
- persistent: false,
|
|
|
- onSuccess: (response) => {/**/ },
|
|
|
- onFailure: (error_code, error_message) => {
|
|
|
- console.log("Error on change");
|
|
|
- }
|
|
|
+ window.atomicQuery({
|
|
|
+ request: queryMessage,
|
|
|
+ persistent: false,
|
|
|
+ onSuccess: resolve,
|
|
|
+ onFailure: (error_code, error_message) => reject({ error_code: error_code, error_message: error_message })
|
|
|
+ });
|
|
|
});
|
|
|
- });
|
|
|
}
|
|
|
|
|
|
-export function loadCode(codeUrl: string) {
|
|
|
- const fileExt = codeUrl.split(".").pop();
|
|
|
-
|
|
|
- // go ahead and set the theme prior to pulling the file across
|
|
|
- editorConfig.configure(fileExt);
|
|
|
-
|
|
|
- const p = new Promise(function(resolve, reject) {
|
|
|
- const xmlHttp = new XMLHttpRequest();
|
|
|
- xmlHttp.onreadystatechange = () => {
|
|
|
- if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {
|
|
|
- resolve(xmlHttp.responseText);
|
|
|
- }
|
|
|
- };
|
|
|
- xmlHttp.open("GET", codeUrl, true); // true for asynchronous
|
|
|
- xmlHttp.send(null);
|
|
|
- }).then(function(src: string) {
|
|
|
- codeLoaded(src, fileExt);
|
|
|
- });
|
|
|
+export default class HostInteropType {
|
|
|
+ static EDITOR_SAVE_CODE = "editorSaveCode";
|
|
|
+ static EDITOR_SAVE_FILE = "editorSaveFile";
|
|
|
+ static EDITOR_LOAD_COMPLETE = "editorLoadComplete";
|
|
|
+ static EDITOR_CHANGE = "editorChange";
|
|
|
+
|
|
|
+ private static _inst: HostInteropType = null;
|
|
|
+ static getInstance(): HostInteropType {
|
|
|
+ if (HostInteropType._inst == null) {
|
|
|
+ HostInteropType._inst = new HostInteropType();
|
|
|
+ }
|
|
|
+ return HostInteropType._inst;
|
|
|
+ }
|
|
|
+
|
|
|
+ constructor() {
|
|
|
+ // Set up the window object so the host can call into it
|
|
|
+ window.HOST_loadCode = this.loadCode.bind(this);
|
|
|
+ window.HOST_saveCode = this.saveCode.bind(this);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Called from the host to notify the client what file to load
|
|
|
+ * @param {string} codeUrl
|
|
|
+ */
|
|
|
+ loadCode(codeUrl: string) {
|
|
|
+ console.log("Load Code called for :" + codeUrl);
|
|
|
+ const fileExt = codeUrl.split(".").pop();
|
|
|
+ const filename = codeUrl.replace("atomic://", "");
|
|
|
+
|
|
|
+ // go ahead and set the theme prior to pulling the file across
|
|
|
+ editorConfig.configure(fileExt, filename);
|
|
|
+
|
|
|
+ // get the code
|
|
|
+ this.getResource(codeUrl).then((src: string) => {
|
|
|
+ editorConfig.loadCodeIntoEditor(src, filename, fileExt);
|
|
|
+ }).catch((e: Editor.ClientExtensions.AtomicErrorMessage) => {
|
|
|
+ console.log("Error loading code: " + e.error_message);
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Save the contents of the editor
|
|
|
+ * @return {Promise}
|
|
|
+ */
|
|
|
+ saveCode(): Promise<{}> {
|
|
|
+ return atomicQueryPromise({
|
|
|
+ message: HostInteropType.EDITOR_SAVE_CODE,
|
|
|
+ payload: editor.session.getValue()
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Save the contents of a file as filename
|
|
|
+ * @param {string} filename
|
|
|
+ * @param {string} fileContents
|
|
|
+ * @return {Promise}
|
|
|
+ */
|
|
|
+ saveFile(filename: string, fileContents: string): Promise<{}> {
|
|
|
+ return atomicQueryPromise({
|
|
|
+ message: HostInteropType.EDITOR_SAVE_FILE,
|
|
|
+ filename: filename,
|
|
|
+ payload: fileContents
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Call this function when the client is fully loaded up. This will notify the host that
|
|
|
+ * it can start loading code
|
|
|
+ */
|
|
|
+ editorLoaded() {
|
|
|
+ if (DEBUG_ALERT) {
|
|
|
+ alert(`Attach chrome dev tools to this instance by navigating to http://localhost:${DEBUG_PORT}`);
|
|
|
+ }
|
|
|
+ atomicQueryPromise(HostInteropType.EDITOR_LOAD_COMPLETE);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Queries the host for a particular resource and returns it in a promise
|
|
|
+ * @param {string} codeUrl
|
|
|
+ * @return {Promise}
|
|
|
+ */
|
|
|
+ getResource(codeUrl: string): Promise<{}> {
|
|
|
+ return new Promise(function(resolve, reject) {
|
|
|
+ const xmlHttp = new XMLHttpRequest();
|
|
|
+ xmlHttp.onreadystatechange = () => {
|
|
|
+ if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {
|
|
|
+ resolve(xmlHttp.responseText);
|
|
|
+ }
|
|
|
+ };
|
|
|
+ xmlHttp.open("GET", codeUrl, true); // true for asynchronous
|
|
|
+ xmlHttp.send(null);
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Returns a file resource from the resources directory
|
|
|
+ * @param {string} filename name and path of file under the project directory or a fully qualified file name
|
|
|
+ * @return {Promise}
|
|
|
+ */
|
|
|
+ getFileResource(filename: string): Promise<{}> {
|
|
|
+ return this.getResource(`atomic://${filename}`);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Notify the host that the contents of the editor has changed
|
|
|
+ */
|
|
|
+ notifyEditorChange() {
|
|
|
+ atomicQueryPromise(HostInteropType.EDITOR_CHANGE).catch((e: Editor.ClientExtensions.AtomicErrorMessage) => {
|
|
|
+ console.log("Error on change: " + e.error_message);
|
|
|
+ });
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
-// Set up the window object so the host can call into it
|
|
|
-window.loadCode = loadCode;
|
|
|
-window.saveCode = saveCode;
|
|
|
+HostInteropType.getInstance().editorLoaded();
|