├── .gitattributes
├── .gitignore
├── LICENSE
├── README.md
├── frame-nlp-service
├── Dockerfile
├── README.md
├── app
│ ├── __init__.py
│ ├── abstractive_summarizer
│ │ ├── __init__.py
│ │ └── abstractive_summarizer.py
│ ├── bidaf-model-2017.09.15-charpad.tar.gz
│ ├── main.py
│ ├── question_answer_model
│ │ ├── __init__.py
│ │ └── question_answer_model.py
│ ├── requirements.txt
│ └── uwsgi.ini
├── docker-compose.override.yml
└── docker-compose.yml
├── frame-website
├── about.html
├── css
│ ├── homepage.css
│ └── slider.css
├── docs.html
├── download.html
├── iconfonts
│ ├── flaticon.css
│ ├── flaticon.eot
│ ├── flaticon.svg
│ ├── flaticon.ttf
│ └── flaticon.woff
├── images
│ ├── Frame-animated-demo-01-14-2019.gif
│ ├── banner.png
│ ├── frame_screenshot_01-21-2019_alice_in_wonderland_information_extraction.png
│ ├── frame_screenshot_01-21-2019_cryptocurrency_analysis.png
│ ├── frame_screenshot_01-21-2019_sicko_mode_visualization.png
│ ├── frame_screenshot_01-21-2019_this_is_water_summarization.png
│ ├── framed_video_animation_demo.mp4
│ ├── liveforms.png
│ ├── scripteden-logo-g.png
│ └── totoro-horizontal.jpg
├── index.html
├── js
│ ├── homepage.js
│ └── slideshow.js
└── semantic-ui
│ ├── semantic.css
│ ├── semantic.js
│ ├── semantic.min.css
│ └── semantic.min.js
├── frame
├── .babelrc
├── .eslintignore
├── .eslintrc.json
├── .flowconfig
├── .gitattributes
├── .jsbeautifyrc
├── .vscode
│ ├── launch.json
│ └── settings.json
├── README.md
├── custom_node_modules
│ ├── medium-draft
│ │ ├── CHANGELOG.md
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── example
│ │ │ ├── index.js
│ │ │ └── package.json
│ │ ├── index.html
│ │ ├── lib
│ │ │ ├── basic.css
│ │ │ ├── components
│ │ │ │ ├── LinkEditComponent.js
│ │ │ │ ├── addbutton.js
│ │ │ │ ├── blocks
│ │ │ │ │ ├── atomic.js
│ │ │ │ │ ├── blockquotecaption.js
│ │ │ │ │ ├── break.js
│ │ │ │ │ ├── caption.js
│ │ │ │ │ ├── image.js
│ │ │ │ │ ├── text.js
│ │ │ │ │ └── todo.js
│ │ │ │ ├── blocktoolbar.js
│ │ │ │ ├── customrenderer.js
│ │ │ │ ├── entities
│ │ │ │ │ └── link.js
│ │ │ │ ├── inlinetoolbar.js
│ │ │ │ ├── sides
│ │ │ │ │ ├── break.js
│ │ │ │ │ └── image.js
│ │ │ │ ├── stylebutton.js
│ │ │ │ └── toolbar.js
│ │ │ ├── createEditor.js
│ │ │ ├── editor.js
│ │ │ ├── exporter.js
│ │ │ ├── handlers
│ │ │ │ ├── blockRenderMap.js
│ │ │ │ ├── blockRendererFn.js
│ │ │ │ ├── blockStyleFn.js
│ │ │ │ ├── handleBeforeInput.js
│ │ │ │ ├── handleKeyCommand.js
│ │ │ │ ├── handlePastedText.js
│ │ │ │ ├── handleReturn.js
│ │ │ │ ├── index.js
│ │ │ │ ├── keyBindingFn.js
│ │ │ │ ├── onTab.js
│ │ │ │ └── onUpArrow.js
│ │ │ ├── importer.js
│ │ │ ├── index.css
│ │ │ ├── index.js
│ │ │ ├── model
│ │ │ │ ├── content.js
│ │ │ │ └── index.js
│ │ │ └── util
│ │ │ │ ├── beforeinput.js
│ │ │ │ ├── blockStyleFn.js
│ │ │ │ ├── constants.js
│ │ │ │ ├── customstylemap.js
│ │ │ │ ├── index.js
│ │ │ │ ├── keybinding.js
│ │ │ │ └── rendermap.js
│ │ ├── package.json
│ │ └── rendered.html
│ └── node-sumbasic
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── package.json
│ │ └── src
│ │ ├── demo.js
│ │ └── index.js
├── package-lock.json
├── package.json
├── public
│ └── electron.js
├── src
│ ├── assets
│ │ ├── css
│ │ │ ├── all.css
│ │ │ ├── all.min.css
│ │ │ ├── brands.css
│ │ │ ├── brands.min.css
│ │ │ ├── fontawesome.css
│ │ │ ├── fontawesome.min.css
│ │ │ ├── quill.snow.css
│ │ │ ├── regular.css
│ │ │ ├── regular.min.css
│ │ │ ├── solid.css
│ │ │ ├── solid.min.css
│ │ │ ├── svg-with-js.css
│ │ │ ├── svg-with-js.min.css
│ │ │ ├── v4-shims.css
│ │ │ └── v4-shims.min.css
│ │ ├── electron.png
│ │ ├── flow.png
│ │ ├── github.png
│ │ ├── js
│ │ │ ├── all.js
│ │ │ ├── all.min.js
│ │ │ ├── brands.js
│ │ │ ├── brands.min.js
│ │ │ ├── fontawesome.js
│ │ │ ├── fontawesome.min.js
│ │ │ ├── regular.js
│ │ │ ├── regular.min.js
│ │ │ ├── solid.js
│ │ │ ├── solid.min.js
│ │ │ ├── v4-shims.js
│ │ │ └── v4-shims.min.js
│ │ ├── react.svg
│ │ ├── redux.svg
│ │ ├── semantic-ui-react.png
│ │ ├── webfonts
│ │ │ ├── fa-brands-400.eot
│ │ │ ├── fa-brands-400.svg
│ │ │ ├── fa-brands-400.ttf
│ │ │ ├── fa-brands-400.woff
│ │ │ ├── fa-brands-400.woff2
│ │ │ ├── fa-regular-400.eot
│ │ │ ├── fa-regular-400.svg
│ │ │ ├── fa-regular-400.ttf
│ │ │ ├── fa-regular-400.woff
│ │ │ ├── fa-regular-400.woff2
│ │ │ ├── fa-solid-900.eot
│ │ │ ├── fa-solid-900.svg
│ │ │ ├── fa-solid-900.ttf
│ │ │ ├── fa-solid-900.woff
│ │ │ └── fa-solid-900.woff2
│ │ └── webpack.svg
│ ├── components
│ │ ├── Analyzer
│ │ │ ├── Analyzer.jsx
│ │ │ ├── Analyzer.scss
│ │ │ └── tabStyle.css
│ │ ├── App
│ │ │ ├── App.jsx
│ │ │ └── App.scss
│ │ ├── Ask
│ │ │ ├── Ask.jsx
│ │ │ └── Ask.scss
│ │ ├── AskMain
│ │ │ ├── AskMain.jsx
│ │ │ └── AskMain.scss
│ │ ├── Brand
│ │ │ ├── Brand.jsx
│ │ │ └── Brand.scss
│ │ ├── EntryCreate
│ │ │ ├── EntryCreate.jsx
│ │ │ └── EntryCreate.scss
│ │ ├── EntryEditForm
│ │ │ ├── EntryEditForm.jsx
│ │ │ └── EntryEditForm.scss
│ │ ├── FJSONEditor
│ │ │ ├── FJSONEditor.jsx
│ │ │ └── FJSONEditor.scss
│ │ ├── Home
│ │ │ ├── Home.jsx
│ │ │ └── Home.scss
│ │ ├── MainMenu
│ │ │ ├── MainMenu.jsx
│ │ │ └── MainMenu.scss
│ │ ├── Notepad
│ │ │ ├── Notepad.jsx
│ │ │ └── Notepad.scss
│ │ ├── SearchLibrary
│ │ │ ├── SearchLibrary.jsx
│ │ │ └── SearchLibrary.scss
│ │ ├── Settings
│ │ │ ├── Settings.jsx
│ │ │ └── Settings.scss
│ │ ├── VisualizeLibrary
│ │ │ ├── VisualizeLibrary.jsx
│ │ │ └── VisualizeLibrary.scss
│ │ ├── Visualizer
│ │ │ ├── Visualizer.jsx
│ │ │ └── Visualizer.scss
│ │ └── vendor
│ │ │ ├── basic.scss
│ │ │ ├── components
│ │ │ ├── LinkEditComponent.js
│ │ │ ├── addbutton.js
│ │ │ ├── addbutton.scss
│ │ │ ├── blocks
│ │ │ │ ├── atomic.js
│ │ │ │ ├── atomic.scss
│ │ │ │ ├── blockquotecaption.js
│ │ │ │ ├── blockquotecaption.scss
│ │ │ │ ├── break.js
│ │ │ │ ├── caption.js
│ │ │ │ ├── caption.scss
│ │ │ │ ├── image.js
│ │ │ │ ├── image.scss
│ │ │ │ ├── text.js
│ │ │ │ ├── text.scss
│ │ │ │ ├── todo.js
│ │ │ │ └── todo.scss
│ │ │ ├── blocktoolbar.js
│ │ │ ├── customrenderer.js
│ │ │ ├── entities
│ │ │ │ └── link.js
│ │ │ ├── inlinetoolbar.js
│ │ │ ├── sides
│ │ │ │ ├── break.js
│ │ │ │ └── image.js
│ │ │ ├── stylebutton.js
│ │ │ ├── toolbar.js
│ │ │ └── toolbar.scss
│ │ │ ├── editor.js
│ │ │ ├── example.js
│ │ │ ├── exporter.js
│ │ │ ├── importer.js
│ │ │ ├── index.js
│ │ │ ├── index.scss
│ │ │ ├── model
│ │ │ ├── content.js
│ │ │ ├── content.spec.js
│ │ │ ├── index.js
│ │ │ └── index.spec.js
│ │ │ └── util
│ │ │ ├── beforeinput.js
│ │ │ ├── beforeinput.spec.js
│ │ │ ├── blockStyleFn.js
│ │ │ ├── blockStyleFn.spec.js
│ │ │ ├── constants.js
│ │ │ ├── constants.spec.js
│ │ │ ├── customstylemap.js
│ │ │ ├── index.js
│ │ │ ├── keybinding.js
│ │ │ ├── rendermap.js
│ │ │ └── rendermap.spec.js
│ ├── data
│ │ ├── config.json
│ │ └── libraries_collections
│ │ │ └── default.json
│ ├── index.js
│ ├── lib
│ │ ├── custom-vendor
│ │ │ ├── node-content-renderer.js
│ │ │ ├── node-content-renderer.scss
│ │ │ ├── react-sortable-tree-style.css
│ │ │ ├── tree-node-renderer.js
│ │ │ └── tree-node-renderer.scss
│ │ └── node-nlp-service.js
│ └── utils
│ │ ├── create-db.js
│ │ ├── entries-traversal.js
│ │ ├── generate-uuid.js
│ │ ├── get-timestamp.js
│ │ ├── load-db.js
│ │ ├── register-service-worker.js
│ │ ├── replace-entry.js
│ │ ├── save-db.js
│ │ ├── session-state.js
│ │ ├── translate-html.js
│ │ └── vendor
│ │ ├── classnames.js
│ │ ├── default-handlers.js
│ │ ├── dnd-manager.js
│ │ ├── generic-utils.js
│ │ ├── generic-utils.test.js
│ │ ├── memoized-tree-data-utils.js
│ │ ├── memoized-tree-data-utils.test.js
│ │ ├── tree-data-utils.js
│ │ └── tree-data-utils.test.js
├── webpack.common.js
├── webpack.config.eslint.js
├── webpack.dev.electron.js
├── webpack.dev.js
├── webpack.prod.electron.js
├── webpack.prod.js
└── yarn.lock
└── screenshots
├── frame_screenshot_01-21-2019_alice_in_wonderland_information_extraction.png
├── frame_screenshot_01-21-2019_cryptocurrency_analysis.png
├── frame_screenshot_01-21-2019_sicko_mode_visualization.png
├── frame_screenshot_01-21-2019_this_is_water_summarization.png
└── framed_video_animation_demo.gif
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.tar filter=lfs diff=lfs merge=lfs -text
2 | *.tar.gz filter=lfs diff=lfs merge=lfs -text
3 | dist/* linguist-vendored=true
4 | node_modules/* linguist-vendored=true
5 | lib/* linguist-vendored=true
6 | output/* linguist-vendored=true
7 | react-sortable-tree-style.css linguist-vendored=true
8 | *.js linguist-vendored=false
9 | *.gz filter=lfs diff=lfs merge=lfs -text
10 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Python
2 |
3 | # Byte-compiled / optimized / DLL files
4 | __pycache__/
5 | *.py[cod]
6 | *$py.class
7 |
8 | # C extensions
9 | *.so
10 |
11 | # Distribution / packaging
12 | .Python
13 | build/
14 | develop-eggs/
15 | dist/
16 | downloads/
17 | eggs/
18 | .eggs/
19 |
20 | lib64/
21 | parts/
22 | sdist/
23 | var/
24 | wheels/
25 | share/python-wheels/
26 | *.egg-info/
27 | .installed.cfg
28 | *.egg
29 | MANIFEST
30 |
31 | # PyInstaller
32 | # Usually these files are written by a python script from
33 | a template
34 | # before PyInstaller builds the exe, so as to inject
35 | date/other infos into it.
36 | *.manifest
37 | *.spec
38 |
39 | # Installer logs
40 | pip-log.txt
41 | pip-delete-this-directory.txt
42 |
43 | # Unit test / coverage reports
44 | htmlcov/
45 | .tox/
46 | .nox/
47 | .coverage
48 | .coverage.*
49 | .cache
50 | nosetests.xml
51 | coverage.xml
52 | *.cover
53 | .hypothesis/
54 | .pytest_cache/
55 |
56 | # Translations
57 | *.mo
58 | *.pot
59 |
60 | # Django stuff:
61 | *.log
62 | local_settings.py
63 | db.sqlite3
64 |
65 | # Flask stuff:
66 | instance/
67 | .webassets-cache
68 |
69 | # Scrapy stuff:
70 | .scrapy
71 |
72 | # Sphinx documentation
73 | docs/_build/
74 |
75 | # PyBuilder
76 | target/
77 |
78 | # Jupyter Notebook
79 | .ipynb_checkpoints
80 |
81 | # IPython
82 | profile_default/
83 | ipython_config.py
84 |
85 | # pyenv
86 | .python-version
87 |
88 | # celery beat schedule file
89 | celerybeat-schedule
90 |
91 | # SageMath parsed files
92 | *.sage.py
93 |
94 | # Environments
95 | .env
96 | .venv
97 | env/
98 | venv/
99 | ENV/
100 | env.bak/
101 | venv.bak/
102 |
103 | # Spyder project settings
104 | .spyderproject
105 | .spyproject
106 |
107 | # Rope project settings
108 | .ropeproject
109 |
110 | # mkdocs documentation
111 | /site
112 |
113 | # mypy
114 | .mypy_cache/
115 | .dmypy.json
116 | dmypy.json
117 |
118 | # Pyre type checker
119 | .pyre/
120 |
121 |
122 | # Node
123 |
124 | # Logs
125 | logs
126 | *.log
127 | npm-debug.log*
128 | yarn-debug.log*
129 | yarn-error.log*
130 |
131 | # Runtime data
132 | pids
133 | *.pid
134 | *.seed
135 | *.pid.lock
136 |
137 | # Directory for instrumented libs generated by
138 | jscoverage/JSCover
139 | lib-cov
140 |
141 | # Coverage directory used by tools like istanbul
142 | coverage
143 |
144 | # nyc test coverage
145 | .nyc_output
146 |
147 | # Grunt intermediate storage
148 | (https://gruntjs.com/creating-plugins#storing-task-files)
149 | .grunt
150 |
151 | # Bower dependency directory (https://bower.io/)
152 | bower_components
153 |
154 | # node-waf configuration
155 | .lock-wscript
156 |
157 | # Compiled binary addons
158 | (https://nodejs.org/api/addons.html)
159 | build/Release
160 |
161 | # Dependency directories
162 | node_modules/
163 | jspm_packages/
164 |
165 | # TypeScript v1 declaration files
166 | typings/
167 |
168 | # Optional npm cache directory
169 | .npm
170 |
171 | # Optional eslint cache
172 | .eslintcache
173 |
174 | # Optional REPL history
175 | .node_repl_history
176 |
177 | # Output of 'npm pack'
178 | *.tgz
179 |
180 | # Yarn Integrity file
181 | .yarn-integrity
182 |
183 | # dotenv environment variables file
184 | .env
185 |
186 | # parcel-bundler cache (https://parceljs.org/)
187 | .cache
188 |
189 | # next.js build output
190 | .next
191 |
192 | # nuxt.js build output
193 | .nuxt
194 |
195 | # vuepress build output
196 | .vuepress/dist
197 |
198 | # Serverless directories
199 | .serverless/
200 |
201 | # FuseBox cache
202 | .fusebox/
203 |
204 | #DynamoDB Local files
205 | .dynamodb/
206 |
207 | # Electron
208 |
209 | electron/
210 |
211 |
212 |
213 | # Other web stuff
214 |
215 | output/
216 | dist/
217 |
218 |
219 | # Virtualenv
220 |
221 | frame-nlp-service-venv
222 |
223 | nohup.out
224 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License
2 |
3 | Copyright (c) 2018 Johnny Dunn
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/frame-nlp-service/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM tiangolo/uwsgi-nginx-flask:python3.7
2 |
3 | ENV STATIC_INDEX 1
4 |
5 | # Set the working directory to /app
6 | WORKDIR /app
7 |
8 | COPY ./app /app
9 |
10 | # Dependencies
11 | RUN pip install --upgrade pip && pip install --trusted-host pypi.python.org -r requirements.txt && python -m spacy download en
12 |
13 | # Make port 80 available to the world outside this container
14 | EXPOSE 80
15 |
16 | # Define environment variable
17 | ENV NAME World
18 |
19 | # Run app.py when the container launches
20 | CMD ["python", "main.py"]
--------------------------------------------------------------------------------
/frame-nlp-service/README.md:
--------------------------------------------------------------------------------
1 | # Frame (NLP Service - Python Backend)
2 |
3 | Frame's abstractive summarization and answer prediction features are done in a Python environment running PyTorch, with an API exposed (by default to all traffic). Frame is still fully functional without the Python backend, and most of the analysis and all visualizations are rendered in the UI files.
4 |
5 | By default, the API will be exposed to port 80, and if run through Docker, served with Nginx.
6 |
7 | # Installation / Running
8 |
9 | ## Virtualenv
10 |
11 | (Virtualenv)
12 |
13 | To install all the packages run:
14 | ```sh
15 | $ pip3 install -r requirements.txt
16 | ```
17 | You may need to install PyTorch and AllenNLP and a few other dependencies manually (depending on the OS).
18 |
19 | To run Flask API (not recommended unless for testing):
20 | ```sh
21 | $ cd app
22 | $ python3 main.py
23 | ```
24 |
25 | ## Docker
26 |
27 | The Docker image is configured to automatically serve the Flask API through Nginx.
28 |
29 | To build the Docker image:
30 |
31 | ```sh
32 | $ docker build -t imgname .
33 | ```
34 |
35 | To run:
36 |
37 | ```sh
38 | $ docker run -d --name mycontainer -p 80:80 imgname
39 | ```
40 |
41 | # API docs
42 |
43 | Creates abstractive summary of text (str). Returns str.
44 |
45 | ```
46 | /api/abstractive_summarize
47 | ```
48 |
49 | Creates abstractive summary of array of texts (items are individually summarized). Returns array.
50 |
51 | ```
52 | /api/abstractive_summarize_paragraphs
53 | ```
54 |
55 | Gets an answer to a question asked in natural language. Takes two args, both strs (first is passage text, second is question). Returns str.
56 |
57 | ```
58 | /api/make_predict
59 | ```
--------------------------------------------------------------------------------
/frame-nlp-service/app/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jddunn/frame/a002056b22d9986ec41d0a07dff3641c3582c6f4/frame-nlp-service/app/__init__.py
--------------------------------------------------------------------------------
/frame-nlp-service/app/abstractive_summarizer/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jddunn/frame/a002056b22d9986ec41d0a07dff3641c3582c6f4/frame-nlp-service/app/abstractive_summarizer/__init__.py
--------------------------------------------------------------------------------
/frame-nlp-service/app/abstractive_summarizer/abstractive_summarizer.py:
--------------------------------------------------------------------------------
1 | from pysummarization.nlpbase.auto_abstractor import AutoAbstractor
2 | from pysummarization.tokenizabledoc.simple_tokenizer import SimpleTokenizer
3 | from pysummarization.abstractabledoc.top_n_rank_abstractor import TopNRankAbstractor
4 |
5 | class AbstractiveSummarizer:
6 |
7 | def __init__(self):
8 | # Object of automatic summarization.
9 | self.auto_abstractor = AutoAbstractor()
10 | # Set tokenizer.
11 | self.auto_abstractor.tokenizable_doc = SimpleTokenizer()
12 | # Set delimiter for making a list of sentence.
13 | self.auto_abstractor.delimiter_list = [".", "\n", "\r\n", "!", "?"]
14 | self.abstractable_doc = TopNRankAbstractor()
15 | return
16 |
17 | def summarize(self, document: str):
18 | result_dict = self.auto_abstractor.summarize(document, self.abstractable_doc)
19 | # print(result_dict)
20 | # for sentence in result_dict["summarize_result"]:
21 | # print(sentence)
22 | return result_dict
23 |
24 | if __name__ != 'main':
25 | abstractive_summarizer = AbstractiveSummarizer()
26 | else:
27 | abstractive_summarizer = AbstractiveSummarizer()
28 |
29 |
--------------------------------------------------------------------------------
/frame-nlp-service/app/bidaf-model-2017.09.15-charpad.tar.gz:
--------------------------------------------------------------------------------
1 | version https://git-lfs.github.com/spec/v1
2 | oid sha256:fe3045f0e56f5d5da26bbec5553b26f7ee57dc9977a8c9a5bbf733efdcef691b
3 | size 46175392
4 |
--------------------------------------------------------------------------------
/frame-nlp-service/app/main.py:
--------------------------------------------------------------------------------
1 | from flask import Flask, request, jsonify
2 | from flask_cors import CORS
3 |
4 | app = Flask(__name__)
5 | cors = CORS(app)
6 |
7 | from abstractive_summarizer import abstractive_summarizer
8 | from question_answer_model import question_answer_model
9 |
10 | QAModel = question_answer_model.QuestionAnswerModel()
11 | ABSummarizer = abstractive_summarizer.AbstractiveSummarizer()
12 |
13 | HOST = '0.0.0.0'
14 | PORT = '80'
15 |
16 | @app.route("/")
17 | def hello():
18 | return("Frame NLP Python backend running at " + HOST + ':' + PORT)
19 |
20 | @app.route("/api/abstractive_summarize", methods=['GET', 'POST'])
21 | def abstract():
22 | # Gets and returs jsonified string
23 | # Builds an abstractive summary of a text
24 | passage = request.get_json()
25 | res = ABSummarizer.summarize(passage)
26 | return jsonify(res)
27 |
28 | @app.route("/api/abstractive_summarize_paragraphs", methods=['GET', 'POST'])
29 | def abstract_paragraphs():
30 | # Builds abstractive summaries of texts by paragraphs
31 | # Gets and returns jsonified array
32 | paragraphs = request.get_json()
33 | results = []
34 | for passage in paragraphs:
35 | res = ABSummarizer.summarize(passage)
36 | results.append(res)
37 | return jsonify(results)
38 |
39 | @app.route("/api/make_predict", methods=['GET', 'POST'])
40 | def ask():
41 | # Gets answer to question in context of a passage of text
42 | # Gets and returns jsonified strings
43 | passage = request.get_json()['passage']
44 | question = request.get_json()['question']
45 | res = QAModel.make_predict(passage, question)
46 | return jsonify(res)
47 |
48 | if __name__ == "__main__":
49 | # Only for debugging while developing
50 | app.run(host=HOST, debug=True, port=PORT)
--------------------------------------------------------------------------------
/frame-nlp-service/app/question_answer_model/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jddunn/frame/a002056b22d9986ec41d0a07dff3641c3582c6f4/frame-nlp-service/app/question_answer_model/__init__.py
--------------------------------------------------------------------------------
/frame-nlp-service/app/question_answer_model/question_answer_model.py:
--------------------------------------------------------------------------------
1 | from allennlp.predictors.predictor import Predictor
2 | import os
3 | import sys
4 |
5 | from pathlib import Path
6 | data = Path("bidaf-model-2017.09.15-charpad.tar.gz")
7 |
8 | scriptPath = os.path.realpath(os.path.dirname(sys.argv[0]))
9 |
10 | class QuestionAnswerModel:
11 |
12 | def __init__(self):
13 | pass
14 |
15 | def make_predict(self, passage: str, question: str):
16 | # For some reason setting Predictor into a class var was returning bad data from the model,
17 | # so let's make it every time I guess
18 | predictor = Predictor.from_path(data)
19 | # predictor = Predictor.from_path("https://s3-us-west-2.amazonaws.com/allennlp/models/bidaf-model-2017.09.15-charpad.tar.gz")
20 | ans = predictor.predict(passage=passage,question=question)
21 | # print(ans['best_span_str'])
22 | return ans['best_span_str']
23 |
24 | if __name__ != 'main':
25 | qa_model = QuestionAnswerModel()
26 | else:
27 | qa_model = QuestionAnswerModel()
28 |
29 |
--------------------------------------------------------------------------------
/frame-nlp-service/app/requirements.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jddunn/frame/a002056b22d9986ec41d0a07dff3641c3582c6f4/frame-nlp-service/app/requirements.txt
--------------------------------------------------------------------------------
/frame-nlp-service/app/uwsgi.ini:
--------------------------------------------------------------------------------
1 | [uwsgi]
2 | module = main
3 | callable = app
4 |
--------------------------------------------------------------------------------
/frame-nlp-service/docker-compose.override.yml:
--------------------------------------------------------------------------------
1 | version: '3'
2 | services:
3 | web:
4 | volumes:
5 | - ./app:/app
6 | ports:
7 | - "80:80"
8 | environment:
9 | - FLASK_APP=main.py
10 | - FLASK_DEBUG=1
11 | - 'RUN=flask run --host=0.0.0.0 --port=80'
12 | command: flask run --host=0.0.0.0 --port=80
13 | # Infinite loop, to keep it alive, for debugging
14 | # command: bash -c "while true; do echo 'sleeping...' && sleep 10; done"
15 |
--------------------------------------------------------------------------------
/frame-nlp-service/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '3'
2 | services:
3 | web:
4 | build: ./
5 |
--------------------------------------------------------------------------------
/frame-website/css/slider.css:
--------------------------------------------------------------------------------
1 | * {box-sizing:border-box}
2 |
3 | /* Slideshow container */
4 | .slideshow-container {
5 | max-width: 1000px;
6 | position: relative;
7 | margin: auto;
8 | margin-bottom: -34px;
9 | padding-bottom: 0;
10 | box-shadow: 0 4px 8px 0 rgba(0,0,0,0.12),
11 | 0 2px 4px 0 rgba(0,0,0,0.08);
12 | }
13 |
14 | /* Hide the images by default */
15 | .mySlides {
16 | display: none;
17 | margin-bottom: 0;
18 | padding-bottom: 0;
19 | }
20 |
21 | /* Next & previous buttons */
22 | .prev, .next {
23 | cursor: pointer;
24 | position: absolute;
25 | z-index: 100;
26 | top: 50%;
27 | width: auto;
28 | margin-top: -22px;
29 | padding: 20px;
30 | color: rgba(87, 87, 87, 0.47);
31 | font-weight: bold;
32 | font-size: 24px;
33 | transition: 0.6s ease;
34 | border-radius: 0 3px 3px 0;
35 | user-select: none;
36 | }
37 |
38 | .prev {
39 | float: left;
40 | left: 0;
41 | }
42 |
43 | .next {
44 | right: 0;
45 | float: right;
46 | }
47 |
48 | /* Position the "next button" to the right */
49 | .next {
50 | right: 0;
51 | border-radius: 3px 0 0 3px;
52 | }
53 |
54 | /* On hover, add a black background color with a little bit see-through */
55 | .prev:hover, .next:hover {
56 | background-color: rgba(0,0,0,0.8);
57 | }
58 |
59 | .sliderDot {
60 | display: inline;
61 | margin: 10px;
62 | }
63 |
64 | /* Caption text */
65 | .text {
66 | color: #f2f2f2;
67 | font-size: 20px;
68 | padding: 8px 12px;
69 | position: absolute;
70 | bottom: 8px;
71 | width: 100%;
72 | text-align: center;
73 | }
74 |
75 | /* Number text (1/3 etc) */
76 | .numbertext {
77 | color: #f2f2f2;
78 | font-size: .7em;
79 | padding: 8px 12px;
80 | position: absolute;
81 | top: 0;
82 | }
83 |
84 | /* The dots/bullets/indicators */
85 | .dot {
86 | cursor: pointer;
87 | height: 12px;
88 | width: 12px;
89 | margin: 0 2px;
90 | background-color: #bbb;
91 | border-radius: 50%;
92 | display: inline-block;
93 | transition: background-color 0.6s ease;
94 | }
95 |
96 | .active, .dot:hover {
97 | background-color: #717171;
98 | }
99 |
100 | /* Fading animation */
101 | .fade {
102 | -webkit-animation-name: fade;
103 | -webkit-animation-duration: 1.5s;
104 | animation-name: fade;
105 | animation-duration: 1.5s;
106 | }
107 |
108 | @-webkit-keyframes fade {
109 | from {opacity: .4}
110 | to {opacity: 1}
111 | }
112 |
113 | @keyframes fade {
114 | from {opacity: .4}
115 | to {opacity: 1}
116 | }
--------------------------------------------------------------------------------
/frame-website/iconfonts/flaticon.css:
--------------------------------------------------------------------------------
1 | @font-face {
2 | font-family: "Flaticon";
3 | src: url("flaticon.eot");
4 | src: url("flaticon.eot#iefix") format("embedded-opentype"),
5 | url("flaticon.woff") format("woff"),
6 | url("flaticon.ttf") format("truetype"),
7 | url("flaticon.svg") format("svg");
8 | font-weight: normal;
9 | font-style: normal;
10 | }
11 | [class^="flaticon-"]:before, [class*=" flaticon-"]:before,
12 | [class^="flaticon-"]:after, [class*=" flaticon-"]:after {
13 | font-family: Flaticon;
14 |
15 | font-style: normal;
16 |
17 | }.flaticon-aim:before {
18 | content: "\e000";
19 | }
20 | .flaticon-arrow:before {
21 | content: "\e001";
22 | }
23 | .flaticon-attachment:before {
24 | content: "\e002";
25 | }
26 | .flaticon-battery:before {
27 | content: "\e003";
28 | }
29 | .flaticon-bluetooth:before {
30 | content: "\e004";
31 | }
32 | .flaticon-calendar:before {
33 | content: "\e005";
34 | }
35 | .flaticon-call:before {
36 | content: "\e006";
37 | }
38 | .flaticon-camera:before {
39 | content: "\e007";
40 | }
41 | .flaticon-code:before {
42 | content: "\e008";
43 | }
44 | .flaticon-connecting:before {
45 | content: "\e009";
46 | }
47 | .flaticon-tick:before {
48 | content: "\e00a";
49 | }
50 | .flaticon-facebook:before {
51 | content: "\e00b";
52 | }
53 | .flaticon-google:before {
54 | content: "\e00c";
55 | }
56 | .flaticon-graduates:before {
57 | content: "\e00d";
58 | }
59 | .flaticon-heart:before {
60 | content: "\e00e";
61 | }
62 | .flaticon-home:before {
63 | content: "\e00f";
64 | }
65 | .flaticon-layers:before {
66 | content: "\e010";
67 | }
68 | .flaticon-list:before {
69 | content: "\e011";
70 | }
71 | .flaticon-mail:before {
72 | content: "\e012";
73 | }
74 | .flaticon-more:before {
75 | content: "\e013";
76 | }
77 | .flaticon-move:before {
78 | content: "\e014";
79 | }
80 | .flaticon-outcoming:before {
81 | content: "\e015";
82 | }
83 | .flaticon-pinterest:before {
84 | content: "\e016";
85 | }
86 | .flaticon-play:before {
87 | content: "\e017";
88 | }
89 | .flaticon-plus:before {
90 | content: "\e018";
91 | }
92 | .flaticon-position:before {
93 | content: "\e019";
94 | }
95 | .flaticon-round:before {
96 | content: "\e01a";
97 | }
98 | .flaticon-settings:before {
99 | content: "\e01b";
100 | }
101 | .flaticon-shopping:before {
102 | content: "\e01c";
103 | }
104 | .flaticon-shutdown:before {
105 | content: "\e01d";
106 | }
107 | .flaticon-special:before {
108 | content: "\e01e";
109 | }
110 | .flaticon-speech:before {
111 | content: "\e01f";
112 | }
113 | .flaticon-star:before {
114 | content: "\e020";
115 | }
116 | .flaticon-twitter:before {
117 | content: "\e021";
118 | }
119 |
--------------------------------------------------------------------------------
/frame-website/iconfonts/flaticon.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jddunn/frame/a002056b22d9986ec41d0a07dff3641c3582c6f4/frame-website/iconfonts/flaticon.eot
--------------------------------------------------------------------------------
/frame-website/iconfonts/flaticon.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jddunn/frame/a002056b22d9986ec41d0a07dff3641c3582c6f4/frame-website/iconfonts/flaticon.ttf
--------------------------------------------------------------------------------
/frame-website/iconfonts/flaticon.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jddunn/frame/a002056b22d9986ec41d0a07dff3641c3582c6f4/frame-website/iconfonts/flaticon.woff
--------------------------------------------------------------------------------
/frame-website/images/Frame-animated-demo-01-14-2019.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jddunn/frame/a002056b22d9986ec41d0a07dff3641c3582c6f4/frame-website/images/Frame-animated-demo-01-14-2019.gif
--------------------------------------------------------------------------------
/frame-website/images/banner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jddunn/frame/a002056b22d9986ec41d0a07dff3641c3582c6f4/frame-website/images/banner.png
--------------------------------------------------------------------------------
/frame-website/images/frame_screenshot_01-21-2019_alice_in_wonderland_information_extraction.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jddunn/frame/a002056b22d9986ec41d0a07dff3641c3582c6f4/frame-website/images/frame_screenshot_01-21-2019_alice_in_wonderland_information_extraction.png
--------------------------------------------------------------------------------
/frame-website/images/frame_screenshot_01-21-2019_cryptocurrency_analysis.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jddunn/frame/a002056b22d9986ec41d0a07dff3641c3582c6f4/frame-website/images/frame_screenshot_01-21-2019_cryptocurrency_analysis.png
--------------------------------------------------------------------------------
/frame-website/images/frame_screenshot_01-21-2019_sicko_mode_visualization.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jddunn/frame/a002056b22d9986ec41d0a07dff3641c3582c6f4/frame-website/images/frame_screenshot_01-21-2019_sicko_mode_visualization.png
--------------------------------------------------------------------------------
/frame-website/images/frame_screenshot_01-21-2019_this_is_water_summarization.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jddunn/frame/a002056b22d9986ec41d0a07dff3641c3582c6f4/frame-website/images/frame_screenshot_01-21-2019_this_is_water_summarization.png
--------------------------------------------------------------------------------
/frame-website/images/framed_video_animation_demo.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jddunn/frame/a002056b22d9986ec41d0a07dff3641c3582c6f4/frame-website/images/framed_video_animation_demo.mp4
--------------------------------------------------------------------------------
/frame-website/images/liveforms.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jddunn/frame/a002056b22d9986ec41d0a07dff3641c3582c6f4/frame-website/images/liveforms.png
--------------------------------------------------------------------------------
/frame-website/images/scripteden-logo-g.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jddunn/frame/a002056b22d9986ec41d0a07dff3641c3582c6f4/frame-website/images/scripteden-logo-g.png
--------------------------------------------------------------------------------
/frame-website/images/totoro-horizontal.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jddunn/frame/a002056b22d9986ec41d0a07dff3641c3582c6f4/frame-website/images/totoro-horizontal.jpg
--------------------------------------------------------------------------------
/frame-website/js/homepage.js:
--------------------------------------------------------------------------------
1 | $(document)
2 | .ready(function() {
3 |
4 | var
5 | changeSides = function() {
6 | $('.ui.shape')
7 | .eq(0)
8 | .shape('flip over')
9 | .end()
10 | .eq(1)
11 | .shape('flip over')
12 | .end()
13 | .eq(2)
14 | .shape('flip back')
15 | .end()
16 | .eq(3)
17 | .shape('flip back')
18 | .end()
19 | ;
20 | },
21 | validationRules = {
22 | firstName: {
23 | identifier : 'email',
24 | rules: [
25 | {
26 | type : 'empty',
27 | prompt : 'Please enter an e-mail'
28 | },
29 | {
30 | type : 'email',
31 | prompt : 'Please enter a valid e-mail'
32 | }
33 | ]
34 | }
35 | }
36 | ;
37 |
38 | $('.ui.dropdown')
39 | .dropdown({
40 | on: 'hover'
41 | })
42 | ;
43 |
44 | $('.ui.form')
45 | .form(validationRules, {
46 | on: 'blur'
47 | })
48 | ;
49 |
50 | $('.masthead .information')
51 | .transition('scale in', 1000)
52 | ;
53 |
54 | setInterval(changeSides, 3000);
55 |
56 | })
57 | ;
--------------------------------------------------------------------------------
/frame-website/js/slideshow.js:
--------------------------------------------------------------------------------
1 | var slideIndex = 1;
2 | showSlides(slideIndex);
3 |
4 | // Next/previous controls
5 | function plusSlides(n) {
6 | showSlides(slideIndex += n);
7 | }
8 |
9 | // Thumbnail image controls
10 | function currentSlide(n) {
11 | showSlides(slideIndex = n);
12 | }
13 |
14 | function showSlides(n) {
15 | var i;
16 | var slides = document.getElementsByClassName("mySlides");
17 | var dots = document.getElementsByClassName("dot");
18 | if (n > slides.length) {slideIndex = 1}
19 | if (n < 1) {slideIndex = slides.length}
20 | for (i = 0; i < slides.length; i++) {
21 | slides[i].style.display = "none";
22 | }
23 | for (i = 0; i < dots.length; i++) {
24 | dots[i].className = dots[i].className.replace(" active", "");
25 | }
26 | if (slideIndex > slides.length) {slideIndex = 1}
27 | slides[slideIndex-1].style.display = "block";
28 | dots[slideIndex-1].className += " active";
29 | setTimeout(showSlides, 40000); // Change image every 40 seconds
30 | }
--------------------------------------------------------------------------------
/frame/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["env", "stage-3", "react",
3 | [
4 | "env",
5 | {
6 | "targets": {
7 | "browsers": ["last 2 versions"]
8 | },
9 | "debug": true,
10 | "modules": "commonjs"
11 | }
12 | ]
13 | ],
14 | "plugins": ["add-module-exports"],
15 | "env": {
16 | "test": {
17 | "plugins": [
18 | "@babel/plugin-transform-modules-commonjs"
19 | ]
20 | },
21 | "production": {
22 | "presets": ["react-optimize"],
23 | "plugins": ["dev-expression"]
24 | },
25 | "development": {
26 | "plugins": [
27 | ["transform-class-properties", { "spec": true }],
28 | "transform-es2015-classes",
29 | ["flow-runtime", { "assert": false, "annotate": true }],
30 | ["transform-runtime",{"helpers": false,"polyfill": false,"regenerator": true,"moduleName": "babel-runtime"
31 | }
32 | ]
33 | ]
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/frame/.eslintignore:
--------------------------------------------------------------------------------
1 | package.json
2 |
3 |
4 | # Logs
5 | logs
6 | *.log
7 |
8 | # Runtime data
9 | pids
10 | *.pid
11 | *.seed
12 |
13 | # Directory for instrumented libs generated by jscoverage/JSCover
14 | lib-cov
15 |
16 | # Coverage directory used by tools like istanbul
17 | coverage
18 |
19 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
20 | .grunt
21 |
22 | # node-waf configuration
23 | .lock-wscript
24 |
25 | # Compiled binary addons (http://nodejs.org/api/addons.html)
26 | build/Release
27 | .eslintcache
28 |
29 | # Dependency directory
30 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
31 | node_modules
32 | app/node_modules
33 |
34 | # OSX
35 | .DS_Store
36 |
37 | # flow-typed
38 | flow-typed/npm/*
39 | !flow-typed/npm/module_vx.x.x.js
40 |
41 | # App packaged
42 | release
43 | app/main.prod.js
44 | app/main.prod.js.map
45 | app/renderer.prod.js
46 | app/renderer.prod.js.map
47 | app/style.css
48 | app/style.css.map
49 | dist
50 | dll
51 | main.js
52 | main.js.map
53 |
54 | .idea
55 | npm-debug.log.*
56 | __snapshots__
57 |
58 | assets
59 | vendor
--------------------------------------------------------------------------------
/frame/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["airbnb", "prettier", "prettier/react"],
3 | "env": {
4 | "browser": true,
5 | "jest": true
6 | },
7 | "rules": {
8 | "linebreak-style": 0,
9 | "react/jsx-filename-extension": 0,
10 | "react/prefer-stateless-function": 0
11 | },
12 | "parser": "babel-eslint",
13 | "parserOptions": {
14 | "allowImportExportEverywhere": true,
15 | "sourceType": "module"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/frame/.flowconfig:
--------------------------------------------------------------------------------
1 | [ignore]
2 |
3 | [include]
4 |
5 | [libs]
6 |
7 | [options]
--------------------------------------------------------------------------------
/frame/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 | *.tar.gz filter=lfs diff=lfs merge=lfs -text
4 |
--------------------------------------------------------------------------------
/frame/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "0.2.0",
3 | "configurations": [
4 | {
5 | "type": "chrome",
6 | "request": "launch",
7 | "name": "Launch Chrome against localhost",
8 | "url": "http://localhost:3001",
9 | "webRoot": "${workspaceFolder}"
10 | },
11 | {
12 | "type": "chrome",
13 | "request": "attach",
14 | "name": "Attach to Chrome",
15 | "port": 9222,
16 | "webRoot": "${workspaceFolder}"
17 | }
18 | ]
19 | }
--------------------------------------------------------------------------------
/frame/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | // Format a file on save. A formatter must be available, the file must not be auto-saved, and editor must not be shutting down.
3 | "editor.formatOnSave": false,
4 | // Enable/disable JavaScript validation. (For Flow)
5 | "javascript.validate.enable": false,
6 | // Enable/disable default JavaScript formatter (For Prettier)
7 | "javascript.format.enable": true,
8 | // Use 'prettier-eslint' instead of 'prettier'. Other settings will only be fallbacks in case they could not be inferred from eslint rules.
9 | "prettier.eslintIntegration": true,
10 |
11 | // Is flow enabled
12 | "flow.enabled": true,
13 |
14 | // File extensions to consider for flow processing.
15 | "flow.fileExtensions": [
16 | ".js",
17 | ".mjs",
18 | ".jsx",
19 | ".flow",
20 | ".json"
21 | ],
22 | // Path to flow binary. On Windows use '\\' as directory separator
23 | "flow.pathToFlow": "flow",
24 |
25 | // Run Flow on all files, No need to put //@flow comment on top of files.
26 | "flow.runOnAllFiles": false,
27 |
28 | // If true will run flow on every edit, otherwise will run only when changes are saved
29 | "flow.runOnEdit": true,
30 |
31 | // If true will display flow status is the statusbar
32 | "flow.showStatus": true,
33 |
34 | // Stop Flow on Exit
35 | "flow.stopFlowOnExit": true,
36 |
37 | // Support using flow through your node_modules folder, WARNING: Checking this box is a security risk. When you open a project we will immediately run code contained within it.
38 | "flow.useNPMPackagedFlow": true
39 | }
--------------------------------------------------------------------------------
/frame/README.md:
--------------------------------------------------------------------------------
1 | # Frame - Electron & Web App
2 |
3 | Frontend components and config for Frame, which builds for both Electron and the web.
4 |
5 | IMPORT: Included in the folder is /custom_node_modules. You should replace the packages from this folder into your actual /node_modules after running "npm install", since there are certain unofficial fixes made to some libraries to fix bugs.
6 |
7 | Notes:
8 |
9 | - State management is done with key-value retrieval in Window.sessionStorage API and helper functions. As the project grows this should move to Redux and other libraries.
10 | - Currently only builds for Windows have been created. For Linux and Mac, this needs to be done on machines with those OSes. Linux could probably be built on a VM; this should be tried soon.
11 |
12 | # Installation
13 | To install all the packages run either:
14 | ```sh
15 | $ npm install
16 | ```
17 | # Running the source for web
18 | To run in a browser using the webpack dev server in development mode with hot reloading:
19 |
20 | ```sh
21 | $ npm run start
22 | ```
23 |
24 | # Running the source using Electron
25 |
26 | To run a development build with hot reloading in Electron:
27 | ```sh
28 | $ npm run electron-dev
29 | ```
30 |
31 | # Building the source for the web
32 |
33 | To build for production:
34 | ```sh
35 | $ npm run build
36 | ```
37 | To make a development build:
38 | ```sh
39 | $ npm run build-dev
40 | ```
41 |
42 | # Building the source with Electron-Builder
43 |
44 | First build and minify the web files:
45 | ```sh
46 | $ npm run build
47 | ```
48 |
49 | Then build binaries for distribution:
50 |
51 | Default platform (current machine):
52 | ```sh
53 | $ npm run electron-build
54 | ```
55 |
56 | Or:
57 |
58 | ```sh
59 | $ npm run electron-build --linux
60 | ```
61 | ```sh
62 | $ npm run electron-build --mac
63 | ```
64 | ```sh
65 | $ npm run electron-build --windows
66 | ```
67 |
68 | (The reason why the above build commands aren't combined in the package file is because this way it's easier to handle slashes in the paths across Windows and other platforms).
69 |
70 | Binary is saved along with its unpacked contents within ./dist.
--------------------------------------------------------------------------------
/frame/custom_node_modules/medium-draft/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ### 0.6.0-beta
2 |
3 | - A revamped architecture develop custom editor in a better way using plugin-like system.
4 | - Updated draft-convert's version (@mckelvey)
5 |
6 | ### 0.5.5
7 |
8 | - A new prop `toolbarConfig` has been introduced. So instead of passing whole configuration into `blockButtons` and `inlineButtons`, you can just pass, `toolbarConfig` with value
9 | ```json
10 | {block: ["header-three", "blockquote", ...], inline: ["BOLD", "ITALIC", "UNDERLINE", "hyperlink"]}
11 | ```
12 | Note that the string values of the array must already be present in `BLOCK_BUTTON` and `INLINE_BUTTONS` in `medium-draft` (@roy-gbiv)
13 |
14 | - Extra props can be passed to the `component` of each item in `sideButtons` inside the `prop` key. Earlier, only `title` and `component` were accepted. Now a 3rd key `prop` can also be passed whose keys can be accessed inside the `component` through `this.props` (@ jaspersorrio)
15 | - Fixed paste handling when cursor is inside image block caption. Earlier, the `src` of image became `undefined`. Now, plaintext will be pasted if the cursor is inside Image block. Otherwise, Draft's pasting will take over.
16 | - Now a string of text can also be passed to `createEditorState` as the first argument to create initial `editorState` pre-filled with the text.
17 |
18 | ### 0.5.3
19 |
20 | - Added `medium-draft-importer` to convert html exported using `medium-draft-exporter` to draft's json format (@Yukaii)
21 | - Fixed arrow navigation around image blocks
22 | - Allow inline styles to be applied to heading blocks
23 | - Remove hardcoded fonts from css files
24 |
25 | ### 0.5.2
26 |
27 | - Now, the toolbar buttons also accept a react component instead of just a string as label.
28 | This can be used to customize the icon of the toolbar button. For ex - in the
29 | demo, blockquote and link buttons are svg components which previously were
30 | just string labels.
31 | - Added a link info tooltip that shows up when cursor is inside a word with hyperlink.
32 | - The tooltip has option to edit that link or unlink.
33 | - Added medium's shortcut to add a link to text selection
34 | - CTRL/CMD + K -> Add link
35 | - CTRL/CMD + SHIFT + K -> Remove link if cursor is inside a word with link.
36 |
37 | ### 0.5.1
38 |
39 | - Optimized build process by minifying css and removing prop-types from the build files.
40 | - Migrated to React 15.5 (@baldwmic) with external `prop-types` dependency.
41 |
42 | ### 0.5.0
43 |
44 | - Moved away from the deprecated `Entity` usage of `draft-js` and updated to draft-js 0.10.1 (@valthon)
45 | - Fix for unintentional page navigation when adding links (@J00nz)
46 | - Fix where first click on side (+) button made it dissappear (@J00nz)
47 | - Accept only image files through file selector (@anthonyjgrove)
48 |
49 | ### 0.4.1
50 |
51 | - Added medium-draft-exporter to convert the draft-js JSON data to HTML.
52 | - Moved away from string refs to recommended refs in React.
53 |
54 | ### 0.4.0
55 |
56 | - Updated to use draft-js v0.9.1
57 | - Namespaced all classes to start with `md-`
58 | - Add relevant class to editor container based on whether editing is enabled or disabled
59 |
--------------------------------------------------------------------------------
/frame/custom_node_modules/medium-draft/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) Brijesh Bittu
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/frame/custom_node_modules/medium-draft/example/index.js:
--------------------------------------------------------------------------------
1 | // import React from 'react';
2 |
3 | import 'draft-js/dist/Draft.css';
4 | // eslint-disable-next-line
5 | import 'hint.css/hint.min.css';
6 |
7 | import '../src/index.scss';
8 | import '../src/components/addbutton.scss';
9 | import '../src/components/toolbar.scss';
10 | import '../src/components/blocks/text.scss';
11 | import '../src/components/blocks/atomic.scss';
12 | import '../src/components/blocks/blockquotecaption.scss';
13 | import '../src/components/blocks/caption.scss';
14 | import '../src/components/blocks/todo.scss';
15 | import '../src/components/blocks/image.scss';
16 | // import { Editor, createEditorState } from '../src/';
17 |
18 | import { createEditor } from '../src/';
19 |
20 | const handleQuoteInput = (str, {
21 | getEditorState,
22 | }) => {
23 | const editorState = getEditorState();
24 | return editorState;
25 | };
26 |
27 | const Editor = createEditor({
28 | handleBeforeInput: handleQuoteInput,
29 | });
30 |
31 | export default Editor;
32 |
--------------------------------------------------------------------------------
/frame/custom_node_modules/medium-draft/example/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "example",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "author": "",
10 | "license": "ISC",
11 | "dependencies": {
12 | "medium-draft": "^0.6.0-beta"
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/frame/custom_node_modules/medium-draft/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Editor
6 |
7 |
8 |
49 |
50 |
51 | Loading Editor
52 |
53 |
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/frame/custom_node_modules/medium-draft/lib/basic.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * medium-draft
3 | * Version - 0.6.0-beta1
4 | * Author - Brijesh Bittu (http://bitwiser.in/)
5 | */
6 | .md-block-header-one{font-size:2em}.md-block-header-two{font-size:1.7em}.md-block-header-three{font-size:1.3em}.md-block-header-four{font-size:1em}.md-block-header-five{font-size:.8em}.md-block-header-six{font-size:.7em}.md-block-header-five,.md-block-header-four,.md-block-header-one,.md-block-header-six,.md-block-header-three,.md-block-header-two{margin-bottom:5px}.md-block-blockquote{margin:0;padding-left:15px;border-left:5px solid #4ca8de;padding:10px 0 10px 20px;background-color:#e2f2ff;font-size:1.1em}.md-block-image{margin:0 0 10px}.md-block-image img{width:100%}.md-block-image figcaption{text-align:center;font-size:.9em}.md-block-todo{margin:10px 0}.md-block-todo input[type=checkbox]{float:left;position:relative;top:0;left:-2px}.md-block-todo p{margin-left:18px}.md-block-ordered-list-item,.md-block-unordered-list-item{padding-left:20px}.md-block-ordered-list-item li,.md-block-unordered-list-item li{margin-bottom:5px}.md-block-atomic-embed{margin:10px 0}.md-block-atomic-break hr{max-width:100px;border:2px solid #ccc}.md-inline-code{font-family:Consolas,Liberation Mono,Menlo,Courier,monospace;margin:4px 0;font-size:.9em;padding:1px 3px;color:#555;background-color:#fcfcfc;border-width:1px;border-style:solid;border-color:#ccc #ccc #bbb;border-image:initial;border-radius:3px;box-shadow:inset 0 -1px 0 #bbb}.md-inline-link,.md-inline-link:visited{color:#08c}.md-inline-highlight{background:#ff0;display:inline;padding:2px 4px}p.md-block-block-quote-caption{margin-top:0;font-size:.8em;padding-top:5px;padding-bottom:5px;padding-left:10px;background:#fafafa}p.md-block-block-quote-caption:before{content:"\2013";color:#999;float:left;font-weight:700;display:inline;margin-right:10px}
--------------------------------------------------------------------------------
/frame/custom_node_modules/medium-draft/lib/components/blocks/atomic.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | var _propTypes = require('prop-types');
8 |
9 | var _propTypes2 = _interopRequireDefault(_propTypes);
10 |
11 | var _react = require('react');
12 |
13 | var _react2 = _interopRequireDefault(_react);
14 |
15 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
16 |
17 | var AtomicBlock = function AtomicBlock(props) {
18 | var content = props && props.blockProps.getEditorState().getCurrentContent();
19 | var entity = content.getEntity(props.block.getEntityAt(0));
20 | var data = entity.getData();
21 | var type = entity.getType();
22 | if (type === 'image') {
23 | return _react2.default.createElement(
24 | 'div',
25 | { className: 'md-block-atomic-wrapper' },
26 | _react2.default.createElement('img', { role: 'presentation', src: data.src }),
27 | _react2.default.createElement(
28 | 'div',
29 | { className: 'md-block-atomic-controls' },
30 | _react2.default.createElement(
31 | 'button',
32 | null,
33 | '\xD7'
34 | )
35 | )
36 | );
37 | }
38 | return _react2.default.createElement(
39 | 'p',
40 | null,
41 | 'No supported block for ',
42 | type
43 | );
44 | };
45 | // import './atomic.scss';
46 |
47 | AtomicBlock.propTypes = {
48 | block: _propTypes2.default.object,
49 | getEditorState: _propTypes2.default.func
50 | };
51 |
52 | exports.default = AtomicBlock;
--------------------------------------------------------------------------------
/frame/custom_node_modules/medium-draft/lib/components/blocks/blockquotecaption.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | var _react = require('react');
8 |
9 | var _react2 = _interopRequireDefault(_react);
10 |
11 | var _draftJs = require('draft-js');
12 |
13 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
14 |
15 | // import './blockquotecaption.scss';
16 |
17 | exports.default = function (props) {
18 | return _react2.default.createElement(
19 | 'cite',
20 | null,
21 | _react2.default.createElement(_draftJs.EditorBlock, props)
22 | );
23 | };
--------------------------------------------------------------------------------
/frame/custom_node_modules/medium-draft/lib/components/blocks/break.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | var _react = require("react");
8 |
9 | var _react2 = _interopRequireDefault(_react);
10 |
11 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
12 |
13 | exports.default = function () {
14 | return _react2.default.createElement("hr", { className: "md-block-hr" });
15 | };
--------------------------------------------------------------------------------
/frame/custom_node_modules/medium-draft/lib/components/blocks/caption.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | var _react = require('react');
8 |
9 | var _react2 = _interopRequireDefault(_react);
10 |
11 | var _draftJs = require('draft-js');
12 |
13 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
14 |
15 | // import './caption.scss';
16 |
17 | exports.default = function (props) {
18 | return _react2.default.createElement(_draftJs.EditorBlock, props);
19 | };
--------------------------------------------------------------------------------
/frame/custom_node_modules/medium-draft/lib/components/blocks/text.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | var _react = require('react');
8 |
9 | var _react2 = _interopRequireDefault(_react);
10 |
11 | var _draftJs = require('draft-js');
12 |
13 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
14 |
15 | // export default class Paragraph extends Component {
16 | // render(){
17 | // return (
18 | //
19 | // );
20 | // }
21 | // }
22 |
23 | // import './text.scss';
24 |
25 | exports.default = function (props) {
26 | return _react2.default.createElement(_draftJs.EditorBlock, props);
27 | };
--------------------------------------------------------------------------------
/frame/custom_node_modules/medium-draft/lib/components/blocktoolbar.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
8 |
9 | var _propTypes = require('prop-types');
10 |
11 | var _propTypes2 = _interopRequireDefault(_propTypes);
12 |
13 | var _react = require('react');
14 |
15 | var _react2 = _interopRequireDefault(_react);
16 |
17 | var _draftJs = require('draft-js');
18 |
19 | var _stylebutton = require('./stylebutton');
20 |
21 | var _stylebutton2 = _interopRequireDefault(_stylebutton);
22 |
23 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
24 |
25 | var BlockToolbar = function BlockToolbar(props) {
26 | if (props.buttons.length < 1) {
27 | return null;
28 | }
29 | var editorState = props.editorState;
30 |
31 | var blockType = _draftJs.RichUtils.getCurrentBlockType(editorState);
32 | return _react2.default.createElement(
33 | 'div',
34 | { className: 'md-RichEditor-controls md-RichEditor-controls-block' },
35 | props.buttons.map(function (type) {
36 | var iconLabel = {};
37 | iconLabel.label = type.label;
38 | return _react2.default.createElement(_stylebutton2.default, _extends({}, iconLabel, {
39 | key: type.style,
40 | active: type.style === blockType,
41 | onToggle: props.onToggle,
42 | style: type.style,
43 | description: type.description
44 | }));
45 | })
46 | );
47 | };
48 |
49 | BlockToolbar.propTypes = {
50 | buttons: _propTypes2.default.array,
51 | editorState: _propTypes2.default.object.isRequired,
52 | onToggle: _propTypes2.default.func
53 | };
54 |
55 | exports.default = BlockToolbar;
--------------------------------------------------------------------------------
/frame/custom_node_modules/medium-draft/lib/components/customrenderer.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | var _blockquotecaption = require('./blocks/blockquotecaption');
8 |
9 | var _blockquotecaption2 = _interopRequireDefault(_blockquotecaption);
10 |
11 | var _caption = require('./blocks/caption');
12 |
13 | var _caption2 = _interopRequireDefault(_caption);
14 |
15 | var _atomic = require('./blocks/atomic');
16 |
17 | var _atomic2 = _interopRequireDefault(_atomic);
18 |
19 | var _todo = require('./blocks/todo');
20 |
21 | var _todo2 = _interopRequireDefault(_todo);
22 |
23 | var _image = require('./blocks/image');
24 |
25 | var _image2 = _interopRequireDefault(_image);
26 |
27 | var _break = require('./blocks/break');
28 |
29 | var _break2 = _interopRequireDefault(_break);
30 |
31 | var _constants = require('../util/constants');
32 |
33 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
34 |
35 | exports.default = function (setEditorState, getEditorState) {
36 | return function (contentBlock) {
37 | // console.log(editorState, onChange);
38 | var type = contentBlock.getType();
39 | switch (type) {
40 | case _constants.Block.BLOCKQUOTE_CAPTION:
41 | return {
42 | component: _blockquotecaption2.default
43 | };
44 | case _constants.Block.CAPTION:
45 | return {
46 | component: _caption2.default
47 | };
48 | case _constants.Block.ATOMIC:
49 | return {
50 | component: _atomic2.default,
51 | editable: false,
52 | props: {
53 | getEditorState: getEditorState
54 | }
55 | };
56 | case _constants.Block.TODO:
57 | return {
58 | component: _todo2.default,
59 | props: {
60 | setEditorState: setEditorState,
61 | getEditorState: getEditorState
62 | }
63 | };
64 | case _constants.Block.IMAGE:
65 | return {
66 | component: _image2.default,
67 | props: {
68 | setEditorState: setEditorState,
69 | getEditorState: getEditorState
70 | }
71 | };
72 | case _constants.Block.BREAK:
73 | return {
74 | component: _break2.default,
75 | editable: false
76 | };
77 | default:
78 | return null;
79 | }
80 | };
81 | };
--------------------------------------------------------------------------------
/frame/custom_node_modules/medium-draft/lib/components/entities/link.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 | exports.findLinkEntities = undefined;
7 |
8 | var _propTypes = require('prop-types');
9 |
10 | var _propTypes2 = _interopRequireDefault(_propTypes);
11 |
12 | var _react = require('react');
13 |
14 | var _react2 = _interopRequireDefault(_react);
15 |
16 | var _constants = require('../../util/constants');
17 |
18 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
19 |
20 | var findLinkEntities = exports.findLinkEntities = function findLinkEntities(contentBlock, callback, contentState) {
21 | contentBlock.findEntityRanges(function (character) {
22 | var entityKey = character.getEntity();
23 | return entityKey !== null && contentState.getEntity(entityKey).getType() === _constants.Entity.LINK;
24 | }, callback);
25 | };
26 |
27 | var Link = function Link(props) {
28 | var contentState = props.contentState,
29 | entityKey = props.entityKey;
30 |
31 | var _contentState$getEnti = contentState.getEntity(entityKey).getData(),
32 | url = _contentState$getEnti.url;
33 |
34 | return _react2.default.createElement(
35 | 'a',
36 | {
37 | className: 'md-link',
38 | href: url,
39 | rel: 'noopener noreferrer',
40 | target: '_blank',
41 | 'aria-label': url
42 | },
43 | props.children
44 | );
45 | };
46 |
47 | Link.propTypes = {
48 | children: _propTypes2.default.node,
49 | entityKey: _propTypes2.default.string,
50 | contentState: _propTypes2.default.object.isRequired
51 | };
52 |
53 | exports.default = Link;
--------------------------------------------------------------------------------
/frame/custom_node_modules/medium-draft/lib/components/inlinetoolbar.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
8 |
9 | var _propTypes = require('prop-types');
10 |
11 | var _propTypes2 = _interopRequireDefault(_propTypes);
12 |
13 | var _react = require('react');
14 |
15 | var _react2 = _interopRequireDefault(_react);
16 |
17 | var _stylebutton = require('./stylebutton');
18 |
19 | var _stylebutton2 = _interopRequireDefault(_stylebutton);
20 |
21 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
22 |
23 | var InlineToolbar = function InlineToolbar(props) {
24 | if (props.buttons.length < 1) {
25 | return null;
26 | }
27 | var currentStyle = props.editorState.getCurrentInlineStyle();
28 | return _react2.default.createElement(
29 | 'div',
30 | { className: 'md-RichEditor-controls md-RichEditor-controls-inline' },
31 | props.buttons.map(function (type) {
32 | var iconLabel = {};
33 | iconLabel.label = type.label;
34 | return _react2.default.createElement(_stylebutton2.default, _extends({}, iconLabel, {
35 | key: type.style,
36 | active: currentStyle.has(type.style),
37 | onToggle: props.onToggle,
38 | style: type.style,
39 | description: type.description
40 | }));
41 | })
42 | );
43 | };
44 |
45 | InlineToolbar.propTypes = {
46 | buttons: _propTypes2.default.array,
47 | editorState: _propTypes2.default.object.isRequired,
48 | onToggle: _propTypes2.default.func
49 | };
50 |
51 | exports.default = InlineToolbar;
--------------------------------------------------------------------------------
/frame/custom_node_modules/medium-draft/lib/components/sides/break.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
8 |
9 | var _propTypes = require('prop-types');
10 |
11 | var _propTypes2 = _interopRequireDefault(_propTypes);
12 |
13 | var _react = require('react');
14 |
15 | var _react2 = _interopRequireDefault(_react);
16 |
17 | var _model = require('../../model');
18 |
19 | var _constants = require('../../util/constants');
20 |
21 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
22 |
23 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
24 |
25 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
26 |
27 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
28 |
29 | var BreakButton = function (_React$Component) {
30 | _inherits(BreakButton, _React$Component);
31 |
32 | function BreakButton(props) {
33 | _classCallCheck(this, BreakButton);
34 |
35 | var _this = _possibleConstructorReturn(this, (BreakButton.__proto__ || Object.getPrototypeOf(BreakButton)).call(this, props));
36 |
37 | _this.onClick = _this.onClick.bind(_this);
38 | return _this;
39 | }
40 |
41 | _createClass(BreakButton, [{
42 | key: 'onClick',
43 | value: function onClick() {
44 | this.props.setEditorState((0, _model.addNewBlock)(this.props.getEditorState(), _constants.Block.BREAK));
45 | }
46 | }, {
47 | key: 'render',
48 | value: function render() {
49 | return _react2.default.createElement(
50 | 'button',
51 | { className: 'md-sb-button', onClick: this.onClick, type: 'button' },
52 | _react2.default.createElement('i', { className: 'fa fa-minus' })
53 | );
54 | }
55 | }]);
56 |
57 | return BreakButton;
58 | }(_react2.default.Component);
59 |
60 | exports.default = BreakButton;
61 |
62 |
63 | BreakButton.propTypes = {
64 | setEditorState: _propTypes2.default.func,
65 | getEditorState: _propTypes2.default.func,
66 | close: _propTypes2.default.func
67 | };
--------------------------------------------------------------------------------
/frame/custom_node_modules/medium-draft/lib/components/stylebutton.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
8 |
9 | var _propTypes = require('prop-types');
10 |
11 | var _propTypes2 = _interopRequireDefault(_propTypes);
12 |
13 | var _react = require('react');
14 |
15 | var _react2 = _interopRequireDefault(_react);
16 |
17 | var _constants = require('../util/constants.js');
18 |
19 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
20 |
21 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
22 |
23 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
24 |
25 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
26 |
27 | var StyleButton = function (_React$Component) {
28 | _inherits(StyleButton, _React$Component);
29 |
30 | function StyleButton(props) {
31 | _classCallCheck(this, StyleButton);
32 |
33 | var _this = _possibleConstructorReturn(this, (StyleButton.__proto__ || Object.getPrototypeOf(StyleButton)).call(this, props));
34 |
35 | _this.onToggle = function (e) {
36 | e.preventDefault();
37 | _this.props.onToggle(_this.props.style);
38 | };
39 | return _this;
40 | }
41 |
42 | _createClass(StyleButton, [{
43 | key: 'render',
44 | value: function render() {
45 | if (this.props.style === _constants.HYPERLINK) {
46 | return null;
47 | }
48 | var className = 'md-RichEditor-styleButton';
49 | if (this.props.active) {
50 | className += ' md-RichEditor-activeButton';
51 | }
52 | className += ' md-RichEditor-styleButton-' + this.props.style.toLowerCase();
53 | return _react2.default.createElement(
54 | 'span',
55 | {
56 | className: className + ' hint--top',
57 | onMouseDown: this.onToggle,
58 | 'aria-label': this.props.description
59 | },
60 | this.props.icon ? _react2.default.createElement('i', { className: 'fa fa-' + this.props.icon }) : this.props.label
61 | );
62 | }
63 | }]);
64 |
65 | return StyleButton;
66 | }(_react2.default.Component);
67 |
68 | exports.default = StyleButton;
69 |
70 |
71 | StyleButton.propTypes = {
72 | onToggle: _propTypes2.default.func,
73 | style: _propTypes2.default.string,
74 | active: _propTypes2.default.bool,
75 | icon: _propTypes2.default.string,
76 | label: _propTypes2.default.oneOfType([_propTypes2.default.string, _propTypes2.default.element, _propTypes2.default.object]),
77 | description: _propTypes2.default.string
78 | };
--------------------------------------------------------------------------------
/frame/custom_node_modules/medium-draft/lib/editor.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | var _createEditor = require('./createEditor');
8 |
9 | var _createEditor2 = _interopRequireDefault(_createEditor);
10 |
11 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
12 |
13 | exports.default = (0, _createEditor2.default)();
--------------------------------------------------------------------------------
/frame/custom_node_modules/medium-draft/lib/handlers/blockRenderMap.js:
--------------------------------------------------------------------------------
1 | "use strict";
--------------------------------------------------------------------------------
/frame/custom_node_modules/medium-draft/lib/handlers/blockRendererFn.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 | var customRendererFn = exports.customRendererFn = function customRendererFn(contentBlock, _ref) {
7 | var rendererFn = _ref.rendererFn,
8 | getEditorState = _ref.getEditorState,
9 | setEditorState = _ref.setEditorState;
10 |
11 | var customRenderer = rendererFn(setEditorState, getEditorState);
12 | return customRenderer(contentBlock);
13 | };
14 |
15 | var handlerList = exports.handlerList = [customRendererFn];
16 |
17 | var blockRendererFn = function blockRendererFn(contentBlock, options) {
18 | var handlers = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : handlerList;
19 | var _iteratorNormalCompletion = true;
20 | var _didIteratorError = false;
21 | var _iteratorError = undefined;
22 |
23 | try {
24 | for (var _iterator = handlers[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
25 | var handler = _step.value;
26 |
27 | var res = handler(contentBlock, options);
28 | if (res) {
29 | return res;
30 | }
31 | }
32 | } catch (err) {
33 | _didIteratorError = true;
34 | _iteratorError = err;
35 | } finally {
36 | try {
37 | if (!_iteratorNormalCompletion && _iterator.return) {
38 | _iterator.return();
39 | }
40 | } finally {
41 | if (_didIteratorError) {
42 | throw _iteratorError;
43 | }
44 | }
45 | }
46 |
47 | return null;
48 | };
49 |
50 | exports.default = blockRendererFn;
--------------------------------------------------------------------------------
/frame/custom_node_modules/medium-draft/lib/handlers/blockStyleFn.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 | var inBuiltBlockStyleFn = exports.inBuiltBlockStyleFn = function inBuiltBlockStyleFn(block, _ref) {
7 | var bsFn = _ref.blockStyleFn;
8 | return bsFn(block);
9 | };
10 |
11 | var handlerList = exports.handlerList = [inBuiltBlockStyleFn];
12 |
13 | var blockStyleFn = function blockStyleFn(block, options) {
14 | var handlers = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : handlerList;
15 | var _iteratorNormalCompletion = true;
16 | var _didIteratorError = false;
17 | var _iteratorError = undefined;
18 |
19 | try {
20 | for (var _iterator = handlers[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
21 | var handler = _step.value;
22 |
23 | var res = handler(block, options);
24 | if (res) {
25 | return res;
26 | }
27 | }
28 | } catch (err) {
29 | _didIteratorError = true;
30 | _iteratorError = err;
31 | } finally {
32 | try {
33 | if (!_iteratorNormalCompletion && _iterator.return) {
34 | _iterator.return();
35 | }
36 | } finally {
37 | if (_didIteratorError) {
38 | throw _iteratorError;
39 | }
40 | }
41 | }
42 |
43 | return 'md-block';
44 | };
45 |
46 | exports.default = blockStyleFn;
--------------------------------------------------------------------------------
/frame/custom_node_modules/medium-draft/lib/handlers/handleBeforeInput.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 | exports.handlerList = exports.handlerUsingBeforeInput = undefined;
7 |
8 | var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; /**
9 | * This function is responsible for emitting various commands based on various key combos.
10 | */
11 |
12 | var _constants = require('../util/constants');
13 |
14 | var handlerUsingBeforeInput = exports.handlerUsingBeforeInput = function handlerUsingBeforeInput(str, _ref) {
15 | var getEditorState = _ref.getEditorState,
16 | beforeInput = _ref.beforeInput,
17 | stringToTypeMap = _ref.stringToTypeMap;
18 |
19 | var editorState = getEditorState();
20 | var onChange = function onChange(es) {
21 | editorState = es;
22 | };
23 | var behavior = beforeInput(editorState, str, onChange, stringToTypeMap);
24 | if (behavior === _constants.HANDLED) {
25 | return editorState;
26 | }
27 | return getEditorState();
28 | };
29 |
30 | var handlerList = exports.handlerList = [handlerUsingBeforeInput];
31 |
32 | var handleBeforeInput = function handleBeforeInput(str, es, options) {
33 | var handlers = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : handlerList;
34 |
35 | var originalEs = options.getEditorState();
36 | var editorState = originalEs;
37 |
38 | var _getEs = function _getEs() {
39 | return editorState;
40 | };
41 | var behavior = _constants.NOT_HANDLED;
42 |
43 | var _iteratorNormalCompletion = true;
44 | var _didIteratorError = false;
45 | var _iteratorError = undefined;
46 |
47 | try {
48 | for (var _iterator = handlers[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
49 | var handler = _step.value;
50 |
51 | editorState = handler(str, _extends({}, options, {
52 | getEditorState: _getEs
53 | }));
54 | if (editorState !== originalEs) {
55 | options.setEditorState(editorState);
56 | behavior = _constants.HANDLED;
57 | break;
58 | }
59 | }
60 | } catch (err) {
61 | _didIteratorError = true;
62 | _iteratorError = err;
63 | } finally {
64 | try {
65 | if (!_iteratorNormalCompletion && _iterator.return) {
66 | _iterator.return();
67 | }
68 | } finally {
69 | if (_didIteratorError) {
70 | throw _iteratorError;
71 | }
72 | }
73 | }
74 |
75 | return behavior;
76 | };
77 |
78 | exports.default = handleBeforeInput;
--------------------------------------------------------------------------------
/frame/custom_node_modules/medium-draft/lib/handlers/handlePastedText.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 | exports.handlerList = exports.handlePasteInImageCaption = undefined;
7 |
8 | var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
9 |
10 | var _draftJs = require('draft-js');
11 |
12 | var _model = require('../model');
13 |
14 | var _constants = require('../util/constants');
15 |
16 | /**
17 | * If current block is image and text is pasted, add that as plain
18 | * text at the cursor position.
19 | */
20 | var handlePasteInImageCaption = exports.handlePasteInImageCaption = function handlePasteInImageCaption(text, html, es, _ref) {
21 | var getEditorState = _ref.getEditorState;
22 |
23 | var editorState = getEditorState();
24 | var currentBlock = (0, _model.getCurrentBlock)(editorState);
25 | if (currentBlock.getType() !== _constants.Block.IMAGE) {
26 | return editorState;
27 | }
28 |
29 | return _draftJs.EditorState.push(editorState, _draftJs.Modifier.insertText(editorState.getCurrentContent(), editorState.getSelection(), text));
30 | };
31 |
32 | var handlerList = exports.handlerList = [handlePasteInImageCaption];
33 |
34 | var handlePastedText = function handlePastedText(text, html, es, options) {
35 | var handlers = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : handlerList;
36 |
37 | var originalEs = options.getEditorState();
38 | var editorState = originalEs;
39 |
40 | var _getEs = function _getEs() {
41 | return editorState;
42 | };
43 | var behavior = _constants.NOT_HANDLED;
44 |
45 | var _iteratorNormalCompletion = true;
46 | var _didIteratorError = false;
47 | var _iteratorError = undefined;
48 |
49 | try {
50 | for (var _iterator = handlers[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
51 | var handler = _step.value;
52 |
53 | editorState = handler(text, html, es, _extends({}, options, {
54 | getEditorState: _getEs
55 | }));
56 | if (editorState !== originalEs) {
57 | options.setEditorState(editorState);
58 | behavior = _constants.HANDLED;
59 | break;
60 | }
61 | }
62 | } catch (err) {
63 | _didIteratorError = true;
64 | _iteratorError = err;
65 | } finally {
66 | try {
67 | if (!_iteratorNormalCompletion && _iterator.return) {
68 | _iterator.return();
69 | }
70 | } finally {
71 | if (_didIteratorError) {
72 | throw _iteratorError;
73 | }
74 | }
75 | }
76 |
77 | return behavior;
78 | };
79 |
80 | exports.default = handlePastedText;
--------------------------------------------------------------------------------
/frame/custom_node_modules/medium-draft/lib/handlers/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | var _onTab = require('./onTab');
8 |
9 | var _onTab2 = _interopRequireDefault(_onTab);
10 |
11 | var _onUpArrow = require('./onUpArrow');
12 |
13 | var _onUpArrow2 = _interopRequireDefault(_onUpArrow);
14 |
15 | var _handlePastedText = require('./handlePastedText');
16 |
17 | var _handlePastedText2 = _interopRequireDefault(_handlePastedText);
18 |
19 | var _handleReturn = require('./handleReturn');
20 |
21 | var _handleReturn2 = _interopRequireDefault(_handleReturn);
22 |
23 | var _handleKeyCommand = require('./handleKeyCommand');
24 |
25 | var _handleKeyCommand2 = _interopRequireDefault(_handleKeyCommand);
26 |
27 | var _handleBeforeInput = require('./handleBeforeInput');
28 |
29 | var _handleBeforeInput2 = _interopRequireDefault(_handleBeforeInput);
30 |
31 | var _blockRendererFn = require('./blockRendererFn');
32 |
33 | var _blockRendererFn2 = _interopRequireDefault(_blockRendererFn);
34 |
35 | var _blockStyleFn = require('./blockStyleFn');
36 |
37 | var _blockStyleFn2 = _interopRequireDefault(_blockStyleFn);
38 |
39 | var _keyBindingFn = require('./keyBindingFn');
40 |
41 | var _keyBindingFn2 = _interopRequireDefault(_keyBindingFn);
42 |
43 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
44 |
45 | var defaultPlugins = {
46 | onTab: _onTab2.default,
47 | onUpArrow: _onUpArrow2.default,
48 | handlePastedText: _handlePastedText2.default,
49 | handleReturn: _handleReturn2.default,
50 | handleKeyCommand: _handleKeyCommand2.default,
51 | handleBeforeInput: _handleBeforeInput2.default,
52 | blockRendererFn: _blockRendererFn2.default,
53 | blockStyleFn: _blockStyleFn2.default,
54 | keyBindingFn: _keyBindingFn2.default
55 | };
56 |
57 | exports.default = defaultPlugins;
--------------------------------------------------------------------------------
/frame/custom_node_modules/medium-draft/lib/handlers/keyBindingFn.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 | exports.handlerList = exports.customKeyBindingFn = undefined;
7 |
8 | var _draftJs = require('draft-js');
9 |
10 | var customKeyBindingFn = exports.customKeyBindingFn = function customKeyBindingFn(e, _ref) {
11 | var kbFn = _ref.keyBindingFn;
12 | return kbFn(e);
13 | };
14 |
15 | var handlerList = exports.handlerList = [customKeyBindingFn];
16 |
17 | exports.default = function (e, options) {
18 | var handlers = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : handlerList;
19 | var _iteratorNormalCompletion = true;
20 | var _didIteratorError = false;
21 | var _iteratorError = undefined;
22 |
23 | try {
24 | for (var _iterator = handlers[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
25 | var handler = _step.value;
26 |
27 | var res = handler(e, options);
28 | if (res) {
29 | return res;
30 | }
31 | }
32 | } catch (err) {
33 | _didIteratorError = true;
34 | _iteratorError = err;
35 | } finally {
36 | try {
37 | if (!_iteratorNormalCompletion && _iterator.return) {
38 | _iterator.return();
39 | }
40 | } finally {
41 | if (_didIteratorError) {
42 | throw _iteratorError;
43 | }
44 | }
45 | }
46 |
47 | return (0, _draftJs.getDefaultKeyBinding)(e);
48 | };
--------------------------------------------------------------------------------
/frame/custom_node_modules/medium-draft/lib/handlers/onTab.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 | exports.handlerList = exports.handleTabForListItems = undefined;
7 |
8 | var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
9 |
10 | var _draftJs = require('draft-js');
11 |
12 | var MAX_NESTING_LEVEL = 2;
13 |
14 | var handleTabForListItems = exports.handleTabForListItems = function handleTabForListItems(e, _ref) {
15 | var getEditorState = _ref.getEditorState;
16 |
17 | var editorState = getEditorState();
18 | var newEditorState = _draftJs.RichUtils.onTab(e, editorState, MAX_NESTING_LEVEL);
19 | if (newEditorState === editorState) {
20 | return editorState;
21 | }
22 | return newEditorState;
23 | };
24 |
25 | var handlerList = exports.handlerList = [handleTabForListItems];
26 |
27 | var onTab = function onTab(e, options) {
28 | var handlers = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : handlerList;
29 | var getEditorState = options.getEditorState,
30 | setEditorState = options.setEditorState;
31 |
32 | var newEditorState = handlers.reduce(function (editorState, handler) {
33 | return handler(e, _extends({}, options, {
34 | getEditorState: function getEditorState() {
35 | return editorState;
36 | }
37 | }));
38 | }, getEditorState());
39 | setEditorState(newEditorState);
40 | };
41 |
42 | exports.default = onTab;
--------------------------------------------------------------------------------
/frame/custom_node_modules/medium-draft/lib/model/content.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | var _draftJs = require('draft-js');
8 |
9 | var _link = require('../components/entities/link');
10 |
11 | var _link2 = _interopRequireDefault(_link);
12 |
13 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
14 |
15 | var defaultDecorators = new _draftJs.CompositeDecorator([{
16 | strategy: _link.findLinkEntities,
17 | component: _link2.default
18 | }]);
19 |
20 | var createEditorState = function createEditorState() {
21 | var content = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
22 | var decorators = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : defaultDecorators;
23 |
24 | if (content === null) {
25 | return _draftJs.EditorState.createEmpty(decorators);
26 | }
27 | var contentState = null;
28 | if (typeof content === 'string') {
29 | contentState = _draftJs.ContentState.createFromText(content);
30 | } else {
31 | contentState = (0, _draftJs.convertFromRaw)(content);
32 | }
33 | return _draftJs.EditorState.createWithContent(contentState, decorators);
34 | };
35 |
36 | exports.default = createEditorState;
--------------------------------------------------------------------------------
/frame/custom_node_modules/medium-draft/lib/util/beforeinput.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 | exports.StringToTypeMap = undefined;
7 |
8 | var _model = require('../model');
9 |
10 | var _constants = require('./constants');
11 |
12 | /*
13 | This is a key value pair where the key is the string that is input while typing.
14 | While typing in an empty block, if the entered text matches any of the keys in
15 | this dictionary, that particular block's type will be changed to the value
16 | associated with that key.
17 | */
18 | var StringToTypeMap = exports.StringToTypeMap = {
19 | '--': _constants.Block.BLOCKQUOTE + ':' + _constants.Block.BLOCKQUOTE_CAPTION + ':' + _constants.Block.CAPTION,
20 | '> ': _constants.Block.BLOCKQUOTE,
21 | '*.': _constants.Block.UL,
22 | '* ': _constants.Block.UL,
23 | '- ': _constants.Block.UL,
24 | '1.': _constants.Block.OL,
25 | '# ': _constants.Block.H1,
26 | '##': _constants.Block.H2,
27 | '==': _constants.Block.UNSTYLED,
28 | '[]': _constants.Block.TODO
29 | };
30 |
31 | /*
32 | This function is called before text is input in a block in `draft-js`. It checks
33 | whether the input string (first 2 cahracters only) is present in the `StringToTypeMap`
34 | mapping or not. If present, it converts the current block's type and called the `editor`'s
35 | `onChange` function. Otherwise, does nothing. By defualt, the above key-value mapping
36 | is passed. In custom implementation, users can pass their own mapping or extend
37 | the current one.
38 | */
39 | var beforeInput = function beforeInput(editorState, inputString, onChange) {
40 | var mapping = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : StringToTypeMap;
41 |
42 | var selection = editorState.getSelection();
43 | var block = (0, _model.getCurrentBlock)(editorState);
44 | var blockType = block.getType();
45 | if (blockType.indexOf(_constants.Block.ATOMIC) === 0) {
46 | return _constants.NOT_HANDLED;
47 | }
48 | var blockLength = block.getLength();
49 | if (selection.getAnchorOffset() > 1 || blockLength > 1) {
50 | return _constants.NOT_HANDLED;
51 | }
52 | var blockTo = mapping[block.getText()[0] + inputString];
53 | if (!blockTo) {
54 | return _constants.NOT_HANDLED;
55 | }
56 | var finalType = blockTo.split(':');
57 | if (finalType.length < 1 || finalType.length > 3) {
58 | return _constants.NOT_HANDLED;
59 | }
60 | var fType = finalType[0];
61 | if (finalType.length === 1) {
62 | if (blockType === finalType[0]) {
63 | return _constants.NOT_HANDLED;
64 | }
65 | } else if (finalType.length === 2) {
66 | if (blockType === finalType[1]) {
67 | return _constants.NOT_HANDLED;
68 | }
69 | if (blockType === finalType[0]) {
70 | fType = finalType[1];
71 | }
72 | } else if (finalType.length === 3) {
73 | if (blockType === finalType[2]) {
74 | return _constants.NOT_HANDLED;
75 | }
76 | if (blockType === finalType[0]) {
77 | fType = finalType[1];
78 | } else {
79 | fType = finalType[2];
80 | }
81 | }
82 | onChange((0, _model.resetBlockWithType)(editorState, fType, {
83 | text: ''
84 | }));
85 | return _constants.HANDLED;
86 | };
87 |
88 | exports.default = beforeInput;
--------------------------------------------------------------------------------
/frame/custom_node_modules/medium-draft/lib/util/blockStyleFn.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | var _constants = require('./constants');
8 |
9 | /*
10 | Get custom classnames for each of the different block types supported.
11 | */
12 |
13 | var BASE_BLOCK_CLASS = 'md-block';
14 |
15 | exports.default = function (block) {
16 | switch (block.getType()) {
17 | case _constants.Block.BLOCKQUOTE:
18 | return BASE_BLOCK_CLASS + ' ' + BASE_BLOCK_CLASS + '-quote md-RichEditor-blockquote';
19 | case _constants.Block.UNSTYLED:
20 | return BASE_BLOCK_CLASS + ' ' + BASE_BLOCK_CLASS + '-paragraph';
21 | case _constants.Block.ATOMIC:
22 | return BASE_BLOCK_CLASS + ' ' + BASE_BLOCK_CLASS + '-atomic';
23 | case _constants.Block.CAPTION:
24 | return BASE_BLOCK_CLASS + ' ' + BASE_BLOCK_CLASS + '-caption';
25 | case _constants.Block.TODO:
26 | {
27 | var data = block.getData();
28 | var checkedClass = data.get('checked') === true ? BASE_BLOCK_CLASS + '-todo-checked' : BASE_BLOCK_CLASS + '-todo-unchecked';
29 | var finalClass = BASE_BLOCK_CLASS + ' ' + BASE_BLOCK_CLASS + '-paragraph ';
30 | finalClass += BASE_BLOCK_CLASS + '-todo ' + checkedClass;
31 | return finalClass;
32 | }
33 | case _constants.Block.IMAGE:
34 | return BASE_BLOCK_CLASS + ' ' + BASE_BLOCK_CLASS + '-image';
35 | case _constants.Block.BLOCKQUOTE_CAPTION:
36 | {
37 | var cls = BASE_BLOCK_CLASS + ' ' + BASE_BLOCK_CLASS + '-quote';
38 | return cls + ' md-RichEditor-blockquote ' + BASE_BLOCK_CLASS + '-quote-caption';
39 | }
40 | default:
41 | return BASE_BLOCK_CLASS;
42 | }
43 | };
--------------------------------------------------------------------------------
/frame/custom_node_modules/medium-draft/lib/util/constants.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 | /*
7 | Some of the constants which are used throughout this project instead of
8 | directly using string.
9 | */
10 |
11 | var Block = exports.Block = {
12 | UNSTYLED: 'unstyled',
13 | PARAGRAPH: 'unstyled',
14 | OL: 'ordered-list-item',
15 | UL: 'unordered-list-item',
16 | H1: 'header-one',
17 | H2: 'header-two',
18 | H3: 'header-three',
19 | H4: 'header-four',
20 | H5: 'header-five',
21 | H6: 'header-six',
22 | CODE: 'code-block',
23 | BLOCKQUOTE: 'blockquote',
24 | PULLQUOTE: 'pullquote',
25 | ATOMIC: 'atomic',
26 | BLOCKQUOTE_CAPTION: 'block-quote-caption',
27 | CAPTION: 'caption',
28 | TODO: 'todo',
29 | IMAGE: 'atomic:image',
30 | BREAK: 'atomic:break'
31 | };
32 |
33 | var Inline = exports.Inline = {
34 | BOLD: 'BOLD',
35 | CODE: 'CODE',
36 | ITALIC: 'ITALIC',
37 | STRIKETHROUGH: 'STRIKETHROUGH',
38 | UNDERLINE: 'UNDERLINE',
39 | HIGHLIGHT: 'HIGHLIGHT'
40 | };
41 |
42 | var Entity = exports.Entity = {
43 | LINK: 'LINK'
44 | };
45 |
46 | var HYPERLINK = exports.HYPERLINK = 'hyperlink';
47 | var HANDLED = exports.HANDLED = 'handled';
48 | var NOT_HANDLED = exports.NOT_HANDLED = 'not_handled';
49 |
50 | var KEY_COMMANDS = exports.KEY_COMMANDS = {
51 | addNewBlock: function addNewBlock() {
52 | return 'add-new-block';
53 | },
54 | changeType: function changeType() {
55 | var type = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
56 | return 'changetype:' + type;
57 | },
58 | showLinkInput: function showLinkInput() {
59 | return 'showlinkinput';
60 | },
61 | unlink: function unlink() {
62 | return 'unlink';
63 | },
64 | toggleInline: function toggleInline() {
65 | var type = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
66 | return 'toggleinline:' + type;
67 | },
68 | deleteBlock: function deleteBlock() {
69 | return 'delete-block';
70 | }
71 | };
72 |
73 | exports.default = {
74 | Block: Block,
75 | Inline: Inline,
76 | Entity: Entity
77 | };
--------------------------------------------------------------------------------
/frame/custom_node_modules/medium-draft/lib/util/customstylemap.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | var _customStyleMap;
8 |
9 | var _constants = require('./constants');
10 |
11 | function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
12 |
13 | /*
14 | Custom style map for custom entities like Hihglight.
15 | */
16 | var customStyleMap = (_customStyleMap = {}, _defineProperty(_customStyleMap, _constants.Inline.HIGHLIGHT, {
17 | backgroundColor: 'yellow'
18 | }), _defineProperty(_customStyleMap, _constants.Inline.CODE, {
19 | fontFamily: 'Consolas, "Liberation Mono", Menlo, Courier, monospace',
20 | margin: '4px 0',
21 | fontSize: '0.9em',
22 | padding: '1px 3px',
23 | color: '#555',
24 | backgroundColor: '#fcfcfc',
25 | border: '1px solid #ccc',
26 | borderBottomColor: '#bbb',
27 | borderRadius: 3,
28 | boxShadow: 'inset 0 -1px 0 #bbb'
29 | }), _customStyleMap);
30 |
31 | exports.default = customStyleMap;
--------------------------------------------------------------------------------
/frame/custom_node_modules/medium-draft/lib/util/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 | /*
7 | Returns the `boundingClientRect` of the passed selection.
8 | */
9 | var getSelectionRect = exports.getSelectionRect = function getSelectionRect(selected) {
10 | var _rect = selected.getRangeAt(0).getBoundingClientRect();
11 | // selected.getRangeAt(0).getBoundingClientRect()
12 | var rect = _rect && _rect.top ? _rect : selected.getRangeAt(0).getClientRects()[0];
13 | if (!rect) {
14 | if (selected.anchorNode && selected.anchorNode.getBoundingClientRect) {
15 | rect = selected.anchorNode.getBoundingClientRect();
16 | rect.isEmptyline = true;
17 | } else {
18 | return null;
19 | }
20 | }
21 | return rect;
22 | };
23 |
24 | /*
25 | Returns the native selection node.
26 | */
27 | var getSelection = exports.getSelection = function getSelection(root) {
28 | var t = null;
29 | if (root.getSelection) {
30 | t = root.getSelection();
31 | } else if (root.document.getSelection) {
32 | t = root.document.getSelection();
33 | } else if (root.document.selection) {
34 | t = root.document.selection.createRange().text;
35 | }
36 | return t;
37 | };
38 |
39 | /*
40 | Recursively finds the DOM Element of the block where the cursor is currently present.
41 | If not found, returns null.
42 | */
43 | var getSelectedBlockNode = exports.getSelectedBlockNode = function getSelectedBlockNode(root) {
44 | var selection = root.getSelection();
45 | if (selection.rangeCount === 0) {
46 | return null;
47 | }
48 | var node = selection.getRangeAt(0).startContainer;
49 | // console.log(node);
50 | do {
51 | if (node.getAttribute && node.getAttribute('data-block') === 'true') {
52 | return node;
53 | }
54 | node = node.parentNode;
55 | // console.log(node);
56 | } while (node !== null);
57 | return null;
58 | };
--------------------------------------------------------------------------------
/frame/custom_node_modules/medium-draft/lib/util/keybinding.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | var _draftJs = require('draft-js');
8 |
9 | var _constants = require('./constants');
10 |
11 | var changeType = _constants.KEY_COMMANDS.changeType,
12 | showLinkInput = _constants.KEY_COMMANDS.showLinkInput,
13 | unlink = _constants.KEY_COMMANDS.unlink;
14 |
15 | /*
16 | Emits various key commands to be used by `handleKeyCommand` in `Editor` based
17 | on various key combos.
18 | */
19 |
20 | exports.default = function (e) {
21 | if (_draftJs.KeyBindingUtil.hasCommandModifier(e) && e.which === 75) {
22 | if (e.shiftKey) {
23 | return unlink();
24 | }
25 | return showLinkInput();
26 | }
27 | if (e.altKey === true && !e.ctrlKey) {
28 | if (e.shiftKey === true) {
29 | switch (e.which) {
30 | // Alt + Shift + A
31 | // case 65: return addNewBlock();
32 | default:
33 | return (0, _draftJs.getDefaultKeyBinding)(e);
34 | }
35 | }
36 | switch (e.which) {
37 | // 1
38 | case 49:
39 | return changeType('ordered-list-item');
40 | // @
41 | case 50:
42 | return showLinkInput();
43 | // #
44 | case 51:
45 | return changeType('header-three');
46 | // *
47 | case 56:
48 | return changeType('unordered-list-item');
49 | // <
50 | case 188:
51 | return changeType('caption');
52 | // // -
53 | // case 189: return 'changetype:caption';
54 | // >
55 | case 190:
56 | return changeType('unstyled');
57 | // "
58 | case 222:
59 | return changeType('blockquote');
60 | default:
61 | return (0, _draftJs.getDefaultKeyBinding)(e);
62 | }
63 | }
64 | // if (e.keyCode === 46 && !e.ctrlKey) {
65 | // return KEY_COMMANDS.deleteBlock();
66 | // }
67 | return (0, _draftJs.getDefaultKeyBinding)(e);
68 | };
--------------------------------------------------------------------------------
/frame/custom_node_modules/medium-draft/lib/util/rendermap.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | var _Map;
8 |
9 | var _immutable = require('immutable');
10 |
11 | var _draftJs = require('draft-js');
12 |
13 | var _constants = require('./constants');
14 |
15 | function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
16 |
17 | /*
18 | Mapping that returns containers for the various block types.
19 | */
20 | var RenderMap = (0, _immutable.Map)((_Map = {}, _defineProperty(_Map, _constants.Block.CAPTION, {
21 | element: 'cite'
22 | }), _defineProperty(_Map, _constants.Block.BLOCKQUOTE_CAPTION, {
23 | element: 'blockquote'
24 | }), _defineProperty(_Map, _constants.Block.TODO, {
25 | element: 'div'
26 | }), _defineProperty(_Map, _constants.Block.IMAGE, {
27 | element: 'figure'
28 | }), _defineProperty(_Map, _constants.Block.BREAK, {
29 | element: 'div'
30 | }), _Map)).merge(_draftJs.DefaultDraftBlockRenderMap);
31 |
32 | exports.default = RenderMap;
--------------------------------------------------------------------------------
/frame/custom_node_modules/medium-draft/rendered.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Rendered Content | medium-draft
6 |
7 |
20 |
21 |
22 |
23 |
24 | Open this page by clicking the Render HTML button.
25 |
26 |
27 |
28 |
29 |
30 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/frame/custom_node_modules/node-sumbasic/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Vincent Utomo
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/frame/custom_node_modules/node-sumbasic/README.md:
--------------------------------------------------------------------------------
1 | # node-sumbasic
2 | Implementation of SumBasic on NodeJS.
3 |
4 | Sumbasic is a popular baseline method for document summarization. The explanation could be read from the original paper: Nenkova, A. and Vanderwende, L., 2005. The impact of frequency on summarization. Microsoft Research, Redmond, Washington, Tech. Rep. MSR-TR-2005, 101.
5 |
6 | Here, the SumBasic are created as module inside `./src/index.js`.
7 |
8 | ### NPM package ###
9 | - Run `npm install node-sumbasic --save`
10 | - Require it in your project `const sumBasic = require('node-sumbasic')`
11 | - Call it `sumBasic(documents, target_summary_length, minimum_sentence_length_considered [optional])`
12 | - Example `sumBasic(documents, 100)`
13 |
14 | ### Demo run in project folder ###
15 | - Make sure to install the npm modules first `npm install`
16 | - In the project, run `node ./src/demo.js`
17 |
18 | ### What's new ###
19 |
20 | 0.1.7
21 | - Change dependencies from natural to stemmer
22 | - Add minimum sentence length to the optional parameter
23 |
24 |
25 |
--------------------------------------------------------------------------------
/frame/custom_node_modules/node-sumbasic/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "_from": "node-sumbasic",
3 | "_id": "node-sumbasic@0.1.7",
4 | "_inBundle": false,
5 | "_integrity": "sha512-xHMmNpIz55Ptj7rOTj2vSBBt6vPLfENsRuNVKhhPpOcm+2+77/GLGkEpSIVJ4Qd2m0WhQdZlyHnMOPM1ATxTYg==",
6 | "_location": "/node-sumbasic",
7 | "_phantomChildren": {},
8 | "_requested": {
9 | "type": "tag",
10 | "registry": true,
11 | "raw": "node-sumbasic",
12 | "name": "node-sumbasic",
13 | "escapedName": "node-sumbasic",
14 | "rawSpec": "",
15 | "saveSpec": null,
16 | "fetchSpec": "latest"
17 | },
18 | "_requiredBy": [
19 | "#USER",
20 | "/"
21 | ],
22 | "_resolved": "https://registry.npmjs.org/node-sumbasic/-/node-sumbasic-0.1.7.tgz",
23 | "_shasum": "379a068cda43c49b33b55c930dc0ff00dfc84e86",
24 | "_spec": "node-sumbasic",
25 | "_where": "C:\\Users\\JD\\Documents\\Git\\frame\\frame",
26 | "author": {
27 | "name": "MSVCode",
28 | "email": "msvcode@gmail.com"
29 | },
30 | "bugs": {
31 | "url": "https://github.com/MSVCode/node-sumbasic/issues"
32 | },
33 | "bundleDependencies": false,
34 | "dependencies": {
35 | "stemmer": "^1.0.2"
36 | },
37 | "deprecated": false,
38 | "description": "NodeJS implementation of popular baseline document summarizer 'SumBasic'.",
39 | "homepage": "https://github.com/MSVCode/node-sumbasic",
40 | "keywords": [
41 | "summarizer",
42 | "sumbasic",
43 | "summarization",
44 | "document"
45 | ],
46 | "license": "MIT",
47 | "main": ".\\src\\index.js",
48 | "name": "node-sumbasic",
49 | "repository": {
50 | "type": "git",
51 | "url": "git+https://github.com/MSVCode/node-sumbasic.git"
52 | },
53 | "version": "0.1.7"
54 | }
55 |
--------------------------------------------------------------------------------
/frame/custom_node_modules/node-sumbasic/src/demo.js:
--------------------------------------------------------------------------------
1 | var titles = [
2 | "Google is urging more manufacturers to enable a new security feature in Android Oreo that detects if a device has been downgraded to an earlier version of the OS. Known as rollback protection, the measure adds another layer of security in the event a device is lost or stolen, and the attacker rolls it back to an older Android firmware with known vulnerabilities. Google revealed some details about rollback protection in September, which caught the attention of Android enthusiasts who like the freedom to downgrade Android as they see fit, even though it could be a security risk. While the security feature is part of Oreo, it's not available on every Android device that runs Oreo. According to Google, rollback protection works in tandem with Project Treble, the major redesign of Android in Oreo that separates the Android platform from vendor code. The modular design aims to help Android OEMs deliver new versions of Android to end-users faster. However, Project Treble is only supported on new devices that ship with Android, rather than devices that get upgraded to Oreo. So new handsets like the Pixel 2 and Sony Xperia XZ1 are Treble-compatible, while the Nokia 8 isn't.",
3 | 'Security has long been a sore point for enterprise Android users, but Google has taken steps to improve security in the OS with Android Oreo. In a Wednesday blog post, the firm detailed a feature called rollback protection, which prevents a device from starting up if it has been downgraded to an older OS version that may contain security vulnerabilities. This means that if your business phone is stolen, it will be more difficult for a hacker to leverage security flaws found in a previous version of the OS and access your data. This could add piece of mind for IT professionals managing Android devices in the workplace. While rollback protection is part of Android Oreo, it is up to the individual manufacturers of Android devices to enable the feature, as noted by our sister site ZDNet. Rollback protection is part of Andriod Verified Boot 2.0 (AVB), designed to stop devices from starting up with software that has been altered by hackers, according to the blog post from security team member Gian G. Spicuzza. AVB runs with Project Treble, a "major re-architect" of the Android OS framework meant to make it easier for manufacturers to update to new versions of the OS.',
4 | "Since Android Oreo was made available to Pixel and Nexus devices, Google has been working to harden the security of the mobile platform. Today, the company announced some of the improvements they made in the security department throughout the last few months. Some of these security features have already been implemented like making it safer to get apps and dropping insecure network protocol, while others may be released in the not so distant future. Google confirmed that it's expanding support for hardware security, which means they have added a reference implementation for Verified Boot running with Project Treble. Verified Boot is a special security feature that's been designed to prevent devices from booting up with software that has been tampered with. The improved security implementation is called Android Verified Boot 2.0 (AVB) and offers some nifty features that should allow for easier updates and more security, including rollback protection. The latter will prevent a device to boot if downgraded to an older OS version that might be vulnerable to an exploit. Then, Android Oreo now features the new OEM Lock Hardware Abstraction Layer (HAL), which should offer device manufacturers more flexibility for how they protect in case a device is locked, unlocked, or unlockable. There are many other under the hood security improvements Google implemented into Android Oreo, so make sure to hit the source link for the full list."
5 | ];
6 |
7 | var summary = require('./index');
8 | console.log(summary(titles,50));
9 | var i=0;
--------------------------------------------------------------------------------
/frame/public/electron.js:
--------------------------------------------------------------------------------
1 | const electron = require('electron');
2 | const app = electron.app;
3 | const BrowserWindow = electron.BrowserWindow;
4 |
5 | const path = require('path');
6 | const url = require('url');
7 | const isDev = require('electron-is-dev');
8 |
9 | let mainWindow;
10 |
11 | function createWindow() {
12 | mainWindow = new BrowserWindow({width: 1920, height: 1280});
13 | mainWindow.loadURL(`file://${path.join(__dirname, '../output/webpack/production/index.html')}`);
14 | // mainWindow.webContents.openDevTools();
15 | mainWindow.on('closed', () => mainWindow = null);
16 | }
17 |
18 | app.on('ready', createWindow);
19 |
20 | app.on('window-all-closed', () => {
21 | if (process.platform !== 'darwin') {
22 | app.quit();
23 | }
24 | });
25 |
26 | app.on('activate', () => {
27 | if (mainWindow === null) {
28 | createWindow();
29 | }
30 | });
31 |
32 | // mainWindow.once('ready-to-show', () => {
33 | // mainWindow.show();
34 | // // Open the DevTools automatically if developing
35 | // mainWindow.webContents.openDevTools();
36 | // });
37 |
38 |
--------------------------------------------------------------------------------
/frame/src/assets/css/brands.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * Font Awesome Free 5.6.1 by @fontawesome - https://fontawesome.com
3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
4 | */
5 | @font-face {
6 | font-family: 'Font Awesome 5 Brands';
7 | font-style: normal;
8 | font-weight: normal;
9 | src: url("../webfonts/fa-brands-400.eot");
10 | src: url("../webfonts/fa-brands-400.eot?#iefix") format("embedded-opentype"), url("../webfonts/fa-brands-400.woff2") format("woff2"), url("../webfonts/fa-brands-400.woff") format("woff"), url("../webfonts/fa-brands-400.ttf") format("truetype"), url("../webfonts/fa-brands-400.svg#fontawesome") format("svg"); }
11 |
12 | .fab {
13 | font-family: 'Font Awesome 5 Brands'; }
14 |
--------------------------------------------------------------------------------
/frame/src/assets/css/brands.min.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * Font Awesome Free 5.6.1 by @fontawesome - https://fontawesome.com
3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
4 | */
5 | @font-face{font-family:"Font Awesome 5 Brands";font-style:normal;font-weight:normal;src:url(../webfonts/fa-brands-400.eot);src:url(../webfonts/fa-brands-400.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-brands-400.woff2) format("woff2"),url(../webfonts/fa-brands-400.woff) format("woff"),url(../webfonts/fa-brands-400.ttf) format("truetype"),url(../webfonts/fa-brands-400.svg#fontawesome) format("svg")}.fab{font-family:"Font Awesome 5 Brands"}
--------------------------------------------------------------------------------
/frame/src/assets/css/regular.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * Font Awesome Free 5.6.1 by @fontawesome - https://fontawesome.com
3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
4 | */
5 | @font-face {
6 | font-family: 'Font Awesome 5 Free';
7 | font-style: normal;
8 | font-weight: 400;
9 | src: url("../webfonts/fa-regular-400.eot");
10 | src: url("../webfonts/fa-regular-400.eot?#iefix") format("embedded-opentype"), url("../webfonts/fa-regular-400.woff2") format("woff2"), url("../webfonts/fa-regular-400.woff") format("woff"), url("../webfonts/fa-regular-400.ttf") format("truetype"), url("../webfonts/fa-regular-400.svg#fontawesome") format("svg"); }
11 |
12 | .far {
13 | font-family: 'Font Awesome 5 Free';
14 | font-weight: 400; }
15 |
--------------------------------------------------------------------------------
/frame/src/assets/css/regular.min.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * Font Awesome Free 5.6.1 by @fontawesome - https://fontawesome.com
3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
4 | */
5 | @font-face{font-family:"Font Awesome 5 Free";font-style:normal;font-weight:400;src:url(../webfonts/fa-regular-400.eot);src:url(../webfonts/fa-regular-400.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-regular-400.woff2) format("woff2"),url(../webfonts/fa-regular-400.woff) format("woff"),url(../webfonts/fa-regular-400.ttf) format("truetype"),url(../webfonts/fa-regular-400.svg#fontawesome) format("svg")}.far{font-family:"Font Awesome 5 Free";font-weight:400}
--------------------------------------------------------------------------------
/frame/src/assets/css/solid.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * Font Awesome Free 5.6.1 by @fontawesome - https://fontawesome.com
3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
4 | */
5 | @font-face {
6 | font-family: 'Font Awesome 5 Free';
7 | font-style: normal;
8 | font-weight: 900;
9 | src: url("../webfonts/fa-solid-900.eot");
10 | src: url("../webfonts/fa-solid-900.eot?#iefix") format("embedded-opentype"), url("../webfonts/fa-solid-900.woff2") format("woff2"), url("../webfonts/fa-solid-900.woff") format("woff"), url("../webfonts/fa-solid-900.ttf") format("truetype"), url("../webfonts/fa-solid-900.svg#fontawesome") format("svg"); }
11 |
12 | .fa,
13 | .fas {
14 | font-family: 'Font Awesome 5 Free';
15 | font-weight: 900; }
16 |
--------------------------------------------------------------------------------
/frame/src/assets/css/solid.min.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * Font Awesome Free 5.6.1 by @fontawesome - https://fontawesome.com
3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
4 | */
5 | @font-face{font-family:"Font Awesome 5 Free";font-style:normal;font-weight:900;src:url(../webfonts/fa-solid-900.eot);src:url(../webfonts/fa-solid-900.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.woff) format("woff"),url(../webfonts/fa-solid-900.ttf) format("truetype"),url(../webfonts/fa-solid-900.svg#fontawesome) format("svg")}.fa,.fas{font-family:"Font Awesome 5 Free";font-weight:900}
--------------------------------------------------------------------------------
/frame/src/assets/electron.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jddunn/frame/a002056b22d9986ec41d0a07dff3641c3582c6f4/frame/src/assets/electron.png
--------------------------------------------------------------------------------
/frame/src/assets/flow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jddunn/frame/a002056b22d9986ec41d0a07dff3641c3582c6f4/frame/src/assets/flow.png
--------------------------------------------------------------------------------
/frame/src/assets/github.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jddunn/frame/a002056b22d9986ec41d0a07dff3641c3582c6f4/frame/src/assets/github.png
--------------------------------------------------------------------------------
/frame/src/assets/redux.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/frame/src/assets/semantic-ui-react.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jddunn/frame/a002056b22d9986ec41d0a07dff3641c3582c6f4/frame/src/assets/semantic-ui-react.png
--------------------------------------------------------------------------------
/frame/src/assets/webfonts/fa-brands-400.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jddunn/frame/a002056b22d9986ec41d0a07dff3641c3582c6f4/frame/src/assets/webfonts/fa-brands-400.eot
--------------------------------------------------------------------------------
/frame/src/assets/webfonts/fa-brands-400.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jddunn/frame/a002056b22d9986ec41d0a07dff3641c3582c6f4/frame/src/assets/webfonts/fa-brands-400.ttf
--------------------------------------------------------------------------------
/frame/src/assets/webfonts/fa-brands-400.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jddunn/frame/a002056b22d9986ec41d0a07dff3641c3582c6f4/frame/src/assets/webfonts/fa-brands-400.woff
--------------------------------------------------------------------------------
/frame/src/assets/webfonts/fa-brands-400.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jddunn/frame/a002056b22d9986ec41d0a07dff3641c3582c6f4/frame/src/assets/webfonts/fa-brands-400.woff2
--------------------------------------------------------------------------------
/frame/src/assets/webfonts/fa-regular-400.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jddunn/frame/a002056b22d9986ec41d0a07dff3641c3582c6f4/frame/src/assets/webfonts/fa-regular-400.eot
--------------------------------------------------------------------------------
/frame/src/assets/webfonts/fa-regular-400.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jddunn/frame/a002056b22d9986ec41d0a07dff3641c3582c6f4/frame/src/assets/webfonts/fa-regular-400.ttf
--------------------------------------------------------------------------------
/frame/src/assets/webfonts/fa-regular-400.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jddunn/frame/a002056b22d9986ec41d0a07dff3641c3582c6f4/frame/src/assets/webfonts/fa-regular-400.woff
--------------------------------------------------------------------------------
/frame/src/assets/webfonts/fa-regular-400.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jddunn/frame/a002056b22d9986ec41d0a07dff3641c3582c6f4/frame/src/assets/webfonts/fa-regular-400.woff2
--------------------------------------------------------------------------------
/frame/src/assets/webfonts/fa-solid-900.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jddunn/frame/a002056b22d9986ec41d0a07dff3641c3582c6f4/frame/src/assets/webfonts/fa-solid-900.eot
--------------------------------------------------------------------------------
/frame/src/assets/webfonts/fa-solid-900.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jddunn/frame/a002056b22d9986ec41d0a07dff3641c3582c6f4/frame/src/assets/webfonts/fa-solid-900.ttf
--------------------------------------------------------------------------------
/frame/src/assets/webfonts/fa-solid-900.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jddunn/frame/a002056b22d9986ec41d0a07dff3641c3582c6f4/frame/src/assets/webfonts/fa-solid-900.woff
--------------------------------------------------------------------------------
/frame/src/assets/webfonts/fa-solid-900.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jddunn/frame/a002056b22d9986ec41d0a07dff3641c3582c6f4/frame/src/assets/webfonts/fa-solid-900.woff2
--------------------------------------------------------------------------------
/frame/src/assets/webpack.svg:
--------------------------------------------------------------------------------
1 | icon-square-small
--------------------------------------------------------------------------------
/frame/src/components/Ask/Ask.scss:
--------------------------------------------------------------------------------
1 | .askWrapper {
2 | margin: 0px !important;
3 | padding: 0px !important;
4 | height: 100% !important;
5 | margin-left: auto !important;
6 | margin-right: auto !important;
7 | max-width: calc(65% - 20px) !important;
8 | padding-left: 100px !important;
9 | }
10 |
11 | .questionTextInput {
12 | z-index: 1000 !important;
13 | width: calc(60% - 20px) !important;
14 | height: 50px !important;
15 | margin-top: 18px !important;
16 | margin-left: auto !important;
17 | margin-right: auto !important;
18 | margin-left: 90px !important;
19 | }
20 |
21 | .passageTextDisabled {
22 | width: calc(55% - 20px) !important;
23 | height: 80px !important;
24 | display: none !important;
25 | margin-left: auto !important;
26 | margin-right: auto !important;
27 | }
28 |
29 | .floatingAskButton {
30 | width: calc(60% - 20px) !important;
31 | z-index: 1000 !important;
32 | text-align: center !important;
33 | margin-left: auto !important;
34 | margin-right: auto !important;
35 | margin-left: 90px !important;
36 | // position: sticky !important;
37 | // text-align: center !important;
38 | }
39 |
40 | .smallDetailText {
41 | width: calc(60% - 20px) !important;
42 | // margin-right: auto !important;
43 | // margin-left: auto !important;
44 | margin-left: auto !important;
45 | margin-right: auto !important;
46 | margin-left: 85px !important;
47 | text-align: center !important;
48 | font-size: 1.05vmax !important;
49 | margin-top: 8px !important;
50 | letter-spacing: 1px !important;
51 | // text-align: center !important;
52 | }
53 |
54 | .answerText {
55 | width: calc(60% - 20px) !important;
56 | // margin-right: auto !important;
57 | // margin-left: auto !important;
58 | // margin-left: 100px !important;
59 | margin-left: auto !important;
60 | margin-right: auto !important;
61 | text-align: center !important;
62 | font-size: 1.05vmax !important;
63 | margin-top: 8px !important;
64 | letter-spacing: 1px !important;
65 | color: rgba(204, 204, 204, .8) !important;
66 | // text-align: center !important;
67 | }
68 |
--------------------------------------------------------------------------------
/frame/src/components/AskMain/AskMain.scss:
--------------------------------------------------------------------------------
1 | .askWrapperMain {
2 | margin: 0px !important;
3 | padding: 0px !important;
4 | height: 100% !important;
5 | }
6 |
7 | .questionTextInputMain {
8 | margin: 0px !important;
9 | padding: 0px !important;
10 | z-index: 1000 !important;
11 | height: 50px !important;
12 | margin-top: 18px !important;
13 | text-align: center !important;
14 | width: calc(70% - 20px) !important;
15 | margin-left: auto !important;
16 | margin-right: auto !important;
17 | }
18 |
19 | .passageTextDisabled {
20 | height: 80px !important;
21 | display: none !important;
22 | }
23 |
24 | .floatingAskButtonMain {
25 | margin: 0px !important;
26 | padding: 0px !important;
27 | z-index: 1000 !important;
28 | text-align: center !important;
29 | width: calc(70% - 20px) !important;
30 | margin-left: auto !important;
31 | margin-right: auto !important;
32 | // text-align: center !important;
33 | }
34 |
35 | .smallDetailTextAskMain {
36 | margin-right: auto !important;
37 | margin-left: auto !important;
38 | color: rgba(88, 88, 88, 1.0) !important;
39 | font-size: 1.05em !important;
40 | margin-top: 8px !important;
41 | letter-spacing: 1px !important;
42 | width: calc(70% - 20px) !important;
43 | margin-left: auto !important;
44 | margin-right: auto !important;
45 | text-align: center !important;
46 | // text-align: center !important;
47 | }
48 |
49 |
50 | .answerTextAskMain {
51 | margin-right: auto !important;
52 | margin-left: auto !important;
53 | width: calc(70% - 20px) !important;
54 | margin: 0px !important;
55 | padding: 0px !important;
56 | font-size: 1.25em !important;
57 | margin-top: 8px !important;
58 | margin-left: auto !important;
59 | margin-right: auto !important;
60 | letter-spacing: 1px !important;
61 | color: rgba(204, 204, 204, .8) !important;
62 | text-align: center !important;
63 | margin-bottom: 15px !important;
64 | // text-align: center !important;
65 | }
66 |
67 |
--------------------------------------------------------------------------------
/frame/src/components/Brand/Brand.jsx:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | import React, { Component } from 'react';
3 | import styles from './Brand.scss';
4 |
5 | export default class Brand extends Component {
6 | componentDidMount() {
7 | const options = { onChange: this.props.onChange };
8 | this._container = document.getElementById('jsonEditor');
9 | }
10 |
11 | render() {
12 | return (
13 |
14 |
15 |
F R A M E v 0.1.0
16 |
17 |
18 | );
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/frame/src/components/Brand/Brand.scss:
--------------------------------------------------------------------------------
1 | .brandContainer {
2 | width: 100%;
3 | height: 100%;
4 | margin-top: 1px;
5 | padding-right: 5px;
6 | padding-left: 5px;
7 | padding-top: 10px;
8 | padding-bottom: 10px;
9 | max-height: 53px;
10 | overflow: hidden;
11 | }
12 |
13 | .brandContainer:hover {
14 | // -moz-box-shadow: 0 0 4px rgb(208, 255, 0);
15 | // -webkit-box-shadow: 0 4 6px rgb(208, 255, 0);
16 | // box-shadow: 0px 0px 4px rgb(208, 255, 0);
17 | cursor: pointer;
18 | }
19 |
20 | /*
21 | .brandContainer:hover .brandTitle {
22 | color: rgb(255,223,0) !important;
23 | text-shadow: 1px 1px 1px rgb(84, 97, 91) !important;
24 | }
25 | */
26 |
27 | .brandContainer h4{
28 | letter-spacing: 3px;
29 | font-weight: lighter;
30 | font-size: 1.6em;
31 | color: rgba(240, 240, 240, .95);
32 | text-shadow: 1px 2px 1px rgba(50,20,50,0.05);
33 | }
34 |
35 | .brandContainer p {
36 | letter-spacing: 1px;
37 | font-weight: lighter;
38 | font-size: .6em;
39 | color: rgba(240, 240, 240, .85);
40 | text-shadow: 1px 2px 1px rgba(50,20,50,0.05);
41 | }
42 |
43 | /* Neon glow effect from here: http://enjoycss.com/gallery/text_effects/39 */
44 |
45 | .brandTitle {
46 | -webkit-box-sizing: border-box;
47 | -moz-box-sizing: border-box;
48 | box-sizing: border-box;
49 | border: none;
50 | color: rgba(255,255,255,1);
51 | text-decoration: normal;
52 | text-align: center;
53 | -o-text-overflow: clip;
54 | text-overflow: clip;
55 | white-space: pre;
56 | text-shadow: 0 0 10px rgba(255,255,255,.75) , 0 0 20px rgba(255,255,255,.75) , 0 0 30px rgba(255,255,255,.75) , 0 0 40px #00ffff , 0 0 70px #00ffff , 0 0 80px #00ffff , 0 0 100px #00ffff !important;
57 |
58 | -webkit-transition: all 200ms cubic-bezier(0.42, 0, 0.58, 1) !important;
59 | -moz-transition: all 200ms cubic-bezier(0.42, 0, 0.58, 1) !important;
60 | -o-transition: all 200ms cubic-bezier(0.42, 0, 0.58, 1) !important;
61 | transition: all 200ms cubic-bezier(0.42, 0, 0.58, 1) !important;
62 | display: inline-block;
63 | margin: 0;
64 | margin-left: auto;
65 | margin-right: auto;
66 | text-align: center;
67 | }
68 |
69 | .brandTitle:hover {
70 | text-shadow: 0 0 10px rgba(255,255,255,1) , 0 0 20px rgba(255,255,255,1) , 0 0 30px rgba(255,255,255,1) , 0 0 20px #ff00de , 0 0 40px #ff00de , 0 0 60px #ff00de , 0 0 80px #ff00de !important;
71 |
72 | }
73 |
74 | .brandSubtitle {
75 | margin-left: 20px;
76 | display: inline-block;
77 | text-shadow: 0 0 10px rgba(255,255,255,.3) , 0 0 20px rgba(255,255,255,.3) , 0 0 30px rgba(255,255,255,.3) , 0 0 20px #ff00de , 0 0 40px #ff00de , 0 0 60px #ff00de , 0 0 80px #ff00de !important;
78 | -webkit-transition: all 200ms cubic-bezier(0.42, 0, 0.58, 1) !important;
79 | -moz-transition: all 200ms cubic-bezier(0.42, 0, 0.58, 1) !important;
80 | -o-transition: all 200ms cubic-bezier(0.42, 0, 0.58, 1) !important;
81 | transition: all 200ms cubic-bezier(0.42, 0, 0.58, 1) !important;
82 | }
--------------------------------------------------------------------------------
/frame/src/components/EntryCreate/EntryCreate.scss:
--------------------------------------------------------------------------------
1 | .entryCreateContainer {
2 | display: inline !important;
3 | }
4 |
5 | .formDisabled p {
6 | color: grey !important;
7 | }
8 |
9 | .ant-form-item {
10 | margin: 5px !important;
11 | }
12 |
13 |
14 | .ant-modal-content {
15 | border-radius: 3px !important;
16 | background: rgba(238, 238, 238, .93) !important; /* fallback for old browsers */
17 | box-shadow: 0 0 0 1px rgba(204, 209, 212, 0.2);
18 | }
19 |
20 | .ant-modal-header {
21 | box-shadow: 0 0 0 1px rgba(204, 209, 212, 0.2);
22 | border-radius: 3px !important;
23 | background: rgba(238, 238, 238, .93) !important; /* fallback for old browsers */
24 | }
25 |
26 | .ant-modal-title {
27 | font-size: 1.4em;
28 | height: 40px !important;
29 | }
30 |
31 | .entryTimestampBlock {
32 | top: 0 !important;
33 | left: 0 !important;
34 | color: rgba(65, 65, 65, 0.65);
35 | margin-left: 23px !important;
36 | margin-top: 40px !important;
37 | position: absolute !important;
38 | display: inline !important;
39 | }
40 |
41 | .modalFooterBlock {
42 | position: absolute;
43 | bottom: 0;
44 | left: 0;
45 | margin-bottom: 10px;
46 | margin-left: 10px;
47 | }
--------------------------------------------------------------------------------
/frame/src/components/EntryEditForm/EntryEditForm.scss:
--------------------------------------------------------------------------------
1 | .entryCreateContainer {
2 | display: inline !important;
3 | }
4 |
5 | .formDisabled p {
6 | color: grey !important;
7 | }
8 |
9 | .ant-form-item {
10 | margin: 5px !important;
11 | }
12 |
13 |
14 | .ant-modal-content {
15 | border-radius: 3px !important;
16 | background: rgba(238, 238, 238, .93) !important; /* fallback for old browsers */
17 | box-shadow: 0 0 0 1px rgba(204, 209, 212, 0.2);
18 | }
19 |
20 | .ant-modal-header {
21 | box-shadow: 0 0 0 1px rgba(204, 209, 212, 0.2);
22 | border-radius: 3px !important;
23 | background: rgba(238, 238, 238, .93) !important; /* fallback for old browsers */
24 | }
25 |
26 | .ant-modal-title {
27 | font-size: 1.4em;
28 | height: 40px !important;
29 | }
30 |
31 | .entryTimestampBlock {
32 | top: 0 !important;
33 | left: 0 !important;
34 | color: rgba(65, 65, 65, 0.65);
35 | margin-left: 23px !important;
36 | margin-top: 40px !important;
37 | position: absolute !important;
38 | display: inline !important;
39 | }
40 |
41 | .modalFooterBlock {
42 | position: absolute;
43 | bottom: 0;
44 | left: 0;
45 | margin-bottom: 10px;
46 | margin-left: 10px;
47 | }
--------------------------------------------------------------------------------
/frame/src/components/FJSONEditor/FJSONEditor.jsx:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | import React, { Component } from 'react';
3 | import JSONEditor from 'jsoneditor';
4 | import 'jsoneditor/dist/jsoneditor.css';
5 | import styles from './FJSONEditor.scss';
6 |
7 | export default class FJSONEditor extends Component {
8 | constructor(props) {
9 | super(props);
10 | }
11 |
12 | componentDidMount() {
13 | const options = { onChange: this.props.onChange };
14 | this._container = document.getElementById('jsonEditor');
15 | this._editor = new JSONEditor(this._container, options);
16 | this.props.editorRef(this._editor);
17 | this._editor.set(this.props.json);
18 | }
19 |
20 | componentWillReceiveProps(nextProps) {
21 | this._editor.set(nextProps.json);
22 | }
23 |
24 | render() {
25 | // console.log(this.props.json);
26 | return
;
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/frame/src/components/FJSONEditor/FJSONEditor.scss:
--------------------------------------------------------------------------------
1 | .editor {
2 | height: 100%;
3 | width: 100%;
4 | overflow: auto !important;
5 | }
6 |
7 | .jsoneditor {
8 | border-radius: 3px;
9 | margin-top: 8px;
10 | font-size: .75em !important;
11 | border: none !important;
12 | overflow: auto !important;
13 |
14 | }
15 |
16 | #jsonEditor {
17 | border: none !important;
18 | box-shadow: none !important;
19 | border-radius: 3px !important;
20 | box-shadow: 1px 2px 2px 1px rgba(39, 39, 39, 0.85) !important;
21 | background: rgb(238, 238, 238) !important; /* fallback for old browsers */
22 | min-height: 250px;
23 | max-height: 450px;
24 | overflow: auto !important;
25 | }
26 |
27 | .jsoneditor-menu {
28 | margin-top: 2px !important;
29 | border-radius: 3px;
30 | border-color: rgba(79, 176, 255, .85) !important;
31 | background-color: rgba(79, 176, 255, .85) !important;
32 | }
33 |
34 | .nav-bar-empty {
35 | display: none !important;
36 | }
--------------------------------------------------------------------------------
/frame/src/components/Home/Home.scss:
--------------------------------------------------------------------------------
1 | .homeWrapper {
2 | margin: 0 !important;
3 | padding: 0 !important;
4 | width: 100% !important;
5 | height: 100% !important;
6 | background-color: rgba(250, 250, 250, 1.0) !important;
7 | overflow: auto !important;
8 | }
9 |
10 | .ant-collapse-item, .ant-collapse-item-active {
11 | background-color: transparent !important;
12 | }
13 |
14 | .datetime {
15 | top: 0 !important;
16 | right: 0 !important;
17 | margin: 25px !important;
18 | margin-right: 45px !important;
19 | margin-top: 10px !important;
20 | position: absolute !important;
21 | z-index: 100 !important;
22 | letter-spacing: 1px !important;
23 | }
24 |
25 |
26 | .libraryOverview {
27 | background-color: transparent !important;
28 | padding: 0 !important;
29 | margin: 0 !important;
30 | margin: 20px !important;
31 | // margin: 40px !important;
32 | }
33 |
34 | .libraryOverviewText {
35 | letter-spacing: 1px !important;
36 | font-weight: lighter !important;
37 | font-size: 1.5em !important;
38 | color: rgba(66, 66, 66, 0.9);
39 | text-align: center !important;
40 | }
41 |
42 | .askInput {
43 | background-color: transparent !important;
44 | padding: 0 !important;
45 | margin: 0 !important;
46 | margin: 20px !important;
47 | // margin: 40px !important;
48 | }
49 |
50 | .collapseTransparent {
51 | background-color: transparent !important;
52 | }
53 |
54 | .entriesChart {
55 | background-color: transparent !important;
56 | margin: 20px !important;
57 | // margin-right: -150px !important;
58 | }
59 |
60 | .tagsText {
61 | display: inline !important;
62 | }
63 |
64 | .titleText {
65 | display: inline !important;
66 | }
67 |
68 | .entriesVisualizedText {
69 | margin: 40px !important;
70 | font-weight: lighter !important;
71 | margin-right: 65px !important;
72 | font-size: 1.6em !important;
73 | letter-spacing: 1px !important;
74 | color: rgba(44, 44, 44, 0.9);
75 | text-align: center !important;
76 | }
--------------------------------------------------------------------------------
/frame/src/components/SearchLibrary/SearchLibrary.scss:
--------------------------------------------------------------------------------
1 | .homeWrapper {
2 | margin: 0 !important;
3 | padding: 0 !important;
4 | width: 100% !important;
5 | height: 100% !important;
6 | background-color: rgba(250, 250, 250, 1.0) !important;
7 | overflow: auto !important;
8 | }
9 |
10 | .ant-collapse-item, .ant-collapse-item-active {
11 | background-color: transparent !important;
12 | }
13 |
14 | .datetime {
15 | top: 0 !important;
16 | right: 0 !important;
17 | margin: 25px !important;
18 | margin-right: 45px !important;
19 | margin-top: 10px !important;
20 | position: absolute !important;
21 | z-index: 100 !important;
22 | letter-spacing: 1px !important;
23 | }
24 |
25 | .askInput {
26 | background-color: transparent !important;
27 | padding: 0 !important;
28 | margin: 0 !important;
29 | margin: 20px !important;
30 | text-align: center !important;
31 | // margin: 40px !important;
32 | }
33 |
34 | .titleTextP {
35 | margin: 20px !important;
36 | letter-spacing: 1px !important;
37 | color: rgba(88, 88, 88, 1.0) !important;
38 | font-size: 1.25em !important;
39 | }
40 |
41 | .tagsHolder {
42 | text-align: center !important;
43 | width: calc(70% - 20px) !important;
44 | margin: 20px !important;
45 | margin-left: auto !important;
46 | margin-right: auto !important;
47 | // margin-left: 150px !important;
48 | }
49 |
50 | .collapseTransparent {
51 | background-color: transparent !important;
52 | }
53 |
54 | .entriesChart {
55 | background-color: transparent !important;
56 | margin: 20px !important;
57 | // margin-right: -150px !important;
58 | }
59 |
60 | .tagsText {
61 | display: inline !important;
62 | }
63 |
64 | .titleText {
65 | display: inline !important;
66 | }
67 |
68 | .entriesVisualizedText {
69 | margin: 40px !important;
70 | font-weight: lighter !important;
71 | margin-right: 65px !important;
72 | font-size: 1.6em !important;
73 | letter-spacing: 1px !important;
74 | color: rgba(44, 44, 44, 0.9);
75 | text-align: center !important;
76 | }
--------------------------------------------------------------------------------
/frame/src/components/Settings/Settings.jsx:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | import config from '../../data/config.json';
3 | import React, { Component } from "react";
4 | import PropTypes, { shape } from 'prop-types';
5 | import {setState, getState} from '../../utils/session-state';
6 | import {
7 | Row, Col, Layout, Menu, Breadcrumb,
8 | Icon, Button, Switch, Dropdown, message,
9 | Tooltip, Select, Drawer, Radio, Collapse, List,
10 | Divider, Form, Input
11 | } from 'antd';
12 |
13 | /**
14 | * TODO: Eventually separate out the summarizer too and other analysis components,
15 | * since this class is getting massive.
16 | */
17 |
18 | import { Wrapper, Tab, TabList, TabPanel} from 'react-aria-tabpanel';
19 |
20 | import ReactJson from 'react-json-view';
21 |
22 | import saveToDB from '../../utils/save-db';
23 | import getFromDB from '../../utils/load-db';
24 | import openDB from '../../utils/create-db';
25 | import traverseEntriesById from '../../utils/entries-traversal';
26 | import replaceEntry from '../../utils/replace-entry';
27 |
28 | import './Settings.scss';
29 |
30 | const RadioGroup = Radio.Group;
31 | const Panel = Collapse.Panel;
32 |
33 | /** Data library / source vars */
34 | const savedSettings = config.savedSettings;
35 | const defaultFLib = savedSettings.defaultLibrary;
36 |
37 | export default class Settings extends Component {
38 |
39 | constructor(props) {
40 | super(props);
41 | this.state = {
42 | _isMounted: false,
43 | };
44 | }
45 |
46 | componentDidMount() {
47 | this.setState({_isMounted: true});
48 | }
49 |
50 | componentWillUnount() {
51 | this.setState({_isMounted: false});
52 | }
53 |
54 | render() {
55 | return (
56 |
57 | {/* Settingsssss */}
58 |
59 | );
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/frame/src/components/Settings/Settings.scss:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jddunn/frame/a002056b22d9986ec41d0a07dff3641c3582c6f4/frame/src/components/Settings/Settings.scss
--------------------------------------------------------------------------------
/frame/src/components/VisualizeLibrary/VisualizeLibrary.scss:
--------------------------------------------------------------------------------
1 | .homeWrapper {
2 | margin: 0 !important;
3 | padding: 0 !important;
4 | width: 100% !important;
5 | height: 100% !important;
6 | background-color: rgba(250, 250, 250, 1.0) !important;
7 | overflow: auto !important;
8 | }
9 |
10 | .ant-collapse-item, .ant-collapse-item-active {
11 | background-color: transparent !important;
12 | }
13 |
14 | .datetime {
15 | top: 0 !important;
16 | right: 0 !important;
17 | margin: 25px !important;
18 | margin-right: 45px !important;
19 | margin-top: 10px !important;
20 | position: absolute !important;
21 | z-index: 100 !important;
22 | letter-spacing: 1px !important;
23 | }
24 |
25 | .askInput {
26 | background-color: transparent !important;
27 | padding: 0 !important;
28 | margin: 0 !important;
29 | margin: 20px !important;
30 | // margin: 40px !important;
31 | }
32 |
33 | .collapseTransparent {
34 | background-color: transparent !important;
35 | }
36 |
37 | .entriesChart {
38 | background-color: transparent !important;
39 | margin: 20px !important;
40 | // margin-right: -150px !important;
41 | }
42 |
43 | .tagsText {
44 | display: inline !important;
45 | }
46 |
47 | .titleText {
48 | display: inline !important;
49 | }
50 |
51 | .entriesVisualizedText {
52 | margin: 40px !important;
53 | font-weight: lighter !important;
54 | margin-right: 65px !important;
55 | font-size: 1.6em !important;
56 | letter-spacing: 1px !important;
57 | color: rgba(44, 44, 44, 0.9);
58 | text-align: center !important;
59 | }
--------------------------------------------------------------------------------
/frame/src/components/Visualizer/Visualizer.scss:
--------------------------------------------------------------------------------
1 | .FancyTabs-tabTextSmall {
2 | margin: 0 !important;
3 | padding: 0 !important;
4 | letter-spacing: 1px !important;
5 | font-size: 1.05vmax !important;
6 | margin-top: -10px !important;
7 | }
8 |
9 | .FancyTabs-tablistItemSmall {
10 | height: 32px !important;
11 | box-shadow: 0 1px 1px 0 rgba(53, 53, 53, 0.1) !important;
12 | margin-top: -18px !important;
13 | background-color: rgba(239, 244, 248, 0.923) !important;
14 | }
15 |
16 | .leftViz {
17 | top: 0 !important;
18 | left: 0 !important;
19 | float: left !important;
20 | margin: 0 !important;
21 | padding: 0 !important;
22 | margin-left: 150px !important;
23 | margin-right: 50px !important;
24 | padding: 0 !important;
25 | max-width: calc(55% - 20px) !important;
26 | max-height: calc(75% - 20px) !important;
27 | text-align: center !important;
28 | }
29 |
30 | .rightViz {
31 | top: 0 !important;
32 | right: 0 !important;
33 | margin: 0 !important;
34 | float: right !important;
35 | margin-right: 150px !important;
36 | padding: 0 !important;
37 | max-width: calc(55% - 20px) !important;
38 | max-height: calc(75% - 20px) !important;
39 | text-align: center !important;
40 | }
41 |
42 | .centerViz {
43 | margin: 0 !important;
44 | padding: 0 !important;
45 | text-align: center !important;
46 | margin-left: auto !important;
47 | margin-right: auto !important;
48 | max-width: calc(65% - 20px) !important;
49 | // max-height: calc(80% - 20px) !important;
50 | }
51 |
52 | .leftViz tspan {
53 | font-size: .9vmax !important;
54 | }
55 |
56 | .rightViz tspan {
57 | font-size: .9vmax !important;
58 | }
59 |
60 | .centerViz tspan {
61 | font-size: .9vmax !important;
62 | }
63 |
64 | .innerContentTextCenter {
65 | text-align: center !important;
66 | margin: 0 !important;
67 | padding: 0 !important;
68 | margin-left: auto !important;
69 | margin-right: auto !important;
70 | letter-spacing: 1px !important;
71 | font-size: 1.0vmax !important;
72 | }
73 |
74 |
75 | .FancyTabs-tablistHigher {
76 | list-style-type: none;
77 | margin: 0;
78 | padding: 0;
79 | margin-top: -20px !important;
80 | margin-left: auto !important;
81 | margin-right: auto !important;
82 | text-align: center !important;
83 | width: 100% !important;
84 | }
--------------------------------------------------------------------------------
/frame/src/components/vendor/basic.scss:
--------------------------------------------------------------------------------
1 | .md-block-header-one {
2 | font-size: 2em;
3 | }
4 | .md-block-header-two {
5 | font-size: 1.7em;
6 | }
7 | .md-block-header-three {
8 | font-size: 1.3em;
9 | }
10 | .md-block-header-four {
11 | font-size: 1em;
12 | }
13 | .md-block-header-five {
14 | font-size: 0.8em;
15 | }
16 | .md-block-header-six {
17 | font-size: 0.7em;
18 | }
19 |
20 | .md-block-header-one,
21 | .md-block-header-two,
22 | .md-block-header-three,
23 | .md-block-header-four,
24 | .md-block-header-five,
25 | .md-block-header-six {
26 | margin-bottom: 5px;
27 | }
28 |
29 | .md-block-blockquote {
30 | margin: 0;
31 | padding-left: 15px;
32 | border-left: 5px solid #4CA8DE;
33 | padding: 10px 0 10px 20px;
34 | background-color: #E2F2FF;
35 | font-size: 1.1em;
36 | }
37 |
38 | .md-block-image {
39 | margin: 0 0 10px 0;
40 |
41 | img {
42 | width: 100%;
43 | }
44 |
45 | figcaption {
46 | text-align: center;
47 | font-size: 0.9em;
48 | }
49 | }
50 |
51 | .md-block-todo {
52 | margin: 10px 0 10px 0;
53 |
54 | input[type=checkbox] {
55 | float: left;
56 | position: relative;
57 | top: 0px;
58 | left: -2px;
59 | }
60 | p {
61 | margin-left: 18px;
62 | }
63 | }
64 |
65 | .md-block-unordered-list-item, .md-block-ordered-list-item {
66 | padding-left: 20px;
67 |
68 | li {
69 | margin-bottom: 5px;
70 | }
71 | }
72 |
73 | .md-block-atomic-embed {
74 | margin: 10px 0;
75 | }
76 |
77 | .md-block-atomic-break {
78 | hr {
79 | max-width: 100px;
80 | border: 2px solid #ccc;
81 | }
82 | }
83 |
84 | .md-inline-code {
85 | font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace;
86 | margin: 4px 0px;
87 | font-size: 0.9em;
88 | padding: 1px 3px;
89 | color: rgb(85, 85, 85);
90 | background-color: rgb(252, 252, 252);
91 | border-width: 1px;
92 | border-style: solid;
93 | border-color: rgb(204, 204, 204) rgb(204, 204, 204) rgb(187, 187, 187);
94 | border-image: initial;
95 | border-radius: 3px;
96 | box-shadow: rgb(187, 187, 187) 0px -1px 0px inset;
97 | }
98 |
99 |
100 | .md-inline-link {
101 | color: #08c;
102 |
103 | &:visited {
104 | color: #08c;
105 | }
106 | }
107 |
108 | .md-inline-highlight {
109 | background: yellow;
110 | display: inline;
111 | padding: 2px 4px;
112 | }
113 |
114 | p {
115 | &.md-block-block-quote-caption {
116 |
117 | &::before {
118 | content: '\2013';
119 | color: #999;
120 | float: left;
121 | font-weight: bold;
122 | display: inline;
123 | margin-right: 10px;
124 | }
125 | margin-top: 0;
126 | font-size: 0.8em;
127 | padding-top: 5px;
128 | padding-bottom: 5px;
129 | padding-left: 10px;
130 | background: #fafafa;
131 | }
132 | }
133 |
134 | .md-block-code-container {
135 | font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
136 | white-space: pre;
137 | word-spacing: normal;
138 | word-break: normal;
139 | word-wrap: normal;
140 | background-color: rgba(0, 0, 0, 0.05);
141 | font-size: 16px;
142 | padding: 20px;
143 | margin: 1em 0px;
144 |
145 | > pre {
146 | margin-top: 0;
147 | padding-top: 0;
148 | }
149 | }
150 |
151 | .md-block-code-block {
152 | white-space: pre-wrap;
153 | word-wrap: break-word;
154 | }
155 |
--------------------------------------------------------------------------------
/frame/src/components/vendor/components/LinkEditComponent.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PropTypes from 'prop-types';
3 | import { getVisibleSelectionRect } from 'draft-js';
4 |
5 | const getRelativeParent = (element) => {
6 | if (!element) {
7 | return null;
8 | }
9 |
10 | const position = window.getComputedStyle(element).getPropertyValue('position');
11 | if (position !== 'static') {
12 | return element;
13 | }
14 |
15 | return getRelativeParent(element.parentElement);
16 | };
17 |
18 | export default class LinkEditComponent extends React.Component {
19 |
20 | static propTypes = {
21 | editorState: PropTypes.object.isRequired,
22 | url: PropTypes.string.isRequired,
23 | blockKey: PropTypes.string.isRequired,
24 | entityKey: PropTypes.string.isRequired,
25 | removeLink: PropTypes.func.isRequired,
26 | editLink: PropTypes.func.isRequired,
27 | };
28 |
29 | constructor(props) {
30 | super(props);
31 |
32 | this.state = {
33 | position: {},
34 | };
35 | this.renderedOnce = false;
36 | }
37 |
38 | componentDidMount() {
39 | setTimeout(this.calculatePosition, 0);
40 | }
41 |
42 | shouldComponentUpdate(nextProps, nextState) {
43 | if (this.renderedOnce) {
44 | const { blockKey, entityKey } = this.props;
45 | const ret = !this.hasPosition(nextState.position) || blockKey !== nextProps.blockKey || entityKey !== nextProps.entityKey;
46 | if (ret) {
47 | this.renderedOnce = false;
48 | }
49 | return ret;
50 | }
51 | this.renderedOnce = true;
52 | return true;
53 | }
54 |
55 | componentDidUpdate() {
56 | setTimeout(this.calculatePosition, 0);
57 | }
58 |
59 | hasPosition = (position) => {
60 | if (Object.keys(this.state.position).length === 0) {
61 | return false;
62 | }
63 | const { top, left } = this.state.position;
64 | return position.top === top && position.left === left;
65 | };
66 |
67 | calculatePosition = () => {
68 | if (!this.toolbar) {
69 | return;
70 | }
71 | const relativeParent = getRelativeParent(this.toolbar.parentElement);
72 | const relativeRect = relativeParent ? relativeParent.getBoundingClientRect() : window.document.body.getBoundingClientRect();
73 | const selectionRect = getVisibleSelectionRect(window);
74 | if (!selectionRect) {
75 | return;
76 | }
77 | const position = {
78 | top: (selectionRect.top - relativeRect.top) + 35,
79 | left: (selectionRect.left - relativeRect.left) + (selectionRect.width / 2),
80 | transform: 'translate(-50%) scale(1)',
81 | };
82 | this.setState({ position });
83 | };
84 |
85 | removeLink = (e) => {
86 | e.preventDefault();
87 | e.stopPropagation();
88 | this.props.removeLink(this.props.blockKey, this.props.entityKey);
89 | };
90 |
91 | editLink = (e) => {
92 | e.preventDefault();
93 | e.stopPropagation();
94 | this.props.editLink(this.props.blockKey, this.props.entityKey);
95 | };
96 |
97 | render() {
98 | let url = this.props.url;
99 | if (url.length > 30) {
100 | url = `${url.slice(0, 30)}...`;
101 | }
102 | return (
103 | {
107 | this.toolbar = element;
108 | }}
109 | >
110 |
{url}
111 |
Unlink
112 |
Edit
113 |
114 | );
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/frame/src/components/vendor/components/addbutton.scss:
--------------------------------------------------------------------------------
1 | $add-btn-width: 30px;
2 |
3 |
4 | .md-side-toolbar {
5 | display: flex;
6 | position: absolute;
7 | z-index: 1;
8 | left: -35px;
9 | top: 0;
10 | transition: all 0.2s ease;
11 | }
12 |
13 | .md-sb-button {
14 | background: none;
15 | border: 1px solid #5b5b5b;
16 | color: #6D6D6D;
17 | cursor: pointer;
18 | height: $add-btn-width;
19 | width: $add-btn-width;
20 | border-radius: $add-btn-width/2;
21 | font-weight: bold;
22 | font-size: 20px;
23 | margin-right: 2px;
24 | text-align: center;
25 | transition: all 0.2s ease;
26 |
27 | &:focus {
28 | outline: none;
29 | border-color: #08c;
30 | color: #08c;
31 | }
32 |
33 | &:hover {
34 | color: green;
35 | }
36 |
37 | &.md-sb-img-button {
38 | background: none;
39 | background-color: white;
40 | }
41 |
42 | svg path {
43 | stroke-width: 0;
44 | fill: #545454;
45 | }
46 | }
47 |
48 | .md-add-button {
49 | &.md-open-button {
50 | transform: rotate(45deg);
51 | }
52 | }
53 |
54 | .md-add-btn-anim-appear {
55 | transform: translate3d(-38px, 0px, 0px);
56 | opacity: 0;
57 | }
58 |
59 | .md-add-btn-anim-appear.md-add-btn-anim-appear-active {
60 | transform: translate3d(0px, 0px, 0px);
61 | opacity: 1;
62 | transition: all .5s ease-in;
63 | }
64 |
65 | .md-add-btn-anim-enter {
66 | transform: translate3d(-38px, 0px, 0px);
67 | opacity: 0;
68 | }
69 |
70 | .md-add-btn-anim-enter.md-add-btn-anim-enter-active {
71 | opacity: 1;
72 | transform: translate3d(0px, 0px, 0px);
73 | transition: all 500ms ease-in;
74 | }
75 |
76 | .md-add-btn-anim-exit {
77 | opacity: 1;
78 | }
79 |
80 | .md-add-btn-anim-exit.md-add-btn-anim-exit-active {
81 | opacity: 0.01;
82 | transition: opacity 300ms ease-in;
83 | }
84 |
--------------------------------------------------------------------------------
/frame/src/components/vendor/components/blocks/atomic.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | // import './atomic.scss';
3 |
4 | import React from 'react';
5 |
6 | const AtomicBlock = (props) => {
7 | const content = props.getEditorState().getCurrentContent();
8 | const entity = content.getEntity(props.block.getEntityAt(0));
9 | const data = entity.getData();
10 | const type = entity.getType();
11 | if (type === 'image') {
12 | return (
13 |
14 |
15 |
16 | ×
17 |
18 |
19 | );
20 | }
21 | return No supported block for {type}
;
22 | };
23 |
24 | AtomicBlock.propTypes = {
25 | block: PropTypes.object,
26 | getEditorState: PropTypes.func,
27 | };
28 |
29 | export default AtomicBlock;
30 |
--------------------------------------------------------------------------------
/frame/src/components/vendor/components/blocks/atomic.scss:
--------------------------------------------------------------------------------
1 | $control-btn-width: 22px;
2 |
3 | .md-block-atomic {
4 | margin: 0;
5 | img {
6 | width: 100%;
7 | border: 1px solid #eee;
8 | box-sizing: border-box;
9 | }
10 | }
11 |
12 | .md-block-atomic-wrapper {
13 | position: relative;
14 | }
15 |
16 | .md-block-atomic-controls {
17 | display: none;
18 | position: absolute;
19 | top: 0;
20 | right: 0;
21 | transition: all 0.2s ease;
22 |
23 | button {
24 | display: inline-block;
25 | background-color: #EAEAEA;
26 | border: none;
27 | color: #6D6D6D;
28 | cursor: pointer;
29 | height: $control-btn-width;
30 | width: $control-btn-width;
31 | border-radius: $control-btn-width/2;
32 | position: absolute;
33 | z-index: 1;
34 | left: -27px;
35 | font-weight: bold;
36 | text-align: center;
37 | transition: all 0.2s ease;
38 |
39 | &:focus {
40 | outline: none;
41 | border-color: #08c;
42 | color: #08c;
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/frame/src/components/vendor/components/blocks/blockquotecaption.js:
--------------------------------------------------------------------------------
1 | // import './blockquotecaption.scss';
2 |
3 | import React from 'react';
4 | import { EditorBlock } from 'draft-js';
5 |
6 | export default (props) => (
7 |
8 |
9 |
10 | );
11 |
--------------------------------------------------------------------------------
/frame/src/components/vendor/components/blocks/blockquotecaption.scss:
--------------------------------------------------------------------------------
1 | .md-block-quote {
2 | cite {
3 | display: block;
4 | margin: 0;
5 |
6 | &::before {
7 | content: '\2013';
8 | color: #999;
9 | float: left;
10 | font-weight: bold;
11 | display: inline;
12 | margin-right: 10px;
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/frame/src/components/vendor/components/blocks/break.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | export default () => (
4 |
5 | );
6 |
--------------------------------------------------------------------------------
/frame/src/components/vendor/components/blocks/caption.js:
--------------------------------------------------------------------------------
1 | // import './caption.scss';
2 |
3 | import React from 'react';
4 | import { EditorBlock } from 'draft-js';
5 |
6 | export default (props) => (
7 |
8 | );
9 |
--------------------------------------------------------------------------------
/frame/src/components/vendor/components/blocks/caption.scss:
--------------------------------------------------------------------------------
1 | .md-block-caption {
2 | display: block;
3 | position: relative;
4 | font-style: normal;
5 | padding: 10px 0;
6 | font-family: 'Hoefler Text', 'Georgia', serif;
7 | margin: 0 0 20px 0;
8 | background-color: #F7F7F7;
9 | border-radius: 5px;
10 | line-height: 1.2em;
11 |
12 | &::before {
13 | content: '“';
14 | color: #C6DFFF;
15 | display: inline;
16 | position: absolute;
17 | left: -25px;
18 | top: -5px;
19 | font-size: 3em;
20 | }
21 |
22 | .public-DraftStyleDefault-ltr {
23 | text-align: center;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/frame/src/components/vendor/components/blocks/image.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import React from 'react';
3 |
4 | import { EditorBlock, EditorState, SelectionState } from 'draft-js';
5 |
6 | import { getCurrentBlock } from '../../model/';
7 |
8 | class ImageBlock extends React.Component {
9 |
10 | static propTypes = {
11 | block: PropTypes.object,
12 | blockProps: PropTypes.object,
13 | };
14 |
15 | focusBlock = () => {
16 | const { block, blockProps } = this.props;
17 | const { getEditorState, setEditorState } = blockProps;
18 | const key = block.getKey();
19 | const editorState = getEditorState();
20 | const currentblock = getCurrentBlock(editorState);
21 | if (currentblock.getKey() === key) {
22 | return;
23 | }
24 | const newSelection = new SelectionState({
25 | anchorKey: key,
26 | focusKey: key,
27 | anchorOffset: 0,
28 | focusOffset: 0,
29 | });
30 | setEditorState(EditorState.forceSelection(editorState, newSelection));
31 | };
32 |
33 | render() {
34 | const { block } = this.props;
35 | const data = block.getData();
36 | const src = data.get('src');
37 | if (src !== null) {
38 | return (
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 | );
48 | }
49 | return ;
50 | }
51 | }
52 |
53 | export default ImageBlock;
54 |
--------------------------------------------------------------------------------
/frame/src/components/vendor/components/blocks/image.scss:
--------------------------------------------------------------------------------
1 | figure.md-block-image {
2 | // margin: 0;
3 | margin: 10px 0;
4 | background: #fbfbfb;
5 | img {
6 | cursor: default;
7 | max-width: 100%;
8 | border: 1px solid #eee;
9 | box-sizing: border-box;
10 |
11 | &.is-selected {
12 | box-shadow: 0 0 0 3px #02b875;
13 | }
14 | }
15 |
16 | figcaption {
17 | display: block;
18 | font-size: 14px;
19 | line-height: 1.4;
20 | color: rgba(0,0,0,.6);
21 | letter-spacing: 0;
22 | font-weight: 300;
23 | font-style: normal;
24 | text-align: center;
25 | padding: 5px 0;
26 |
27 | .public-DraftStyleDefault-block {
28 | text-align: center;
29 | }
30 | }
31 |
32 | .md-block-image-inner-container {
33 | position: relative;
34 | }
35 | .md-block-image-toolbar-container {
36 | position: absolute;
37 | top: 0;
38 | right: 10px;
39 | cursor: pointer;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/frame/src/components/vendor/components/blocks/text.js:
--------------------------------------------------------------------------------
1 | // import './text.scss';
2 |
3 | import React from 'react';
4 | import { EditorBlock } from 'draft-js';
5 |
6 | // export default class Paragraph extends Component {
7 | // render(){
8 | // return (
9 | //
10 | // );
11 | // }
12 | // }
13 |
14 | export default (props) => ;
15 |
--------------------------------------------------------------------------------
/frame/src/components/vendor/components/blocks/text.scss:
--------------------------------------------------------------------------------
1 | .public-DraftEditor-content {
2 | .md-block-paragraph {
3 | margin: 20px 0;
4 |
5 | &:first-child {
6 | margin-top: 0;
7 | }
8 |
9 | &:last-child {
10 | margin-bottom: 0;
11 | }
12 | }
13 | }
14 |
15 | .md-block-checkbox {
16 | input[type=checkbox] {
17 | float: left;
18 | margin-right: 10px;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/frame/src/components/vendor/components/blocks/todo.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | // import './todo.scss';
3 |
4 | import React from 'react';
5 | import { EditorBlock } from 'draft-js';
6 |
7 | import { updateDataOfBlock } from '../../model/';
8 |
9 | export default class TodoBlock extends React.Component {
10 | constructor(props) {
11 | super(props);
12 | this.updateData = this.updateData.bind(this);
13 | }
14 |
15 | updateData() {
16 | const { block, blockProps } = this.props;
17 | const { setEditorState, getEditorState } = blockProps;
18 | const data = block.getData();
19 | const checked = (data.has('checked') && data.get('checked') === true);
20 | const newData = data.set('checked', !checked);
21 | setEditorState(updateDataOfBlock(getEditorState(), block, newData));
22 | }
23 |
24 | render() {
25 | const data = this.props.block.getData();
26 | const checked = data.get('checked') === true;
27 | return (
28 |
29 |
30 |
31 |
32 |
33 |
34 | );
35 | }
36 | }
37 |
38 |
39 | TodoBlock.propTypes = {
40 | block: PropTypes.object,
41 | blockProps: PropTypes.object,
42 | };
43 |
--------------------------------------------------------------------------------
/frame/src/components/vendor/components/blocks/todo.scss:
--------------------------------------------------------------------------------
1 | .md-block-todo {
2 |
3 | input[type=checkbox] {
4 | cursor: pointer;
5 | float: left;
6 | position: relative;
7 | top: 4px;
8 | left: -4px;
9 | }
10 |
11 | .public-DraftStyleDefault-block {
12 | margin-left: 18px;
13 | }
14 |
15 | .md-block-todo-completed {
16 | color: #949494;
17 | text-decoration: line-through;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/frame/src/components/vendor/components/blocktoolbar.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import React from 'react';
3 | import { RichUtils } from 'draft-js';
4 |
5 | import StyleButton from './stylebutton';
6 |
7 |
8 | const BlockToolbar = (props) => {
9 | if (props.buttons.length < 1) {
10 | return null;
11 | }
12 | const { editorState } = props;
13 | const blockType = RichUtils.getCurrentBlockType(editorState);
14 | return (
15 |
16 | {props.buttons.map((type) => {
17 | const iconLabel = {};
18 | iconLabel.label = type.label;
19 | return (
20 |
28 | );
29 | })}
30 |
31 | );
32 | };
33 |
34 | BlockToolbar.propTypes = {
35 | buttons: PropTypes.array,
36 | editorState: PropTypes.object.isRequired,
37 | onToggle: PropTypes.func,
38 | };
39 |
40 | export default BlockToolbar;
41 |
--------------------------------------------------------------------------------
/frame/src/components/vendor/components/customrenderer.js:
--------------------------------------------------------------------------------
1 | import QuoteCaptionBlock from './blocks/blockquotecaption';
2 | import CaptionBlock from './blocks/caption';
3 | import AtomicBlock from './blocks/atomic';
4 | import TodoBlock from './blocks/todo';
5 | import ImageBlock from './blocks/image';
6 | import BreakBlock from './blocks/break';
7 |
8 | import { Block } from '../util/constants';
9 |
10 | export default (setEditorState, getEditorState) => (contentBlock) => {
11 | // console.log(editorState, onChange);
12 | const type = contentBlock.getType();
13 | switch (type) {
14 | case Block.BLOCKQUOTE_CAPTION: return {
15 | component: QuoteCaptionBlock,
16 | };
17 | case Block.CAPTION: return {
18 | component: CaptionBlock,
19 | };
20 | case Block.ATOMIC: return {
21 | component: AtomicBlock,
22 | editable: false,
23 | props: {
24 | getEditorState,
25 | },
26 | };
27 | case Block.TODO: return {
28 | component: TodoBlock,
29 | props: {
30 | setEditorState,
31 | getEditorState,
32 | },
33 | };
34 | case Block.IMAGE: return {
35 | component: ImageBlock,
36 | props: {
37 | setEditorState,
38 | getEditorState,
39 | },
40 | };
41 | case Block.BREAK: return {
42 | component: BreakBlock,
43 | editable: false,
44 | };
45 | default: return null;
46 | }
47 | };
48 |
--------------------------------------------------------------------------------
/frame/src/components/vendor/components/entities/link.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import React from 'react';
3 |
4 | import { Entity } from '../../util/constants';
5 |
6 |
7 | export const findLinkEntities = (contentBlock, callback, contentState) => {
8 | contentBlock.findEntityRanges(
9 | (character) => {
10 | const entityKey = character.getEntity();
11 | return (
12 | entityKey !== null &&
13 | contentState.getEntity(entityKey).getType() === Entity.LINK
14 | );
15 | },
16 | callback
17 | );
18 | };
19 |
20 | const Link = (props) => {
21 | const { contentState, entityKey } = props;
22 | const { url } = contentState.getEntity(entityKey).getData();
23 | return (
24 | {props.children}
31 | );
32 | };
33 |
34 | Link.propTypes = {
35 | children: PropTypes.node,
36 | entityKey: PropTypes.string,
37 | contentState: PropTypes.object.isRequired,
38 | };
39 |
40 | export default Link;
41 |
--------------------------------------------------------------------------------
/frame/src/components/vendor/components/inlinetoolbar.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import React from 'react';
3 |
4 | import StyleButton from './stylebutton';
5 |
6 |
7 | const InlineToolbar = (props) => {
8 | if (props.buttons.length < 1) {
9 | return null;
10 | }
11 | const currentStyle = props.editorState.getCurrentInlineStyle();
12 | return (
13 |
14 | {props.buttons.map(type => {
15 | const iconLabel = {};
16 | iconLabel.label = type.label;
17 | return (
18 |
26 | );
27 | })}
28 |
29 | );
30 | };
31 |
32 | InlineToolbar.propTypes = {
33 | buttons: PropTypes.array,
34 | editorState: PropTypes.object.isRequired,
35 | onToggle: PropTypes.func,
36 | };
37 |
38 | export default InlineToolbar;
39 |
--------------------------------------------------------------------------------
/frame/src/components/vendor/components/sides/break.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import React from 'react';
3 |
4 | import { addNewBlock } from '../../model';
5 | import { Block } from '../../util/constants';
6 |
7 | export default class BreakButton extends React.Component {
8 |
9 | constructor(props) {
10 | super(props);
11 |
12 | this.onClick = this.onClick.bind(this);
13 | }
14 |
15 | onClick() {
16 | this.props.setEditorState(addNewBlock(
17 | this.props.getEditorState(),
18 | Block.BREAK
19 | ));
20 | }
21 |
22 | render() {
23 | return (
24 |
25 |
26 |
27 | );
28 | }
29 | }
30 |
31 | BreakButton.propTypes = {
32 | setEditorState: PropTypes.func,
33 | getEditorState: PropTypes.func,
34 | close: PropTypes.func,
35 | };
36 |
--------------------------------------------------------------------------------
/frame/src/components/vendor/components/sides/image.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import React from 'react';
3 |
4 | import { addNewBlock } from '../../model';
5 | import { Block } from '../../util/constants';
6 |
7 | export default class ImageButton extends React.Component {
8 |
9 | static propTypes = {
10 | setEditorState: PropTypes.func,
11 | getEditorState: PropTypes.func,
12 | close: PropTypes.func,
13 | };
14 |
15 | constructor(props) {
16 | super(props);
17 |
18 | this.onClick = this.onClick.bind(this);
19 | this.onChange = this.onChange.bind(this);
20 | }
21 |
22 | onClick() {
23 | this.input.value = null;
24 | this.input.click();
25 | }
26 |
27 |
28 | /*
29 | This is an example of how an image button can be added
30 | on the side control. This Button handles the image addition locally
31 | by creating an object url. You can override this method to upload
32 | images to your server first, then get the image url in return and then
33 | add to the editor.
34 | */
35 | onChange(e) {
36 | // e.preventDefault();
37 | const file = e.target.files[0];
38 | if (file.type.indexOf('image/') === 0) {
39 | // console.log(this.props.getEditorState());
40 | // eslint-disable-next-line no-undef
41 | const src = URL.createObjectURL(file);
42 | this.props.setEditorState(addNewBlock(
43 | this.props.getEditorState(),
44 | Block.IMAGE, {
45 | src,
46 | }
47 | ));
48 | }
49 | this.props.close();
50 | }
51 |
52 | render() {
53 | return (
54 |
60 |
61 | { this.input = c; }}
65 | onChange={this.onChange}
66 | style={{ display: 'none' }}
67 | />
68 |
69 | );
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/frame/src/components/vendor/components/stylebutton.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import React from 'react';
3 |
4 | import { HYPERLINK } from '../util/constants.js';
5 |
6 | export default class StyleButton extends React.Component {
7 | constructor(props) {
8 | super(props);
9 | this.onToggle = (e) => {
10 | e.preventDefault();
11 | this.props.onToggle(this.props.style);
12 | };
13 | }
14 |
15 | render() {
16 | if (this.props.style === HYPERLINK) {
17 | return null;
18 | }
19 | let className = 'md-RichEditor-styleButton';
20 | if (this.props.active) {
21 | className += ' md-RichEditor-activeButton';
22 | }
23 | className += ` md-RichEditor-styleButton-${this.props.style.toLowerCase()}`;
24 | return (
25 |
30 | {this.props.icon ? : this.props.label}
31 |
32 | );
33 | }
34 | }
35 |
36 |
37 | StyleButton.propTypes = {
38 | onToggle: PropTypes.func,
39 | style: PropTypes.string,
40 | active: PropTypes.bool,
41 | icon: PropTypes.string,
42 | label: PropTypes.oneOfType([
43 | PropTypes.string,
44 | PropTypes.element,
45 | PropTypes.object,
46 | ]),
47 | description: PropTypes.string,
48 | };
49 |
--------------------------------------------------------------------------------
/frame/src/components/vendor/index.js:
--------------------------------------------------------------------------------
1 | import Editor from './editor';
2 |
3 | import beforeInput, { StringToTypeMap } from './util/beforeinput';
4 | import RenderMap from './util/rendermap';
5 | import Link, { findLinkEntities } from './components/entities/link';
6 | import keyBindingFn from './util/keybinding';
7 | import rendererFn from './components/customrenderer';
8 | import customStyleMap from './util/customstylemap';
9 | import createEditorState from './model/content';
10 |
11 | import QuoteCaptionBlock from './components/blocks/blockquotecaption';
12 | import CaptionBlock from './components/blocks/caption';
13 | import AtomicBlock from './components/blocks/atomic';
14 | import TodoBlock from './components/blocks/todo';
15 | import ImageBlock from './components/blocks/image';
16 | import BreakBlock from './components/blocks/break';
17 |
18 | import ImageSideButton from './components/sides/image';
19 | import BreakSideButton from './components/sides/break';
20 |
21 | export { Block, Inline, Entity, HANDLED, NOT_HANDLED } from './util/constants';
22 | export { BLOCK_BUTTONS, INLINE_BUTTONS } from './components/toolbar';
23 |
24 | export {
25 | getDefaultBlockData,
26 | getCurrentBlock,
27 | addNewBlock,
28 | resetBlockWithType,
29 | updateDataOfBlock,
30 | addNewBlockAt,
31 | } from './model';
32 |
33 | // eslint-disable-next-line no-undef
34 | // export const _version = __VERSION__;
35 |
36 | export {
37 | Editor,
38 | createEditorState,
39 | StringToTypeMap,
40 | RenderMap,
41 | Link,
42 | findLinkEntities,
43 | beforeInput,
44 | customStyleMap,
45 | keyBindingFn,
46 | rendererFn,
47 | QuoteCaptionBlock,
48 | CaptionBlock,
49 | AtomicBlock,
50 | TodoBlock,
51 | ImageBlock,
52 | BreakBlock,
53 | ImageSideButton,
54 | BreakSideButton,
55 | };
56 |
57 | export default Editor;
58 |
--------------------------------------------------------------------------------
/frame/src/components/vendor/index.scss:
--------------------------------------------------------------------------------
1 | .md-RichEditor-root {
2 | background: #fff;
3 | box-sizing: border-box;
4 | //font-family: 'Georgia', serif;
5 | padding: 15px 30px;
6 | position: relative;
7 | line-height: 1.4em;
8 | }
9 |
10 |
11 | .md-RichEditor-editor {
12 | cursor: text;
13 | margin-top: 10px;
14 | position: relative;
15 | margin: 0 auto;
16 |
17 | h3 {
18 | font-size: 1.3em;
19 | margin: 1.2em 0;
20 | }
21 | }
22 |
23 | .md-RichEditor-editor .public-DraftEditorPlaceholder-root,
24 | .md-RichEditor-editor .public-DraftEditor-content {
25 | margin: 0px -15px -15px;
26 | padding: 15px;
27 | }
28 |
29 | .md-RichEditor-editor .public-DraftEditor-content {
30 | min-height: 100px;
31 | }
32 |
33 | .md-RichEditor-hidePlaceholder .public-DraftEditorPlaceholder-root {
34 | display: none;
35 | }
36 |
37 | .md-RichEditor-editor .md-RichEditor-blockquote {
38 | border-left: 5px solid #4CA8DE;
39 | color: #555;
40 | //font-family: 'Hoefler Text', 'Georgia', serif;
41 | font-size: 1.2em;
42 | margin: 0;
43 | padding: 10px 0 10px 20px;
44 | background-color: #E2F2FF;
45 | }
46 |
47 | .md-RichEditor-blockquote {
48 | a {
49 | text-decoration: underline;
50 | }
51 | }
52 |
53 | .public-DraftEditor-content {
54 | .md-block:first-child {
55 | margin-top: 0;
56 | padding-top: 0;
57 | }
58 | }
59 |
60 | .md-RichEditor-editor .public-DraftStyleDefault-pre {
61 | background-color: rgba(0, 0, 0, 0.05);
62 | //font-family: 'Inconsolata', 'Menlo', 'Consolas', monospace;
63 | font-size: 16px;
64 | padding: 20px;
65 | }
66 |
67 | .public-DraftStyleDefault-unorderedListItem,
68 | .public-DraftStyleDefault-orderedListItem {
69 | margin-bottom: 10px;
70 | }
71 |
72 | .md-editor-action {
73 | position: fixed;
74 | top: 5px;
75 | left: 5px;
76 |
77 | button {
78 | display: block;
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/frame/src/components/vendor/model/content.js:
--------------------------------------------------------------------------------
1 | import {
2 | EditorState,
3 | convertFromRaw,
4 | CompositeDecorator,
5 | ContentState,
6 | } from 'draft-js';
7 |
8 | import Link, { findLinkEntities } from '../components/entities/link';
9 |
10 |
11 | const defaultDecorators = new CompositeDecorator([
12 | {
13 | strategy: findLinkEntities,
14 | component: Link,
15 | },
16 | ]);
17 |
18 |
19 | const createEditorState = (content = null, decorators = defaultDecorators) => {
20 | if (content === null) {
21 | return EditorState.createEmpty(decorators);
22 | }
23 | let contentState = null;
24 | if (typeof content === 'string') {
25 | contentState = ContentState.createFromText(content);
26 | } else {
27 | contentState = convertFromRaw(content);
28 | }
29 | return EditorState.createWithContent(contentState, decorators);
30 | };
31 |
32 | export default createEditorState;
33 |
--------------------------------------------------------------------------------
/frame/src/components/vendor/model/content.spec.js:
--------------------------------------------------------------------------------
1 | import { convertToRaw, CompositeDecorator } from 'draft-js';
2 | import createEditorState from './content';
3 | import { Block } from '../util/constants';
4 |
5 | import preData from '../../docs/data.json';
6 | import Link, { findLinkEntities } from '../components/entities/link';
7 |
8 | describe('createEditorState', () => {
9 | const es = createEditorState();
10 |
11 | it('creates empty editorState when no argument or null is passed', () => {
12 | const raw = convertToRaw(es.getCurrentContent());
13 | expect(raw.blocks).to.be.instanceof(Array);
14 | expect(raw.blocks[0].type).to.equal(Block.UNSTYLED);
15 | expect(raw.blocks[0].text).to.equal('');
16 | expect(raw.blocks[0]).to.include.keys('data', 'key');
17 | });
18 |
19 | it('adds link decorator by default in CompositeDecorator', () => {
20 | expect(es.getDecorator()).to.be.instanceof(CompositeDecorator);
21 | expect(es.getDecorator()._decorators.length).to.equal(1);
22 | expect(es.getDecorator()._decorators[0]).to.deep.equal({
23 | strategy: findLinkEntities,
24 | component: Link,
25 | });
26 | });
27 |
28 | const esContent = createEditorState(preData);
29 |
30 | it('fills data from provided json', () => {
31 | const blocks = esContent.getCurrentContent().getBlockMap();
32 | expect(blocks.size).to.be.above(1);
33 |
34 | expect(esContent.getDecorator()).to.be.instanceof(CompositeDecorator);
35 | expect(esContent.getDecorator()._decorators.length).to.equal(1);
36 | expect(esContent.getDecorator()._decorators[0]).to.deep.equal({
37 | strategy: findLinkEntities,
38 | component: Link,
39 | });
40 | });
41 | });
42 |
--------------------------------------------------------------------------------
/frame/src/components/vendor/util/beforeinput.js:
--------------------------------------------------------------------------------
1 | import { resetBlockWithType, getCurrentBlock } from '../model';
2 | import { Block, HANDLED, NOT_HANDLED } from './constants';
3 |
4 |
5 | /*
6 | This is a key value pair where the key is the string that is input while typing.
7 | While typing in an empty block, if the entered text matches any of the keys in
8 | this dictionary, that particular block's type will be changed to the value
9 | associated with that key.
10 | */
11 | export const StringToTypeMap = {
12 | '--': `${Block.BLOCKQUOTE}:${Block.BLOCKQUOTE_CAPTION}:${Block.CAPTION}`,
13 | '> ': Block.BLOCKQUOTE,
14 | '*.': Block.UL,
15 | '* ': Block.UL,
16 | '- ': Block.UL,
17 | '1.': Block.OL,
18 | '# ': Block.H1,
19 | '##': Block.H2,
20 | '==': Block.UNSTYLED,
21 | '[]': Block.TODO,
22 | };
23 |
24 |
25 | /*
26 | This function is called before text is input in a block in `draft-js`. It checks
27 | whether the input string (first 2 cahracters only) is present in the `StringToTypeMap`
28 | mapping or not. If present, it converts the current block's type and called the `editor`'s
29 | `onChange` function. Otherwise, does nothing. By defualt, the above key-value mapping
30 | is passed. In custom implementation, users can pass their own mapping or extend
31 | the current one.
32 | */
33 | const beforeInput = (editorState, inputString, onChange, mapping = StringToTypeMap) => {
34 | const selection = editorState.getSelection();
35 | const block = getCurrentBlock(editorState);
36 | const blockType = block.getType();
37 | if (blockType.indexOf(Block.ATOMIC) === 0) {
38 | return NOT_HANDLED;
39 | }
40 | const blockLength = block.getLength();
41 | if (selection.getAnchorOffset() > 1 || blockLength > 1) {
42 | return NOT_HANDLED;
43 | }
44 | const blockTo = mapping[block.getText()[0] + inputString];
45 | if (!blockTo) {
46 | return NOT_HANDLED;
47 | }
48 | const finalType = blockTo.split(':');
49 | if (finalType.length < 1 || finalType.length > 3) {
50 | return NOT_HANDLED;
51 | }
52 | let fType = finalType[0];
53 | if (finalType.length === 1) {
54 | if (blockType === finalType[0]) {
55 | return NOT_HANDLED;
56 | }
57 | } else if (finalType.length === 2) {
58 | if (blockType === finalType[1]) {
59 | return NOT_HANDLED;
60 | }
61 | if (blockType === finalType[0]) {
62 | fType = finalType[1];
63 | }
64 | } else if (finalType.length === 3) {
65 | if (blockType === finalType[2]) {
66 | return NOT_HANDLED;
67 | }
68 | if (blockType === finalType[0]) {
69 | fType = finalType[1];
70 | } else {
71 | fType = finalType[2];
72 | }
73 | }
74 | onChange(resetBlockWithType(editorState, fType, {
75 | text: '',
76 | }));
77 | return HANDLED;
78 | };
79 |
80 |
81 | export default beforeInput;
82 |
--------------------------------------------------------------------------------
/frame/src/components/vendor/util/beforeinput.spec.js:
--------------------------------------------------------------------------------
1 | import createEditorState from '../model/content';
2 |
3 | import { Block, /* HANDLED,*/ NOT_HANDLED } from './constants';
4 | import beforeInput from './beforeinput';
5 |
6 | describe('beforeInput()', () => {
7 | it('returns NOT_HANDLED for atomic like blocks', () => {
8 | const dummyData = {
9 | entityMap: {},
10 | blocks: [{
11 | key: 'etee',
12 | text: 'E',
13 | type: 'atomic',
14 | depth: 0,
15 | inlineStyleRanges: [],
16 | entityRanges: [
17 | {
18 | offset: 0,
19 | length: 1,
20 | key: 3,
21 | },
22 | ],
23 | data: {},
24 | }],
25 | };
26 | let es = createEditorState(dummyData);
27 | expect(beforeInput(es)).to.equal(NOT_HANDLED);
28 | dummyData.blocks[0].type = Block.IMAGE;
29 | es = createEditorState(dummyData);
30 | expect(beforeInput(es)).to.equal(NOT_HANDLED);
31 | });
32 | });
33 |
--------------------------------------------------------------------------------
/frame/src/components/vendor/util/blockStyleFn.js:
--------------------------------------------------------------------------------
1 | import { Block } from './constants';
2 |
3 | /*
4 | Get custom classnames for each of the different block types supported.
5 | */
6 |
7 | const BASE_BLOCK_CLASS = 'md-block';
8 |
9 | export default (block) => {
10 | switch (block.getType()) {
11 | case Block.BLOCKQUOTE:
12 | return `${BASE_BLOCK_CLASS} ${BASE_BLOCK_CLASS}-quote md-RichEditor-blockquote`;
13 | case Block.UNSTYLED:
14 | return `${BASE_BLOCK_CLASS} ${BASE_BLOCK_CLASS}-paragraph`;
15 | case Block.ATOMIC:
16 | return `${BASE_BLOCK_CLASS} ${BASE_BLOCK_CLASS}-atomic`;
17 | case Block.CAPTION:
18 | return `${BASE_BLOCK_CLASS} ${BASE_BLOCK_CLASS}-caption`;
19 | case Block.TODO: {
20 | const data = block.getData();
21 | const checkedClass = data.get('checked') === true ?
22 | `${BASE_BLOCK_CLASS}-todo-checked` : `${BASE_BLOCK_CLASS}-todo-unchecked`;
23 | let finalClass = `${BASE_BLOCK_CLASS} ${BASE_BLOCK_CLASS}-paragraph `;
24 | finalClass += `${BASE_BLOCK_CLASS}-todo ${checkedClass}`;
25 | return finalClass;
26 | }
27 | case Block.IMAGE:
28 | return `${BASE_BLOCK_CLASS} ${BASE_BLOCK_CLASS}-image`;
29 | case Block.BLOCKQUOTE_CAPTION: {
30 | const cls = `${BASE_BLOCK_CLASS} ${BASE_BLOCK_CLASS}-quote`;
31 | return `${cls} md-RichEditor-blockquote ${BASE_BLOCK_CLASS}-quote-caption`;
32 | }
33 | case Block.CODE:
34 | return `${BASE_BLOCK_CLASS} ${BASE_BLOCK_CLASS}-code-block`;
35 | default: return BASE_BLOCK_CLASS;
36 | }
37 | };
38 |
--------------------------------------------------------------------------------
/frame/src/components/vendor/util/blockStyleFn.spec.js:
--------------------------------------------------------------------------------
1 | import { Map } from 'immutable';
2 | import { ContentBlock } from 'draft-js';
3 | import blockStyleFn from './blockStyleFn';
4 | import { Block } from './constants';
5 |
6 | const BASE_BLOCK_CLASS = 'md-block';
7 |
8 | describe('blockStyleFn()', () => {
9 | it('should return block class for UNKNOWN', () => {
10 | const normalBlock = new ContentBlock({
11 | type: 'some-unknown-type',
12 | });
13 | expect(blockStyleFn(normalBlock)).to.equal(BASE_BLOCK_CLASS);
14 | });
15 |
16 | it('should return block class for UNSTYLED', () => {
17 | const normalBlock = new ContentBlock({
18 | type: Block.UNSTYLED,
19 | });
20 | expect(blockStyleFn(normalBlock)).to.equal(`${BASE_BLOCK_CLASS} ${BASE_BLOCK_CLASS}-paragraph`);
21 | });
22 |
23 | it('should return block class for CAPTION', () => {
24 | const normalBlock = new ContentBlock({
25 | type: Block.CAPTION,
26 | });
27 | expect(blockStyleFn(normalBlock)).to.equal(`${BASE_BLOCK_CLASS} ${BASE_BLOCK_CLASS}-caption`);
28 | });
29 |
30 | it('should return block class for BLOCKQUOTE_CAPTION', () => {
31 | const normalBlock = new ContentBlock({
32 | type: Block.BLOCKQUOTE_CAPTION,
33 | });
34 | const cls = `${BASE_BLOCK_CLASS} ${BASE_BLOCK_CLASS}-quote`;
35 | expect(blockStyleFn(normalBlock)).to.equal(
36 | `${cls} md-RichEditor-blockquote ${BASE_BLOCK_CLASS}-quote-caption`);
37 | });
38 |
39 | it('should return block class for BLOCKQUOTE', () => {
40 | const normalBlock = new ContentBlock({
41 | type: Block.BLOCKQUOTE,
42 | });
43 | expect(blockStyleFn(normalBlock)).to.equal(
44 | `${BASE_BLOCK_CLASS} ${BASE_BLOCK_CLASS}-quote md-RichEditor-blockquote`);
45 | });
46 |
47 | it('should return block class for ATOMIC', () => {
48 | const normalBlock = new ContentBlock({
49 | type: Block.ATOMIC,
50 | });
51 | expect(blockStyleFn(normalBlock)).to.equal(
52 | `${BASE_BLOCK_CLASS} ${BASE_BLOCK_CLASS}-atomic`);
53 | });
54 |
55 | it('should return block class for IMAGE', () => {
56 | const normalBlock = new ContentBlock({
57 | type: Block.IMAGE,
58 | });
59 | expect(blockStyleFn(normalBlock)).to.equal(
60 | `${BASE_BLOCK_CLASS} ${BASE_BLOCK_CLASS}-image`);
61 | });
62 |
63 | it('should return block class for TODO', () => {
64 | const todoBlock = new ContentBlock({
65 | type: Block.TODO,
66 | });
67 | const todoBlockChecked = new ContentBlock({
68 | type: Block.TODO,
69 | data: Map({
70 | checked: true,
71 | }),
72 | });
73 |
74 | const baseTodoClass = `${BASE_BLOCK_CLASS} ${BASE_BLOCK_CLASS}-paragraph`;
75 |
76 | expect(blockStyleFn(todoBlock)).to.equal(
77 | `${baseTodoClass} ${BASE_BLOCK_CLASS}-todo ${BASE_BLOCK_CLASS}-todo-unchecked`);
78 | expect(blockStyleFn(todoBlockChecked)).to.equal(
79 | `${baseTodoClass} ${BASE_BLOCK_CLASS}-todo ${BASE_BLOCK_CLASS}-todo-checked`);
80 | });
81 |
82 | it('should return block class for CODE', () => {
83 | const normalBlock = new ContentBlock({
84 | type: Block.CODE,
85 | });
86 | expect(blockStyleFn(normalBlock)).to.equal(
87 | `${BASE_BLOCK_CLASS} ${BASE_BLOCK_CLASS}-code-block`);
88 | });
89 | });
90 |
--------------------------------------------------------------------------------
/frame/src/components/vendor/util/constants.js:
--------------------------------------------------------------------------------
1 | /*
2 | Some of the constants which are used throughout this project instead of
3 | directly using string.
4 | */
5 |
6 | export const Block = {
7 | UNSTYLED: 'unstyled',
8 | PARAGRAPH: 'unstyled',
9 | OL: 'ordered-list-item',
10 | UL: 'unordered-list-item',
11 | H1: 'header-one',
12 | H2: 'header-two',
13 | H3: 'header-three',
14 | H4: 'header-four',
15 | H5: 'header-five',
16 | H6: 'header-six',
17 | CODE: 'code-block',
18 | BLOCKQUOTE: 'blockquote',
19 | PULLQUOTE: 'pullquote',
20 | ATOMIC: 'atomic',
21 | BLOCKQUOTE_CAPTION: 'block-quote-caption',
22 | CAPTION: 'caption',
23 | TODO: 'todo',
24 | IMAGE: 'atomic:image',
25 | BREAK: 'atomic:break',
26 | };
27 |
28 | export const Inline = {
29 | BOLD: 'BOLD',
30 | CODE: 'CODE',
31 | ITALIC: 'ITALIC',
32 | STRIKETHROUGH: 'STRIKETHROUGH',
33 | UNDERLINE: 'UNDERLINE',
34 | HIGHLIGHT: 'HIGHLIGHT',
35 | };
36 |
37 | export const Entity = {
38 | LINK: 'LINK',
39 | };
40 |
41 | export const HYPERLINK = 'hyperlink';
42 | export const HANDLED = 'handled';
43 | export const NOT_HANDLED = 'not_handled';
44 |
45 | export const KEY_COMMANDS = {
46 | addNewBlock: () => 'add-new-block',
47 | changeType: (type = '') => `changetype:${type}`,
48 | showLinkInput: () => 'showlinkinput',
49 | unlink: () => 'unlink',
50 | toggleInline: (type = '') => `toggleinline:${type}`,
51 | deleteBlock: () => 'delete-block',
52 | };
53 |
54 | export default {
55 | Block,
56 | Inline,
57 | Entity,
58 | };
59 |
--------------------------------------------------------------------------------
/frame/src/components/vendor/util/constants.spec.js:
--------------------------------------------------------------------------------
1 | import { KEY_COMMANDS, Block, Inline } from './constants';
2 |
3 | describe('constants', () => {
4 | it('changeType should return appended with block type', () => {
5 | expect(KEY_COMMANDS.changeType()).to.equal('changetype:');
6 | expect(KEY_COMMANDS.changeType('')).to.equal('changetype:');
7 | expect(KEY_COMMANDS.changeType(Block.ATOMIC)).to.equal(`changetype:${Block.ATOMIC}`);
8 | expect(KEY_COMMANDS.changeType(Block.IMAGE)).to.equal(`changetype:${Block.IMAGE}`);
9 | });
10 |
11 | it('toggleInline should return appended with inline type', () => {
12 | expect(KEY_COMMANDS.toggleInline()).to.equal('toggleinline:');
13 | expect(KEY_COMMANDS.toggleInline('')).to.equal('toggleinline:');
14 | expect(KEY_COMMANDS.toggleInline(Inline.BOLD)).to.equal(`toggleinline:${Inline.BOLD}`);
15 | expect(KEY_COMMANDS.toggleInline(Inline.ITALIC)).to.equal(`toggleinline:${Inline.ITALIC}`);
16 | });
17 |
18 | it('showLinkInput', () => {
19 | expect(KEY_COMMANDS.showLinkInput()).to.equal('showlinkinput');
20 | });
21 |
22 | it('addNewBlock', () => {
23 | expect(KEY_COMMANDS.addNewBlock()).to.equal('add-new-block');
24 | });
25 |
26 | it('deleteBlock', () => {
27 | expect(KEY_COMMANDS.deleteBlock()).to.equal('delete-block');
28 | });
29 | });
30 |
--------------------------------------------------------------------------------
/frame/src/components/vendor/util/customstylemap.js:
--------------------------------------------------------------------------------
1 | import { Inline } from './constants';
2 |
3 | /*
4 | Custom style map for custom entities like Hihglight.
5 | */
6 | const customStyleMap = {
7 | [Inline.HIGHLIGHT]: {
8 | backgroundColor: 'yellow',
9 | },
10 | [Inline.CODE]: {
11 | fontFamily: 'Consolas, "Liberation Mono", Menlo, Courier, monospace',
12 | margin: '4px 0',
13 | fontSize: '0.9em',
14 | padding: '1px 3px',
15 | color: '#555',
16 | backgroundColor: '#fcfcfc',
17 | border: '1px solid #ccc',
18 | borderBottomColor: '#bbb',
19 | borderRadius: 3,
20 | boxShadow: 'inset 0 -1px 0 #bbb',
21 | },
22 | };
23 |
24 | export default customStyleMap;
25 |
--------------------------------------------------------------------------------
/frame/src/components/vendor/util/index.js:
--------------------------------------------------------------------------------
1 | /*
2 | Returns the `boundingClientRect` of the passed selection.
3 | */
4 | export const getSelectionRect = (selected) => {
5 | const _rect = selected.getRangeAt(0).getBoundingClientRect();
6 | // selected.getRangeAt(0).getBoundingClientRect()
7 | let rect = _rect && _rect.top ? _rect : selected.getRangeAt(0).getClientRects()[0];
8 | if (!rect) {
9 | if (selected.anchorNode && selected.anchorNode.getBoundingClientRect) {
10 | rect = selected.anchorNode.getBoundingClientRect();
11 | rect.isEmptyline = true;
12 | } else {
13 | return null;
14 | }
15 | }
16 | return rect;
17 | };
18 |
19 | /*
20 | Returns the native selection node.
21 | */
22 | export const getSelection = (root) => {
23 | let t = null;
24 | if (root.getSelection) {
25 | t = root.getSelection();
26 | } else if (root.document.getSelection) {
27 | t = root.document.getSelection();
28 | } else if (root.document.selection) {
29 | t = root.document.selection.createRange().text;
30 | }
31 | return t;
32 | };
33 |
34 | /*
35 | Recursively finds the DOM Element of the block where the cursor is currently present.
36 | If not found, returns null.
37 | */
38 | export const getSelectedBlockNode = (root) => {
39 | const selection = root.getSelection();
40 | if (selection.rangeCount === 0) {
41 | return null;
42 | }
43 | let node = selection.getRangeAt(0).startContainer;
44 | // console.log(node);
45 | do {
46 | if (node.getAttribute && node.getAttribute('data-block') === 'true') {
47 | return node;
48 | }
49 | node = node.parentNode;
50 | // console.log(node);
51 | } while (node !== null);
52 | return null;
53 | };
54 |
--------------------------------------------------------------------------------
/frame/src/components/vendor/util/keybinding.js:
--------------------------------------------------------------------------------
1 | import { getDefaultKeyBinding, KeyBindingUtil } from 'draft-js';
2 |
3 | import { KEY_COMMANDS } from './constants';
4 |
5 | const { changeType, showLinkInput, unlink } = KEY_COMMANDS;
6 |
7 | /*
8 | Emits various key commands to be used by `handleKeyCommand` in `Editor` based
9 | on various key combos.
10 | */
11 | export default (e) => {
12 | if (KeyBindingUtil.hasCommandModifier(e) && e.which === 75) {
13 | if (e.shiftKey) {
14 | return unlink();
15 | }
16 | return showLinkInput();
17 | }
18 | if (e.altKey === true && !e.ctrlKey) {
19 | if (e.shiftKey === true) {
20 | switch (e.which) {
21 | // Alt + Shift + A
22 | // case 65: return addNewBlock();
23 | default: return getDefaultKeyBinding(e);
24 | }
25 | }
26 | switch (e.which) {
27 | // 1
28 | case 49: return changeType('ordered-list-item');
29 | // @
30 | case 50: return showLinkInput();
31 | // #
32 | case 51: return changeType('header-three');
33 | // *
34 | case 56: return changeType('unordered-list-item');
35 | // <
36 | case 188: return changeType('caption');
37 | // // -
38 | // case 189: return 'changetype:caption';
39 | // >
40 | case 190: return changeType('unstyled');
41 | // "
42 | case 222: return changeType('blockquote');
43 | default: return getDefaultKeyBinding(e);
44 | }
45 | }
46 | // if (e.keyCode === 46 && !e.ctrlKey) {
47 | // return KEY_COMMANDS.deleteBlock();
48 | // }
49 | return getDefaultKeyBinding(e);
50 | };
51 |
--------------------------------------------------------------------------------
/frame/src/components/vendor/util/rendermap.js:
--------------------------------------------------------------------------------
1 | import { Map } from 'immutable';
2 | import { DefaultDraftBlockRenderMap } from 'draft-js';
3 |
4 | import { Block } from './constants';
5 |
6 | /*
7 | Mapping that returns containers for the various block types.
8 | */
9 | const RenderMap = Map({
10 | [Block.CAPTION]: {
11 | element: 'cite',
12 | },
13 | [Block.BLOCKQUOTE_CAPTION]: {
14 | element: 'blockquote',
15 | },
16 | [Block.TODO]: {
17 | element: 'div',
18 | },
19 | [Block.IMAGE]: {
20 | element: 'figure',
21 | },
22 | [Block.BREAK]: {
23 | element: 'div',
24 | },
25 | }).merge(DefaultDraftBlockRenderMap);
26 |
27 |
28 | export default RenderMap;
29 |
--------------------------------------------------------------------------------
/frame/src/components/vendor/util/rendermap.spec.js:
--------------------------------------------------------------------------------
1 | import renderMap from './rendermap';
2 | import { Block } from './constants';
3 |
4 | describe('rendermap', () => {
5 | it('returns cite for CAPTION', () => {
6 | expect(renderMap.get(Block.CAPTION)).to.deep.equal({
7 | element: 'cite',
8 | });
9 | });
10 |
11 | it('returns blockquote for BLOCKQUOTE_CAPTION', () => {
12 | expect(renderMap.get(Block.BLOCKQUOTE_CAPTION)).to.deep.equal({
13 | element: 'blockquote',
14 | });
15 | });
16 |
17 | it('returns div for TODO', () => {
18 | expect(renderMap.get(Block.TODO)).to.deep.equal({
19 | element: 'div',
20 | });
21 | });
22 |
23 | it('returns figure for IMAGE', () => {
24 | expect(renderMap.get(Block.IMAGE)).to.deep.equal({
25 | element: 'figure',
26 | });
27 | });
28 | });
29 |
--------------------------------------------------------------------------------
/frame/src/data/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "savedSettings": {
3 | "online": false,
4 | "NLPServer": "http://localhost:80/",
5 | "activeTheme": "ocean",
6 | "loadedThemes": [
7 | "light",
8 | "dark",
9 | "clean",
10 | "black",
11 | "ocean",
12 | "dim",
13 | "neon",
14 | "night",
15 | "paper",
16 | "present"
17 | ],
18 | "librariesPath": "src/data/libraries_collections",
19 | "defaultLibrary": "default"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/frame/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import App from './components/App/App'
4 |
5 | import './assets/css/all.css';
6 | import './assets/js/all';
7 | // import registerServiceWorker from "./registerServiceWorker";
8 |
9 | // Create root element in DOM
10 | const root = document.createElement('div');
11 | root.id = "app";
12 | document.body.appendChild( root );
13 | document.title = "Frame - notebook that insights";
14 |
15 | const appEl = document.getElementById('app');
16 |
17 | function render() {
18 | ReactDOM.render(
19 | ,
20 | appEl
21 | );
22 | };
23 |
24 | render();
25 |
26 | // registerServiceWorker();
--------------------------------------------------------------------------------
/frame/src/lib/custom-vendor/tree-node-renderer.js:
--------------------------------------------------------------------------------
1 | import React, { Component, Children, cloneElement } from 'react';
2 | import PropTypes from 'prop-types';
3 | import styles from './tree-node-renderer.scss';
4 |
5 | class MinimalThemeTreeNodeRenderer extends Component {
6 | constructor (props) {
7 | super(props)
8 |
9 | this.state = {}
10 | this.bound = {
11 | handleMouseOver: this.handleMouseOver.bind(this),
12 | handleMouseLeave: this.handleMouseLeave.bind(this)
13 | }
14 | }
15 |
16 | handleMouseOver () {
17 | if (!this.state.highlight) {
18 | this.setState({highlight: true})
19 | }
20 | }
21 |
22 | handleMouseLeave () {
23 | this.setState({highlight: false})
24 | }
25 |
26 | render() {
27 | const {
28 | children,
29 | swapFrom,
30 | swapLength,
31 | swapDepth,
32 | scaffoldBlockPxWidth,
33 | lowerSiblingCounts,
34 | connectDropTarget,
35 | isOver,
36 | draggedNode,
37 | canDrop,
38 | treeIndex,
39 | treeId,
40 | listIndex,
41 | rowDirection,
42 | getPrevRow, // Delete from otherProps
43 | node, // Delete from otherProps
44 | path, // Delete from otherProps
45 | ...otherProps
46 | } = this.props;
47 | // Construct the scaffold representing the structure of the tree
48 | const scaffoldBlockCount = lowerSiblingCounts.length - 1;
49 | let dropType
50 | if (canDrop && !isOver) {
51 | dropType = 'validDrop'
52 | } else if (!canDrop && isOver) {
53 | dropType = 'invalidDrop'
54 | }
55 |
56 | return connectDropTarget(
57 | {} } className={styles.node + (this.state.highlight ? ` ${styles.highlight}` : '') + (dropType ? ` ${styles[dropType]}` : '')}>
58 |
62 | {Children.map(children, child =>
63 | cloneElement(child, {
64 | isOver,
65 | canDrop,
66 | draggedNode,
67 | })
68 | )}
69 |
70 |
71 | );
72 | }
73 | }
74 | MinimalThemeTreeNodeRenderer.defaultProps = {
75 | swapFrom: null,
76 | swapDepth: null,
77 | swapLength: null,
78 | canDrop: false,
79 | draggedNode: null,
80 | rowDirection: 'ltr'
81 | };
82 |
83 | MinimalThemeTreeNodeRenderer.propTypes = {
84 | treeIndex: PropTypes.number.isRequired,
85 | swapFrom: PropTypes.number,
86 | swapDepth: PropTypes.number,
87 | swapLength: PropTypes.number,
88 | scaffoldBlockPxWidth: PropTypes.number.isRequired,
89 | lowerSiblingCounts: PropTypes.arrayOf(PropTypes.number).isRequired,
90 | treeId: PropTypes.string.isRequired,
91 | listIndex: PropTypes.number.isRequired,
92 | rowDirection: PropTypes.string,
93 | children: PropTypes.node.isRequired,
94 |
95 | // Drop target
96 | connectDropTarget: PropTypes.func.isRequired,
97 | isOver: PropTypes.bool.isRequired,
98 | canDrop: PropTypes.bool,
99 | draggedNode: PropTypes.shape({}),
100 |
101 | // used in dndManager
102 | getPrevRow: PropTypes.func.isRequired,
103 | node: PropTypes.shape({}).isRequired,
104 | path: PropTypes.arrayOf(
105 | PropTypes.oneOfType([PropTypes.string, PropTypes.number])
106 | ).isRequired
107 | };
108 |
109 | export default MinimalThemeTreeNodeRenderer;
110 |
--------------------------------------------------------------------------------
/frame/src/lib/custom-vendor/tree-node-renderer.scss:
--------------------------------------------------------------------------------
1 | .node {
2 | width: 50%;
3 | white-space: nowrap;
4 | position: relative;
5 | text-align: left;
6 | min-width: 100%;
7 | overflow: hidden;
8 | }
9 |
10 | .nodeContent {
11 | position: absolute;
12 | top: 0;
13 | bottom: 0;
14 | width: 80%;
15 | }
16 |
17 | .validDrop {
18 | background: #26C281;
19 | }
20 |
21 | .invalidDrop {
22 | background: #C0392B;
23 | }
24 |
25 | .highlight {
26 | background: rgba(240, 240, 240, 0.7);
27 | height: 100%;
28 | cursor: pointer;
29 | }
--------------------------------------------------------------------------------
/frame/src/utils/create-db.js:
--------------------------------------------------------------------------------
1 | /* eslint no-unused-vars: 0 */
2 |
3 | import localforage from 'localforage';
4 |
5 |
6 | export default function openDB(key) {
7 | const store = localforage.createInstance({name: "default"});
8 | return store;
9 | }
--------------------------------------------------------------------------------
/frame/src/utils/generate-uuid.js:
--------------------------------------------------------------------------------
1 | // https://gist.github.com/jed/982883
2 | export default function generateUUID() {
3 | return ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, c =>
4 | (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16) // eslint-disable-line no-bitwise
5 | )
6 | }
7 |
--------------------------------------------------------------------------------
/frame/src/utils/get-timestamp.js:
--------------------------------------------------------------------------------
1 | export default function getTimestamp(date, locale) {
2 | const event = (date===undefined) ? new Date() : new Date(date);
3 | return `${event.toLocaleDateString(locale)} ${event.toLocaleTimeString(locale)}`
4 | };
--------------------------------------------------------------------------------
/frame/src/utils/load-db.js:
--------------------------------------------------------------------------------
1 | /* eslint prefer-arrow-callback: 0 */
2 | /* eslint func-names: 0 */
3 | /* eslint no-unused-vars: 0 */
4 | /* eslint no-var: 0 */
5 | /* eslint no-console: 0 */
6 | /* eslint consistent-return: 0 */
7 | /* eslint no-alert: 0 */
8 |
9 | import localforage from "localforage";
10 |
11 | // Load from LocalForage (default offline storage option)
12 | export default function getFromDB (key) {
13 | localforage.getItem(key, function(err, value) {
14 | if (err) {
15 | console.error(err);
16 | alert(err);
17 | return null;
18 | }
19 | // console.log("Getting item from ", key, value);
20 | return value;
21 | });
22 | }
--------------------------------------------------------------------------------
/frame/src/utils/replace-entry.js:
--------------------------------------------------------------------------------
1 | /* eslint prefer-arrow-callback: 0 */
2 | /* eslint func-names: 0 */
3 | /* eslint no-unused-vars: 0 */
4 | /* eslint no-var: 0 */
5 | /* eslint no-console: 0 */
6 | /* eslint no-plusplus: 0 */
7 | /* eslint no-empty: 0 */
8 |
9 | export default function replaceEntry(entry, Entries) {
10 | const newEntries = Entries;
11 | for (let i=0; i").join("\r\r\n\n");
28 | const reg = /(<([^>]+)>)/ig;
29 | stripped = stripped.replace(reg, "")
30 | stripped = stripped.replace(/[^\x00-\x7F]/g, "");
31 | stripped = stripped.replace(/'/g,"'");
32 | stripped = stripped.replace("&'", "'");
33 | stripped = stripped.replace(/"/g, '"');
34 | return stripped;
35 | }
--------------------------------------------------------------------------------
/frame/src/utils/vendor/classnames.js:
--------------------------------------------------------------------------------
1 | // very simple className utility for creating a classname string...
2 | // Falsy arguments are ignored:
3 | //
4 | // const active = true
5 | // const className = classnames(
6 | // "class1",
7 | // !active && "class2",
8 | // active && "class3"
9 | // ); // returns -> class1 class3";
10 | //
11 | export default function classnames(...classes) {
12 | // Use Boolean constructor as a filter callback
13 | // Allows for loose type truthy/falsey checks
14 | // Boolean("") === false;
15 | // Boolean(false) === false;
16 | // Boolean(undefined) === false;
17 | // Boolean(null) === false;
18 | // Boolean(0) === false;
19 | // Boolean("classname") === true;
20 | return classes.filter(Boolean).join(' ');
21 | }
22 |
--------------------------------------------------------------------------------
/frame/src/utils/vendor/default-handlers.js:
--------------------------------------------------------------------------------
1 | export function defaultGetNodeKey({ treeIndex }) {
2 | return treeIndex;
3 | }
4 |
5 | // Cheap hack to get the text of a react object
6 | function getReactElementText(parent) {
7 | if (typeof parent === 'string') {
8 | return parent;
9 | }
10 |
11 | if (
12 | typeof parent !== 'object' ||
13 | !parent.props ||
14 | !parent.props.children ||
15 | (typeof parent.props.children !== 'string' &&
16 | typeof parent.props.children !== 'object')
17 | ) {
18 | return '';
19 | }
20 |
21 | if (typeof parent.props.children === 'string') {
22 | return parent.props.children;
23 | }
24 |
25 | return parent.props.children
26 | .map(child => getReactElementText(child))
27 | .join('');
28 | }
29 |
30 | // Search for a query string inside a node property
31 | function stringSearch(key, searchQuery, node, path, treeIndex) {
32 | if (typeof node[key] === 'function') {
33 | // Search within text after calling its function to generate the text
34 | return (
35 | String(node[key]({ node, path, treeIndex })).indexOf(searchQuery) > -1
36 | );
37 | }
38 | if (typeof node[key] === 'object') {
39 | // Search within text inside react elements
40 | return getReactElementText(node[key]).indexOf(searchQuery) > -1;
41 | }
42 |
43 | // Search within string
44 | return node[key] && String(node[key]).indexOf(searchQuery) > -1;
45 | }
46 |
47 | export function defaultSearchMethod({ node, path, treeIndex, searchQuery }) {
48 | return (
49 | stringSearch('title', searchQuery, node, path, treeIndex) ||
50 | stringSearch('subtitle', searchQuery, node, path, treeIndex)
51 | );
52 | }
53 |
--------------------------------------------------------------------------------
/frame/src/utils/vendor/generic-utils.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable import/prefer-default-export */
2 |
3 | export function slideRows(rows, fromIndex, toIndex, count = 1) {
4 | const rowsWithoutMoved = [
5 | ...rows.slice(0, fromIndex),
6 | ...rows.slice(fromIndex + count),
7 | ];
8 |
9 | return [
10 | ...rowsWithoutMoved.slice(0, toIndex),
11 | ...rows.slice(fromIndex, fromIndex + count),
12 | ...rowsWithoutMoved.slice(toIndex),
13 | ];
14 | }
15 |
--------------------------------------------------------------------------------
/frame/src/utils/vendor/generic-utils.test.js:
--------------------------------------------------------------------------------
1 | import { slideRows } from './generic-utils';
2 |
3 | describe('slideRows', () => {
4 | it('should handle empty slide', () => {
5 | expect(slideRows([0, 1, 2], 1, 2, 0)).toEqual([0, 1, 2]);
6 | expect(slideRows([0, 1, 2], 1, 0, 0)).toEqual([0, 1, 2]);
7 | expect(slideRows([0, 1, 2], 1, 1, 0)).toEqual([0, 1, 2]);
8 | });
9 |
10 | it('should handle single slides', () => {
11 | expect(slideRows([0, 1, 2], 1, 1, 1)).toEqual([0, 1, 2]);
12 | expect(slideRows([0, 1, 2], 1, 2, 1)).toEqual([0, 2, 1]);
13 | expect(slideRows([0, 1, 2], 1, 0, 1)).toEqual([1, 0, 2]);
14 | expect(slideRows([0, 1, 2], 0, 2, 1)).toEqual([1, 2, 0]);
15 | });
16 |
17 | it('should handle multi slides', () => {
18 | expect(slideRows([0, 1, 2], 1, 0, 2)).toEqual([1, 2, 0]);
19 | expect(slideRows([0, 1, 2, 3], 0, 2, 2)).toEqual([2, 3, 0, 1]);
20 | expect(slideRows([0, 1, 2, 3], 3, 0, 2)).toEqual([3, 0, 1, 2]);
21 | });
22 | });
23 |
--------------------------------------------------------------------------------
/frame/src/utils/vendor/memoized-tree-data-utils.js:
--------------------------------------------------------------------------------
1 | import {
2 | insertNode,
3 | getDescendantCount,
4 | getFlatDataFromTree,
5 | } from './tree-data-utils';
6 |
7 | const memoize = f => {
8 | let savedArgsArray = [];
9 | let savedKeysArray = [];
10 | let savedResult = null;
11 |
12 | return args => {
13 | const keysArray = Object.keys(args).sort();
14 | const argsArray = keysArray.map(key => args[key]);
15 |
16 | // If the arguments for the last insert operation are different than this time,
17 | // recalculate the result
18 | if (
19 | argsArray.length !== savedArgsArray.length ||
20 | argsArray.some((arg, index) => arg !== savedArgsArray[index]) ||
21 | keysArray.some((key, index) => key !== savedKeysArray[index])
22 | ) {
23 | savedArgsArray = argsArray;
24 | savedKeysArray = keysArray;
25 | savedResult = f(args);
26 | }
27 |
28 | return savedResult;
29 | };
30 | };
31 |
32 | export const memoizedInsertNode = memoize(insertNode);
33 | export const memoizedGetFlatDataFromTree = memoize(getFlatDataFromTree);
34 | export const memoizedGetDescendantCount = memoize(getDescendantCount);
35 |
--------------------------------------------------------------------------------
/frame/src/utils/vendor/memoized-tree-data-utils.test.js:
--------------------------------------------------------------------------------
1 | import { insertNode } from './tree-data-utils';
2 |
3 | import { memoizedInsertNode } from './memoized-tree-data-utils';
4 |
5 | describe('insertNode', () => {
6 | it('should handle empty data', () => {
7 | const params = {
8 | treeData: [],
9 | depth: 0,
10 | minimumTreeIndex: 0,
11 | newNode: {},
12 | getNodeKey: ({ treeIndex }) => treeIndex,
13 | };
14 |
15 | let firstCall = insertNode(params);
16 | let secondCall = insertNode(params);
17 | expect(firstCall === secondCall).toEqual(false);
18 |
19 | firstCall = memoizedInsertNode(params);
20 | secondCall = memoizedInsertNode(params);
21 | expect(firstCall === secondCall).toEqual(true);
22 |
23 | expect(
24 | memoizedInsertNode(params) ===
25 | memoizedInsertNode({ ...params, treeData: [{}] })
26 | ).toEqual(false);
27 | });
28 | });
29 |
--------------------------------------------------------------------------------
/frame/webpack.common.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 | const CleanWebpackPlugin = require('clean-webpack-plugin');
3 | const HtmlWebpackPlugin = require('html-webpack-plugin');
4 | const webpack = require("webpack");
5 |
6 | module.exports = {
7 | entry:["babel-polyfill", path.resolve(__dirname, 'src/index.js')],
8 | resolve: {extensions: ['.js', '.jsx', '.tsx', '.ts']},
9 | node: {
10 | fs: "empty"
11 | },
12 | module: {
13 | rules: [
14 | {
15 | test: /\.jsx?$/,
16 | exclude: /(node_modules|bower_components)/,
17 | use: {
18 | loader: "babel-loader",
19 | options: {
20 | cacheDirectory: true,
21 | plugins: [
22 | // Here, we include babel plugins that are only required for the
23 | // renderer process. The 'transform-*' plugins must be included
24 | // before react-hot-loader/babel
25 | 'transform-class-properties',
26 | 'transform-es2015-classes',
27 | 'react-hot-loader/babel'
28 | ]
29 | }
30 | }
31 | },
32 | {
33 | test: /\.tsx?$/,
34 | use: 'ts-loader',
35 | exclude: /node_modules/
36 | },
37 | {
38 | test: /\.scss$/,
39 | loader: "style-loader!css-loader"
40 | },
41 | {
42 | test: /\.css$/,
43 | loader: "style-loader!css-loader"
44 | },
45 |
46 | {
47 | test: /\.(png|jpg|gif|svg|eot|ttf|woff|woff2)$/,
48 | loader: "url-loader",
49 | options: {
50 | limit: 10000
51 | }
52 | },
53 | {
54 | test: /vendor\/.+\.(jsx|js)$/,
55 | loader: "imports?jQuery=jquery,$=jquery,this=>window"
56 | }
57 | ]
58 | },
59 | plugins: [ new HtmlWebpackPlugin() ],
60 | stats: {
61 | warnings: false
62 | }
63 | };
--------------------------------------------------------------------------------
/frame/webpack.config.eslint.js:
--------------------------------------------------------------------------------
1 | require('babel-register');
2 |
3 | module.exports = require('./webpack.dev');
4 |
--------------------------------------------------------------------------------
/frame/webpack.dev.electron.js:
--------------------------------------------------------------------------------
1 | const webpack = require('webpack');
2 | const path = require('path');
3 | const HtmlWebpackPlugin = require('html-webpack-plugin');
4 | const { spawn } = require('child_process');
5 |
6 | // Config directories
7 | const SRC_DIR = path.resolve(__dirname, 'src');
8 | const OUTPUT_DIR = path.resolve(__dirname, 'electron/dev/dist');
9 |
10 | // Any directories you will be adding code/files into, need to be added to this array so webpack will pick them up
11 | const defaultInclude = [SRC_DIR];
12 | module.exports = {
13 | mode: 'development',
14 | entry: ['babel-polyfill', path.resolve(__dirname, 'src/index.js')],
15 | resolve: {extensions: [".js", ".jsx", ".tsx", ".ts"]},
16 | output: {
17 | path: OUTPUT_DIR,
18 | publicPath: '/',
19 | filename: 'bundle-electron-dev.js'
20 | },
21 | module: {
22 | rules: [
23 | {
24 | test: /\.jsx?$/,
25 | exclude: /(node_modules|bower_components)/,
26 | use: {
27 | loader: "babel-loader",
28 | options: {
29 | cacheDirectory: true,
30 | plugins: [
31 | // Here, we include babel plugins that are only required for the
32 | // renderer process. The 'transform-*' plugins must be included
33 | // before react-hot-loader/babel
34 | 'transform-class-properties',
35 | 'transform-es2015-classes',
36 | 'react-hot-loader/babel'
37 | ]
38 | }
39 | }
40 | },
41 | {
42 | test: /\.tsx?$/,
43 | use: 'ts-loader',
44 | exclude: /node_modules/
45 | },
46 | {
47 | test: /\.scss$/,
48 | loader: "style-loader!css-loader"
49 | },
50 | {
51 | test: /\.css$/,
52 | loader: "style-loader!css-loader"
53 | },
54 |
55 | {
56 | test: /\.(png|jpg|gif|svg|eot|ttf|woff|woff2)$/,
57 | loader: "url-loader",
58 | options: {
59 | limit: 10000
60 | }
61 | },
62 | {
63 | test: /vendor\/.+\.(jsx|js)$/,
64 | loader: "imports?jQuery=jquery,$=jquery,this=>window"
65 | }
66 | ]
67 | },
68 | target: 'electron-renderer',
69 | plugins: [
70 | new HtmlWebpackPlugin(),
71 | new webpack.DefinePlugin({'process.env.NODE_ENV': JSON.stringify('development')})
72 | ],
73 | devtool: 'cheap-source-map',
74 | devServer: {
75 | contentBase: OUTPUT_DIR,
76 | stats: {
77 | colors: true,
78 | chunks: false,
79 | children: false
80 | },
81 | setup() {
82 | spawn(
83 | 'electron',
84 | ['.'],
85 | { shell: true, env: process.env, stdio: 'inherit' }
86 | )
87 | .on('close', code => process.exit(0))
88 | .on('error', spawnError => console.ernror(spawnError));
89 | }
90 | }
91 | };
92 |
--------------------------------------------------------------------------------
/frame/webpack.dev.js:
--------------------------------------------------------------------------------
1 | const merge = require('webpack-merge');
2 | const common = require('./webpack.common.js');
3 | const webpack = require("webpack");
4 | const path = require('path');
5 | const FriendlyErrorsWebpackPlugin = require("friendly-errors-webpack-plugin");
6 | const CleanWebpackPlugin = require('clean-webpack-plugin');
7 | const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
8 | const DashboardPlugin = require('webpack-dashboard/plugin');
9 |
10 | module.exports = merge(common,
11 | {
12 | mode: 'development',
13 | output: { path: path.resolve("./output/webpack/development"),filename: "bundle-web-dev.js"},
14 | devtool: 'inline-source-map',
15 | devServer: {
16 | disableHostCheck: true,
17 | hot: true,
18 | historyApiFallback: true,
19 | contentBase: "./output/webpack/devserver",
20 | watchContentBase: true,
21 | port: 3001,
22 | overlay: { warnings: true,errors: true},
23 | stats: {
24 | assets: false,
25 | colors: true,
26 | version: false,
27 | hash: false,
28 | timings: false,
29 | chunks: false,
30 | chunkModules: false,
31 | modules: true,
32 | errorDetails: true
33 | }
34 | },
35 | plugins: [
36 | new CleanWebpackPlugin(['./output/webpack/development']),
37 | new FriendlyErrorsWebpackPlugin(),
38 | new webpack.HotModuleReplacementPlugin(),
39 | //new webpack.NoEmitOnErrorsPlugin(), // Causes it to go to console instead of web page
40 | new webpack.DefinePlugin({"process.env.NODE_ENV": JSON.stringify("development")}),
41 | new webpack.LoaderOptionsPlugin({debug: true}),
42 | //new BundleAnalyzerPlugin(),
43 | new DashboardPlugin()
44 | ],
45 | module: {
46 | rules: [
47 | {
48 | enforce: "pre",
49 | test: /\.js$/,
50 | exclude: /node_modules/,
51 | use: {
52 | loader: "eslint-loader",
53 | options: {
54 | formatter: require("eslint-friendly-formatter"),
55 | quiet: false,
56 | failOnError: true,
57 | failOnWarning: false,
58 | emitError: true,
59 | emitWarning: true,
60 | configFile: "./.eslintrc.json",
61 | outputReport: {
62 | filePath: 'checkstyle.xml',
63 | formatter: require('eslint/lib/formatters/checkstyle')
64 | }
65 | }
66 | },
67 | }
68 | ]
69 | },
70 | stats: {
71 | warnings: false
72 | }
73 | });
--------------------------------------------------------------------------------
/frame/webpack.prod.electron.js:
--------------------------------------------------------------------------------
1 | const webpack = require('webpack');
2 | const path = require('path');
3 | const HtmlWebpackPlugin = require('html-webpack-plugin');
4 | const BabiliPlugin = require('babili-webpack-plugin');
5 | const ExtractTextPlugin = require('extract-text-webpack-plugin');
6 |
7 | // Config directories
8 | const SRC_DIR = path.resolve(__dirname, 'src');
9 | const OUTPUT_DIR = path.resolve(__dirname, 'electron/prod/dist');
10 |
11 | // Any directories you will be adding code/files into, need to be added to this array so webpack will pick them up
12 | const defaultInclude = [SRC_DIR];
13 |
14 | module.exports = {
15 | mode: 'production',
16 | entry: ['babel-polyfill', path.resolve(__dirname, 'src/index.js')],
17 | resolve: {extensions: [".js", ".jsx", ".tsx", ".ts"]},
18 | output: {
19 | path: OUTPUT_DIR,
20 | publicPath: './',
21 | filename: 'bundle-electron-prod.js'
22 | },
23 | module: {
24 | rules: [
25 | {
26 | test: /\.jsx?$/,
27 | exclude: /(node_modules|bower_components)/,
28 | use: {
29 | loader: "babel-loader",
30 | options: {
31 | cacheDirectory: true,
32 | plugins: [
33 | // Here, we include babel plugins that are only required for the
34 | // renderer process. The 'transform-*' plugins must be included
35 | // before react-hot-loader/babel
36 | 'transform-class-properties',
37 | 'transform-es2015-classes',
38 | 'react-hot-loader/babel'
39 | ]
40 | }
41 | }
42 | },
43 | {
44 | test: /\.tsx?$/,
45 | use: 'ts-loader',
46 | exclude: /node_modules/
47 | },
48 | {
49 | test: /\.scss$/,
50 | loader: "style-loader!css-loader"
51 | },
52 | {
53 | test: /\.css$/,
54 | loader: "style-loader!css-loader"
55 | },
56 |
57 | {
58 | test: /\.(png|jpg|gif|svg|eot|ttf|woff|woff2)$/,
59 | loader: "url-loader",
60 | options: {
61 | limit: 10000
62 | }
63 | },
64 | {
65 | test: /vendor\/.+\.(jsx|js)$/,
66 | loader: "imports?jQuery=jquery,$=jquery,this=>window"
67 | }
68 | ]
69 | },
70 | target: 'electron-renderer',
71 | plugins: [
72 | new HtmlWebpackPlugin(),
73 | new ExtractTextPlugin('bundle.css'),
74 | new webpack.DefinePlugin({
75 | 'process.env.NODE_ENV': JSON.stringify('production')
76 | }),
77 | new BabiliPlugin()
78 | ],
79 | stats: {
80 | colors: true,
81 | children: false,
82 | chunks: false,
83 | modules: false
84 | }
85 | };
86 |
--------------------------------------------------------------------------------
/frame/webpack.prod.js:
--------------------------------------------------------------------------------
1 | const merge = require('webpack-merge');
2 | const webpack = require('webpack');
3 | const UglifyJSPlugin = require('uglifyjs-webpack-plugin');
4 | const common = require('./webpack.common.js');
5 | const CleanWebpackPlugin = require('clean-webpack-plugin');
6 | const path = require('path');
7 |
8 | module.exports = merge(common, {
9 | mode: 'production',
10 | output: { path: path.resolve("./output/webpack/production"),filename: "bundle-web-prod.js"},
11 | plugins: [
12 | new UglifyJSPlugin({ sourceMap: true }),
13 | new webpack.DefinePlugin({'process.env.NODE_ENV': JSON.stringify('production')}),
14 | new CleanWebpackPlugin(['./output/webpack/production']),
15 | ],
16 | });
--------------------------------------------------------------------------------
/screenshots/frame_screenshot_01-21-2019_alice_in_wonderland_information_extraction.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jddunn/frame/a002056b22d9986ec41d0a07dff3641c3582c6f4/screenshots/frame_screenshot_01-21-2019_alice_in_wonderland_information_extraction.png
--------------------------------------------------------------------------------
/screenshots/frame_screenshot_01-21-2019_cryptocurrency_analysis.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jddunn/frame/a002056b22d9986ec41d0a07dff3641c3582c6f4/screenshots/frame_screenshot_01-21-2019_cryptocurrency_analysis.png
--------------------------------------------------------------------------------
/screenshots/frame_screenshot_01-21-2019_sicko_mode_visualization.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jddunn/frame/a002056b22d9986ec41d0a07dff3641c3582c6f4/screenshots/frame_screenshot_01-21-2019_sicko_mode_visualization.png
--------------------------------------------------------------------------------
/screenshots/frame_screenshot_01-21-2019_this_is_water_summarization.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jddunn/frame/a002056b22d9986ec41d0a07dff3641c3582c6f4/screenshots/frame_screenshot_01-21-2019_this_is_water_summarization.png
--------------------------------------------------------------------------------
/screenshots/framed_video_animation_demo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jddunn/frame/a002056b22d9986ec41d0a07dff3641c3582c6f4/screenshots/framed_video_animation_demo.gif
--------------------------------------------------------------------------------