Skip to content
This repository was archived by the owner on Mar 5, 2021. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions plugins/default/typescript/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
**/node_modules
6 changes: 6 additions & 0 deletions plugins/default/typescript/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# supWeb-typescript
A typescript plugin for superpowers web system

Github of superpowers web system: https://github.com/superpowers/superpowers-web

Github of superpowers: https://github.com/superpowers
160 changes: 160 additions & 0 deletions plugins/default/typescript/data/TypescriptAsset.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
/// <reference path="../../../common/textEditorWidget/operational-transform.d.ts" />

import * as OT from "operational-transform";
import * as mkdirp from "mkdirp";
import * as dummy_fs from "fs";
import * as dummy_path from "path";
import * as ts from "typescript";
import * as browserify from "browserify";

// Since we're doing weird things to the fs module,
// the code won't browserify properly with brfs
// so we'll only require them on the server-side
let serverRequire = require;

let fs: typeof dummy_fs;
let path: typeof dummy_path;
if ((<any>global).window == null) {
fs = serverRequire("fs");
path = serverRequire("path");
}

interface TypescriptAssetPub {
text: string;
draft: string;
revisionId: number;
}

export default class TypescriptAsset extends SupCore.Data.Base.Asset {
static schema: SupCore.Data.Base.Schema = {
text: { type: "string" },
draft: { type: "string" },
revisionId: { type: "integer" }
};

pub: TypescriptAssetPub;
document: OT.Document;
hasDraft: boolean;

constructor(id: string, pub: TypescriptAssetPub, server: ProjectServer) {
super(id, pub, TypescriptAsset.schema, server);
}

init(options: any, callback: Function) {
this.pub = {
text: "",
draft: "",
revisionId: 0
};

super.init(options, callback);
}

setup() {
this.document = new OT.Document(this.pub.draft, this.pub.revisionId);
this.hasDraft = this.pub.text !== this.pub.draft;
}

restore() {
if (this.hasDraft) this.emit("setBadge", "draft", "info");
}

load(assetPath: string) {
let pub: TypescriptAssetPub;
fs.readFile(path.join(assetPath, "data.ts"), { encoding: "utf8" }, (err, text) => {
fs.readFile(path.join(assetPath, "draft.ts"), { encoding: "utf8" }, (err, draft) => {
pub = { revisionId: 0, text, draft: (draft != null) ? draft : text };
this._onLoaded(assetPath, pub);
});
});
}

save(assetPath: string, callback: (err: Error) => any) {
fs.writeFile(path.join(assetPath, "data.ts"), this.pub.text, { encoding: "utf8" }, (err) => {
if (err != null) { callback(err); return; }

if (this.hasDraft) {
fs.writeFile(path.join(assetPath, "draft.ts"), this.pub.draft, { encoding: "utf8" }, callback);
} else {
fs.unlink(path.join(assetPath, "draft.ts"), (err) => {
if (err != null && err.code !== "ENOENT") { callback(err); return; }
callback(null);
});
}
});
}

publish(buildPath: string, callback: (err: Error) => any) {
let pathFromId = this.server.data.entries.getPathFromId(this.id);
//if (pathFromId.lastIndexOf(".ts") === pathFromId.length - 5) pathFromId = pathFromId.slice(0, -5);
let outputPath = `${buildPath}/assets/${pathFromId}.js`;
let parentPath = outputPath.slice(0, outputPath.lastIndexOf("/"));

let code = this.pub.text;
let text = ts.transpile(code);
if(text.indexOf("/// browserify") > -1) {
mkdirp(parentPath, () => { fs.writeFile(outputPath, text,
() => {
var browserify = require('browserify');
var b = browserify();
b.add(`${buildPath}/assets/${pathFromId}.js`);
b.bundle((err: any, data: any) => {
var StringDecoder = require('string_decoder').StringDecoder;
var decoder = new StringDecoder('utf8');

text = decoder.write(data);

mkdirp(parentPath, function () { fs.writeFile(outputPath, text, callback); });
});
});
});
} else {
mkdirp(parentPath, function () { fs.writeFile(outputPath, text, callback); });
}

}

server_editText(client: any, operationData: OperationData, revisionIndex: number, callback: (err: string, operationData?: any, revisionIndex?: number) => any) {
if (operationData.userId !== client.id) { callback("Invalid client id"); return; }

let operation = new OT.TextOperation();
if (!operation.deserialize(operationData)) { callback("Invalid operation data"); return; }

try { operation = this.document.apply(operation, revisionIndex); }
catch (err) { callback("Operation can't be applied"); return; }

this.pub.draft = this.document.text;
this.pub.revisionId++;

callback(null, operation.serialize(), this.document.getRevisionId() - 1);

if (!this.hasDraft) {
this.hasDraft = true;
this.emit("setBadge", "draft", "info");
}
this.emit("change");
}

client_editText(operationData: OperationData, revisionIndex: number) {
let operation = new OT.TextOperation();
operation.deserialize(operationData);
this.document.apply(operation, revisionIndex);
this.pub.draft = this.document.text;
this.pub.revisionId++;
}

server_applyDraftChanges(client: any, callback: (err: string) => any) {
this.pub.text = this.pub.draft;

callback(null);

if (this.hasDraft) {
this.hasDraft = false;
this.emit("clearBadge", "draft");
}

this.emit("change");
}

client_applyDraftChanges() { this.pub.text = this.pub.draft; }
}
3 changes: 3 additions & 0 deletions plugins/default/typescript/data/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import TypescriptAsset from "./TypescriptAsset";

