pageflow-react 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/.jshintrc +15 -0
- data/CHANGELOG.md +7 -0
- data/Gemfile +10 -0
- data/LICENSE.txt +22 -0
- data/README.md +40 -0
- data/Rakefile +4 -0
- data/app/assets/javascripts/pageflow/react.js +8975 -0
- data/app/assets/javascripts/pageflow/react/components.js +4 -0
- data/app/views/pageflow/react/_widget.html.erb +1 -0
- data/app/views/pageflow/react/page.html.erb +7 -0
- data/js/.eslintrc +33 -0
- data/js/.gitignore +1 -0
- data/js/karma.conf.js +61 -0
- data/js/package.json +43 -0
- data/js/spec/.eslintrc +8 -0
- data/js/spec/components/background_image_spec.js +47 -0
- data/js/spec/components/page_thumbnail_spec.js +213 -0
- data/js/spec/create_container_spec.js +82 -0
- data/js/spec/resolve_spec.js +3 -0
- data/js/spec/resolvers/backbone_model_resolver_spec.js +256 -0
- data/js/spec/resolvers/create_recursive_resolver_spec.js +120 -0
- data/js/spec/resolvers/editor_file_ids_resolver_spec.js +49 -0
- data/js/spec/resolvers/i18n_resolver_spec.js +20 -0
- data/js/spec/resolvers/object_resolver_spec.js +165 -0
- data/js/spec/resolvers/page_type_resolver_spec.js +23 -0
- data/js/spec/resolvers/seed_resolver_spec.js +128 -0
- data/js/spec/stub_spec.js +16 -0
- data/js/spec/support/render_component.js +7 -0
- data/js/src/components/background_image.jsx +60 -0
- data/js/src/components/lazy_background_image.jsx +23 -0
- data/js/src/components/lazy_loaded_page_thumbnail.jsx +19 -0
- data/js/src/components/page_background.jsx +11 -0
- data/js/src/components/page_background_image.jsx +13 -0
- data/js/src/components/page_content.jsx +51 -0
- data/js/src/components/page_header.jsx +15 -0
- data/js/src/components/page_link.jsx +35 -0
- data/js/src/components/page_shadow.jsx +19 -0
- data/js/src/components/page_text.jsx +17 -0
- data/js/src/components/page_thumbnail.jsx +86 -0
- data/js/src/components/page_wrapper.jsx +11 -0
- data/js/src/components/scroller.js +43 -0
- data/js/src/create_container.jsx +53 -0
- data/js/src/create_page.jsx +38 -0
- data/js/src/create_page_component.jsx +45 -0
- data/js/src/create_page_type.js +57 -0
- data/js/src/create_resolver_root.jsx +21 -0
- data/js/src/create_widget.jsx +3 -0
- data/js/src/create_widget_type.js +12 -0
- data/js/src/index.js +69 -0
- data/js/src/mutate.js +17 -0
- data/js/src/mutations/mutation.js +5 -0
- data/js/src/mutations/update_page_link_mutation.js +30 -0
- data/js/src/mutations/update_page_mutation.js +19 -0
- data/js/src/resolve.js +45 -0
- data/js/src/resolvers/backbone_model_resolver.js +118 -0
- data/js/src/resolvers/create_recursive_resolver.js +20 -0
- data/js/src/resolvers/current_parent_page_resolver.js +38 -0
- data/js/src/resolvers/editor_chapter_resolver.js +10 -0
- data/js/src/resolvers/editor_file_ids_resolver.js +30 -0
- data/js/src/resolvers/editor_page_resolver.js +11 -0
- data/js/src/resolvers/i18n_resolver.js +11 -0
- data/js/src/resolvers/object_resolver.js +58 -0
- data/js/src/resolvers/page_type_resolver.js +12 -0
- data/js/src/resolvers/resolver.js +16 -0
- data/js/src/resolvers/seed_chapter_resolver.js +10 -0
- data/js/src/resolvers/seed_file_ids_resolver.js +11 -0
- data/js/src/resolvers/seed_page_resolver.js +11 -0
- data/js/src/resolvers/seed_resolver.js +75 -0
- data/js/src/utils/camelize.js +29 -0
- data/js/webpack.config.js +31 -0
- data/lib/pageflow-react.rb +13 -0
- data/lib/pageflow/react/engine.rb +15 -0
- data/lib/pageflow/react/page_type.rb +16 -0
- data/lib/pageflow/react/version.rb +5 -0
- data/lib/pageflow/react/widget_type.rb +21 -0
- data/pageflow-react.gemspec +29 -0
- metadata +205 -0
@@ -0,0 +1,10 @@
|
|
1
|
+
import BackboneModelResolver from './backbone_model_resolver';
|
2
|
+
|
3
|
+
export default function(options, callback) {
|
4
|
+
return new BackboneModelResolver({
|
5
|
+
collection: () => pageflow.chapters,
|
6
|
+
attributesForProps: ['id', 'title', 'position'],
|
7
|
+
property: 'chapterId',
|
8
|
+
...options
|
9
|
+
}, callback);
|
10
|
+
};
|
@@ -0,0 +1,30 @@
|
|
1
|
+
import Resolver from './resolver';
|
2
|
+
|
3
|
+
export default class extends Resolver {
|
4
|
+
constructor(options, callback) {
|
5
|
+
super(callback);
|
6
|
+
this._options = {
|
7
|
+
collections: () => pageflow.files,
|
8
|
+
...options
|
9
|
+
};
|
10
|
+
|
11
|
+
Object.values(this._options.collections()).forEach((collection) =>
|
12
|
+
collection.on('remove', this._handleChange, this)
|
13
|
+
);
|
14
|
+
}
|
15
|
+
|
16
|
+
get() {
|
17
|
+
var files = this._options.collections();
|
18
|
+
|
19
|
+
return Object.keys(files).reduce((result, collectionName) => {
|
20
|
+
result[collectionName] = files[collectionName].map((file) => file.id);
|
21
|
+
return result;
|
22
|
+
}, {});
|
23
|
+
}
|
24
|
+
|
25
|
+
dispose() {
|
26
|
+
Object.values(this._options.collections()).forEach((collection) =>
|
27
|
+
collection.off('remove', this._handleChange, this)
|
28
|
+
);
|
29
|
+
}
|
30
|
+
};
|
@@ -0,0 +1,11 @@
|
|
1
|
+
import BackboneModelResolver from './backbone_model_resolver';
|
2
|
+
|
3
|
+
export default function(options, callback) {
|
4
|
+
return new BackboneModelResolver({
|
5
|
+
collection: () => pageflow.pages,
|
6
|
+
idAttribute: 'perma_id',
|
7
|
+
attributesForProps: ['perma_id', ['type', 'template'], 'chapter_id'],
|
8
|
+
includeConfiguration: true,
|
9
|
+
...options
|
10
|
+
}, callback);
|
11
|
+
};
|
@@ -0,0 +1,58 @@
|
|
1
|
+
import Resolver from './resolver';
|
2
|
+
|
3
|
+
export default class ObjectResolver extends Resolver {
|
4
|
+
constructor(fragment, callback, propertyName) {
|
5
|
+
super(callback);
|
6
|
+
this._fragment = fragment;
|
7
|
+
this._resolvers = {};
|
8
|
+
this._propertyName = propertyName;
|
9
|
+
}
|
10
|
+
|
11
|
+
get(props, seed) {
|
12
|
+
this._updateResolvers();
|
13
|
+
|
14
|
+
if (this._propertyName) {
|
15
|
+
props = props[this._propertyName];
|
16
|
+
}
|
17
|
+
|
18
|
+
if (!props) {
|
19
|
+
return null;
|
20
|
+
}
|
21
|
+
|
22
|
+
return Object.keys(this._resolvers).reduce((result, key) => {
|
23
|
+
const resolver = this._resolvers[key];
|
24
|
+
|
25
|
+
result[key] = resolver.get(props, seed);
|
26
|
+
return result;
|
27
|
+
}, {...props});
|
28
|
+
}
|
29
|
+
|
30
|
+
dispose() {
|
31
|
+
Object.keys(this._resolvers).forEach((key) => {
|
32
|
+
this._resolvers[key].dispose();
|
33
|
+
});
|
34
|
+
}
|
35
|
+
|
36
|
+
_updateResolvers() {
|
37
|
+
var resolvers = this._resolvers;
|
38
|
+
|
39
|
+
Object.keys(this._fragment || {}).forEach((key) => {
|
40
|
+
const resolverProvider = this._fragment[key];
|
41
|
+
|
42
|
+
if (!resolvers[key]) {
|
43
|
+
resolvers[key] = this._createResolver(resolverProvider, key);
|
44
|
+
}
|
45
|
+
});
|
46
|
+
}
|
47
|
+
|
48
|
+
_createResolver(provider, key) {
|
49
|
+
var handleChange = this._handleChange.bind(this);
|
50
|
+
|
51
|
+
if (typeof provider === 'object') {
|
52
|
+
return new ObjectResolver(provider, handleChange, key);
|
53
|
+
}
|
54
|
+
else {
|
55
|
+
return provider(handleChange);
|
56
|
+
}
|
57
|
+
}
|
58
|
+
}
|
@@ -0,0 +1,11 @@
|
|
1
|
+
import SeedResolver from './seed_resolver';
|
2
|
+
|
3
|
+
export default function(options, callback) {
|
4
|
+
return new SeedResolver({
|
5
|
+
seedProperty: 'pages',
|
6
|
+
idAttribute: 'perma_id',
|
7
|
+
attributesForProps: ['perma_id', ['type', 'template'], 'chapter_id'],
|
8
|
+
includeConfiguration: true,
|
9
|
+
...options
|
10
|
+
}, callback);
|
11
|
+
};
|
@@ -0,0 +1,75 @@
|
|
1
|
+
import Resolver from './resolver';
|
2
|
+
import createRecursiveResolver from './create_recursive_resolver';
|
3
|
+
|
4
|
+
import camelize from '../utils/camelize';
|
5
|
+
|
6
|
+
/**
|
7
|
+
* Resolves a foreign key to an object of attributes from the seed
|
8
|
+
* data.
|
9
|
+
*/
|
10
|
+
class SeedResolver extends Resolver {
|
11
|
+
constructor(options, callback) {
|
12
|
+
super(callback);
|
13
|
+
|
14
|
+
this._options = {
|
15
|
+
idAttribute: 'id',
|
16
|
+
attributesForProps: ['id'],
|
17
|
+
includeConfiguration: false,
|
18
|
+
...options
|
19
|
+
};
|
20
|
+
}
|
21
|
+
|
22
|
+
get(props, seed) {
|
23
|
+
var attributes = this._getAttributes(props, seed);
|
24
|
+
return this._getProps(attributes);
|
25
|
+
}
|
26
|
+
|
27
|
+
_getAttributes(props, seed) {
|
28
|
+
return this._getAttributesById(this._getModelId(props), seed);
|
29
|
+
}
|
30
|
+
|
31
|
+
_getAttributesById(id, seed) {
|
32
|
+
const collection = seed[this._options.seedProperty];
|
33
|
+
|
34
|
+
if (!collection) {
|
35
|
+
return null;
|
36
|
+
}
|
37
|
+
|
38
|
+
return collection.find((attributes) => {
|
39
|
+
return attributes[this._options.idAttribute] === id;
|
40
|
+
});
|
41
|
+
}
|
42
|
+
|
43
|
+
_getModelId(props) {
|
44
|
+
return props[this._options.property];
|
45
|
+
}
|
46
|
+
|
47
|
+
_getProps(attributes) {
|
48
|
+
var props;
|
49
|
+
|
50
|
+
if (!attributes) {
|
51
|
+
return null;
|
52
|
+
}
|
53
|
+
|
54
|
+
props = this._getPropsFromAttributes(attributes);
|
55
|
+
|
56
|
+
if (this._options.includeConfiguration) {
|
57
|
+
Object.assign(props, camelize.deep(attributes.configuration));
|
58
|
+
}
|
59
|
+
|
60
|
+
return props;
|
61
|
+
}
|
62
|
+
|
63
|
+
_getPropsFromAttributes(attributes) {
|
64
|
+
return this._options.attributesForProps.reduce((result, name) => {
|
65
|
+
if (typeof name === 'string') {
|
66
|
+
name = [camelize(name), name];
|
67
|
+
}
|
68
|
+
|
69
|
+
result[name[0]] = attributes[name[1]];
|
70
|
+
return result;
|
71
|
+
}, {})
|
72
|
+
}
|
73
|
+
};
|
74
|
+
|
75
|
+
export default createRecursiveResolver(SeedResolver);
|
@@ -0,0 +1,29 @@
|
|
1
|
+
function camelize(snakeCase) {
|
2
|
+
return snakeCase.replace(/_[a-z]/g, function(match) {
|
3
|
+
return match[1].toUpperCase();
|
4
|
+
});
|
5
|
+
};
|
6
|
+
|
7
|
+
camelize.keys = function(object) {
|
8
|
+
return Object.keys(object).reduce((result, key) => {
|
9
|
+
result[camelize(key)] = object[key];
|
10
|
+
return result;
|
11
|
+
}, {});
|
12
|
+
};
|
13
|
+
|
14
|
+
camelize.deep = function(object) {
|
15
|
+
if (Array.isArray(object)) {
|
16
|
+
return object.map(camelize.deep);
|
17
|
+
}
|
18
|
+
else if (typeof object === 'object' && object) {
|
19
|
+
return Object.keys(object).reduce((result, key) => {
|
20
|
+
result[camelize(key)] = camelize.deep(object[key]);
|
21
|
+
return result;
|
22
|
+
}, {});
|
23
|
+
}
|
24
|
+
else {
|
25
|
+
return object;
|
26
|
+
}
|
27
|
+
};
|
28
|
+
|
29
|
+
export default camelize;
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module.exports = {
|
2
|
+
context: __dirname + '/src',
|
3
|
+
entry: [
|
4
|
+
'babel-polyfill',
|
5
|
+
'./index.js'
|
6
|
+
],
|
7
|
+
|
8
|
+
module: {
|
9
|
+
loaders: [
|
10
|
+
{
|
11
|
+
test: /\.jsx?$/,
|
12
|
+
exclude: /node_modules/,
|
13
|
+
loaders: ['babel-loader?stage=0'],
|
14
|
+
}
|
15
|
+
],
|
16
|
+
},
|
17
|
+
|
18
|
+
output: {
|
19
|
+
path: __dirname + '/../app/assets/javascripts/pageflow',
|
20
|
+
filename: 'react.js',
|
21
|
+
|
22
|
+
libraryTarget: 'assign',
|
23
|
+
library: ['pageflow', 'react']
|
24
|
+
},
|
25
|
+
|
26
|
+
externals: {
|
27
|
+
pageflow: 'pageflow',
|
28
|
+
react: 'React',
|
29
|
+
'react-dom': 'ReactDOM'
|
30
|
+
}
|
31
|
+
};
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'pageflow/react/engine'
|
2
|
+
|
3
|
+
module Pageflow
|
4
|
+
module React
|
5
|
+
def self.create_page_type(name, component_name)
|
6
|
+
Pageflow::React::PageType.new(name, component_name)
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.create_widget_type(name, role, component_name)
|
10
|
+
Pageflow::React::WidgetType.new(name, role, component_name)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'react-rails'
|
2
|
+
|
3
|
+
module Pageflow
|
4
|
+
module React
|
5
|
+
class Engine < Rails::Engine
|
6
|
+
isolate_namespace Pageflow::React
|
7
|
+
|
8
|
+
config.autoload_paths << File.join(config.root, 'lib')
|
9
|
+
|
10
|
+
initializer "pageflow-react.add_watchable_files", group: :all do |app|
|
11
|
+
app.config.watchable_files.concat Dir["#{config.root}/app/assets/javascripts/**/*.jsx*"]
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Pageflow
|
2
|
+
module React
|
3
|
+
class PageType < Pageflow::PageType
|
4
|
+
attr_reader :name, :component_name
|
5
|
+
|
6
|
+
def initialize(name, component_name)
|
7
|
+
@name = name
|
8
|
+
@component_name = component_name
|
9
|
+
end
|
10
|
+
|
11
|
+
def template_path
|
12
|
+
'pageflow/react/page'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Pageflow
|
2
|
+
module React
|
3
|
+
class WidgetType < Pageflow::WidgetType
|
4
|
+
attr_reader :name, :role, :component_name
|
5
|
+
|
6
|
+
def initialize(name, role, component_name)
|
7
|
+
@name = name
|
8
|
+
@role = role
|
9
|
+
@component_name = component_name
|
10
|
+
end
|
11
|
+
|
12
|
+
def roles
|
13
|
+
[role]
|
14
|
+
end
|
15
|
+
|
16
|
+
def render(template, _)
|
17
|
+
template.render(File.join('pageflow', 'react', 'widget'), name: name)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'pageflow/react/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "pageflow-react"
|
8
|
+
spec.version = Pageflow::React::VERSION
|
9
|
+
spec.authors = ["Tim Fischbach"]
|
10
|
+
spec.email = ["mail@timfischbach.de"]
|
11
|
+
spec.summary = %q{Building Pageflow page types with React.js}
|
12
|
+
spec.homepage = "https://github.com/codevise/pageflow-react"
|
13
|
+
spec.license = "MIT"
|
14
|
+
|
15
|
+
spec.files = `git ls-files`.split($/)
|
16
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
17
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
|
+
spec.require_paths = ["lib"]
|
19
|
+
|
20
|
+
spec.add_dependency "pageflow", "~> 0.10"
|
21
|
+
spec.add_dependency "react-rails", "~> 1.6.0"
|
22
|
+
spec.add_dependency "multi_json", "~> 1.11"
|
23
|
+
|
24
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
25
|
+
spec.add_development_dependency "rake"
|
26
|
+
|
27
|
+
# Semantic versioning rake tasks
|
28
|
+
spec.add_development_dependency 'semmy', '~> 0.2'
|
29
|
+
end
|