From 6c7af575296a06223765388b96cc71ffcfd079f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Mon, 17 Oct 2016 11:56:42 +0200 Subject: [PATCH] Initial import of new UI (compiled JS code) (#2220) * Normalizing dapps format for signer. * Adding new ui * Adding New UI to dapps * Adding parity styles for signer errors * Adding pre-compiled JS as submodule * Fixing struct declaration [ci:skip] * Bumping js * Adding styles * build dest * Correct whitespace @tomusdrw please note the alterations - no mixing tabs and spaces in the indentation portion and always just one tab per indent. --- .gitmodules | 3 + Cargo.lock | 27 +++-- dapps/Cargo.toml | 7 +- dapps/js-glue/Cargo.toml | 31 ++++++ dapps/js-glue/README.md | 65 +++++++++++ dapps/js-glue/build.rs | 45 ++++++++ dapps/js-glue/src/build.rs | 66 +++++++++++ dapps/js-glue/src/codegen.rs | 189 ++++++++++++++++++++++++++++++++ dapps/js-glue/src/js.rs | 89 +++++++++++++++ dapps/js-glue/src/lib.rs | 39 +++++++ dapps/js-glue/src/lib.rs.in | 45 ++++++++ dapps/src/apps/mod.rs | 57 +++++++++- dapps/src/lib.rs | 5 +- dapps/ui/Cargo.toml | 19 ++++ dapps/ui/build.rs | 22 ++++ dapps/ui/src/lib.rs | 22 ++++ dapps/ui/src/lib.rs.in | 55 ++++++++++ js/build | 1 + signer/Cargo.toml | 9 +- signer/src/lib.rs | 4 - signer/src/ws_server/session.rs | 24 ++-- 21 files changed, 794 insertions(+), 30 deletions(-) create mode 100644 dapps/js-glue/Cargo.toml create mode 100644 dapps/js-glue/README.md create mode 100644 dapps/js-glue/build.rs create mode 100644 dapps/js-glue/src/build.rs create mode 100644 dapps/js-glue/src/codegen.rs create mode 100644 dapps/js-glue/src/js.rs create mode 100644 dapps/js-glue/src/lib.rs create mode 100644 dapps/js-glue/src/lib.rs.in create mode 100644 dapps/ui/Cargo.toml create mode 100644 dapps/ui/build.rs create mode 100644 dapps/ui/src/lib.rs create mode 100644 dapps/ui/src/lib.rs.in create mode 160000 js/build diff --git a/.gitmodules b/.gitmodules index 06b71f6ae..a3e70108b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -2,3 +2,6 @@ path = ethcore/res/ethereum/tests url = https://github.com/ethereum/tests.git branch = develop +[submodule "js/build"] + path = js/build + url = https://github.com/ethcore/js-precompiled diff --git a/Cargo.lock b/Cargo.lock index 2cfb39db8..c63bff471 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -337,9 +337,11 @@ dependencies = [ "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "mime_guess 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "parity-dapps 1.4.0 (git+https://github.com/ethcore/parity-ui.git)", + "parity-dapps-glue 1.4.0", "parity-dapps-home 1.4.0 (git+https://github.com/ethcore/parity-ui.git)", "parity-dapps-status 1.4.0 (git+https://github.com/ethcore/parity-ui.git)", "parity-dapps-wallet 1.4.0 (git+https://github.com/ethcore/parity-ui.git)", + "parity-ui 1.4.0", "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -505,8 +507,8 @@ dependencies = [ "ethcore-util 1.4.0", "jsonrpc-core 3.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-dapps 1.4.0 (git+https://github.com/ethcore/parity-ui.git)", - "parity-dapps-signer 1.4.0 (git+https://github.com/ethcore/parity-ui.git)", + "parity-dapps-glue 1.4.0", + "parity-ui 1.4.0", "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "ws 0.5.2 (git+https://github.com/ethcore/ws-rs.git?branch=mio-upstream-stable)", @@ -1180,15 +1182,20 @@ dependencies = [ ] [[package]] -name = "parity-dapps-home" +name = "parity-dapps-glue" version = "1.4.0" -source = "git+https://github.com/ethcore/parity-ui.git#8b1c31319228ad4cf9bd4ae740a0b933aa9e19c7" dependencies = [ - "parity-dapps 1.4.0 (git+https://github.com/ethcore/parity-ui.git)", + "aster 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", + "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "mime_guess 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "quasi 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "quasi_codegen 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex_syntax 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "parity-dapps-signer" +name = "parity-dapps-home" version = "1.4.0" source = "git+https://github.com/ethcore/parity-ui.git#8b1c31319228ad4cf9bd4ae740a0b933aa9e19c7" dependencies = [ @@ -1211,6 +1218,13 @@ dependencies = [ "parity-dapps 1.4.0 (git+https://github.com/ethcore/parity-ui.git)", ] +[[package]] +name = "parity-ui" +version = "1.4.0" +dependencies = [ + "parity-dapps-glue 1.4.0", +] + [[package]] name = "parking_lot" version = "0.2.6" @@ -1985,7 +1999,6 @@ dependencies = [ "checksum odds 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)" = "b28c06e81b0f789122d415d6394b5fe849bde8067469f4c2980d3cdc10c78ec1" "checksum parity-dapps 1.4.0 (git+https://github.com/ethcore/parity-ui.git)" = "" "checksum parity-dapps-home 1.4.0 (git+https://github.com/ethcore/parity-ui.git)" = "" -"checksum parity-dapps-signer 1.4.0 (git+https://github.com/ethcore/parity-ui.git)" = "" "checksum parity-dapps-status 1.4.0 (git+https://github.com/ethcore/parity-ui.git)" = "" "checksum parity-dapps-wallet 1.4.0 (git+https://github.com/ethcore/parity-ui.git)" = "" "checksum parking_lot 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "e0fd1be2c3cf5fef20a6d18fec252c4f3c87c14fc3039002eb7d4ed91e436826" diff --git a/dapps/Cargo.toml b/dapps/Cargo.toml index 1019e5460..8eb343e68 100644 --- a/dapps/Cargo.toml +++ b/dapps/Cargo.toml @@ -27,11 +27,15 @@ ethcore-devtools = { path = "../devtools" } ethcore-rpc = { path = "../rpc" } ethcore-util = { path = "../util" } fetch = { path = "../util/fetch" } +parity-ui = { path = "./ui" } +parity-dapps-glue = { path = "./js-glue" } +### DEPRECATED parity-dapps = { git = "https://github.com/ethcore/parity-ui.git", version = "1.4" } -# List of apps parity-dapps-status = { git = "https://github.com/ethcore/parity-ui.git", version = "1.4" } parity-dapps-home = { git = "https://github.com/ethcore/parity-ui.git", version = "1.4" } parity-dapps-wallet = { git = "https://github.com/ethcore/parity-ui.git", version = "1.4", optional = true } +### /DEPRECATED + mime_guess = { version = "1.6.1" } clippy = { version = "0.0.90", optional = true} @@ -45,6 +49,7 @@ nightly = ["serde_macros"] dev = ["clippy", "ethcore-rpc/dev", "ethcore-util/dev"] use-precompiled-js = [ + "parity-ui/use-precompiled-js", "parity-dapps-status/use-precompiled-js", "parity-dapps-home/use-precompiled-js", "parity-dapps-wallet/use-precompiled-js" diff --git a/dapps/js-glue/Cargo.toml b/dapps/js-glue/Cargo.toml new file mode 100644 index 000000000..b85122e90 --- /dev/null +++ b/dapps/js-glue/Cargo.toml @@ -0,0 +1,31 @@ +[package] +description = "Base Package for all Parity built-in dapps" +name = "parity-dapps-glue" +version = "1.4.0" +license = "GPL-3.0" +authors = ["Ethcore + ``` + + The `inject.js` script will create global `web3` instance with proper provider that should be used by your dapp. + +1. Create `./parity/dapps/myapp/Cargo.toml` with you apps details. See example here: [parity-status Cargo.toml](https://github.com/ethcore/parity-ui/blob/master/status/Cargo.toml). + + ```bash + $ git clone https://github.com/ethcore/parity-ui.git + $ cd ./parity-ui/ + $ cp ./home/Cargo.toml ../parity/dapps/myapp/Cargo.toml + $ cp ./home/build.rs ../parity/dapps/myapp/build.rs + $ cp ./home/src/lib.rs ../parity/dapps/myapp/src/lib.rs + $ cp ./home/src/lib.rs.in ../parity/dapps/myapp/src/lib.rs.in + # And edit the details of your app + $ vim ../parity/dapps/myapp/Cargo.toml # Edit the details + $ vim ./parity/dapps/myapp/src/lib.rs.in # Edit the details + ``` +# How to include your Dapp into `Parity`? +1. Edit `dapps/Cargo.toml` and add dependency to your application (it can be optional) + + ```toml + # Use git repo and version + parity-dapps-myapp = { path="./myapp" } + ``` + +1. Edit `dapps/src/apps.rs` and add your application to `all_pages` (if it's optional you need to specify two functions - see `parity-dapps-wallet` example) + +1. Compile parity. + + ```bash + $ cargo build --release # While inside `parity` + ``` + +1. Commit the results. + + ```bash + $ git add myapp && git commit -am "My first Parity Dapp". + ``` diff --git a/dapps/js-glue/build.rs b/dapps/js-glue/build.rs new file mode 100644 index 000000000..82f990188 --- /dev/null +++ b/dapps/js-glue/build.rs @@ -0,0 +1,45 @@ +// Copyright 2015, 2016 Ethcore (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + + +#[cfg(feature = "with-syntex")] +mod inner { + extern crate syntex; + extern crate quasi_codegen; + + use std::env; + use std::path::Path; + + pub fn main() { + let out_dir = env::var_os("OUT_DIR").unwrap(); + let mut registry = syntex::Registry::new(); + quasi_codegen::register(&mut registry); + + let src = Path::new("src/lib.rs.in"); + let dst = Path::new(&out_dir).join("lib.rs"); + + registry.expand("", &src, &dst).unwrap(); + } +} + +#[cfg(not(feature = "with-syntex"))] +mod inner { + pub fn main() {} +} + +fn main() { + inner::main(); +} diff --git a/dapps/js-glue/src/build.rs b/dapps/js-glue/src/build.rs new file mode 100644 index 000000000..86c93171b --- /dev/null +++ b/dapps/js-glue/src/build.rs @@ -0,0 +1,66 @@ + +#[cfg(feature = "with-syntex")] +pub mod inner { + use syntex; + use codegen; + use syntax::{ast, fold}; + use std::env; + use std::path::Path; + + fn strip_attributes(krate: ast::Crate) -> ast::Crate { + /// Helper folder that strips the serde attributes after the extensions have been expanded. + struct StripAttributeFolder; + + impl fold::Folder for StripAttributeFolder { + fn fold_attribute(&mut self, attr: ast::Attribute) -> Option { + match attr.node.value.node { + ast::MetaItemKind::List(ref n, _) if n == &"webapp" => { return None; } + _ => {} + } + + Some(attr) + } + + fn fold_mac(&mut self, mac: ast::Mac) -> ast::Mac { + fold::noop_fold_mac(mac, self) + } + } + + fold::Folder::fold_crate(&mut StripAttributeFolder, krate) + } + + pub fn register(reg: &mut syntex::Registry) { + reg.add_attr("feature(custom_derive)"); + reg.add_attr("feature(custom_attribute)"); + + reg.add_decorator("derive_WebAppFiles", codegen::expand_webapp_implementation); + reg.add_post_expansion_pass(strip_attributes); + } + + pub fn generate() { + let out_dir = env::var_os("OUT_DIR").unwrap(); + let mut registry = syntex::Registry::new(); + register(&mut registry); + + let src = Path::new("src/lib.rs.in"); + let dst = Path::new(&out_dir).join("lib.rs"); + + registry.expand("", &src, &dst).unwrap(); + } +} + +#[cfg(not(feature = "with-syntex"))] +pub mod inner { + use codegen; + + pub fn register(reg: &mut rustc_plugin::Registry) { + reg.register_syntax_extension( + syntax::parse::token::intern("derive_WebAppFiles"), + syntax::ext::base::MultiDecorator( + Box::new(codegen::expand_webapp_implementation))); + + reg.register_attribute("webapp".to_owned(), AttributeType::Normal); + } + + pub fn generate() {} +} diff --git a/dapps/js-glue/src/codegen.rs b/dapps/js-glue/src/codegen.rs new file mode 100644 index 000000000..1a6b6fc7e --- /dev/null +++ b/dapps/js-glue/src/codegen.rs @@ -0,0 +1,189 @@ +// Copyright 2015, 2016 Ethcore (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +extern crate aster; +extern crate glob; +extern crate mime_guess; + +use self::mime_guess::guess_mime_type; +use std::path::{self, Path, PathBuf}; +use std::ops::Deref; + +use syntax::ast::{MetaItem, Item}; + +use syntax::ast; +use syntax::attr; +use syntax::codemap::Span; +use syntax::ext::base::{Annotatable, ExtCtxt}; +use syntax::ptr::P; +use syntax::print::pprust::{lit_to_string}; +use syntax::parse::token::{InternedString}; + + +pub fn expand_webapp_implementation( + cx: &mut ExtCtxt, + span: Span, + meta_item: &MetaItem, + annotatable: &Annotatable, + push: &mut FnMut(Annotatable) +) { + let item = match *annotatable { + Annotatable::Item(ref item) => item, + _ => { + cx.span_err(meta_item.span, "`#[derive(WebAppFiles)]` may only be applied to struct implementations"); + return; + }, + }; + let builder = aster::AstBuilder::new().span(span); + implement_webapp(cx, &builder, &item, push); +} + +fn implement_webapp(cx: &ExtCtxt, builder: &aster::AstBuilder, item: &Item, push: &mut FnMut(Annotatable)) { + let static_files_dir = extract_path(cx, item); + + let src = Path::new("src"); + let static_files = { + let mut buf = src.to_path_buf(); + buf.push(static_files_dir.deref()); + buf + }; + + let search_location = { + let mut buf = static_files.to_path_buf(); + buf.push("**"); + buf.push("*"); + buf + }; + + let files = glob::glob(search_location.to_str().expect("Valid UTF8 path")) + .expect("The sources directory is missing.") + .collect::, glob::GlobError>>() + .expect("There should be no error when reading a list of files."); + + let statements = files + .iter() + .filter(|path_buf| path_buf.is_file()) + .map(|path_buf| { + let path = path_buf.as_path(); + let filename = path.file_name().and_then(|s| s.to_str()).expect("Only UTF8 paths."); + let mime_type = guess_mime_type(filename).to_string(); + let file_path = as_uri(path.strip_prefix(&static_files).ok().expect("Prefix is always there, cause it's absolute path;qed")); + let file_path_in_source = path.to_str().expect("Only UTF8 paths."); + + let path_lit = builder.expr().str(file_path.as_str()); + let mime_lit = builder.expr().str(mime_type.as_str()); + let web_path_lit = builder.expr().str(file_path_in_source); + let separator_lit = builder.expr().str(path::MAIN_SEPARATOR.to_string().as_str()); + let concat_id = builder.id("concat!"); + let env_id = builder.id("env!"); + let macro_id = builder.id("include_bytes!"); + + let content = quote_expr!( + cx, + $macro_id($concat_id($env_id("CARGO_MANIFEST_DIR"), $separator_lit, $web_path_lit)) + ); + quote_stmt!( + cx, + files.insert($path_lit, File { path: $path_lit, content_type: $mime_lit, content: $content }); + ).expect("The statement is always ok, because it just uses literals.") + }).collect::>(); + + let type_name = item.ident; + + let files_impl = quote_item!(cx, + impl $type_name { + fn files() -> ::std::collections::HashMap<&'static str, File> { + let mut files = ::std::collections::HashMap::new(); + $statements + files + } + } + ).unwrap(); + + push(Annotatable::Item(files_impl)); +} + +fn extract_path(cx: &ExtCtxt, item: &Item) -> String { + for meta_items in item.attrs().iter().filter_map(webapp_meta_items) { + for meta_item in meta_items { + match meta_item.node { + ast::MetaItemKind::NameValue(ref name, ref lit) if name == &"path" => { + if let Some(s) = get_str_from_lit(cx, name, lit) { + return s.deref().to_owned(); + } + }, + _ => {}, + } + } + } + + // default + "web".to_owned() +} + +fn get_str_from_lit(cx: &ExtCtxt, name: &str, lit: &ast::Lit) -> Option { + match lit.node { + ast::LitKind::Str(ref s, _) => Some(s.clone()), + _ => { + cx.span_err( + lit.span, + &format!("webapp annotation `{}` must be a string, not `{}`", + name, + lit_to_string(lit) + ) + ); + return None; + } + } +} + +fn webapp_meta_items(attr: &ast::Attribute) -> Option<&[P]> { + match attr.node.value.node { + ast::MetaItemKind::List(ref name, ref items) if name == &"webapp" => { + attr::mark_used(&attr); + Some(items) + } + _ => None + } +} + +fn as_uri(path: &Path) -> String { + let mut s = String::new(); + for component in path.iter() { + s.push_str(component.to_str().expect("Only UTF-8 filenames are supported.")); + s.push('/'); + } + s[0..s.len()-1].into() +} + + +#[test] +fn should_convert_path_separators_on_all_platforms() { + // given + let p = { + let mut p = PathBuf::new(); + p.push("web"); + p.push("src"); + p.push("index.html"); + p + }; + + // when + let path = as_uri(&p); + + // then + assert_eq!(path, "web/src/index.html".to_owned()); +} diff --git a/dapps/js-glue/src/js.rs b/dapps/js-glue/src/js.rs new file mode 100644 index 000000000..d3593a306 --- /dev/null +++ b/dapps/js-glue/src/js.rs @@ -0,0 +1,89 @@ +// Copyright 2015, 2016 Ethcore (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +#![cfg_attr(feature="use-precompiled-js", allow(dead_code))] +#![cfg_attr(feature="use-precompiled-js", allow(unused_imports))] + +use std::fmt; +use std::process::Command; + +#[cfg(not(windows))] +mod platform { + use std::process::Command; + + pub static NPM_CMD: &'static str = "npm"; + pub fn handle_fd(cmd: &mut Command) -> &mut Command { + cmd + } +} + +#[cfg(windows)] +mod platform { + use std::process::{Command, Stdio}; + + pub static NPM_CMD: &'static str = "npm.cmd"; + // NOTE [ToDr] For some reason on windows + // We cannot have any file descriptors open when running a child process + // during build phase. + pub fn handle_fd(cmd: &mut Command) -> &mut Command { + cmd.stdin(Stdio::null()) + .stdout(Stdio::null()) + .stderr(Stdio::null()) + } +} + +fn die(s: &'static str, e: T) -> ! { + panic!("Error: {}: {:?}", s, e); +} + +#[cfg(feature = "use-precompiled-js")] +pub fn test(_path: &str) { +} +#[cfg(feature = "use-precompiled-js")] +pub fn build(_path: &str) { +} + +#[cfg(not(feature = "use-precompiled-js"))] +pub fn build(path: &str) { + let child = platform::handle_fd(&mut Command::new(platform::NPM_CMD)) + .arg("install") + .arg("--no-progress") + .current_dir(path) + .status() + .unwrap_or_else(|e| die("Installing node.js dependencies with npm", e)); + assert!(child.success(), "There was an error installing dependencies."); + + let child = platform::handle_fd(&mut Command::new(platform::NPM_CMD)) + .arg("run") + .arg("build") + .env("NODE_ENV", "production") + .env("BUILD_DEST", "build") + .current_dir(path) + .status() + .unwrap_or_else(|e| die("Building JS code", e)); + assert!(child.success(), "There was an error build JS code."); +} + +#[cfg(not(feature = "use-precompiled-js"))] +pub fn test(path: &str) { + let child = Command::new(platform::NPM_CMD) + .arg("run") + .arg("test") + .current_dir(path) + .status() + .unwrap_or_else(|e| die("Running test command", e)); + assert!(child.success(), "There was an error while running JS tests."); +} diff --git a/dapps/js-glue/src/lib.rs b/dapps/js-glue/src/lib.rs new file mode 100644 index 000000000..28ac8d712 --- /dev/null +++ b/dapps/js-glue/src/lib.rs @@ -0,0 +1,39 @@ +// Copyright 2015, 2016 Ethcore (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + + +#![cfg_attr(not(feature = "with-syntex"), feature(rustc_private, plugin))] +#![cfg_attr(not(feature = "with-syntex"), plugin(quasi_macros))] + +#[cfg(feature = "with-syntex")] +extern crate syntex; + +#[cfg(feature = "with-syntex")] +#[macro_use] +extern crate syntex_syntax as syntax; + +#[cfg(feature = "with-syntex")] +include!(concat!(env!("OUT_DIR"), "/lib.rs")); + +#[cfg(not(feature = "with-syntex"))] +#[macro_use] +extern crate syntax; + +#[cfg(not(feature = "with-syntex"))] +extern crate rustc_plugin; + +#[cfg(not(feature = "with-syntex"))] +include!("lib.rs.in"); diff --git a/dapps/js-glue/src/lib.rs.in b/dapps/js-glue/src/lib.rs.in new file mode 100644 index 000000000..fa6c17de5 --- /dev/null +++ b/dapps/js-glue/src/lib.rs.in @@ -0,0 +1,45 @@ +// Copyright 2015, 2016 Ethcore (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +extern crate quasi; + +mod codegen; +mod build; +pub mod js; +pub use build::inner::generate; + +use std::default::Default; + +#[derive(Clone)] +pub struct File { + pub path: &'static str, + pub content: &'static [u8], + pub content_type: &'static str, +} + +#[derive(Clone, Debug)] +pub struct Info { + pub name: &'static str, + pub version: &'static str, + pub author: &'static str, + pub description: &'static str, + pub icon_url: &'static str, +} + +pub trait WebApp : Default + Send + Sync { + fn file(&self, path: &str) -> Option<&File>; + fn info(&self) -> Info; +} diff --git a/dapps/src/apps/mod.rs b/dapps/src/apps/mod.rs index 65bee587d..90f22be12 100644 --- a/dapps/src/apps/mod.rs +++ b/dapps/src/apps/mod.rs @@ -17,7 +17,8 @@ use endpoint::{Endpoints, Endpoint}; use page::PageEndpoint; use proxypac::ProxyPac; -use parity_dapps::WebApp; +use parity_dapps::{self, WebApp}; +use parity_dapps_glue::WebApp as NewWebApp; mod cache; mod fs; @@ -27,6 +28,7 @@ pub mod manifest; extern crate parity_dapps_status; extern crate parity_dapps_home; +extern crate parity_ui; pub const DAPPS_DOMAIN : &'static str = ".parity"; pub const RPC_PATH : &'static str = "rpc"; @@ -57,9 +59,13 @@ pub fn all_endpoints(dapps_path: String) -> Endpoints { pages.insert("home".into(), Box::new( PageEndpoint::new_safe_to_embed(parity_dapps_home::App::default()) )); + // NOTE [ToDr] Dapps will be currently embeded on 8180 + pages.insert("ui".into(), Box::new( + PageEndpoint::new_safe_to_embed(NewUi::default()) + )); pages.insert("proxy".into(), ProxyPac::boxed()); - insert::(&mut pages, "parity"); insert::(&mut pages, "status"); + insert::(&mut pages, "parity"); // Optional dapps wallet_page(&mut pages); @@ -78,3 +84,50 @@ fn wallet_page(_pages: &mut Endpoints) {} fn insert(pages: &mut Endpoints, id: &str) { pages.insert(id.to_owned(), Box::new(PageEndpoint::new(T::default()))); } + +// TODO [ToDr] Temporary wrapper until we get rid of old built-ins. +use std::collections::HashMap; + +struct NewUi { + app: parity_ui::App, + files: HashMap<&'static str, parity_dapps::File>, +} + +impl Default for NewUi { + fn default() -> Self { + let app = parity_ui::App::default(); + let files = { + let mut files = HashMap::new(); + for (k, v) in &app.files { + files.insert(*k, parity_dapps::File { + path: v.path, + content: v.content, + content_type: v.content_type, + }); + } + files + }; + + NewUi { + app: app, + files: files, + } + } +} + +impl WebApp for NewUi { + fn file(&self, path: &str) -> Option<&parity_dapps::File> { + self.files.get(path) + } + + fn info(&self) -> parity_dapps::Info { + let info = self.app.info(); + parity_dapps::Info { + name: info.name, + version: info.version, + author: info.author, + description: info.description, + icon_url: info.icon_url, + } + } +} diff --git a/dapps/src/lib.rs b/dapps/src/lib.rs index cac42f893..d863de18a 100644 --- a/dapps/src/lib.rs +++ b/dapps/src/lib.rs @@ -57,7 +57,6 @@ extern crate jsonrpc_core; extern crate jsonrpc_http_server; extern crate mime_guess; extern crate rustc_serialize; -extern crate parity_dapps; extern crate ethcore_rpc; extern crate ethcore_util as util; extern crate linked_hash_map; @@ -65,6 +64,10 @@ extern crate fetch; #[cfg(test)] extern crate ethcore_devtools as devtools; +extern crate parity_dapps_glue; +// TODO [ToDr] - Deprecate when we get rid of old dapps. +extern crate parity_dapps; + mod endpoint; mod apps; mod page; diff --git a/dapps/ui/Cargo.toml b/dapps/ui/Cargo.toml new file mode 100644 index 000000000..ff88d0f80 --- /dev/null +++ b/dapps/ui/Cargo.toml @@ -0,0 +1,19 @@ +[package] +description = "Parity built-in dapps." +name = "parity-ui" +version = "1.4.0" +license = "GPL-3.0" +authors = ["Ethcore "] +build = "build.rs" + +[features] +default = ["with-syntex"] +use-precompiled-js = ["parity-dapps-glue/use-precompiled-js"] +with-syntex = ["parity-dapps-glue/with-syntex"] + +[build-dependencies] +parity-dapps-glue = { path = "../js-glue" } + +[dependencies] +parity-dapps-glue = { path = "../js-glue" } + diff --git a/dapps/ui/build.rs b/dapps/ui/build.rs new file mode 100644 index 000000000..c4982b09c --- /dev/null +++ b/dapps/ui/build.rs @@ -0,0 +1,22 @@ +// Copyright 2015, 2016 Ethcore (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +extern crate parity_dapps_glue; + +fn main() { + parity_dapps_glue::js::build(concat!(env!("CARGO_MANIFEST_DIR"), "../../js")); + parity_dapps_glue::generate(); +} diff --git a/dapps/ui/src/lib.rs b/dapps/ui/src/lib.rs new file mode 100644 index 000000000..25d336fab --- /dev/null +++ b/dapps/ui/src/lib.rs @@ -0,0 +1,22 @@ +// Copyright 2015, 2016 Ethcore (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +#[cfg(feature = "with-syntex")] +include!(concat!(env!("OUT_DIR"), "/lib.rs")); + +#[cfg(not(feature = "with-syntex"))] +include!("lib.rs.in"); + diff --git a/dapps/ui/src/lib.rs.in b/dapps/ui/src/lib.rs.in new file mode 100644 index 000000000..81f46086d --- /dev/null +++ b/dapps/ui/src/lib.rs.in @@ -0,0 +1,55 @@ +// Copyright 2015, 2016 Ethcore (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +extern crate parity_dapps_glue; + +use std::collections::HashMap; +use parity_dapps_glue::{WebApp, File, Info}; + +#[derive(WebAppFiles)] +#[webapp(path = "../../../js/build")] +pub struct App { + pub files: HashMap<&'static str, File>, +} + +impl Default for App { + fn default() -> App { + App { + files: Self::files(), + } + } +} + +impl WebApp for App { + fn file(&self, path: &str) -> Option<&File> { + self.files.get(path) + } + + fn info(&self) -> Info { + Info { + name: "Parity UI", + version: env!("CARGO_PKG_VERSION"), + author: "Ethcore ", + description: "New UI for Parity. (Experimental)", + icon_url: "icon.png", + } + } +} + +#[test] +fn test_js() { + parity_dapps_glue::js::build(concat!(env!("CARGO_MANIFEST_DIR"), "../../js")); +} diff --git a/js/build b/js/build new file mode 160000 index 000000000..95a7d08eb --- /dev/null +++ b/js/build @@ -0,0 +1 @@ +Subproject commit 95a7d08eb67e6e31367af6bf7fa874128d71c1df diff --git a/signer/Cargo.toml b/signer/Cargo.toml index 43b6bd84a..892b5009c 100644 --- a/signer/Cargo.toml +++ b/signer/Cargo.toml @@ -20,12 +20,13 @@ ethcore-util = { path = "../util" } ethcore-io = { path = "../util/io" } ethcore-rpc = { path = "../rpc" } ethcore-devtools = { path = "../devtools" } -parity-dapps = { git = "https://github.com/ethcore/parity-ui.git", version = "1.4", optional = true} -parity-dapps-signer = { git = "https://github.com/ethcore/parity-ui.git", version = "1.4", optional = true} +parity-dapps-glue = { path = "../dapps/js-glue", version = "1.4", optional = true} +parity-ui = { path = "../dapps/ui", version = "1.4", optional = true} clippy = { version = "0.0.90", optional = true} [features] dev = ["clippy"] -ui = ["parity-dapps", "parity-dapps-signer"] -use-precompiled-js = ["parity-dapps-signer/use-precompiled-js"] +ui = ["parity-dapps-glue", "parity-ui"] +use-precompiled-js = ["parity-ui/use-precompiled-js"] + diff --git a/signer/src/lib.rs b/signer/src/lib.rs index 630cefb82..f05d8c625 100644 --- a/signer/src/lib.rs +++ b/signer/src/lib.rs @@ -52,10 +52,6 @@ extern crate ethcore_io as io; extern crate ethcore_rpc as rpc; extern crate jsonrpc_core; extern crate ws; -#[cfg(feature = "ui")] -extern crate parity_dapps_signer as signer; -#[cfg(feature = "ui")] -extern crate parity_dapps as dapps; #[cfg(test)] extern crate ethcore_devtools as devtools; diff --git a/signer/src/ws_server/session.rs b/signer/src/ws_server/session.rs index 14c619a28..45146f988 100644 --- a/signer/src/ws_server/session.rs +++ b/signer/src/ws_server/session.rs @@ -25,13 +25,15 @@ use jsonrpc_core::IoHandler; use util::{H256, Mutex, version}; #[cfg(feature = "ui")] -mod signer { - use signer::SignerApp; - use dapps::{self, WebApp}; +mod ui { + extern crate parity_ui as ui; + extern crate parity_dapps_glue as dapps; + + use self::dapps::WebApp; #[derive(Default)] pub struct Handler { - signer: SignerApp, + ui: ui::App, } impl Handler { @@ -40,20 +42,20 @@ mod signer { "" | "/" => "index.html", path => &path[1..], }; - self.signer.file(file) + self.ui.file(file) } } } #[cfg(not(feature = "ui"))] -mod signer { +mod ui { pub struct File { + pub content: &'static str, pub content: &'static [u8], pub content_type: &'static str, } #[derive(Default)] - pub struct Handler { - } + pub struct Handler; impl Handler { pub fn handle(&self, _req: &str) -> Option<&File> { @@ -125,7 +127,7 @@ pub struct Session { self_origin: String, authcodes_path: PathBuf, handler: Arc, - file_handler: Arc, + file_handler: Arc, } impl ws::Handler for Session { @@ -200,7 +202,7 @@ pub struct Factory { skip_origin_validation: bool, self_origin: String, authcodes_path: PathBuf, - file_handler: Arc, + file_handler: Arc, } impl Factory { @@ -210,7 +212,7 @@ impl Factory { skip_origin_validation: skip_origin_validation, self_origin: self_origin, authcodes_path: authcodes_path, - file_handler: Arc::new(signer::Handler::default()), + file_handler: Arc::new(ui::Handler::default()), } } }