SupCore.system.data.registerAssetClass("typescript", TypescriptAsset);
20 changes: 20 additions & 0 deletions plugins/default/typescript/editors/typescript/index.jade
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
doctype html
html
head
link(rel="stylesheet",href="/styles/reset.css")
// link(rel="stylesheet",href="/styles/perfectResize.css")
link(rel="stylesheet",href="/styles/dialogs.css")
link(rel="stylesheet",href="../../../../common/textEditorWidget/widget.css")
link(rel="stylesheet",href="index.css")

body
.text-editor-container
textarea().text-editor

script(src="/SupCore.js")
script(src="/SupClient.js")
script(src="../../bundles/data.js")
script(src="../../../../common/textEditorWidget/bundles/data.js")
script(src="../../../../common/textEditorWidget/widget.js")
script(src="../../../../common/textEditorWidget/codemirror/mode/javascript/javascript.js")
script(src="index.js")
10 changes: 10 additions & 0 deletions plugins/default/typescript/editors/typescript/index.styl
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
body
display flex
flex-direction column
flex 1

.text-editor-container
min-height 100px

.CodeMirror .CodeMirror-overwrite .CodeMirror-cursor
border-left 8px solid rgba(86, 86, 232, 0.5)
63 changes: 63 additions & 0 deletions plugins/default/typescript/editors/typescript/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import TypescriptAsset from "../../data/TypescriptAsset";

SupClient.setupHotkeys();

let socket: SocketIOClient.Socket;
let projectClient: SupClient.ProjectClient;
let editor: TextEditorWidget;
let asset: TypescriptAsset;

socket = SupClient.connect(SupClient.query.project);
socket.on("welcome", onWelcome);
socket.on("disconnect", SupClient.onDisconnected);

function onWelcome(clientId: number) {
projectClient = new SupClient.ProjectClient(socket);
setupEditor(clientId);

let subscriber: SupClient.AssetSubscriber = {
onAssetReceived, onAssetEdited,
onAssetTrashed: SupClient.onAssetTrashed
};

projectClient.subAsset(SupClient.query.asset, "typescript", subscriber);
}

function onAssetReceived(assetId: string, theAsset: TypescriptAsset) {
asset = theAsset;
editor.setText(asset.pub.draft);
}

function onAssetEdited(assetId: string, command: string, ...args: any[]) {
if (command === "editText") {
// errorPaneStatus.classList.add("has-draft");
editor.receiveEditText(args[0]);
} else if (command === "applyDraftChanges") {
// errorPaneStatus.classList.remove("has-draft");
}
}

function setupEditor(clientId: number) {
let textArea = <HTMLTextAreaElement>document.querySelector(".text-editor");
editor = new TextEditorWidget(projectClient, clientId, textArea, {
mode: "text/typescript",
extraKeys: {
"Ctrl-S": () => { applyDraftChanges(); },
"Cmd-S": () => { applyDraftChanges(); },
},
editCallback: onEditText,
sendOperationCallback: onSendOperation
});
}

function onEditText(text: string, origin: string) { /* Ignore */ }

function onSendOperation(operation: OperationData) {
socket.emit("edit:assets", SupClient.query.asset, "editText", operation, asset.document.getRevisionId(), (err: string) => {
if (err != null) { alert(err); SupClient.onDisconnected(); }
});
}

function applyDraftChanges() {
socket.emit("edit:assets", SupClient.query.asset, "applyDraftChanges", (err: string) => { if (err != null) { alert(err); SupClient.onDisconnected(); }});
}
3 changes: 3 additions & 0 deletions plugins/default/typescript/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/// <reference path="../../../../../SupCore/SupCore.d.ts" />
/// <reference path="../../../../../SupClient/SupClient.d.ts" />
/// <reference path="../../common/textEditorWidget/widget.d.ts" />
14 changes: 14 additions & 0 deletions plugins/default/typescript/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"name": "superpowers-web-cocadev-typescript-plugin",
"description": "Typescript plugin for Superpowers Web, the collaborative static site editor",
"version": "1.0.0",
"license": "ISC",
"scripts": {
"build": "gulp --gulpfile=../../../../../scripts/pluginGulpfile.js --cwd=."
},
"dependencies": {
"browserify": "^12.0.1",
"operational-transform": "^0.2.3",
"typescript": "^1.7.5"
}
}
96 changes: 96 additions & 0 deletions plugins/default/typescript/public/editors/typescript/icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions plugins/default/typescript/public/locales/en/plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"editors": {
"typescript": {
"title": "Typescript"
}
}
}
Loading