Removed sandstorm files
This commit is contained in:
parent
f0a6aa7a46
commit
8298fab035
14 changed files with 0 additions and 1236 deletions
|
@ -1,24 +0,0 @@
|
|||
19-APR-2016: 6.5.4
|
||||
|
||||
- Updates to draw.io 6.5.4
|
||||
- Compress resources to avoid load errors
|
||||
|
||||
09-SEP-2016: 5.6.0.3
|
||||
|
||||
- Updates to draw.io 5.6.0.3
|
||||
- Fixes Saving... status
|
||||
- Adds read-only permission option
|
||||
|
||||
28-AUG-2015: 5.0.2.3
|
||||
|
||||
- Updates to draw.io 5.0.2.3
|
||||
|
||||
06-FEB-2015: 0.1.1.0
|
||||
|
||||
- Fixes external image export (probably)
|
||||
- Fixes iconfinder calls (probably)
|
||||
- Updates draw to head
|
||||
|
||||
02-FEB-2015: 0.1.0.0
|
||||
|
||||
- Initial release
|
|
@ -1,23 +0,0 @@
|
|||
CXX=g++
|
||||
CXXFLAGS=-O2 -Wall
|
||||
CXXFLAGS2=-std=c++1y -Itmp $(CXXFLAGS)
|
||||
SANDSTORM_CAPNP_DIR=/opt/sandstorm/latest/usr/include
|
||||
|
||||
.PHONEY: all clean dev
|
||||
|
||||
package.spk: server sandstorm-pkgdef.capnp
|
||||
spk pack --keyring="drawio.key" package.spk
|
||||
|
||||
dev: server sandstorm-pkgdef.capnp
|
||||
spk dev
|
||||
|
||||
clean:
|
||||
rm -rf tmp server package.spk
|
||||
|
||||
tmp/genfiles:
|
||||
@mkdir -p tmp
|
||||
capnp compile --src-prefix=$(SANDSTORM_CAPNP_DIR) -oc++:tmp $(SANDSTORM_CAPNP_DIR)/sandstorm/*.capnp
|
||||
@touch tmp/genfiles
|
||||
|
||||
server: tmp/genfiles server.c++
|
||||
$(CXX) -static server.c++ tmp/sandstorm/*.capnp.c++ -o server $(CXXFLAGS2) `pkg-config capnp-rpc --cflags --libs`
|
|
@ -1,19 +0,0 @@
|
|||
- Get the draw.io project from github
|
||||
- Navigate to `drawio/etc/sandstorm`
|
||||
- Create a directory named `build`
|
||||
- [Install vagrant-spk](https://docs.sandstorm.io/en/latest/vagrant-spk/installation/)
|
||||
- `cd build`
|
||||
- `vagrant-spk setupvm diy`
|
||||
- `vagrant-spk vm up`
|
||||
- `cd ..`
|
||||
- Invoke `./stage.sh` to stage the build files. gfind is gnu find on OS X.
|
||||
- Log into the vagrant box `vagrant-spk vm ssh`
|
||||
- `sudo apt-get install g++`
|
||||
- [Install latest capnp](https://capnproto.org/install.html)
|
||||
- In the vm, under `/opt/app/.sandstorm` run `make dev`
|
||||
|
||||
To package
|
||||
- Transfer the correct `sandstorm-keyring` file to `/host-dot-sandstorm`
|
||||
- Update the `sandstorm-pkgdef.capnp` to the correct version (re-stage prior to packaging)
|
||||
- In the host under `/opt/app/.sandstorm` `spk pack --keyring=/host-dot-sandstorm/sandstorm-keyring --pkg-def=/opt/app/.sandstorm/sandstorm-pkgdef.capnp:pkgdef /home/vagrant/sandstorm-package.spk && spk verify --details /home/vagrant/sandstorm-package.spk && mv /home/vagrant/sandstorm-package.spk /opt/app/sandstorm-drawio.spk`
|
||||
- In the host under `/opt/app` `spk publish -k /host-dot-sandstorm/sandstorm-keyring sandstorm-drawio.spk`
|
|
@ -1,6 +0,0 @@
|
|||
#! /bin/bash
|
||||
#
|
||||
# Copyright (c) 2016, JGraph Ltd
|
||||
BUILD="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
cd $BUILD
|
||||
make server
|
|
@ -1,5 +0,0 @@
|
|||
**The web's most popular open source diagram editor in your Sandstorm**
|
||||
|
||||
draw.io is a leading web based diagramming application designed to be simple to use, yet satisfy the power users.
|
||||
|
||||
This is the official Sandstorm port of draw.io based on the [online version of draw.io](https://www.draw.io?splash=0).
|
Binary file not shown.
Before Width: | Height: | Size: 70 KiB |
Binary file not shown.
Binary file not shown.
|
@ -1,7 +0,0 @@
|
|||
description.md
|
||||
Makefile
|
||||
pgp-keyring
|
||||
pgp-signature
|
||||
sandstorm-pkgdef.capnp
|
||||
server.c++
|
||||
shortDesc.txt
|
|
@ -1,118 +0,0 @@
|
|||
@0xeef286f78b0168e0;
|
||||
# When cloning the example, you'll want to replace the above file ID with a new
|
||||
# one generated using the `capnp id` command.
|
||||
|
||||
using Spk = import "/sandstorm/package.capnp";
|
||||
using Grain = import "/sandstorm/grain.capnp";
|
||||
|
||||
# This imports:
|
||||
# $SANDSTORM_HOME/latest/usr/include/sandstorm/package.capnp
|
||||
# Check out that file to see the full, documented package definition format.
|
||||
|
||||
const pkgdef :Spk.PackageDefinition = (
|
||||
# The package definition. Note that the spk tool looks specifically for the
|
||||
# "pkgdef" constant.
|
||||
|
||||
id = "a3w50h1435gsxczugm16q0amwkqm9f4crykzea53sv61pt7phk8h",
|
||||
# The app ID is actually the public key used to sign the app package.
|
||||
# All packages with the same ID are versions of the same app.
|
||||
#
|
||||
# If you are working from the example, you'll need to replace the above
|
||||
# public key with one of your own. Use the `spk keygen` command to generate
|
||||
# a new one.
|
||||
|
||||
manifest = (
|
||||
# This manifest is included in your app package to tell Sandstorm
|
||||
# about your app.
|
||||
|
||||
appVersion = 3, # Increment this for every release.
|
||||
|
||||
appTitle = (defaultText = "draw.io"),
|
||||
|
||||
appMarketingVersion = (defaultText = "6.5.4"),
|
||||
|
||||
actions = [
|
||||
# Define your "new document" handlers here.
|
||||
( title = (defaultText = "New draw.io diagram"),
|
||||
nounPhrase = (defaultText = "diagram"),
|
||||
command = .myCommand
|
||||
# The command to run when starting for the first time. (".myCommand"
|
||||
# is just a constant defined at the bottom of the file.)
|
||||
)
|
||||
],
|
||||
|
||||
continueCommand = .myCommand,
|
||||
# This is the command called to start your app back up after it has been
|
||||
# shut down for inactivity. Here we're using the same command as for
|
||||
# starting a new instance, but you could use different commands for each
|
||||
# case.
|
||||
|
||||
metadata = (
|
||||
icons = (
|
||||
appGrid = (png = (dpi1x = embed "client/images/drawlogo128.png")),
|
||||
grain = (png = (dpi1x = embed "client/images/drawlogo48.png")),
|
||||
market = (png = (dpi1x = embed "client/images/drawlogo256.png")),
|
||||
),
|
||||
|
||||
website = "https://www.draw.io/",
|
||||
codeUrl = "https://github.com/jgraph/draw.io",
|
||||
license = (openSource = gpl3),
|
||||
categories = [office, productivity],
|
||||
|
||||
author = (
|
||||
upstreamAuthor = "JGraph",
|
||||
contactEmail = "support@draw.io",
|
||||
pgpSignature = embed "pgp-signature",
|
||||
),
|
||||
pgpKeyring = embed "pgp-keyring",
|
||||
|
||||
description = (defaultText = embed "description.md"),
|
||||
|
||||
shortDescription = (defaultText = embed "shortDesc.txt"),
|
||||
|
||||
screenshots = [
|
||||
(width = 448, height = 243, png = embed "client/images/drawio448.png")
|
||||
],
|
||||
|
||||
changeLog = (defaultText = embed "ChangeLog"),
|
||||
)
|
||||
),
|
||||
|
||||
sourceMap = (
|
||||
# Here we define where to look for files to copy into your package.
|
||||
searchPath = [
|
||||
( packagePath = "server", sourcePath = "server" ),
|
||||
# Map server binary at "/server".
|
||||
|
||||
( packagePath = "client", sourcePath = "client" ),
|
||||
# Map client directory at "/client".
|
||||
]
|
||||
),
|
||||
|
||||
alwaysInclude = [ "." ]
|
||||
# Always include all mapped files, whether or not they are opened during
|
||||
# "spk dev".
|
||||
);
|
||||
|
||||
const appIndexViewInfo :Grain.UiView.ViewInfo = (
|
||||
permissions = [(name = "write", title = (defaultText = "write"),
|
||||
description = (defaultText = "allows editing diagrams")),
|
||||
(name = "read", title = (defaultText = "read"),
|
||||
description = (defaultText = "allows viewing diagrams"))],
|
||||
roles = [(title = (defaultText = "editor"),
|
||||
permissions = [true, true],
|
||||
verbPhrase = (defaultText = "can edit"),
|
||||
default = true),
|
||||
(title = (defaultText = "viewer"),
|
||||
permissions = [false, true],
|
||||
verbPhrase = (defaultText = "can view"))]
|
||||
);
|
||||
|
||||
const myCommand :Spk.Manifest.Command = (
|
||||
# Here we define the command used to start up your server.
|
||||
argv = ["/server"],
|
||||
environ = [
|
||||
# Note that this defines the *entire* environment seen by your app.
|
||||
(key = "PATH", value = "/usr/local/bin:/usr/bin:/bin")
|
||||
]
|
||||
);
|
|
@ -1,445 +0,0 @@
|
|||
// Copyright (c) 2014 Sandstorm Development Group, Inc.
|
||||
// Licensed under the MIT License:
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
// Hack around stdlib bug with C++14.
|
||||
#include <initializer_list> // force libstdc++ to include its config
|
||||
#undef _GLIBCXX_HAVE_GETS // correct broken config
|
||||
// End hack.
|
||||
|
||||
#include <kj/main.h>
|
||||
#include <kj/debug.h>
|
||||
#include <kj/io.h>
|
||||
#include <kj/async-io.h>
|
||||
#include <capnp/rpc-twoparty.h>
|
||||
#include <capnp/serialize.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <sandstorm/grain.capnp.h>
|
||||
#include <sandstorm/web-session.capnp.h>
|
||||
#include <sandstorm/hack-session.capnp.h>
|
||||
|
||||
namespace {
|
||||
|
||||
#if __QTCREATOR
|
||||
#define KJ_MVCAP(var) var
|
||||
// QtCreator dosen't understand C++14 syntax yet.
|
||||
#else
|
||||
#define KJ_MVCAP(var) var = ::kj::mv(var)
|
||||
// Capture the given variable by move. Place this in a lambda capture list. Requires C++14.
|
||||
//
|
||||
// TODO(cleanup): Move to libkj.
|
||||
#endif
|
||||
|
||||
typedef unsigned int uint;
|
||||
typedef unsigned char byte;
|
||||
|
||||
// =======================================================================================
|
||||
// Utility functions
|
||||
//
|
||||
// Most of these should be moved to the KJ library someday.
|
||||
|
||||
kj::AutoCloseFd createFile(kj::StringPtr name, int flags, mode_t mode = 0666) {
|
||||
// Create a file, returning an RAII wrapper around the file descriptor. Errors throw exceptinos.
|
||||
|
||||
int fd;
|
||||
KJ_SYSCALL(fd = open(name.cStr(), O_CREAT | flags, mode), name);
|
||||
return kj::AutoCloseFd(fd);
|
||||
}
|
||||
|
||||
size_t getFileSize(int fd, kj::StringPtr filename) {
|
||||
struct stat stats;
|
||||
KJ_SYSCALL(fstat(fd, &stats));
|
||||
KJ_REQUIRE(S_ISREG(stats.st_mode), "Not a regular file.", filename);
|
||||
return stats.st_size;
|
||||
}
|
||||
|
||||
kj::Maybe<kj::AutoCloseFd> tryOpen(kj::StringPtr name, int flags, mode_t mode = 0666) {
|
||||
// Try to open a file, returning an RAII wrapper around the file descriptor, or null if the
|
||||
// file doesn't exist. All other errors throw exceptions.
|
||||
|
||||
int fd;
|
||||
|
||||
while ((fd = open(name.cStr(), flags, mode)) < 0) {
|
||||
int error = errno;
|
||||
if (error == ENOENT) {
|
||||
return nullptr;
|
||||
} else if (error != EINTR) {
|
||||
KJ_FAIL_SYSCALL("open(name)", error, name);
|
||||
}
|
||||
}
|
||||
|
||||
return kj::AutoCloseFd(fd);
|
||||
}
|
||||
|
||||
bool isDirectory(kj::StringPtr filename) {
|
||||
// Return true if the parameter names a directory, false if it's any other kind of node or
|
||||
// doesn't exist.
|
||||
|
||||
struct stat stats;
|
||||
while (stat(filename.cStr(), &stats) < 0) {
|
||||
if (errno != EINTR) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return S_ISDIR(stats.st_mode);
|
||||
}
|
||||
|
||||
kj::Vector<kj::String> listDirectory(kj::StringPtr dirname) {
|
||||
// Return a list of all filenames in the given directory, except "." and "..".
|
||||
|
||||
kj::Vector<kj::String> entries;
|
||||
|
||||
DIR* dir = opendir(dirname.cStr());
|
||||
if (dir == nullptr) {
|
||||
KJ_FAIL_SYSCALL("opendir", errno, dirname);
|
||||
}
|
||||
KJ_DEFER(closedir(dir));
|
||||
|
||||
for (;;) {
|
||||
errno = 0;
|
||||
struct dirent* entry = readdir(dir);
|
||||
if (entry == nullptr) {
|
||||
int error = errno;
|
||||
if (error == 0) {
|
||||
break;
|
||||
} else {
|
||||
KJ_FAIL_SYSCALL("readdir", error, dirname);
|
||||
}
|
||||
}
|
||||
|
||||
kj::StringPtr name = entry->d_name;
|
||||
if (name != "." && name != "..") {
|
||||
entries.add(kj::heapString(entry->d_name));
|
||||
}
|
||||
}
|
||||
|
||||
return entries;
|
||||
}
|
||||
|
||||
// =======================================================================================
|
||||
// WebSession implementation (interface declared in sandstorm/web-session.capnp)
|
||||
|
||||
class WebSessionImpl final: public sandstorm::WebSession::Server {
|
||||
public:
|
||||
WebSessionImpl(sandstorm::UserInfo::Reader userInfo,
|
||||
sandstorm::SessionContext::Client context,
|
||||
sandstorm::WebSession::Params::Reader params) {
|
||||
// Permission #0 is "write". Check if bit 0 in the PermissionSet is set.
|
||||
auto permissions = userInfo.getPermissions();
|
||||
canWrite = permissions.size() > 0 && (permissions[0] & 1);
|
||||
|
||||
// `UserInfo` is defined in `sandstorm/grain.capnp` and contains info like:
|
||||
// - A stable ID for the user, so you can correlate sessions from the same user.
|
||||
// - The user's display name, e.g. "Mark Miller", useful for identifying the user to other
|
||||
// users.
|
||||
// - The user's permissions (seen above).
|
||||
|
||||
// `WebSession::Params` is defined in `sandstorm/web-session.capnp` and contains info like:
|
||||
// - The hostname where the grain was mapped for this user. Every time a user opens a grain,
|
||||
// it is mapped at a new random hostname for security reasons.
|
||||
// - The user's User-Agent and Accept-Languages headers.
|
||||
|
||||
// `SessionContext` is defined in `sandstorm/grain.capnp` and implements callbacks for
|
||||
// sharing/access control and service publishing/discovery.
|
||||
}
|
||||
|
||||
kj::Promise<void> get(GetContext context) override {
|
||||
// HTTP GET request.
|
||||
|
||||
auto path = context.getParams().getPath();
|
||||
requireCanonicalPath(path);
|
||||
|
||||
if (path == "var" || path == "var/") {
|
||||
// Return a listing of the directory contents, one per line.
|
||||
auto text = kj::strArray(listDirectory("var"), "\n");
|
||||
auto response = context.getResults().initContent();
|
||||
response.setMimeType("text/plain");
|
||||
response.getBody().setBytes(
|
||||
kj::arrayPtr(reinterpret_cast<byte*>(text.begin()), text.size()));
|
||||
return kj::READY_NOW;
|
||||
} else if (path.startsWith("var/")) {
|
||||
// Serve all files under /var with type application/octet-stream since it comes from the
|
||||
// user. E.g. serving as "text/html" here would allow someone to trivially XSS other users
|
||||
// of the grain by PUTing malicious HTML content. (Such an attack wouldn't be a huge deal:
|
||||
// it would only allow the attacker to hijack another user's access to this grain, not to
|
||||
// Sandstorm in general, and if they attacker already has write access to upload the
|
||||
// malicious content, they have little to gain from hijacking another session.)
|
||||
return readFile(path, context, "application/octet-stream");
|
||||
} else if (path == ".can-write") {
|
||||
// Fetch "/.can-write" to determine if the user has write permission, so you can show them
|
||||
// a different UI if not.
|
||||
auto response = context.getResults().initContent();
|
||||
response.setMimeType("text/plain");
|
||||
response.getBody().setBytes(kj::str(canWrite).asBytes());
|
||||
return kj::READY_NOW;
|
||||
} else if (path == "" || path.endsWith("/")) {
|
||||
// A directory. Serve "index.html".
|
||||
return readFile(kj::str("client/", path, "ssindex.html"), context, "text/html; charset=UTF-8");
|
||||
} else {
|
||||
// Request for a static file. Look for it under "client/".
|
||||
auto filename = kj::str("client/", path);
|
||||
|
||||
// Check if it's a directory.
|
||||
if (isDirectory(filename)) {
|
||||
// It is. Return redirect to add '/'.
|
||||
auto redirect = context.getResults().initRedirect();
|
||||
redirect.setIsPermanent(true);
|
||||
redirect.setSwitchToGet(true);
|
||||
redirect.setLocation(kj::str(path, '/'));
|
||||
return kj::READY_NOW;
|
||||
}
|
||||
|
||||
// Regular file (or non-existent).
|
||||
return readFile(kj::mv(filename), context, inferContentType(path));
|
||||
}
|
||||
}
|
||||
|
||||
kj::Promise<void> put(PutContext context) override {
|
||||
// HTTP PUT request.
|
||||
|
||||
auto params = context.getParams();
|
||||
auto path = params.getPath();
|
||||
requireCanonicalPath(path);
|
||||
|
||||
KJ_REQUIRE(path.startsWith("var/"), "PUT only supported under /var.");
|
||||
|
||||
if (!canWrite) {
|
||||
context.getResults().initClientError()
|
||||
.setStatusCode(sandstorm::WebSession::Response::ClientErrorCode::FORBIDDEN);
|
||||
} else {
|
||||
auto tempPath = kj::str(path, ".uploading");
|
||||
auto data = params.getContent().getContent();
|
||||
|
||||
kj::FdOutputStream(createFile(tempPath, O_WRONLY | O_TRUNC))
|
||||
.write(data.begin(), data.size());
|
||||
|
||||
KJ_SYSCALL(rename(tempPath.cStr(), path.cStr()));
|
||||
context.getResults().initNoContent();
|
||||
}
|
||||
|
||||
return kj::READY_NOW;
|
||||
}
|
||||
|
||||
kj::Promise<void> delete_(DeleteContext context) override {
|
||||
// HTTP DELETE request.
|
||||
|
||||
auto path = context.getParams().getPath();
|
||||
requireCanonicalPath(path);
|
||||
|
||||
KJ_REQUIRE(path.startsWith("var/"), "DELETE only supported under /var.");
|
||||
|
||||
if (!canWrite) {
|
||||
context.getResults().initClientError()
|
||||
.setStatusCode(sandstorm::WebSession::Response::ClientErrorCode::FORBIDDEN);
|
||||
} else {
|
||||
while (unlink(path.cStr()) != 0) {
|
||||
int error = errno;
|
||||
if (error == ENOENT) {
|
||||
// Ignore file-not-found for idempotency.
|
||||
break;
|
||||
} else if (error != EINTR) {
|
||||
KJ_FAIL_SYSCALL("unlink", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return kj::READY_NOW;
|
||||
}
|
||||
|
||||
private:
|
||||
bool canWrite;
|
||||
// True if the user has write permission.
|
||||
|
||||
void requireCanonicalPath(kj::StringPtr path) {
|
||||
// Require that the path doesn't contain "." or ".." or consecutive slashes, to prevent path
|
||||
// injection attacks.
|
||||
//
|
||||
// Note that such attacks wouldn't actually accomplish much since everything outside /var
|
||||
// is a read-only filesystem anyway, containing the app package contents which are non-secret.
|
||||
|
||||
KJ_REQUIRE(!path.startsWith("/"));
|
||||
KJ_REQUIRE(!path.startsWith("./") && path != ".");
|
||||
KJ_REQUIRE(!path.startsWith("../") && path != "..");
|
||||
|
||||
KJ_IF_MAYBE(slashPos, path.findFirst('/')) {
|
||||
requireCanonicalPath(path.slice(*slashPos + 1));
|
||||
}
|
||||
}
|
||||
|
||||
kj::StringPtr inferContentType(kj::StringPtr filename) {
|
||||
if (filename.endsWith(".html")) {
|
||||
return "text/html; charset=UTF-8";
|
||||
} else if (filename.endsWith(".js")) {
|
||||
return "text/javascript; charset=UTF-8";
|
||||
} else if (filename.endsWith(".css")) {
|
||||
return "text/css; charset=UTF-8";
|
||||
} else if (filename.endsWith(".png")) {
|
||||
return "image/png";
|
||||
} else if (filename.endsWith(".gif")) {
|
||||
return "image/gif";
|
||||
} else if (filename.endsWith(".jpg") || filename.endsWith(".jpeg")) {
|
||||
return "image/jpeg";
|
||||
} else if (filename.endsWith(".svg")) {
|
||||
return "image/svg+xml; charset=UTF-8";
|
||||
} else if (filename.endsWith(".txt")) {
|
||||
return "text/plain; charset=UTF-8";
|
||||
} else {
|
||||
return "application/octet-stream";
|
||||
}
|
||||
}
|
||||
|
||||
kj::Promise<void> readFile(
|
||||
kj::StringPtr filename, GetContext context, kj::StringPtr contentType) {
|
||||
// Do we support compression?
|
||||
bool canGzip = false;
|
||||
for (auto accept: context.getParams().getContext().getAcceptEncoding()) {
|
||||
if (accept.getContentCoding() == "gzip") {
|
||||
canGzip = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If compression is supported, look for file with .gz extension.
|
||||
kj::Maybe<kj::AutoCloseFd> maybeFd;
|
||||
bool isGzipped = false;
|
||||
if (canGzip) {
|
||||
maybeFd = tryOpen(kj::str(filename, ".gz"), O_RDONLY);
|
||||
isGzipped = maybeFd != nullptr;
|
||||
}
|
||||
|
||||
// If we haven't found a suitable file yet, look for the uncompressed version.
|
||||
if (maybeFd == nullptr) {
|
||||
maybeFd = tryOpen(filename, O_RDONLY);
|
||||
}
|
||||
|
||||
// Serve it.
|
||||
KJ_IF_MAYBE(fd, kj::mv(maybeFd)) {
|
||||
auto size = getFileSize(*fd, filename);
|
||||
kj::FdInputStream stream(kj::mv(*fd));
|
||||
auto response = context.getResults(capnp::MessageSize { size / sizeof(capnp::word) + 32, 0 });
|
||||
auto content = response.initContent();
|
||||
content.setStatusCode(sandstorm::WebSession::Response::SuccessCode::OK);
|
||||
content.setMimeType(contentType);
|
||||
if (isGzipped) {
|
||||
content.setEncoding("gzip");
|
||||
}
|
||||
stream.read(content.getBody().initBytes(size).begin(), size);
|
||||
return kj::READY_NOW;
|
||||
} else {
|
||||
auto error = context.getResults().initClientError();
|
||||
error.setStatusCode(sandstorm::WebSession::Response::ClientErrorCode::NOT_FOUND);
|
||||
return kj::READY_NOW;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// =======================================================================================
|
||||
// UiView implementation (interface declared in sandstorm/grain.capnp)
|
||||
|
||||
class UiViewImpl final: public sandstorm::UiView::Server {
|
||||
public:
|
||||
kj::Promise<void> getViewInfo(GetViewInfoContext context) override {
|
||||
auto viewInfo = context.initResults();
|
||||
|
||||
// Define a "write" permission, and then define roles "editor" and "viewer" where only "editor"
|
||||
// has the "write" permission. This will allow people to share read-only.
|
||||
auto perms = viewInfo.initPermissions(1);
|
||||
perms[0].setName("write");
|
||||
auto write = perms[0];
|
||||
write.setName("write");
|
||||
write.initTitle().setDefaultText("write");
|
||||
|
||||
auto roles = viewInfo.initRoles(2);
|
||||
auto editor = roles[0];
|
||||
editor.initTitle().setDefaultText("editor");
|
||||
editor.initVerbPhrase().setDefaultText("can edit");
|
||||
editor.initPermissions(1).set(0, true); // has "write" permission
|
||||
auto viewer = roles[1];
|
||||
viewer.initTitle().setDefaultText("viewer");
|
||||
viewer.initVerbPhrase().setDefaultText("can view");
|
||||
viewer.initPermissions(1).set(0, false); // does not have "write" permission
|
||||
|
||||
return kj::READY_NOW;
|
||||
}
|
||||
|
||||
kj::Promise<void> newSession(NewSessionContext context) override {
|
||||
auto params = context.getParams();
|
||||
|
||||
KJ_REQUIRE(params.getSessionType() == capnp::typeId<sandstorm::WebSession>(),
|
||||
"Unsupported session type.");
|
||||
|
||||
context.getResults().setSession(
|
||||
kj::heap<WebSessionImpl>(params.getUserInfo(), params.getContext(),
|
||||
params.getSessionParams().getAs<sandstorm::WebSession::Params>()));
|
||||
|
||||
return kj::READY_NOW;
|
||||
}
|
||||
};
|
||||
|
||||
// =======================================================================================
|
||||
// Program main
|
||||
|
||||
class ServerMain {
|
||||
public:
|
||||
ServerMain(kj::ProcessContext& context): context(context), ioContext(kj::setupAsyncIo()) {}
|
||||
|
||||
kj::MainFunc getMain() {
|
||||
return kj::MainBuilder(context, "Sandstorm Thin Server",
|
||||
"Intended to be run as the root process of a Sandstorm app.")
|
||||
.callAfterParsing(KJ_BIND_METHOD(*this, run))
|
||||
.build();
|
||||
}
|
||||
|
||||
kj::MainBuilder::Validity run() {
|
||||
// Set up RPC on file descriptor 3.
|
||||
auto stream = ioContext.lowLevelProvider->wrapSocketFd(3);
|
||||
capnp::TwoPartyVatNetwork network(*stream, capnp::rpc::twoparty::Side::CLIENT);
|
||||
auto rpcSystem = capnp::makeRpcServer(network, kj::heap<UiViewImpl>());
|
||||
|
||||
// Get the SandstormApi default capability from the supervisor.
|
||||
// TODO(soon): We don't use this, but for some reason the connection doesn't come up if we
|
||||
// don't do this restore. Cap'n Proto bug? v8capnp bug? Shell bug?
|
||||
{
|
||||
capnp::MallocMessageBuilder message;
|
||||
auto vatId = message.getRoot<capnp::rpc::twoparty::VatId>();
|
||||
vatId.setSide(capnp::rpc::twoparty::Side::SERVER);
|
||||
sandstorm::SandstormApi<>::Client api =
|
||||
rpcSystem.bootstrap(vatId).castAs<sandstorm::SandstormApi<>>();
|
||||
}
|
||||
|
||||
kj::NEVER_DONE.wait(ioContext.waitScope);
|
||||
}
|
||||
|
||||
private:
|
||||
kj::ProcessContext& context;
|
||||
kj::AsyncIoContext ioContext;
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
KJ_MAIN(ServerMain)
|
|
@ -1 +0,0 @@
|
|||
Web Diagramming
|
|
@ -1,539 +0,0 @@
|
|||
<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=5,IE=9" ><![endif]-->
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Flowchart Maker & Online Diagram Software</title>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta name="Description" content="draw.io is free online diagram software for making flowcharts, process diagrams, org charts, UML, ER and network diagrams">
|
||||
<meta name="Keywords" content="diagram, online, flow chart, flowchart maker, uml, erd">
|
||||
<meta itemprop="name" content="draw.io - free flowchart maker and diagrams online">
|
||||
<meta itemprop="description" content="draw.io is a free online diagramming application and flowchart maker . You can use it to create UML, entity relationship,
|
||||
org charts, BPMN and BPM, database schema and networks. Also possible are telecommunication network, workflow, flowcharts, maps overlays and GIS, electronic
|
||||
circuit and social network diagrams.">
|
||||
<meta itemprop="image" content="https://lh4.googleusercontent.com/-cLKEldMbT_E/Tx8qXDuw6eI/AAAAAAAAAAs/Ke0pnlk8Gpg/w500-h344-k/BPMN%2Bdiagram%2Brc2f.png">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||||
<meta name="mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
||||
<link rel="canonical" href="https://www.draw.io">
|
||||
<script type="text/javascript">
|
||||
/**
|
||||
* URL Parameters and protocol description are here:
|
||||
*
|
||||
* https://support.draw.io/pages/viewpage.action?pageId=12878136
|
||||
*
|
||||
* Parameters for developers:
|
||||
*
|
||||
* - dev=1: For developers only
|
||||
* - test=1: For developers only
|
||||
* - drawdev=1: For developers only
|
||||
* - export=URL for export: For developers only
|
||||
* - pages=1: For developers only
|
||||
* - page=n: For developers only
|
||||
* - ignoremime=1: For developers only (see DriveClient.js). Use Cmd-S to override mime.
|
||||
* - createindex=1: For depelopers only (see etc/build/README)
|
||||
* - filesupport=0: For developers only (see Editor.js in core)
|
||||
* - savesidebar=1: For developers only (see Sidebar.js)
|
||||
* - pages=1: For developers only (see Pages.js)
|
||||
* - lic=email: For developers only (see LicenseServlet.java)
|
||||
* --
|
||||
* - networkshapes=1: For testing network shapes (temporary)
|
||||
*/
|
||||
var urlParams = (function()
|
||||
{
|
||||
var result = new Object();
|
||||
var params = window.location.search.slice(1).split('&');
|
||||
|
||||
for (var i = 0; i < params.length; i++)
|
||||
{
|
||||
idx = params[i].indexOf('=');
|
||||
|
||||
if (idx > 0)
|
||||
{
|
||||
result[params[i].substring(0, idx)] = params[i].substring(idx + 1);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
})();
|
||||
</script>
|
||||
<link rel="alternate" type="application/rss+xml" title="RSS Feed for draw.io" href="http://blog.draw.io/feed/">
|
||||
<link rel="chrome-webstore-item" href="https://chrome.google.com/webstore/detail/plgmlhohecdddhbmmkncjdmlhcmaachm">
|
||||
<link rel="apple-touch-icon" sizes="57x57" href="images/apple-touch-icon-57x57.png">
|
||||
<link rel="apple-touch-icon" sizes="60x60" href="images/apple-touch-icon-60x60.png">
|
||||
<link rel="apple-touch-icon" sizes="72x72" href="images/apple-touch-icon-72x72.png">
|
||||
<link rel="apple-touch-icon" sizes="76x76" href="images/apple-touch-icon-76x76.png">
|
||||
<link rel="apple-touch-icon" sizes="114x114" href="images/apple-touch-icon-114x114.png">
|
||||
<link rel="apple-touch-icon" sizes="120x120" href="images/apple-touch-icon-120x120.png">
|
||||
<link rel="apple-touch-icon" sizes="144x144" href="images/apple-touch-icon-144x144.png">
|
||||
<link rel="apple-touch-icon" sizes="152x152" href="images/apple-touch-icon-152x152.png">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="images/apple-touch-icon-180x180.png">
|
||||
<link rel="icon" type="image/png" href="images/favicon-32x32.png" sizes="32x32">
|
||||
<link rel="icon" type="image/png" href="images/favicon-194x194.png" sizes="194x194">
|
||||
<link rel="icon" type="image/png" href="images/favicon-96x96.png" sizes="96x96">
|
||||
<link rel="icon" type="image/png" href="images/android-chrome-192x192.png" sizes="192x192">
|
||||
<link rel="icon" type="image/png" href="images/favicon-16x16.png" sizes="16x16">
|
||||
<link rel="manifest" href="images/manifest.json">
|
||||
<link rel="mask-icon" href="images/safari-pinned-tab.svg" color="#f18808">
|
||||
<meta name="msapplication-TileColor" content="#da532c">
|
||||
<meta name="msapplication-TileImage" content="images/mstile-144x144.png">
|
||||
<meta name="msapplication-config" content="images/browserconfig.xml">
|
||||
<meta name="theme-color" content="#f18808">
|
||||
<link rel="apple-touch-startup-image" href="images/logo-flat.png">
|
||||
<link rel="stylesheet" type="text/css" href="styles/grapheditor.css">
|
||||
<style type="text/css">
|
||||
body { overflow:hidden; }
|
||||
.geSidebarContainer .geTitle { color:#505050; }
|
||||
.geSidebarContainer .geTitle input {
|
||||
font-size:8pt;
|
||||
color:#606060;
|
||||
}
|
||||
.geBlock {
|
||||
z-index:-3;
|
||||
margin:100px;
|
||||
margin-top:40px;
|
||||
margin-bottom:30px;
|
||||
padding:20px;
|
||||
}
|
||||
.geBlock h1, .geBlock h2 {
|
||||
margin-top:0px;
|
||||
padding-top:0px;
|
||||
}
|
||||
.geEditor ::-webkit-scrollbar {
|
||||
width:12px;
|
||||
height:12px;
|
||||
}
|
||||
.geEditor ::-webkit-scrollbar-track {
|
||||
background:whiteSmoke;
|
||||
-webkit-box-shadow:inset 0 0 4px rgba(0,0,0,0.1);
|
||||
}
|
||||
.geEditor ::-webkit-scrollbar-thumb {
|
||||
background:#c5c5c5;
|
||||
border-radius:10px;
|
||||
border:whiteSmoke solid 3px;
|
||||
}
|
||||
.geEditor ::-webkit-scrollbar-thumb:hover {
|
||||
background:#b5b5b5;
|
||||
}
|
||||
.geTemplate {
|
||||
border:1px solid transparent;
|
||||
display:inline-block;
|
||||
_display:inline;
|
||||
vertical-align:top;
|
||||
border-radius:3px;
|
||||
overflow:hidden;
|
||||
font-size:14pt;
|
||||
cursor:pointer;
|
||||
margin:5px;
|
||||
}
|
||||
.geFooterContainer div.geSocialFooter a {
|
||||
display:inline;
|
||||
padding:0px;
|
||||
}
|
||||
.geFooterContainer div.geSocialFooter a img {
|
||||
margin-top:10px;
|
||||
opacity:0.8;
|
||||
}
|
||||
.geFooterContainer div.geSocialFooter a img:hover {
|
||||
opacity:1;
|
||||
}
|
||||
#geFooterItem1 {
|
||||
background-color: #cdcdcd;
|
||||
}
|
||||
#geFooterItem1:hover {
|
||||
background-color: #b0b0b0;
|
||||
}
|
||||
.geFooterContainer>div>img {
|
||||
opacity:0.5;
|
||||
background:#e5e5e5;
|
||||
border:1px solid transparent;
|
||||
cusor:pointer;
|
||||
margin-top:3px;
|
||||
margin-right:6px;
|
||||
position:absolute;
|
||||
right:4px;
|
||||
top:12px;
|
||||
padding:1px;
|
||||
cursor:pointer;
|
||||
}
|
||||
.geFooterContainer>div>img:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
.geBlink {
|
||||
animation: geBlinker 1s linear infinite;
|
||||
}
|
||||
@keyframes geBlinker {
|
||||
50% { opacity: 0.0; }
|
||||
}
|
||||
</style>
|
||||
<!-- Workaround for binary XHR in IE 9/10, see App.loadUrl -->
|
||||
<!--[if (IE 9)|(IE 10)]><!-->
|
||||
<script type="text/vbscript">
|
||||
Function mxUtilsBinaryToArray(Binary)
|
||||
Dim i
|
||||
ReDim byteArray(LenB(Binary))
|
||||
For i = 1 To LenB(Binary)
|
||||
byteArray(i-1) = AscB(MidB(Binary, i, 1))
|
||||
Next
|
||||
mxUtilsBinaryToArray = byteArray
|
||||
End Function
|
||||
</script>
|
||||
<!--<![endif]-->
|
||||
<script type="text/javascript">
|
||||
/**
|
||||
* Synchronously adds scripts to the page.
|
||||
*/
|
||||
function mxscript(src, onLoad, id, dataAppKey)
|
||||
{
|
||||
if (onLoad != null)
|
||||
{
|
||||
var s = document.createElement('script');
|
||||
s.setAttribute('type', 'text/javascript');
|
||||
s.setAttribute('src', src);
|
||||
var r = false;
|
||||
|
||||
if (id != null)
|
||||
{
|
||||
s.setAttribute('id', id);
|
||||
}
|
||||
|
||||
if (dataAppKey != null)
|
||||
{
|
||||
s.setAttribute('data-app-key', dataAppKey);
|
||||
}
|
||||
|
||||
s.onload = s.onreadystatechange = function()
|
||||
{
|
||||
if (!r && (!this.readyState || this.readyState == 'complete'))
|
||||
{
|
||||
r = true;
|
||||
onLoad();
|
||||
}
|
||||
};
|
||||
|
||||
var t = document.getElementsByTagName('script')[0];
|
||||
t.parentNode.insertBefore(s, t);
|
||||
}
|
||||
else
|
||||
{
|
||||
document.write('<script src="' + src + '"' + ((id != null) ? ' id="' + id +'" ' : '') +
|
||||
((dataAppKey != null) ? ' data-app-key="' + dataAppKey +'" ' : '') + '></scr' + 'ipt>');
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Asynchronously adds scripts to the page.
|
||||
*/
|
||||
function mxinclude(src)
|
||||
{
|
||||
var g = document.createElement('script'); g.type = 'text/javascript'; g.async = true; g.src = src;
|
||||
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(g, s);
|
||||
};
|
||||
|
||||
// Checks for local storage and SVG support
|
||||
var isLocalStorage = false; // No local storage in sandstorm because of subdomains - typeof(localStorage) != 'undefined';
|
||||
|
||||
var t0 = new Date();
|
||||
|
||||
// Public global variables
|
||||
var SANDSTORM = true;
|
||||
var MAX_REQUEST_SIZE = 10485760;
|
||||
var MAX_AREA = 10000 * 10000;
|
||||
|
||||
// CUSTOM_PARAMETERS - URLs for save and export
|
||||
var EXPORT_URL = 'https://exp.draw.io/ImageExport4/export';
|
||||
|
||||
var SAVE_URL = 'save';
|
||||
var OPEN_URL = 'open';
|
||||
var PROXY_URL = 'proxy';
|
||||
|
||||
// Paths and files
|
||||
var STENCIL_PATH = 'stencils';
|
||||
var SHAPES_PATH = 'shapes';
|
||||
var IMAGE_PATH = 'images';
|
||||
// Path for images inside the diagram
|
||||
var GRAPH_IMAGE_PATH = 'img';
|
||||
ICONFINDER_PATH = (navigator.userAgent.indexOf('MSIE') >= 0) ? 'iconfinder' : 'https://www.draw.io/iconfinder';
|
||||
|
||||
// Used to request grapheditor/mxgraph sources in dev mode
|
||||
var mxDevUrl = document.location.protocol + '//devhost.jgraph.com/mxgraph2';
|
||||
|
||||
// Used to request draw.io sources in dev mode
|
||||
var drawDevUrl = '';
|
||||
|
||||
if (urlParams['drawdev'] == '1')
|
||||
{
|
||||
drawDevUrl = document.location.protocol + '//drawhost.jgraph.com/';
|
||||
}
|
||||
|
||||
// Customizes export URL
|
||||
var ex = urlParams['export'];
|
||||
|
||||
if (ex != null)
|
||||
{
|
||||
EXPORT_URL = ex;
|
||||
}
|
||||
|
||||
urlParams['analytics'] = '0';
|
||||
urlParams['picker'] = '0';
|
||||
urlParams['gapi'] = '0';
|
||||
urlParams['db'] = '0';
|
||||
urlParams['od'] = '0';
|
||||
urlParams['embed'] = '1';
|
||||
|
||||
// Changes paths for local development environment
|
||||
if (urlParams['dev'] == '1')
|
||||
{
|
||||
// Used to request draw.io sources in dev mode
|
||||
var drawDevUrl = '';
|
||||
|
||||
if (urlParams['drawdev'] == '1')
|
||||
{
|
||||
drawDevUrl = document.location.protocol + '//drawhost.jgraph.com/';
|
||||
}
|
||||
|
||||
mxscript(drawDevUrl + 'js/diagramly/Init.js');
|
||||
mxscript(geBasePath + '/Init.js');
|
||||
|
||||
// Used to request grapheditor/mxgraph sources in dev mode
|
||||
var mxDevUrl = document.location.protocol + '//devhost.jgraph.com/mxgraph2';
|
||||
geBasePath = mxDevUrl + '/javascript/examples/grapheditor/www/js';
|
||||
mxBasePath = mxDevUrl + '/javascript/src';
|
||||
mxscript(mxBasePath + '/js/mxClient.js');
|
||||
|
||||
// Adds all JS code that depends on mxClient. This indirection via Devel.js is
|
||||
// required in some browsers to make sure mxClient.js (and the files that it
|
||||
// loads asynchronously) are available when the code loaded in Devel.js runs.
|
||||
mxscript(drawDevUrl + 'js/diagramly/Devel.js');
|
||||
//mxscript(drawDevUrl + 'js/sandstorm/SandstormFile.js');
|
||||
}
|
||||
else
|
||||
{
|
||||
mxscript('js/app.min.js');
|
||||
//mxscript('js/sandstorm/SandstormFile.js');
|
||||
}
|
||||
|
||||
// Loads JSON for older browsers
|
||||
if (typeof(JSON) == 'undefined')
|
||||
{
|
||||
mxscript('js/json/json2.min.js');
|
||||
}
|
||||
|
||||
// Adds basic error handling
|
||||
window.onerror = function()
|
||||
{
|
||||
var status = document.getElementById('geStatus');
|
||||
|
||||
if (status != null)
|
||||
{
|
||||
status.innerHTML = 'Page could not be loaded. Please try refreshing.';
|
||||
}
|
||||
};
|
||||
</script>
|
||||
</head>
|
||||
<body class="geEditor">
|
||||
<div id="geInfo">
|
||||
<div class="geBlock" style="text-align:center;">
|
||||
<h3 id="geStatus">Loading... Please ensure JavaScript is enabled</h2>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
|
||||
(function()
|
||||
{
|
||||
EditorUi.prototype.footerHeight = 0;
|
||||
|
||||
EditorUi.prototype.initializeEmbedMode = function()
|
||||
{
|
||||
mxUtils.get('var/drawiodiagram.xml', mxUtils.bind(this, function(req)
|
||||
{
|
||||
if (req.getStatus() == 200)
|
||||
{
|
||||
mxUtils.get('.can-write', mxUtils.bind(this, function(req2)
|
||||
{
|
||||
var ssFile = new SandstormFile(this, req.getText(), null);
|
||||
|
||||
if (req2.getText() == "false")
|
||||
{
|
||||
ssFile.editable = false;
|
||||
}
|
||||
|
||||
this.spinner.stop();
|
||||
this.fileLoaded(ssFile);
|
||||
|
||||
}), mxUtils.bind(this, function()
|
||||
{
|
||||
// No action, only failed to read the write status
|
||||
}));
|
||||
}
|
||||
else if (req.getStatus() == 404)
|
||||
{
|
||||
this.fileLoaded(null);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.handleError(null, mxResources.get('errorLoadingFile'), reconnect);
|
||||
}
|
||||
}), mxUtils.bind(this, function()
|
||||
{
|
||||
this.handleError(null, mxResources.get('errorLoadingFile'), reconnect);
|
||||
}));
|
||||
};
|
||||
|
||||
App.prototype.showSplash = function()
|
||||
{
|
||||
this.hideDialog();
|
||||
this.actions.get('new').funct();
|
||||
};
|
||||
|
||||
App.prototype.createFile = function(title, data, libs, mode, done)
|
||||
{
|
||||
data = (data != null) ? data : this.emptyDiagramXml;
|
||||
|
||||
var error = mxUtils.bind(this, function(resp)
|
||||
{
|
||||
if (resp == null && this.getCurrentFile() == null && this.dialog == null)
|
||||
{
|
||||
this.showSplash();
|
||||
}
|
||||
else if (resp != null)
|
||||
{
|
||||
this.handleError(resp);
|
||||
}
|
||||
});
|
||||
|
||||
if (done != null)
|
||||
{
|
||||
done();
|
||||
}
|
||||
|
||||
this.fileCreated(new SandstormFile(this, data, title), libs);
|
||||
};
|
||||
|
||||
//////////////// Sandstorm File ///////////////////
|
||||
SandstormFile = function(ui, data, title)
|
||||
{
|
||||
DrawioFile.call(this, ui, data);
|
||||
|
||||
this.title = title;
|
||||
this.editable = true;
|
||||
};
|
||||
|
||||
mxUtils.extend(SandstormFile, DrawioFile);
|
||||
|
||||
SandstormFile.prototype.isAutosave = function() { return true; };
|
||||
SandstormFile.prototype.getMode = function() { return App.MODE_DEVICE; };
|
||||
SandstormFile.prototype.getTitle = function() { return this.title; };
|
||||
SandstormFile.prototype.isRenamable = function() { return this.editable; };
|
||||
SandstormFile.prototype.isEditable = function() { return this.editable; };
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
SandstormFile.prototype.save = function(revision, success, error)
|
||||
{
|
||||
this.saveAs(this.title, success, error);
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
SandstormFile.prototype.saveAs = function(title, success, error)
|
||||
{
|
||||
DrawioFile.prototype.save.apply(this, arguments);
|
||||
this.saveFile(this.title, null, success, error);
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
SandstormFile.prototype.saveFile = function(title, revision, success, error, unloading)
|
||||
{
|
||||
var data = this.getData();
|
||||
this.title = title;
|
||||
|
||||
var request = new mxXmlRequest('var/drawiodiagram.xml', data, 'PUT');
|
||||
|
||||
request.send(mxUtils.bind(this, function(req)
|
||||
{
|
||||
this.ui.editor.setStatus(mxUtils.htmlEntities(mxResources.get('allChangesSaved')));
|
||||
}), mxUtils.bind(this, function()
|
||||
{
|
||||
this.ui.editor.setStatus(mxUtils.htmlEntities(mxResources.get('unsavedChanges')));
|
||||
}));
|
||||
|
||||
this.contentChanged();
|
||||
|
||||
if (success != null)
|
||||
{
|
||||
success();
|
||||
}
|
||||
};
|
||||
//////////////// End Sandstorm File ///////////////////
|
||||
|
||||
//////////////// Custom menu actions //////////////////
|
||||
|
||||
|
||||
|
||||
//////////////// End custom menu actions //////////////////
|
||||
|
||||
/**
|
||||
* Main
|
||||
*/
|
||||
App.prototype.enableLogging = false;
|
||||
|
||||
App.main(function(ui)
|
||||
{
|
||||
ui.actions.get('save').visible = false;
|
||||
ui.actions.get('exit').visible = false;
|
||||
ui.actions.get('feedback').visible = false;
|
||||
|
||||
// Changes support link in Help menu
|
||||
ui.actions.addAction('support...', function()
|
||||
{
|
||||
window.open('https://support.draw.io/display/DFS/draw.io+for+Sandstorm+Home');
|
||||
});
|
||||
});
|
||||
|
||||
// EditorUi.prototype.isExportToCanvas = function()
|
||||
// {
|
||||
// // LATER: Fix security error caused by foreignObjects in Safari for toDataUri (tainted canvas)
|
||||
// return false;
|
||||
// };
|
||||
|
||||
// // Loads and executes the plugins
|
||||
// if (urlParams['offline'] != '1')
|
||||
// {
|
||||
// var plugins = mxSettings.getPlugins();
|
||||
|
||||
// if (plugins != null && plugins.length > 0 && urlParams['plugins'] != '0')
|
||||
// {
|
||||
// // Global entry point for plugins is Draw.loadPlugin. This is the only
|
||||
// // long-term supported solution for access to the EditorUi instance.
|
||||
// window.Draw = new Object();
|
||||
// window.Draw.loadPlugin = function(callback)
|
||||
// {
|
||||
// callback(ui);
|
||||
// };
|
||||
|
||||
// if (plugins.length == 1 && (plugins[0].charAt(0) == '/' ||
|
||||
// plugins[0].indexOf(window.location.protocol + '//' + window.location.host) == 0))
|
||||
// {
|
||||
// mxscript(plugins[0]);
|
||||
// }
|
||||
// // Loads plugins asynchronously
|
||||
// else if (mxUtils.confirm(mxResources.get('pluginWarning', [plugins.join('\n')]).replace(/\\n/g, '\n')))
|
||||
// {
|
||||
// for (var i = 0; i < plugins.length; i++)
|
||||
// {
|
||||
// mxscript(plugins[i]);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
#! /bin/bash
|
||||
#
|
||||
# Copyright (c) 2016, JGraph Ltd
|
||||
|
||||
# https://stackoverflow.com/questions/59895/can-a-bash-script-tell-what-directory-its-stored-in
|
||||
mkdir -p build/.sandstorm/client
|
||||
cp -v ssindex.html build/.sandstorm/client
|
||||
cp -v sandstorm-pkgdef.capnp build/.sandstorm
|
||||
cp -v ChangeLog build/.sandstorm
|
||||
cp -v pgp-keyring build/.sandstorm
|
||||
cp -v pgp-signature build/.sandstorm
|
||||
cp -v description.md build/.sandstorm
|
||||
cp -v shortDesc.txt build/.sandstorm
|
||||
cp -v Makefile build/.sandstorm
|
||||
cp -v server.c++ build/.sandstorm
|
||||
cp -v ../../war/export.html build/.sandstorm/client
|
||||
cp -v ../../war/favicon.ico build/.sandstorm/client
|
||||
cp -v ../../war/open.html build/.sandstorm/client
|
||||
cp -v ../../war/stencils.xml build/.sandstorm/client
|
||||
cp -v ../../war/search.xml build/.sandstorm/client
|
||||
mkdir -p build/.sandstorm/client/images
|
||||
cp -rf ../../war/images/* build/.sandstorm/client/images/
|
||||
cp -v images/drawio448.png build/.sandstorm/client/images/
|
||||
mkdir -p build/.sandstorm/client/img
|
||||
cp -rf ../../war/img/* build/.sandstorm/client/img/
|
||||
mkdir -p build/.sandstorm/client/js
|
||||
cp -rf ../../war/js/* build/.sandstorm/client/js/
|
||||
mkdir -p build/.sandstorm/client/mxgraph
|
||||
cp -rf ../../war/mxgraph/* build/.sandstorm/client/mxgraph/
|
||||
mkdir -p build/.sandstorm/client/plugins
|
||||
cp -rf ../../war/plugins/* build/.sandstorm/client/plugins/
|
||||
mkdir -p build/.sandstorm/client/resources
|
||||
cp -rf ../../war/resources/* build/.sandstorm/client/resources/
|
||||
mkdir -p build/.sandstorm/client/shapes
|
||||
cp -rf ../../war/shapes/* build/.sandstorm/client/shapes/
|
||||
mkdir -p build/.sandstorm/client/stencils
|
||||
cp -rf ../../war/stencils/* build/.sandstorm/client/stencils/
|
||||
mkdir -p build/.sandstorm/client/styles
|
||||
cp -rf ../../war/styles/* build/.sandstorm/client/styles/
|
||||
mkdir -p build/.sandstorm/client/templates
|
||||
cp -rf ../../war/templates/* build/.sandstorm/client/templates/
|
||||
|
||||
echo "Compressing assets"
|
||||
gfind build/.sandstorm/client -name '*.html' -o -name '*.css' -o -name '*.js' -o -name '*.txt' -o -name '*.xml' | xargs gzip -k
|
||||
|
||||
echo "Creating file list"
|
||||
cd build/.sandstorm
|
||||
gfind ./client -type f -printf "%p\n" | cut -c 3- > sandstorm-files.list
|
||||
cat ../../rootFiles >> sandstorm-files.list
|
Loading…
Reference in a new issue