Removed sandstorm files

This commit is contained in:
David Benson 2019-09-16 09:44:10 +01:00
parent f0a6aa7a46
commit 8298fab035
14 changed files with 0 additions and 1236 deletions

View file

@ -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

View file

@ -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`

View file

@ -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`

View file

@ -1,6 +0,0 @@
#! /bin/bash
#
# Copyright (c) 2016, JGraph Ltd
BUILD="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
cd $BUILD
make server

View file

@ -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.

View file

@ -1,7 +0,0 @@
description.md
Makefile
pgp-keyring
pgp-signature
sandstorm-pkgdef.capnp
server.c++
shortDesc.txt

View file

@ -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")
]
);

View file

@ -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)

View file

@ -1 +0,0 @@
Web Diagramming

View file

@ -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 &amp; 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>

View file

@ -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