Deploy 0.8.0
This commit is contained in:
parent
ff006c92d7
commit
0ec83aa431
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,5 +1,5 @@
|
||||
node_modules
|
||||
Examples/bower_components
|
||||
./Examples/bower_components
|
||||
.directory
|
||||
.codio
|
||||
.settings
|
||||
|
@ -9,7 +9,15 @@
|
||||
"license": "MIT",
|
||||
"ignore": [],
|
||||
"dependencies": {
|
||||
"yjs": "../",
|
||||
"y-webrtc": "~0.6.4"
|
||||
"yjs": "~0.7.6",
|
||||
"y-array": "~0.7.5",
|
||||
"y-map": "~0.7.2",
|
||||
"y-memory": "~0.7.0",
|
||||
"y-richtext": "~0.7.5",
|
||||
"y-webrtc": "~0.7.1",
|
||||
"y-websockets-client": "~0.7.10",
|
||||
"y-text": "~0.7.1",
|
||||
"y-indexeddb": "~0.7.1",
|
||||
"quill": "~0.20.1"
|
||||
}
|
||||
}
|
||||
|
35
Examples/bower_components/quill/.bower.json
vendored
Normal file
35
Examples/bower_components/quill/.bower.json
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
{
|
||||
"name": "quill",
|
||||
"version": "0.20.1",
|
||||
"homepage": "http://quilljs.com",
|
||||
"authors": [
|
||||
"Jason Chen <jhchen7@gmail.com>"
|
||||
],
|
||||
"contributors": [
|
||||
"Byron Milligan <byronner@gmail.com>",
|
||||
"Keegan Poppen <keegan.poppen@gmail.com>"
|
||||
],
|
||||
"description": "Cross browser rich text editor",
|
||||
"main": "dist/quill.js",
|
||||
"license": "BSD",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"config",
|
||||
"examples",
|
||||
"src",
|
||||
"test",
|
||||
"Gruntfile.coffee",
|
||||
"index.js",
|
||||
"package.json"
|
||||
],
|
||||
"_release": "0.20.1",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "v0.20.1",
|
||||
"commit": "07b7f54dfe8997e1c8fe180be6f0817693215c48"
|
||||
},
|
||||
"_source": "git://github.com/quilljs/quill.git",
|
||||
"_target": "~0.20.1",
|
||||
"_originalSource": "quill",
|
||||
"_direct": true
|
||||
}
|
30
Examples/bower_components/quill/LICENSE
vendored
Normal file
30
Examples/bower_components/quill/LICENSE
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
Copyright (c) 2014, Jason Chen
|
||||
Copyright (c) 2013, salesforce.com
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
136
Examples/bower_components/quill/README.md
vendored
Normal file
136
Examples/bower_components/quill/README.md
vendored
Normal file
@ -0,0 +1,136 @@
|
||||
# [Quill Rich Text Editor](http://quilljs.com/) [](http://travis-ci.org/quilljs/quill)
|
||||
|
||||
[](https://saucelabs.com/u/quill)
|
||||
|
||||
Quill is a modern rich text editor built for compatibility and extensibility. It was created by [Jason Chen](https://twitter.com/jhchen) and [Byron Milligan](https://twitter.com/byronmilligan) and open sourced by [Salesforce.com](http://www.salesforce.com).
|
||||
|
||||
To get started, check out the [Quill Github Page](http://quilljs.com/) or jump straight into the [demo](http://quilljs.com/examples/).
|
||||
|
||||
## Quickstart
|
||||
|
||||
Instantiate a new Quill object with a css selector for the div that should become the editor.
|
||||
|
||||
```html
|
||||
<!-- Create the toolbar container -->
|
||||
<div id="toolbar">
|
||||
<button class="ql-bold">Bold</button>
|
||||
<button class="ql-italic">Italic</button>
|
||||
</div>
|
||||
|
||||
<!-- Create the editor container -->
|
||||
<div id="editor">
|
||||
<div>Hello World!</div>
|
||||
</div>
|
||||
|
||||
<!-- Include the Quill library -->
|
||||
<script src="http://cdn.quilljs.com/latest/quill.js"></script>
|
||||
|
||||
<!-- Initialize Quill editor -->
|
||||
<script>
|
||||
var editor = new Quill('#editor');
|
||||
editor.addModule('toolbar', { container: '#toolbar' });
|
||||
</script>
|
||||
```
|
||||
|
||||
|
||||
## Downloading Quill
|
||||
|
||||
There are a number of ways to download the latest or versioned copy of Quill.
|
||||
|
||||
- npm: `npm install quill`
|
||||
- bower: `bower install quill`
|
||||
- tar: https://github.com/quilljs/quill/releases
|
||||
|
||||
### CDN
|
||||
|
||||
```html
|
||||
<link rel="stylesheet" href="//cdn.quilljs.com/0.19.10/quill.snow.css" />
|
||||
<script src="//cdn.quilljs.com/0.19.10/quill.min.js"></script>
|
||||
```
|
||||
|
||||
|
||||
## Local Development
|
||||
|
||||
Quill's source is in [Coffeescript](http://coffeescript.org/) and utilizes [Browserify](http://browserify.org/) to organize its files.
|
||||
|
||||
### Installation
|
||||
|
||||
npm install -g grunt-cli
|
||||
npm install
|
||||
|
||||
### Building
|
||||
|
||||
grunt dist - compile and browserify
|
||||
grunt server - starts a local server that will build and serve assets on the fly
|
||||
|
||||
### Examples
|
||||
|
||||
With the local server (`grunt server`) running you can try out some minimal examples on:
|
||||
|
||||
- [localhost:9000/examples/index.html](http://localhost:9000/examples/index.html)
|
||||
- [localhost:9000/examples/advanced.html](http://localhost:9000/examples/advanced.html)
|
||||
|
||||
Quill [releases](https://github.com/quilljs/quill/releases) also contain these examples as built static files you can try without needing to run the local development server.
|
||||
|
||||
### Testing
|
||||
|
||||
grunt test:unit - runs javascript test suite with Chrome
|
||||
grunt test:e2e - runs end to end tests with Webdriver + Chrome
|
||||
grunt test:coverage - run tests measuring coverage with Chrome
|
||||
|
||||
Tests are run by [Karma](http://karma-runner.github.io/) and [Protractor](https://github.com/angular/protractor) using [Jasmine](http://jasmine.github.io/). Check out `Gruntfile.coffee` and `config/grunt/` for more testing options.
|
||||
|
||||
|
||||
## Contributing
|
||||
|
||||
### Community
|
||||
|
||||
Get help or stay up to date.
|
||||
|
||||
- Follow [@quilljs](https://twitter.com/quilljs) on Twitter
|
||||
- Ask questions on [Stack Overflow](http://stackoverflow.com/questions/tagged/quill) (tag with quill)
|
||||
- If a private channel is required, you may also email support@quilljs.com
|
||||
|
||||
### Bug Reports
|
||||
|
||||
Search through [Github Issues](https://github.com/quilljs/quill/issues) to see if the bug has already been reported. If so, please comment with any additional information about the bug.
|
||||
|
||||
For new issues, create a new issue and tag with the appropriate browser tag. Include as much detail as possible such as:
|
||||
|
||||
- Detailed description of faulty behavior
|
||||
- Affected platforms
|
||||
- Steps for reproduction
|
||||
- Failing test case
|
||||
|
||||
The more details you provide, the more likely we or someone else will be able to find and fix the bug.
|
||||
|
||||
### Feature Requests
|
||||
|
||||
We welcome feature requests. Please make sure they are within scope of Quill's goals and submit them in [Github Issues](https://github.com/quilljs/quill/issues) tagged with the 'feature' tag. The more complete and compelling the request, the more likely it will be implemented. Garnering community support will help as well!
|
||||
|
||||
### Pull Requests
|
||||
|
||||
1. Please check to make sure your plans fall within Quill's scope (likely through Github Issues).
|
||||
2. Fork Quill
|
||||
3. Branch off of the 'develop' branch.
|
||||
4. Implement your changes.
|
||||
5. Submit a Pull Request.
|
||||
|
||||
Pull requests will not be accepted without adhering to the following:
|
||||
|
||||
1. Conform to existing [coding styles](docs/style-guide.md).
|
||||
2. New functionality are accompanied by tests.
|
||||
3. Serve a single atomic purpose (add one feature or fix one bug)
|
||||
4. Introduce only changes that further the PR's singular purpose (ex. do not tweak an unrelated config along with adding your feature).
|
||||
|
||||
**Important:** By issuing a Pull Request you agree to allow the project owners to license your work under the terms of the [License](https://github.com/quilljs/quill/blob/master/LICENSE).
|
||||
|
||||
|
||||
## Thanks
|
||||
|
||||
[Swift](https://github.com/theycallmeswift), for providing the npm package name. If you're looking for his blogging engine see [v0.1.5-1](https://www.npmjs.org/package/quill/0.1.5-1).
|
||||
|
||||
|
||||
## License
|
||||
|
||||
BSD 3-clause
|
23
Examples/bower_components/quill/bower.json
vendored
Normal file
23
Examples/bower_components/quill/bower.json
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
{
|
||||
"name": "quill",
|
||||
"version": "0.20.1",
|
||||
"homepage": "http://quilljs.com",
|
||||
"authors": ["Jason Chen <jhchen7@gmail.com>"],
|
||||
"contributors": [
|
||||
"Byron Milligan <byronner@gmail.com>",
|
||||
"Keegan Poppen <keegan.poppen@gmail.com>"
|
||||
],
|
||||
"description": "Cross browser rich text editor",
|
||||
"main": "dist/quill.js",
|
||||
"license": "BSD",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"config",
|
||||
"examples",
|
||||
"src",
|
||||
"test",
|
||||
"Gruntfile.coffee",
|
||||
"index.js",
|
||||
"package.json"
|
||||
]
|
||||
}
|
194
Examples/bower_components/quill/dist/quill.base.css
vendored
Normal file
194
Examples/bower_components/quill/dist/quill.base.css
vendored
Normal file
@ -0,0 +1,194 @@
|
||||
/*! Quill Editor v0.20.1
|
||||
* https://quilljs.com/
|
||||
* Copyright (c) 2014, Jason Chen
|
||||
* Copyright (c) 2013, salesforce.com
|
||||
*/
|
||||
.ql-image-tooltip {
|
||||
padding: 10px;
|
||||
width: 300px;
|
||||
}
|
||||
.ql-image-tooltip:after {
|
||||
clear: both;
|
||||
content: "";
|
||||
display: table;
|
||||
}
|
||||
.ql-image-tooltip a {
|
||||
border: 1px solid #000;
|
||||
box-sizing: border-box;
|
||||
display: inline-block;
|
||||
float: left;
|
||||
padding: 5px;
|
||||
text-align: center;
|
||||
width: 50%;
|
||||
}
|
||||
.ql-image-tooltip img {
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
margin: auto;
|
||||
max-height: 100%;
|
||||
max-width: 100%;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
}
|
||||
.ql-image-tooltip .input {
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
}
|
||||
.ql-image-tooltip .preview {
|
||||
margin: 10px 0px;
|
||||
position: relative;
|
||||
border: 1px dashed #000;
|
||||
height: 200px;
|
||||
}
|
||||
.ql-image-tooltip .preview span {
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
top: 40%;
|
||||
width: 100%;
|
||||
}
|
||||
.ql-link-tooltip {
|
||||
padding: 5px 10px;
|
||||
}
|
||||
.ql-link-tooltip input.input {
|
||||
width: 170px;
|
||||
}
|
||||
.ql-link-tooltip input.input,
|
||||
.ql-link-tooltip a.done {
|
||||
display: none;
|
||||
}
|
||||
.ql-link-tooltip a.change {
|
||||
margin-right: 4px;
|
||||
}
|
||||
.ql-link-tooltip.editing input.input,
|
||||
.ql-link-tooltip.editing a.done {
|
||||
display: inline-block;
|
||||
}
|
||||
.ql-link-tooltip.editing a.url,
|
||||
.ql-link-tooltip.editing a.change,
|
||||
.ql-link-tooltip.editing a.remove {
|
||||
display: none;
|
||||
}
|
||||
.ql-multi-cursor {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
z-index: 1000;
|
||||
}
|
||||
.ql-multi-cursor .cursor {
|
||||
margin-left: -1px;
|
||||
position: absolute;
|
||||
}
|
||||
.ql-multi-cursor .cursor-flag {
|
||||
bottom: 100%;
|
||||
position: absolute;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.ql-multi-cursor .cursor-name {
|
||||
display: inline-block;
|
||||
color: #fff;
|
||||
padding: 2px 8px;
|
||||
}
|
||||
.ql-multi-cursor .cursor-caret {
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
width: 2px;
|
||||
}
|
||||
.ql-multi-cursor .cursor.hidden .cursor-flag {
|
||||
display: none;
|
||||
}
|
||||
.ql-multi-cursor .cursor.top .cursor-flag {
|
||||
bottom: auto;
|
||||
top: 100%;
|
||||
}
|
||||
.ql-multi-cursor .cursor.right .cursor-flag {
|
||||
right: -2px;
|
||||
}
|
||||
.ql-paste-manager {
|
||||
left: -100000px;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
}
|
||||
.ql-toolbar {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.ql-tooltip {
|
||||
background-color: #fff;
|
||||
border: 1px solid #000;
|
||||
box-sizing: border-box;
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
white-space: nowrap;
|
||||
z-index: 2000;
|
||||
}
|
||||
.ql-tooltip a {
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
}
|
||||
.ql-container {
|
||||
box-sizing: border-box;
|
||||
cursor: text;
|
||||
font-family: Helvetica, 'Arial', sans-serif;
|
||||
font-size: 13px;
|
||||
height: 100%;
|
||||
line-height: 1.42;
|
||||
margin: 0px;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
padding: 12px 15px;
|
||||
position: relative;
|
||||
}
|
||||
.ql-editor {
|
||||
box-sizing: border-box;
|
||||
min-height: 100%;
|
||||
outline: none;
|
||||
tab-size: 4;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
.ql-editor div {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.ql-editor a {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.ql-editor b {
|
||||
font-weight: bold;
|
||||
}
|
||||
.ql-editor i {
|
||||
font-style: italic;
|
||||
}
|
||||
.ql-editor s {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
.ql-editor u {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.ql-editor a,
|
||||
.ql-editor b,
|
||||
.ql-editor i,
|
||||
.ql-editor s,
|
||||
.ql-editor u,
|
||||
.ql-editor span {
|
||||
background-color: inherit;
|
||||
}
|
||||
.ql-editor img {
|
||||
max-width: 100%;
|
||||
}
|
||||
.ql-editor blockquote,
|
||||
.ql-editor ol,
|
||||
.ql-editor ul {
|
||||
margin: 0 0 0 2em;
|
||||
padding: 0;
|
||||
}
|
||||
.ql-editor ol {
|
||||
list-style-type: decimal;
|
||||
}
|
||||
.ql-editor ul {
|
||||
list-style-type: disc;
|
||||
}
|
||||
.ql-editor.ql-ie-9 br,
|
||||
.ql-editor.ql-ie-10 br {
|
||||
display: none;
|
||||
}
|
10749
Examples/bower_components/quill/dist/quill.js
vendored
Normal file
10749
Examples/bower_components/quill/dist/quill.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
9
Examples/bower_components/quill/dist/quill.min.js
vendored
Normal file
9
Examples/bower_components/quill/dist/quill.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
917
Examples/bower_components/quill/dist/quill.snow.css
vendored
Normal file
917
Examples/bower_components/quill/dist/quill.snow.css
vendored
Normal file
@ -0,0 +1,917 @@
|
||||
/*! Quill Editor v0.20.1
|
||||
* https://quilljs.com/
|
||||
* Copyright (c) 2014, Jason Chen
|
||||
* Copyright (c) 2013, salesforce.com
|
||||
*/
|
||||
.ql-image-tooltip {
|
||||
padding: 10px;
|
||||
width: 300px;
|
||||
}
|
||||
.ql-image-tooltip:after {
|
||||
clear: both;
|
||||
content: "";
|
||||
display: table;
|
||||
}
|
||||
.ql-image-tooltip a {
|
||||
border: 1px solid #000;
|
||||
box-sizing: border-box;
|
||||
display: inline-block;
|
||||
float: left;
|
||||
padding: 5px;
|
||||
text-align: center;
|
||||
width: 50%;
|
||||
}
|
||||
.ql-image-tooltip img {
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
margin: auto;
|
||||
max-height: 100%;
|
||||
max-width: 100%;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
}
|
||||
.ql-image-tooltip .input {
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
}
|
||||
.ql-image-tooltip .preview {
|
||||
margin: 10px 0px;
|
||||
position: relative;
|
||||
border: 1px dashed #000;
|
||||
height: 200px;
|
||||
}
|
||||
.ql-image-tooltip .preview span {
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
top: 40%;
|
||||
width: 100%;
|
||||
}
|
||||
.ql-link-tooltip {
|
||||
padding: 5px 10px;
|
||||
}
|
||||
.ql-link-tooltip input.input {
|
||||
width: 170px;
|
||||
}
|
||||
.ql-link-tooltip input.input,
|
||||
.ql-link-tooltip a.done {
|
||||
display: none;
|
||||
}
|
||||
.ql-link-tooltip a.change {
|
||||
margin-right: 4px;
|
||||
}
|
||||
.ql-link-tooltip.editing input.input,
|
||||
.ql-link-tooltip.editing a.done {
|
||||
display: inline-block;
|
||||
}
|
||||
.ql-link-tooltip.editing a.url,
|
||||
.ql-link-tooltip.editing a.change,
|
||||
.ql-link-tooltip.editing a.remove {
|
||||
display: none;
|
||||
}
|
||||
.ql-multi-cursor {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
z-index: 1000;
|
||||
}
|
||||
.ql-multi-cursor .cursor {
|
||||
margin-left: -1px;
|
||||
position: absolute;
|
||||
}
|
||||
.ql-multi-cursor .cursor-flag {
|
||||
bottom: 100%;
|
||||
position: absolute;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.ql-multi-cursor .cursor-name {
|
||||
display: inline-block;
|
||||
color: #fff;
|
||||
padding: 2px 8px;
|
||||
}
|
||||
.ql-multi-cursor .cursor-caret {
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
width: 2px;
|
||||
}
|
||||
.ql-multi-cursor .cursor.hidden .cursor-flag {
|
||||
display: none;
|
||||
}
|
||||
.ql-multi-cursor .cursor.top .cursor-flag {
|
||||
bottom: auto;
|
||||
top: 100%;
|
||||
}
|
||||
.ql-multi-cursor .cursor.right .cursor-flag {
|
||||
right: -2px;
|
||||
}
|
||||
.ql-paste-manager {
|
||||
left: -100000px;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
}
|
||||
.ql-toolbar {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.ql-tooltip {
|
||||
background-color: #fff;
|
||||
border: 1px solid #000;
|
||||
box-sizing: border-box;
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
white-space: nowrap;
|
||||
z-index: 2000;
|
||||
}
|
||||
.ql-tooltip a {
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
}
|
||||
.ql-container {
|
||||
box-sizing: border-box;
|
||||
cursor: text;
|
||||
font-family: Helvetica, 'Arial', sans-serif;
|
||||
font-size: 13px;
|
||||
height: 100%;
|
||||
line-height: 1.42;
|
||||
margin: 0px;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
padding: 12px 15px;
|
||||
position: relative;
|
||||
}
|
||||
.ql-editor {
|
||||
box-sizing: border-box;
|
||||
min-height: 100%;
|
||||
outline: none;
|
||||
tab-size: 4;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
.ql-editor div {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.ql-editor a {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.ql-editor b {
|
||||
font-weight: bold;
|
||||
}
|
||||
.ql-editor i {
|
||||
font-style: italic;
|
||||
}
|
||||
.ql-editor s {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
.ql-editor u {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.ql-editor a,
|
||||
.ql-editor b,
|
||||
.ql-editor i,
|
||||
.ql-editor s,
|
||||
.ql-editor u,
|
||||
.ql-editor span {
|
||||
background-color: inherit;
|
||||
}
|
||||
.ql-editor img {
|
||||
max-width: 100%;
|
||||
}
|
||||
.ql-editor blockquote,
|
||||
.ql-editor ol,
|
||||
.ql-editor ul {
|
||||
margin: 0 0 0 2em;
|
||||
padding: 0;
|
||||
}
|
||||
.ql-editor ol {
|
||||
list-style-type: decimal;
|
||||
}
|
||||
.ql-editor ul {
|
||||
list-style-type: disc;
|
||||
}
|
||||
.ql-editor.ql-ie-9 br,
|
||||
.ql-editor.ql-ie-10 br {
|
||||
display: none;
|
||||
}
|
||||
.ql-snow .ql-image-tooltip a {
|
||||
border: 1px solid #06c;
|
||||
}
|
||||
.ql-snow .ql-image-tooltip a.insert {
|
||||
background-color: #06c;
|
||||
color: #fff;
|
||||
}
|
||||
.ql-snow .ql-image-tooltip .preview {
|
||||
border-color: #ccc;
|
||||
color: #ccc;
|
||||
}
|
||||
.ql-snow .ql-link-tooltip a,
|
||||
.ql-snow .ql-link-tooltip span {
|
||||
line-height: 25px;
|
||||
}
|
||||
.ql-snow .ql-multi-cursor .cursor-name {
|
||||
border-radius: 4px;
|
||||
font-size: 11px;
|
||||
font-family: Arial;
|
||||
margin-left: -50%;
|
||||
padding: 4px 10px;
|
||||
}
|
||||
.ql-snow .ql-multi-cursor .cursor-triangle {
|
||||
border-left: 4px solid transparent;
|
||||
border-right: 4px solid transparent;
|
||||
height: 0px;
|
||||
margin-left: -3px;
|
||||
width: 0px;
|
||||
}
|
||||
.ql-snow .ql-multi-cursor .cursor.left .cursor-name {
|
||||
margin-left: -8px;
|
||||
}
|
||||
.ql-snow .ql-multi-cursor .cursor.right .cursor-flag {
|
||||
right: auto;
|
||||
}
|
||||
.ql-snow .ql-multi-cursor .cursor.right .cursor-name {
|
||||
margin-left: -100%;
|
||||
margin-right: -8px;
|
||||
}
|
||||
.ql-snow .ql-multi-cursor .cursor-triangle.bottom {
|
||||
border-top: 4px solid transparent;
|
||||
display: block;
|
||||
margin-bottom: -1px;
|
||||
}
|
||||
.ql-snow .ql-multi-cursor .cursor-triangle.top {
|
||||
border-bottom: 4px solid transparent;
|
||||
display: none;
|
||||
margin-top: -1px;
|
||||
}
|
||||
.ql-snow .ql-multi-cursor .cursor.top .cursor-triangle.bottom {
|
||||
display: none;
|
||||
}
|
||||
.ql-snow .ql-multi-cursor .cursor.top .cursor-triangle.top {
|
||||
display: block;
|
||||
}
|
||||
.ql-snow.ql-toolbar {
|
||||
box-sizing: border-box;
|
||||
padding: 8px;
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-format-group {
|
||||
display: inline-block;
|
||||
margin-right: 15px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-format-separator {
|
||||
box-sizing: border-box;
|
||||
background-color: #ddd;
|
||||
display: inline-block;
|
||||
height: 14px;
|
||||
margin-left: 4px;
|
||||
margin-right: 4px;
|
||||
vertical-align: middle;
|
||||
width: 1px;
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-format-button {
|
||||
box-sizing: border-box;
|
||||
display: inline-block;
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
vertical-align: middle;
|
||||
background-position: center center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: 18px 18px;
|
||||
box-sizing: border-box;
|
||||
cursor: pointer;
|
||||
text-align: center;
|
||||
width: 24px;
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-picker {
|
||||
box-sizing: border-box;
|
||||
color: #444;
|
||||
display: inline-block;
|
||||
font-family: 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
position: relative;
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-label {
|
||||
box-sizing: border-box;
|
||||
display: inline-block;
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
vertical-align: middle;
|
||||
background-color: #fff;
|
||||
background-position: right center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: 18px 18px;
|
||||
border: 1px solid transparent;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-label.ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-label:hover {
|
||||
color: #06c;
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-options {
|
||||
background-color: #fff;
|
||||
border: 1px solid transparent;
|
||||
box-sizing: border-box;
|
||||
display: none;
|
||||
padding: 4px 8px;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-options .ql-picker-item {
|
||||
background-position: center center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: 18px 18px;
|
||||
box-sizing: border-box;
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
padding-bottom: 5px;
|
||||
padding-top: 5px;
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-options .ql-picker-item.ql-selected,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-options .ql-picker-item:hover {
|
||||
color: #06c;
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-expanded .ql-picker-label {
|
||||
border-color: #ccc;
|
||||
color: #ccc;
|
||||
z-index: 2;
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-expanded .ql-picker-options {
|
||||
border-color: #ccc;
|
||||
box-shadow: rgba(0,0,0,0.2) 0 2px 8px;
|
||||
display: block;
|
||||
margin-top: -1px;
|
||||
z-index: 1;
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-color-picker .ql-picker-label {
|
||||
background-position: center center;
|
||||
width: 28px;
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-color-picker .ql-picker-options {
|
||||
padding: 5px;
|
||||
width: 152px;
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-color-picker .ql-picker-options .ql-picker-item {
|
||||
border: 1px solid transparent;
|
||||
float: left;
|
||||
height: 16px;
|
||||
margin: 2px;
|
||||
padding: 0px;
|
||||
width: 16px;
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-color-picker .ql-picker-options .ql-picker-item.ql-primary-color {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-color-picker .ql-picker-options .ql-picker-item.ql-selected,
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-color-picker .ql-picker-options .ql-picker-item:hover {
|
||||
border-color: #000;
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-font {
|
||||
width: 105px;
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-size {
|
||||
width: 80px;
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-font .ql-picker-label,
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-size .ql-picker-label {
|
||||
padding-left: 8px;
|
||||
padding-right: 8px;
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-align .ql-picker-label {
|
||||
background-position: center center;
|
||||
width: 28px;
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-align .ql-picker-item {
|
||||
box-sizing: border-box;
|
||||
display: inline-block;
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
vertical-align: middle;
|
||||
padding: 0px;
|
||||
width: 28px;
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-align .ql-picker-options {
|
||||
padding: 4px 0px;
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-label {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASBAMAAACk4JNkAAAAKlBMVEUAAABJSUlAQEBERERFRUVERERERERERERERERFRUVEREREREREREREREQJcW6NAAAADXRSTlMAFRzExcbLzM/Q0dLbKbcyLwAAADVJREFUCNdjYCAeMKYJQFnSdzdCWbl3r0NZvnev4tFre/cKlNV79yaUpXP3EJTFtEqBBHcAAHyoDQk0vM/lAAAAAElFTkSuQmCC");
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-expanded .ql-picker-label {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAdElEQVR42mP4//8/VfBINGjVqlUMhw4dEj148OBpEAaxQWKkGgQz5BIQ/4fiSyAxkg2CuuQ/Gj5DjkFHsRh0jJwwwooHzCCQ145g8dpRcgw6j8WgCyQbtH//fhmgxttIhtwGiZETRjDDLoIwiA0UG820FGAA5b25+qRqGXcAAAAASUVORK5CYII=");
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-active:not(.ql-expanded) .ql-picker-label,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker:not(.ql-expanded) .ql-picker-label:hover {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASBAMAAACk4JNkAAAAKlBMVEUAAAAAYc4AZMgAZcwAZs0AZs0AZs0AZ8wAZswAZs0AZswAZswAZswAZsx12LPhAAAADXRSTlMAFRzExcbLzM/Q0dLbKbcyLwAAADVJREFUCNdjYCAeMKYJQFnSdzdCWbl3r0NZvnev4tFre/cKlNV79yaUpXP3EJTFtEqBBHcAAHyoDQk0vM/lAAAAAElFTkSuQmCC");
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-format-button.ql-bold,
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-bold .ql-picker-label,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-label[data-value=bold],
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-item[data-value=bold] {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAMAAABhEH5lAAAAYFBMVEUAAACAgIBAQEA5OTlAQEBERERAQEBERERERERERERDQ0NERERERERERERDQ0NERERERERFRUVERERERERFRUVERERERERERERERERERERERERERERERERERERERERERESN6WzHAAAAH3RSTlMAAggJDA8cQEtTWHF/i4yTpau+xMXX3O7v8/f6+/z+qN9w2AAAAFZJREFUeNqlzMcSgCAMRVEsYO+9vv//S9FhNIYld5HFmSTCqQ66dazkRzA1lPSQGRZGIsDMKMxRW7+2yCIcyf/QUyUGSnc+dkaqoFumM32pf2BqY+HUBfQaCPgVIBc1AAAAAElFTkSuQmCC");
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-format-button.ql-bold.ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-bold .ql-picker-label.ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-label[data-value=bold].ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-item[data-value=bold].ql-selected,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-format-button.ql-bold:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker.ql-bold .ql-picker-label:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker .ql-picker-label[data-value=bold]:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker .ql-picker-item[data-value=bold]:hover {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAMAAABhEH5lAAAAYFBMVEUAAAAAgP8AYL8AccYAatUAZswAZMgAZMsAZswAZcsAZcsAZssAZssAZ80AZswAZs0AZswAZ8wAZswAZcwAZs0AZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZsxCU9XcAAAAH3RSTlMAAggJDA8cQEtTWHF/i4yTpau+xMXX3O7v8/f6+/z+qN9w2AAAAFZJREFUeNqlzMcSgCAMRVEsYO+9vv//S9FhNIYld5HFmSTCqQ66dazkRzA1lPSQGRZGIsDMKMxRW7+2yCIcyf/QUyUGSnc+dkaqoFumM32pf2BqY+HUBfQaCPgVIBc1AAAAAElFTkSuQmCC");
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-format-button.ql-italic,
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-italic .ql-picker-label,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-label[data-value=italic],
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-item[data-value=italic] {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAi0lEQVR42mMYvoARl4SLi0sNkGoAYmY0qf+MjIztu3fvrkYWZGLADZhB8pS4CN1lQUBqLRDvAQJXHMqIstEISp8BEZQYZAIi/v//f5ZSg0xBBCMj4ymyDQKGjxKQEgLiV8DweUS2QUBXGEOZp0EEJV4zgdJnKDLo379/JsS6iJHSFA0DTDhT9CiAAQBbWyIY/pd4rQAAAABJRU5ErkJggg==");
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-format-button.ql-italic.ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-italic .ql-picker-label.ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-label[data-value=italic].ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-item[data-value=italic].ql-selected,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-format-button.ql-italic:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker.ql-italic .ql-picker-label:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker .ql-picker-label[data-value=italic]:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker .ql-picker-item[data-value=italic]:hover {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAk0lEQVR42u3SsQ3CMBBA0X/2BozACMQswg4EMQMUdOyQVdggdpagZAc4ihjJjYmU66K8xpZsfdnSsVxCzTFdEW6AB0oKcqdrLhQcNaK+PLc79QfapLTDgz8cU9Tv8ibZQqIBgI8OxhexH29KPz90jltgA7zownN+6C0Nowhg+JqEvCZbSDSHNDJBLBNdctWJXv18Ad5dJL0jVfDhAAAAAElFTkSuQmCC");
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-format-button.ql-underline,
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-underline .ql-picker-label,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-label[data-value=underline],
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-item[data-value=underline] {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAMAAABhEH5lAAAAM1BMVEUAAABLS0tFRUVDQ0NERERDQ0NFRUVFRUVERERDQ0NERERFRUVERERERERERERERERERESvCHKbAAAAEHRSTlMAERpMbW6Bgry9xMXh5PP51ZZfkwAAAEdJREFUeNq9yEEKgDAMRNHERDWq6dz/tFLBQUC6KfRtPnzpsh/sC2AHrcRUo0iuDXONI7gMxVW9wIQWPFb5sMgMk5YTdMmvGw2DA8yS9di7AAAAAElFTkSuQmCC");
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-format-button.ql-underline.ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-underline .ql-picker-label.ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-label[data-value=underline].ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-item[data-value=underline].ql-selected,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-format-button.ql-underline:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker.ql-underline .ql-picker-label:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker .ql-picker-label[data-value=underline]:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker .ql-picker-item[data-value=underline]:hover {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAMAAABhEH5lAAAAM1BMVEUAAAAAadIAYs4AZc0AZcwAZswAZ84AZswAZs0AZ8wAZcwAZs0AZswAZswAZswAZswAZsycBlETAAAAEHRSTlMAERpMbW6Bgry9xMXh5PP51ZZfkwAAAEdJREFUeNq9yEEKgDAMRNHERDWq6dz/tFLBQUC6KfRtPnzpsh/sC2AHrcRUo0iuDXONI7gMxVW9wIQWPFb5sMgMk5YTdMmvGw2DA8yS9di7AAAAAElFTkSuQmCC");
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-format-button.ql-strike,
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-strike .ql-picker-label,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-label[data-value=strike],
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-item[data-value=strike] {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAMAAABhEH5lAAAAn1BMVEUAAAAAAACAgIBAQEA7OztAQEBLS0tHR0dAQEBJSUlGRkZERERCQkJERERDQ0NERERERERDQ0NFRUVERERERERERERERERERERFRUVERERERERERERFRUVDQ0NFRUVERERFRUVFRUVERERFRUVFRUVFRUVERERFRUVFRUVERERERERERERERERERERERERERERERERERERERERERERERERfrjwTAAAANHRSTlMAAQIMDRAREhQVKCk6PEhLT1xkZWZ4e4CCg4SIiZucoaersLK2wcTFydLX2ODi5err8fX3BKZfrQAAAH5JREFUGBmlwOEWgTAYBuC3isgMxCYAmwRh++7/2qRzttP/HnQTZjdjilkALzhR4wBvQiaLk8WXOJwlHVHjYgxnSmbeR0swGEkpxWZ3vt7fL/w9P4/ist+KdZ7zYYiWiCnScFYiRq1HFo4mxaKIKdJw0ooaVQovkaW1pUzQyQ86Agx4yKmWPAAAAABJRU5ErkJggg==");
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-format-button.ql-strike.ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-strike .ql-picker-label.ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-label[data-value=strike].ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-item[data-value=strike].ql-selected,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-format-button.ql-strike:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker.ql-strike .ql-picker-label:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker .ql-picker-label[data-value=strike]:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker .ql-picker-item[data-value=strike]:hover {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAMAAABhEH5lAAAAolBMVEUAAAAAAP8AgP8AatUAYsQAYM8AadIAY8YAZswAYc4AZswAZM0AZcoAZswAZ8oAZswAZMsAZ8oAZswAZcoAZ8sAZswAZssAZssAZs0AZswAZ8wAZs0AZ8wAZs0AZswAZ8wAZ8wAZs0AZ8wAZ8wAZs0AZs0AZs0AZcwAZs0AZcwAZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZsyiCU+yAAAANXRSTlMAAQIMDRAREhQVKCk6PEhLT1xkZWZ4e4CAgoOEiImbnKGnq7CytsHExcnS19jg4uXq6/H190B1i7AAAAB/SURBVBgZpcDhFoEwGAbgt4pIBmImAJsEYfvu/9ZU52yn/z3oxk/vWuczD453psYRzoR0GkaLHzFYSzqhwvgY1pT0vI8WbzASQvDt/nJ7fN6ovb7P/HrYrTdZxoY+WoJEkoK14iEqPTKwFMkkCBJJClZcUqOM4USiMKYQETr5A2SVDLpJv6ZtAAAAAElFTkSuQmCC");
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-format-button.ql-link,
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-link .ql-picker-label,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-label[data-value=link],
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-item[data-value=link] {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAMAAABhEH5lAAAAllBMVEUAAAD///9VVVVJSUk5OTlAQEBHR0dFRUVCQkJHR0dBQUFCQkJGRkZDQ0NGRkZFRUVCQkJDQ0NERERDQ0NERERFRUVERERFRUVDQ0NERERFRUVERERERERFRUVERERERERERERERERFRUVERERFRUVFRUVERERERERERERERERERERERERERERERERERERERERERERERETx5KUoAAAAMXRSTlMAAAYHCQwZGiMkJzIzOUJOYGNlfoCJl5ibnaCxtLa8xsfIycrQ1OHi5uvs7e/19vn8NGTYeAAAAJdJREFUeNqN0McOgkAARdGnFJWiKGBhEEFpSn3//3OGjMmQ6MK7PMuLxVe/CXDTPl5DJmk3cOTTmZE7MDQES11RyhBY5vQU9aOB2z3gWVFMsXywYx3t9Q9tXsyDjlOVLQlOyanOL1ibkqB7l5odM01QSJqK6GdXmGwUHVhowImJIr2iMI9sLUWwa5LtFjPCSjSJBUl//HoDlmQPy0DFuCkAAAAASUVORK5CYII=");
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-format-button.ql-link.ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-link .ql-picker-label.ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-label[data-value=link].ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-item[data-value=link].ql-selected,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-format-button.ql-link:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker.ql-link .ql-picker-label:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker .ql-picker-label[data-value=link]:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker .ql-picker-item[data-value=link]:hover {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAMAAABhEH5lAAAAmVBMVEUAAAD///8AVdUAbdsAccYAatUAZswAYs4AZswAY80AacsAZswAZM0AZ8kAZM0AZcsAZcoAZMsAZcoAZcoAZssAZs0AZs0AZ8wAZs0AZswAZs0AZswAZs0AZswAZs0AZs0AZs0AZ8wAZswAZcwAZs0AZs0AZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZsy/jsjWAAAAMnRSTlMAAAYHCQwZGiMkJzIzOUJOYGNlfoCAiZeYm52gsbS2vMbHyMnK0NTh4ubr7O3v9fb5/BM/koAAAACXSURBVHjajdDbEoFQAIXhpROqiAjaSdGJSq33fzjTbDO7GS78l9/lj9lXvwnw0le8gEzSuufAhzshr2doCpaGopQhoOX0Fb0GE9fbnidFMYV2Z8c62hgfWj6Z7zqOVY4kuCXHuqBgbUmC4Z9rdsx0QSFpLGKQXWCxUbRloQNHJoqMisI6sLUVwalJtitMCHPRJDYk/fHrDdIHECSPJag6AAAAAElFTkSuQmCC");
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-format-button.ql-image,
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-image .ql-picker-label,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-label[data-value=image],
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-item[data-value=image] {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASBAMAAACk4JNkAAAAElBMVEUAAABERERERERFRUVEREREREQbmEZBAAAABXRSTlMAeMTFxj7M9NAAAABBSURBVAjXY2DAD1RDQSAYyAqFABALLANmMRnAWMwODIIMUFnGUAEIS1A0NADMYgTqhLBY4SyEKXCTTcGMEAJuAgBa9RKl6Fva+wAAAABJRU5ErkJggg==");
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-format-button.ql-image.ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-image .ql-picker-label.ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-label[data-value=image].ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-item[data-value=image].ql-selected,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-format-button.ql-image:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker.ql-image .ql-picker-label:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker .ql-picker-label[data-value=image]:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker .ql-picker-item[data-value=image]:hover {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASBAMAAACk4JNkAAAAElBMVEUAAAAAZswAZcwAZs0AZs0AZszYB6XUAAAABXRSTlMAeMTFxj7M9NAAAABBSURBVAjXY2DAD1RDQSAYyAqFABALLANmMRnAWMwODIIMUFnGUAEIS1A0NADMYgTqhLBY4SyEKXCTTcGMEAJuAgBa9RKl6Fva+wAAAABJRU5ErkJggg==");
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-format-button.ql-list,
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-list .ql-picker-label,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-label[data-value=list],
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-item[data-value=list] {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAMAAABhEH5lAAAAS1BMVEUAAABCQkJFRUVGRkZFRUVCQkJFRUVDQ0NFRUVFRUVFRUVERERERERERERERERFRUVERERERERERERERERERERERERERERERERERET32eciAAAAGHRSTlMAMjRCQ0lOfYKQlJmaocTFxuHi5OXm9falfyKhAAAATElEQVR42mMgFnCKYIpJMDDwSUABP1yIHyYkABYRlBAmwngucV50IXZGIXTjmQTZ0I0XIcp4DjEedCFWFlF041mZRdCN5xDjZiAdAACXwgbrzvG+ZgAAAABJRU5ErkJggg==");
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-format-button.ql-list.ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-list .ql-picker-label.ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-label[data-value=list].ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-item[data-value=list].ql-selected,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-format-button.ql-list:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker.ql-list .ql-picker-label:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker .ql-picker-label[data-value=list]:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker .ql-picker-item[data-value=list]:hover {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAMAAABhEH5lAAAAS1BMVEUAAAAAZswAZ8kAZM0AZ8oAZcsAZcsAZswAZswAZ80AZs0AZs0AZ80AZ8wAZcwAZs0AZs0AZswAZswAZswAZswAZswAZswAZswAZswCB3gJAAAAGHRSTlMAMjRCQ0lOfYKQlJmaocTFxuHi5OXm9falfyKhAAAATElEQVR42mMgFnCKYIpJMDDwSUABP1yIHyYkABYRlBAmwngucV50IXZGIXTjmQTZ0I0XIcp4DjEedCFWFlF041mZRdCN5xDjZiAdAACXwgbrzvG+ZgAAAABJRU5ErkJggg==");
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-format-button.ql-bullet,
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-bullet .ql-picker-label,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-label[data-value=bullet],
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-item[data-value=bullet] {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASBAMAAACk4JNkAAAAD1BMVEUAAABERERFRUVERERERETRGyWnAAAABHRSTlMAxMXG4b8ciAAAABxJREFUCNdjYMAPhBhdgMAJyFJmArGcGRgGXAcA/t0ImAOSO9kAAAAASUVORK5CYII=");
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-format-button.ql-bullet.ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-bullet .ql-picker-label.ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-label[data-value=bullet].ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-item[data-value=bullet].ql-selected,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-format-button.ql-bullet:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker.ql-bullet .ql-picker-label:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker .ql-picker-label[data-value=bullet]:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker .ql-picker-item[data-value=bullet]:hover {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASBAMAAACk4JNkAAAAD1BMVEUAAAAAZcwAZs0AZs0AZsyEYJIjAAAABHRSTlMAxMXG4b8ciAAAABxJREFUCNdjYMAPhBhdgMAJyFJmArGcGRgGXAcA/t0ImAOSO9kAAAAASUVORK5CYII=");
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-format-button.ql-authorship,
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-authorship .ql-picker-label,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-label[data-value=authorship],
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-item[data-value=authorship] {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAMAAABhEH5lAAAARVBMVEUAAABFRUVFRUUAAAAAAABERERDQ0NEREQAAABERERERERERERERERERERFRUVERERERERERERERERERERERERERERERERVeSBUAAAAFnRSTlMAMDtOT1JfYmassMfN09Ta6vD4+fz9w8DTTwAAAExJREFUGBmVwEkSgCAMBMBRQUEU4zb/f6oFF5KbNLp4EQ8rkxnWQ76whBRYkYwwxo08ZijDzWJBs7La0ZysLjSJVUKXKSgOhQuKw08fJOYE1SddZQoAAAAASUVORK5CYII=");
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-format-button.ql-authorship.ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-authorship .ql-picker-label.ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-label[data-value=authorship].ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-item[data-value=authorship].ql-selected,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-format-button.ql-authorship:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker.ql-authorship .ql-picker-label:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker .ql-picker-label[data-value=authorship]:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker .ql-picker-item[data-value=authorship]:hover {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAMAAABhEH5lAAAARVBMVEUAAAAAZcoAaMsAZc4AZ8sAZ8oAZswAZcsAZ80AZs0AZ8wAZ8wAZswAZswAZswAZs0AZswAZswAZswAZswAZswAZswAZszAoUIuAAAAFnRSTlMAMDtOT1JfYmassMfN09Ta6vD4+fz9w8DTTwAAAExJREFUGBmVwEkSgCAMBMBRQUEU4zb/f6oFF5KbNLp4EQ8rkxnWQ76whBRYkYwwxo08ZijDzWJBs7La0ZysLjSJVUKXKSgOhQuKw08fJOYE1SddZQoAAAAASUVORK5CYII=");
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-format-button.ql-color,
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-color .ql-picker-label,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-label[data-value=color],
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-item[data-value=color] {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAMAAABhEH5lAAAAgVBMVEUAAAAAAACAgIBAQEBVVVVDQ0NGRkZGRkZFRUVERERDQ0NDQ0NDQ0NCQkIAAABFRUUAAABDQ0NEREREREREREQAAABDQ0NDQ0NERERFRUVERERERERERERDQ0NERERERERFRUVFRUVERERERERERERERERERERERERERERERERERERLPkdWAAAAKnRSTlMAAQIEBhMWISUtLkVMTU5OT1BTVlpmeX6OkJmdvL3GztTj5/Hy8/b3/f5utmv0AAAAX0lEQVR42pXIRQ6AQABDUdzd3bX3PyCWwAwr+Is2ecyvuKriXmQD5otKoKBFQz+sKkU5khQZKdK8yMoyiQTFOIseEbqLWv6mAPW+bAPvJmN0j/N7nfmTFRI5Jzk0fWwD4sYJPnqIyzwAAAAASUVORK5CYII=");
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-format-button.ql-color.ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-color .ql-picker-label.ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-label[data-value=color].ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-item[data-value=color].ql-selected,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-format-button.ql-color:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker.ql-color .ql-picker-label:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker .ql-picker-label[data-value=color]:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker .ql-picker-item[data-value=color]:hover {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAMAAABhEH5lAAAAgVBMVEUAAAAAAP8AgP8AgL8AVdUAa8kAaNEAZMkAZ8gAZswAZM0AZMsAZc0AZ8oAZcsAZc4AZ8sAZswAZcsAZc0AZswAZ80AZcoAZcoAZs0AZ80AZs0AZs0AZs0AZ8wAZs0AZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZsy3JBcuAAAAKnRSTlMAAQIEBhMWISUtLkVMTU5OT1BTVlpmeX6OkJmdvL3GztTj5/Hy8/b3/f5utmv0AAAAX0lEQVR42pXIRQ6AQABDUdzd3bX3PyCWwAwr+Is2ecyvuKriXmQB5otKoKBFQz+sKkU5khQZKdK8yMoyiQTFOIseEbqLWv6mAPW+bAPvJmN0j/N7nfmTHRI5Jzk0fWwD4foJPqgJbeoAAAAASUVORK5CYII=");
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-format-button.ql-background,
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-background .ql-picker-label,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-label[data-value=background],
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-item[data-value=background] {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAMAAABhEH5lAAAAnFBMVEUAAAAAAACAgIBAQEAAAABVVVUAAAAAAAAAAABDQ0MAAABGRkZGRkYAAABFRUVERERDQ0MAAAAAAAAAAAAAAABDQ0MAAABDQ0MAAABCQkJFRUVDQ0NERERERERERERDQ0NDQ0NERERFRUVERERERERERERDQ0NERERERERFRUVFRUVERERERERERERERERERERERERERERERERERETMTXVbAAAAM3RSTlMAAQIEBgYHCBMTFBYhIyUtLjE2N0JFS0xNTU5QU1ZaeX6OkJmdvL3GztTj5/Hy8/b3/f5Qd6EEAAAAf0lEQVR42o2PRw6DQBRDHVJISCUhvTd69/3vhgT6MLPDmoX15KfRR++c6mdKgVIOTRFoeJ6hE+tCnjXRgUv+oc02jJNyrYk/vj/8jhRxnheLVZHNupn1Yp3nVIgzjhoUDlvxQR/AIOBtKbNjerUB+x7vhZjARPkLyslbYIe+qQDqMQxGJwkBGwAAAABJRU5ErkJggg==");
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-format-button.ql-background.ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-background .ql-picker-label.ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-label[data-value=background].ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-item[data-value=background].ql-selected,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-format-button.ql-background:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker.ql-background .ql-picker-label:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker .ql-picker-label[data-value=background]:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker .ql-picker-item[data-value=background]:hover {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAMAAABhEH5lAAAAllBMVEUAAAAAAP8AgP8AgL8AVdUAbbYAYL8Aa8kAZswAaNEAZMkAZswAZ8gAZswAZM0AaMsAaNAAZswAZM0AZMsAZswAZc0AZ8oAZ80AZcsAZswAZcsAZc0AZswAZcoAZcoAZs0AZ80AZs0AZs0AZs0AZ8wAZs0AZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZsy8dW5vAAAAMXRSTlMAAQIEBgcIExQWISMlLS4xNjdCRUtMTU1OUFNWWnl+jpCZnby9xs7U4+fx8vP29/3+dqGBzgAAAH5JREFUeNqNj0cOg0AUQx1CgFQS0nujd9//ckigDzM7rFlYT34afYzOuX2WFCjl0BWBRhAYOnEu5EkTPfjkH9pswzSr15r44/vDr6mI87JarKrCHmbOi22ethDPTDoUT3vxwRDAJOJtKbNjfnUB957uhVjATPkLyslbYIexaQB/ngudkm14XQAAAABJRU5ErkJggg==");
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-format-button.ql-left,
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-left .ql-picker-label,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-label[data-value=left],
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-item[data-value=left] {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASBAMAAACk4JNkAAAAD1BMVEUAAABERERFRUVERERERETRGyWnAAAABHRSTlMAxMXG4b8ciAAAAClJREFUCNdjYMAPRFxcnCAsFRcXZwYiAFCHC0STCpjlTJwOJwaYDoIaAKIACBBRNsu4AAAAAElFTkSuQmCC");
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-format-button.ql-left.ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-left .ql-picker-label.ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-label[data-value=left].ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-item[data-value=left].ql-selected,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-format-button.ql-left:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker.ql-left .ql-picker-label:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker .ql-picker-label[data-value=left]:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker .ql-picker-item[data-value=left]:hover {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASBAMAAACk4JNkAAAAD1BMVEUAAAAAZcwAZs0AZs0AZsyEYJIjAAAABHRSTlMAxMXG4b8ciAAAAClJREFUCNdjYMAPRFxcnCAsFRcXZwYiAFCHC0STCpjlTJwOJwaYDoIaAKIACBBRNsu4AAAAAElFTkSuQmCC");
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-format-button.ql-right,
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-right .ql-picker-label,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-label[data-value=right],
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-item[data-value=right] {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASBAMAAACk4JNkAAAAD1BMVEUAAABERERFRUVERERERETRGyWnAAAABHRSTlMAxMXG4b8ciAAAAChJREFUCNdjYCAIRFxcnCAsFRcXZ2KUu0B0qIBZzgzEaXFigGkhpAMAmbwIEMJ9k/cAAAAASUVORK5CYII=");
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-format-button.ql-right.ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-right .ql-picker-label.ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-label[data-value=right].ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-item[data-value=right].ql-selected,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-format-button.ql-right:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker.ql-right .ql-picker-label:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker .ql-picker-label[data-value=right]:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker .ql-picker-item[data-value=right]:hover {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASBAMAAACk4JNkAAAAD1BMVEUAAAAAZcwAZs0AZs0AZsyEYJIjAAAABHRSTlMAxMXG4b8ciAAAAChJREFUCNdjYCAIRFxcnCAsFRcXZ2KUu0B0qIBZzgzEaXFigGkhpAMAmbwIEMJ9k/cAAAAASUVORK5CYII=");
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-format-button.ql-center,
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-center .ql-picker-label,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-label[data-value=center],
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-item[data-value=center] {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASBAMAAACk4JNkAAAAD1BMVEUAAABERERFRUVERERERETRGyWnAAAABHRSTlMAxMXG4b8ciAAAAC1JREFUCNdjYCAAGF1cXBTALCYgy4CBIBBxAQEnIEsFzHJmIMYKiCVMYBYhSwCyqQhMfft6AQAAAABJRU5ErkJggg==");
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-format-button.ql-center.ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-center .ql-picker-label.ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-label[data-value=center].ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-item[data-value=center].ql-selected,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-format-button.ql-center:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker.ql-center .ql-picker-label:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker .ql-picker-label[data-value=center]:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker .ql-picker-item[data-value=center]:hover {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASBAMAAACk4JNkAAAAD1BMVEUAAAAAZcwAZs0AZs0AZsyEYJIjAAAABHRSTlMAxMXG4b8ciAAAAC1JREFUCNdjYCAAGF1cXBTALCYgy4CBIBBxAQEnIEsFzHJmIMYKiCVMYBYhSwCyqQhMfft6AQAAAABJRU5ErkJggg==");
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-format-button.ql-justify,
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-justify .ql-picker-label,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-label[data-value=justify],
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-item[data-value=justify] {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASBAMAAACk4JNkAAAAD1BMVEUAAABERERFRUVERERERETRGyWnAAAABHRSTlMAxMXG4b8ciAAAABpJREFUCNdjYMAPRFxAwAnIUgGznBkYBlwHAJGzCjB/C3owAAAAAElFTkSuQmCC");
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-format-button.ql-justify.ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-justify .ql-picker-label.ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-label[data-value=justify].ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-item[data-value=justify].ql-selected,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-format-button.ql-justify:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker.ql-justify .ql-picker-label:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker .ql-picker-label[data-value=justify]:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker .ql-picker-item[data-value=justify]:hover {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAALklEQVR42mMYvoARzko9cwTIsyZR+zGGWcZgPUwIMUZGShwyGtijgT0a2EMMAADESwwWta/i5QAAAABJRU5ErkJggg==");
|
||||
}
|
||||
@media (-webkit-min-device-pixel-ratio: 2) {
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-label {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkBAMAAAATLoWrAAAAIVBMVEUAAABCQkJDQ0NDQ0NERERERERERERERERERERERERERERehmmoAAAACnRSTlMATVRbaeXo6fz+NPhZJgAAAF9JREFUKM9jYBjkQC0JXYS5a4UBmpDFqlXN6IpWrUJTprEKCJpQhLJAQsswhZaiCImDhAJp5kMxkPGJZLjLEiQ0GUWIZdaqVSsdUM33XLVqCpqVLLPQFTEwmAcP9qQAAFUgKabkwE6gAAAAAElFTkSuQmCC");
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-expanded .ql-picker-label {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkBAMAAAATLoWrAAAAJFBMVEWqqqr////AwMDAwMDAwMDBwcHBwcHBwcHBwcHBwcHBwcHBwcEexLCPAAAAC3RSTlMAAE1UW2nl6On8/tZA57EAAABxSURBVHjazc4hFkBAGMTxL3AAp+AGniYiyaLnBETHoKkknbc7l7OrzW7zhP3HX5mRxCskEsknEaZoU6VDNbAyRRugSqICpoVotnT7dBFllnpefPuHUpjGD78aSztRfAK65cUOOIQpPnXrkFSDEFFB0APtK1HCkKpz1wAAAABJRU5ErkJggg==");
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-active:not(.ql-expanded) .ql-picker-label,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker:not(.ql-expanded) .ql-picker-label:hover {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkBAMAAAATLoWrAAAAIVBMVEUAAAAAZ8oAZMsAZc0AZswAZswAZswAZswAZswAZswAZswhMkyGAAAACnRSTlMATVRbaeXo6fz+NPhZJgAAAF9JREFUKM9jYBjkQC0JXYS5a4UBmpDFqlXN6IpWrUJTprEKCJpQhLJAQsswhZaiCImDhAJp5kMxkPGJZLjLEiQ0GUWIZdaqVSsdUM33XLVqCpqVLLPQFTEwmAcP9qQAAFUgKabkwE6gAAAAAElFTkSuQmCC");
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-format-button.ql-bold,
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-bold .ql-picker-label,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-label[data-value=bold],
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-item[data-value=bold] {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAMAAADW3miqAAAAxlBMVEUAAABVVVUzMzNVVVVJSUlGRkZAQEBJSUlAQEBAQEBAQEBHR0dCQkJGRkZAQEBGRkZCQkJERERDQ0NDQ0NGRkZERERDQ0NFRUVCQkJFRUVERERDQ0NDQ0NFRUVDQ0NERERERERERERERERERERERERERERERERERERFRUVDQ0NERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERfjmwgAAAAQXRSTlMAAwUGBwsMDhAUGBkbHSAhIykuOUJERUpNUVZYXGRne3yAi4+SmqWmq67R1tfY2dve5ujp7/Dy8/T19vf4+fv8/mUg1b0AAACrSURBVDjL5dPFDgJBEEXRxt3d3d11gPv/P8WCEAgZuno/b1WLk1TqJaWUI1Jc8852Mqz5bdHHALDK2CF+ckgYIHp/0GtypxpHYKlFSqkycJeQD7hIKADMJFQHulrkSrYs2MflCnZZgzKvo7RJmZeSAWIf1V3nihSGAG19BUq1gKmEQsBZQkHAklATmOuQN5zvP4COQQWnmIxuFfERWOTsXmrztWg8qHqUU/IEzOhNFx6Ncl4AAAAASUVORK5CYII=");
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-format-button.ql-bold.ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-bold .ql-picker-label.ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-label[data-value=bold].ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-item[data-value=bold].ql-selected,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-format-button.ql-bold:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker.ql-bold .ql-picker-label:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker .ql-picker-label[data-value=bold]:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker .ql-picker-item[data-value=bold]:hover {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAMAAADW3miqAAAAxlBMVEUAAAAAVaoAZswAVdUAbdsAXdEAatUAbcgAYM8AZswAasoAZswAaNAAasoAaMcAZMkAZswAZM0AZM0AZ8kAZM0AZcsAZMsAZMsAZ8oAZc0AZc0AZcsAZ8oAZswAZssAZssAZcwAZssAZ80AZs0AZ8wAZ80AZswAZ8wAZ8wAZ8wAZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZsyeO+aMAAAAQXRSTlMAAwUGBwsMDhAUGBkbHSAhIykuOUJERUpNUVZYXGRne3yAi4+SmqWmq67R1tfY2dve5ujp7/Dy8/T19vf4+fv8/mUg1b0AAACrSURBVDjL5dPFDgJBEEXRxt3d3d11gPv/P8WCEAgZuno/b1WLk1TqJaWUI1Jc8852Mqz5bdHHALDK2CF+ckgYIHp/0GtypxpHYKlFSqkycJeQD7hIKADMJFQHulrkSrYs2MflCnZZgzKvo7RJmZeSAWIf1V3nihSGAG19BUq1gKmEQsBZQkHAklATmOuQN5zvP4COQQWnmIxuFfERWOTsXmrztWg8qHqUU/IEzOhNFx6Ncl4AAAAASUVORK5CYII=");
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-format-button.ql-italic,
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-italic .ql-picker-label,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-label[data-value=italic],
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-item[data-value=italic] {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAMAAADW3miqAAAAjVBMVEUAAAAAAACAgIBAQEBVVVVAQEBAQEBCQkJCQkJFRUVDQ0NBQUFDQ0NDQ0NDQ0NFRUVERERERERERERDQ0NERERDQ0NERERERERERERFRUVFRUVERERFRUVERERERERDQ0NERERERERERERDQ0NFRUVEREREREREREREREREREREREREREREREREREREREQUqV1+AAAALnRSTlMAAQIEBggMGyMlKisuUFhZXmJmb3R9hIiKjZGTlKWprrG0uL3BxObt8PL19/j9SqrrawAAAIJJREFUOMvl0jUOQgEQRVHc3d1dzv6XRwch+WRq4NYnmVdMKvU35RZXz+7LQiJqe6uXiDrvqJuI8vM7ALd14fOwIabR+i1agUmfUA1QGedMgJrYRZPGGEVoh0ZgMmeUAlTBMbrWwiZCEwwitEc9MNkLigGq4RBda2MVoRn6X/jfv9YDjuYgGnCpSqcAAAAASUVORK5CYII=");
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-format-button.ql-italic.ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-italic .ql-picker-label.ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-label[data-value=italic].ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-item[data-value=italic].ql-selected,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-format-button.ql-italic:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker.ql-italic .ql-picker-label:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker .ql-picker-label[data-value=italic]:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker .ql-picker-item[data-value=italic]:hover {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAMAAADW3miqAAAAjVBMVEUAAAAAAP8AgP8AgL8AVdUAYL8AatUAaNAAZswAZ8gAZ8gAZcoAZM0AZswAZcsAZMsAZMsAZcsAZ8sAZcoAZcoAZswAZs0AZ8wAZs0AZ8wAZswAZs0AZs0AZswAZ8wAZ8wAZs0AZswAZ8wAZ8wAZs0AZcwAZswAZswAZswAZswAZswAZswAZswAZswAZsyyI9XbAAAALnRSTlMAAQIEBggMGyMlKisuUFhZXmJmb3R9hIiKjZGTlKWprrG0uL3BxObt8PL19/j9SqrrawAAAIJJREFUOMvl0jUOQgEQRVHc3d1dzv6XRwch+WRq4NYnmVdMKvU35RZXz+7LQiJqe6uXiDrvqJuI8vM7ALd14fOwIabR+i1agUmfUA1QGedMgJrYRZPGGEVoh0ZgMmeUAlTBMbrWwiZCEwwitEc9MNkLigGq4RBda2MVoRn6X/jfv9YDjuYgGnCpSqcAAAAASUVORK5CYII=");
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-format-button.ql-underline,
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-underline .ql-picker-label,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-label[data-value=underline],
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-item[data-value=underline] {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAMAAADW3miqAAAAWlBMVEUAAAAAAAAzMzNAQEBGRkZERERERERCQkJERERDQ0NFRUVERERERERFRUVERERERERERERFRUVERERERERERERDQ0NFRUVERERERERERERERERERERERERERET15sOLAAAAHXRSTlMAAQUMLC04TU9UVYePkJKkxMXG2Nrf4+jz9/n6/qlZ0HQAAACUSURBVHja7Y3BDsIgEAW3UCmCFatQxLL//5uuiQ0py1EPxs5tHhMW/oMhxoF5TUSMzGuQqH2PfiO60yiLStIHi260qqKKNLDI0XouOpI6Fh1f/x9W6xOpYZHwNM/9u5lJvACGzvSQRiWlOiUkNDSwuMFCi87mkmTbQRvt18aXWwxhXFiW4IyAr3LBJtMmmtrRFT7ME0B0HEswIOSJAAAAAElFTkSuQmCC");
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-format-button.ql-underline.ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-underline .ql-picker-label.ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-label[data-value=underline].ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-item[data-value=underline].ql-selected,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-format-button.ql-underline:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker.ql-underline .ql-picker-label:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker .ql-picker-label[data-value=underline]:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker .ql-picker-item[data-value=underline]:hover {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAMAAADW3miqAAAAWlBMVEUAAAAAAP8AZswAatUAaMsAZswAZM0AZ8oAZMsAZMsAZswAZswAZs0AZ80AZ8wAZ8wAZcwAZs0AZs0AZswAZs0AZswAZswAZswAZswAZswAZswAZswAZswAZszogqY1AAAAHXRSTlMAAQUMLC04TU9UVYePkJKkxMXG2Nrf4+jz9/n6/qlZ0HQAAACUSURBVHja7Y3BDsIgEAW3UCmCFatQxLL//5uuiQ0py1EPxs5tHhMW/oMhxoF5TUSMzGuQqH2PfiO60yiLStIHi260qqKKNLDI0XouOpI6Fh1f/x9W6xOpYZHwNM/9u5lJvACGzvSQRiWlOiUkNDSwuMFCi87mkmTbQRvt18aXWwxhXFiW4IyAr3LBJtMmmtrRFT7ME0B0HEswIOSJAAAAAElFTkSuQmCC");
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-format-button.ql-strike,
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-strike .ql-picker-label,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-label[data-value=strike],
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-item[data-value=strike] {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAMAAADW3miqAAABLFBMVEUAAACAgIBVVVVAQEAzMzNVVVVAQEA5OTlNTU1JSUlERERHR0dDQ0NGRkZDQ0NAQEBCQkJAQEBGRkZAQEBGRkZERERBQUFERERGRkZCQkJGRkZERERFRUVERERDQ0NFRUVERERDQ0NFRUVCQkJDQ0NFRUVCQkJDQ0NERERDQ0NERERERERDQ0NFRUVERERERERERERERERFRUVERERDQ0NFRUVERERERERFRUVERERERERDQ0NDQ0NFRUVERERERERFRUVERERERERFRUVERERERERDQ0NERERFRUVERERERERERERFRUVERERERERERERERERFRUVERERERERERERFRUVERERERERERERERERERERERERERERERERERERERERERERERERERERERET5TTiyAAAAY3RSTlMAAgMEBQYICQoODxITFhcYGxwdICEtLzEzNjc4P0BFRkdISk1YWWBjaWtsdHZ3f4CHiImKjJGSk5SVl5ufo6Smp625uru8vb/BwsPExcbMzs/Q0dPi4+Tl6+zv8PL19vf4+/z2SQ4sAAABE0lEQVQ4y2NgGDmAV8c5PCkxxFGDE6cSDuOEZCiI0WXGroY/OBkJeHJhU8Pkm4wCXBixKFIHyUTqibJzS5lEgNhqWBT5AMWD+CFsHg8gxxuLoniguCyMIwLkxGFRBPKZDKEw8gMqCuAloEgb7HADMTZ8ijisjHTUlCSFOdgFxeVUNPXM7Z38QmJ9EApQxFFCyxeuxhtFPC7U39nBQl9LVV5CiAMpiFDEOYQlldR0jGwM8DmOVVDRLBpkpDIBr/KBXOBKKNSEgYpiMUQjgaLChBQ5A0W94AHO6wXkumEoUgY5NcpUUYCFRUDBNAqHw22T0YAdNp9bo6qxZMLqI4VAhJIgBZwelzZ0D4uLC3M3lB5B5QgAFQdgZ6NzzvYAAAAASUVORK5CYII=");
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-format-button.ql-strike.ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-strike .ql-picker-label.ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-label[data-value=strike].ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-item[data-value=strike].ql-selected,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-format-button.ql-strike:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker.ql-strike .ql-picker-label:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker .ql-picker-label[data-value=strike]:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker .ql-picker-item[data-value=strike]:hover {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAMAAADW3miqAAABLFBMVEUAAAAAgP8AVaoAgL8AZswAVdUAYL8AccYAZswAbcgAZswAY8YAa8kAaNEAZMgAasoAaNAAZMgAasoAaMcAZMkAZswAZ8kAaMsAZM0AaMsAZswAZM0AZcoAZMsAZMsAZswAZc0AZ8oAZMsAZ8oAZcsAZMsAZcoAZMsAZswAZssAZssAZcoAZssAZcwAZssAZs0AZswAZ8wAZs0AZs0AZswAZswAZ8wAZs0AZs0AZ80AZ8wAZswAZ8wAZs0AZ8wAZ8wAZs0AZs0AZswAZ8wAZs0AZs0AZ8wAZcwAZs0AZ8wAZswAZcwAZs0AZs0AZ8wAZswAZswAZs0AZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZswL5dPDAAAAY3RSTlMAAgMEBQYICQoODxITFhcYGxwdICEtLzEzNjc4P0BFRkdISk1YWWBjaWtsdHZ3f4CHiImKjJGSk5SVl5ufo6Smp625uru8vb/BwsPExcbMzs/Q0dPi4+Tl6+zv8PL19vf4+/z2SQ4sAAABE0lEQVQ4y2NgGDmAV8c5PCkxxFGDE6cSDuOEZCiI0WXGroY/OBkJeHJhU8Pkm4wCXBixKFIHyUTqibJzS5lEgNhqWBT5AMWD+CFsHg8gxxuLoniguCyMIwLkxGFRBPKZDKEw8gMqCuAloEgb7HADMTZ8ijisjHTUlCSFOdgFxeVUNPXM7Z38QmJ9EApQxFFCyxeuxhtFPC7U39nBQl9LVV5CiAMpiFDEOYQlldR0jGwM8DmOVVDRLBpkpDIBr/KBXOBKKNSEgYpiMUQjgaLChBQ5A0W94AHO6wXkumEoUgY5NcpUUYCFRUDBNAqHw22T0YAdNp9bo6qxZMLqI4VAhJIgBZwelzZ0D4uLC3M3lB5B5QgAFQdgZ6NzzvYAAAAASUVORK5CYII=");
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-format-button.ql-link,
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-link .ql-picker-label,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-label[data-value=link],
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-item[data-value=link] {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAMAAADW3miqAAABDlBMVEUAAAD///8AAACAgIBVVVVAQEAzMzNVVVVAQEBNTU1HR0dAQEBJSUlGRkZDQ0NAQEBERERHR0dGRkZDQ0NBQUFGRkZERERCQkJGRkZFRUVCQkJFRUVERERDQ0NDQ0NCQkJFRUVDQ0NERERDQ0NFRUVDQ0NFRUVFRUVFRUVFRUVERERDQ0NFRUVERERFRUVERERERERDQ0NFRUVFRUVERERERERERERERERFRUVERERERERERERFRUVDQ0NERERERERFRUVERERERERERERERERERERERERERERERERERERERERFRUVERERERERERERERERERERERERERERERERERERERERERERERERERERERESFPz0UAAAAWXRSTlMAAAECAwQFBggKEhQVFhccHiQoKissLTIzNDpGR0hMTU5QUlRVW12BgoaHjI2PmJmam5ygpKWosbKztLW6vcDD0NLT2Nna3N7g4eLj5Ofo6err7u/w8vn7/A90CXkAAAFqSURBVDjLzdTHUgJREIXho8yo6JgFc0LFjAkVMZAFJYrCzP/+L+JCtJipS5U7Patbt79Vd1dr6BfRHyBJUiie6dSSiwrEh2aeAPAO7cEoUqWXdHgQirQAOh7A46gZzVQBzsfmSgAnRhR6AjiS5OQAd9aE4t9GmqoCCRPKAGe9zzhQDxlQBzpjknab9c2RD2DBgGrgzUlqQnfrHlg3oGug6Eh1oFsAEtvLVhAteUBuSjseP2lfzQf6dARQjY/s9SncY9uH7DQA7+ky/XkI+8YSfvRVC6k3AO4s34BHT90+1N2yYq8A+/5V0Wyi0ac2NJkD3KgfSaGF9QRQ9oCC5JSAiyCStA2k9jzISooCFQNaBlpWrJBdkTThQsOA7DYQ+3pbKeDWgHQFvDiSNJwEWDWheRfIOZKVBLiRCekYoBiZSAHkx83IfgDABXielhkpfAcAkJ/WICTrwAXgZlyDkRS9rDRu1wJL98/u0yeVYHcP1mwWWgAAAABJRU5ErkJggg==");
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-format-button.ql-link.ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-link .ql-picker-label.ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-label[data-value=link].ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-item[data-value=link].ql-selected,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-format-button.ql-link:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker.ql-link .ql-picker-label:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker .ql-picker-label[data-value=link]:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker .ql-picker-item[data-value=link]:hover {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAMAAADW3miqAAABDlBMVEUAAAD///8AAP8AgP8AVaoAgL8AZswAVdUAYL8AZswAY8YAZswAYc4AaNEAZMgAZMgAZswAY80AZswAZ8gAZcoAaMsAZswAZswAZM0AZ8kAZcoAZswAZc0AZ8oAZc0AZ8oAZcsAZswAZ8oAZMsAZswAZc0AZcsAZ84AZswAZ84AZswAZswAZ8wAZs0AZs0AZs0AZ80AZswAZ8wAZswAZ8wAZswAZs0AZs0AZs0AZ8wAZswAZ8wAZ8wAZ8wAZs0AZswAZs0AZswAZswAZswAZswAZs0AZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZsxCnEEHAAAAWXRSTlMAAAECAwQFBggKEhQVFhccHiQoKissLTIzNDpGR0hMTU5QUlRVW12BgoaHjI2PmJmam5ygpKWosbKztLW6vcDD0NLT2Nna3N7g4eLj5Ofo6err7u/w8vn7/A90CXkAAAFqSURBVDjLzdTHUgJREIXho8yo6JgFc0LFjAkVMZAFJYrCzP/+L+JCtJipS5U7Patbt79Vd1dr6BfRHyBJUiie6dSSiwrEh2aeAPAO7cEoUqWXdHgQirQAOh7A46gZzVQBzsfmSgAnRhR6AjiS5OQAd9aE4t9GmqoCCRPKAGe9zzhQDxlQBzpjknab9c2RD2DBgGrgzUlqQnfrHlg3oGug6Eh1oFsAEtvLVhAteUBuSjseP2lfzQf6dARQjY/s9SncY9uH7DQA7+ky/XkI+8YSfvRVC6k3AO4s34BHT90+1N2yYq8A+/5V0Wyi0ac2NJkD3KgfSaGF9QRQ9oCC5JSAiyCStA2k9jzISooCFQNaBlpWrJBdkTThQsOA7DYQ+3pbKeDWgHQFvDiSNJwEWDWheRfIOZKVBLiRCekYoBiZSAHkx83IfgDABXielhkpfAcAkJ/WICTrwAXgZlyDkRS9rDRu1wJL98/u0yeVYHcP1mwWWgAAAABJRU5ErkJggg==");
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-format-button.ql-image,
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-image .ql-picker-label,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-label[data-value=image],
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-item[data-value=image] {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkBAMAAAATLoWrAAAAFVBMVEUAAABCQkJEREREREREREREREREREQL6X1nAAAABnRSTlMATXjl6OmAFiJpAAAAZklEQVR42sXQsQ3AIAxEUeQZoKdyzwg0DALo9h8hiCYXo4R0/MbSK1ycO5EHlScVpj4Jj97p/vtJPi9U+kptXIlMIY2r1b4XIBpSoDJJFIyYtKohAWBIV8Ke9kv8X7WwtEmBKbkDXfWkWdehkaSCAAAAAElFTkSuQmCC");
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-format-button.ql-image.ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-image .ql-picker-label.ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-label[data-value=image].ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-item[data-value=image].ql-selected,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-format-button.ql-image:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker.ql-image .ql-picker-label:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker .ql-picker-label[data-value=image]:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker .ql-picker-item[data-value=image]:hover {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkBAMAAAATLoWrAAAAFVBMVEUAAAAAZ8oAZswAZswAZswAZswAZsx4QzxlAAAABnRSTlMATXjl6OmAFiJpAAAAZklEQVR42sXQsQ3AIAxEUeQZoKdyzwg0DALo9h8hiCYXo4R0/MbSK1ycO5EHlScVpj4Jj97p/vtJPi9U+kptXIlMIY2r1b4XIBpSoDJJFIyYtKohAWBIV8Ke9kv8X7WwtEmBKbkDXfWkWdehkaSCAAAAAElFTkSuQmCC");
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-format-button.ql-list,
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-list .ql-picker-label,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-label[data-value=list],
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-item[data-value=list] {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAMAAADW3miqAAAAw1BMVEUAAAAAAABVVVVAQEBERERAQEBJSUlGRkZHR0dFRUVCQkJERERAQEBGRkZDQ0NFRUVDQ0NCQkJGRkZDQ0NCQkJERERDQ0NFRUVERERFRUVERERDQ0NERERERERDQ0NFRUVERERERERERERERERERERERERERERFRUVERERERERERERFRUVERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERESFbZw4AAAAQHRSTlMAAQYIDxAVFhkaGx4gKCo0NTY3OU10fYKIiYqMj56fo6SmqKmvtLe6vr/ExcbLz9fh4uXm5+jp7O/w8vP3+vv9Z7IwDAAAAK1JREFUOMvV0scOglAQQFGwYO+oiIq9YldEFPX+/1e5cGEii2FFdNY3b/JORlF+dAqNrS1GQyDEW+9Id/gaRw9EgQacMNEhuO4caD7rlgDS/2yAVWTiia53HWeEaMLzwUKIdvt08n4TxLMptc1UEo/38YqCuGZzKknimxDi6jpa8Vjn6I4kcQNgLkSmVSvjizeeb9ITbzxXxxLETatSxRfEWwAzicC4uANN+at5AdptTQ0Ubk4LAAAAAElFTkSuQmCC");
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-format-button.ql-list.ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-list .ql-picker-label.ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-label[data-value=list].ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-item[data-value=list].ql-selected,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-format-button.ql-list:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker.ql-list .ql-picker-label:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker .ql-picker-label[data-value=list]:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker .ql-picker-item[data-value=list]:hover {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAMAAADW3miqAAAAw1BMVEUAAAAAAP8AVdUAYL8AZswAYM8AYc4AaNEAZswAYs4AaNAAZswAaMcAZswAZ8gAZ8kAZcoAaMsAZswAZ8kAZ8oAZcoAZswAZswAZ8wAZs0AZs0AZswAZs0AZs0AZ8wAZs0AZ8wAZ8wAZs0AZ8wAZswAZswAZs0AZ8wAZswAZcwAZcwAZs0AZs0AZs0AZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZszno9YmAAAAQHRSTlMAAQYIDxAVFhkaGx4gKCo0NTY3OU10fYKIiYqMj56fo6SmqKmvtLe6vr/ExcbLz9fh4uXm5+jp7O/w8vP3+vv9Z7IwDAAAAK1JREFUOMvV0scOglAQQFGwYO+oiIq9YldEFPX+/1e5cGEii2FFdNY3b/JORlF+dAqNrS1GQyDEW+9Id/gaRw9EgQacMNEhuO4caD7rlgDS/2yAVWTiia53HWeEaMLzwUKIdvt08n4TxLMptc1UEo/38YqCuGZzKknimxDi6jpa8Vjn6I4kcQNgLkSmVSvjizeeb9ITbzxXxxLETatSxRfEWwAzicC4uANN+at5AdptTQ0Ubk4LAAAAAElFTkSuQmCC");
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-format-button.ql-bullet,
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-bullet .ql-picker-label,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-label[data-value=bullet],
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-item[data-value=bullet] {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkBAMAAAATLoWrAAAAElBMVEUAAABCQkJEREREREREREREREQc4xmxAAAABXRSTlMATeXo6UtNtyIAAAAzSURBVCjPY2AYACBsyCAcCgOGYCHTYAZTuFAwRCgISSgILCSiyCACF1JkGBgw6voBcj0AFsUtDasGrUcAAAAASUVORK5CYII=");
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-format-button.ql-bullet.ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-bullet .ql-picker-label.ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-label[data-value=bullet].ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-item[data-value=bullet].ql-selected,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-format-button.ql-bullet:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker.ql-bullet .ql-picker-label:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker .ql-picker-label[data-value=bullet]:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker .ql-picker-item[data-value=bullet]:hover {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkBAMAAAATLoWrAAAAElBMVEUAAAAAZ8oAZswAZswAZswAZsxixJGvAAAABXRSTlMATeXo6UtNtyIAAAAzSURBVCjPY2AYACBsyCAcCgOGYCHTYAZTuFAwRCgISSgILCSiyCACF1JkGBgw6voBcj0AFsUtDasGrUcAAAAASUVORK5CYII=");
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-format-button.ql-authorship,
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-authorship .ql-picker-label,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-label[data-value=authorship],
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-item[data-value=authorship] {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAMAAADW3miqAAAAllBMVEUAAACAgIBAQEBCQkIAAABCQkJAQEBGRkZERERERERCQkJGRkZDQ0NDQ0NDQ0MAAAAAAAAAAABDQ0NFRUVERERFRUVERERFRUVERERFRUVERERERERERERERERERERERERERERFRUVEREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREQe3JVeAAAAMXRSTlMAAhgbHx8gIS0xMjM5VFdcXWZyd3yChImPkKy4yMrO0tPj5ebq7e7v8PLz9/j6/P3+mEwo9QAAAJxJREFUGBnVwNcOgjAYBeCj4l7FjeAGUZzn/V9O0kikSftf44c/0A+Tc9iFqHll7tKEJKAWQLKjtockpZZC8qL2hiSjlkESUYsgmVNbQtKhNoCgNrwz95w14NTe8Os2gUP9wJ8p7NYsebRg06NhAZsVDRFstjQksMlogs2Rhhg2o5glpxGqz1O+g/JQUL6TQkH5TmMUPOU7jD1U1AdG8S1kERvjygAAAABJRU5ErkJggg==");
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-format-button.ql-authorship.ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-authorship .ql-picker-label.ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-label[data-value=authorship].ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-item[data-value=authorship].ql-selected,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-format-button.ql-authorship:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker.ql-authorship .ql-picker-label:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker .ql-picker-label[data-value=authorship]:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker .ql-picker-item[data-value=authorship]:hover {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAMAAADW3miqAAAAllBMVEUAAAAAgP8AasoAaNAAY84AaMcAZMkAZswAaMsAZswAZM0AZ8kAZMsAZ8oAZ8oAZcsAZc4AZ80AZcwAZcwAZcwAZswAZs0AZs0AZs0AZ80AZs0AZ8wAZswAZs0AZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZsyCDIYeAAAAMXRSTlMAAhgbHyAhLTEyMzlUV1xdXWZyd3yChImPkKy4yMrO0tPj5ebq7e7v8PLz9/j6/P3+PxHOPAAAAJxJREFUGBnVwNcOgjAYBeCj1j0q7oEbRHGe9385SSORJu1/jR/+QGcdn9ctiNSVmYuCZEljCcmOxh6ShEYCyYvGG5KURgpJSCOEZEpjDkmTRheCSu/OzHNSg1djw6/bCB7VA3/GcFux4FGHS5uWGVwWtIRw2dISwyWlDS5HWiK49CMWnPooP6UDD62Q04GXRk4HXgPk1DDwGCiU1AcZWy1RmD8CRQAAAABJRU5ErkJggg==");
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-format-button.ql-color,
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-color .ql-picker-label,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-label[data-value=color],
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-item[data-value=color] {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAMAAADW3miqAAAAz1BMVEUAAAAAAACAgIBVVVVAQEBVVVU5OTk7OztLS0tHR0dGRkZCQkIAAABERERDQ0NDQ0NDQ0NDQ0NGRkZERERERERCQkJFRUVERERFRUVEREQAAAAAAABDQ0NFRUVEREQAAABERERFRUVERERDQ0NDQ0NERERERERERERERERERERERERERERERERERERFRUVFRUVERERERERERERERERERERDQ0NERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERbYaT1AAAARHRSTlMAAQIDBAYJDRESFhsfIiYqNUFCREtNVVZZWlxdY2RlZm1zdXZ9hI6Tl6Sws7nExcnS09XY2d/g5ejp6+zt8PP09/n9/idH/qoAAADKSURBVBgZ1cDXUsJAAIXhg2KMGruxsGoUe8cWoij1f/9nYiZDGJjsLrfwaRHEWRZrhuAXWoH8zgBO5VVpADTktU9uVz5P5B7lsdUn19+U2x3w+gbcyilsA0cnwP+qXOpAWl1pAhdyqKZAXboGvpZkdwi0Q2m9CxzI7oUJz7LaYdJgWzYPTLmXxUaPKZ01ld0A7xXllr+BK5VlwLlGLoFPlWXQCjQSduBDZfFPM9bY8V+6p7kXmcTBRCqYxMmoYBKnmgqRSRxqkebUEKsKOlxMa6IbAAAAAElFTkSuQmCC");
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-format-button.ql-color.ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-color .ql-picker-label.ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-label[data-value=color].ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-item[data-value=color].ql-selected,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-format-button.ql-color:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker.ql-color .ql-picker-label:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker .ql-picker-label[data-value=color]:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker .ql-picker-item[data-value=color]:hover {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAMAAADW3miqAAAA0lBMVEUAAAAAAP8AgP8AVaoAgL8AVdUAccYAYsQAadIAY8YAaNEAaNAAY84AacsAZckAZ8gAZcoAZswAZM0AZcsAZswAZ8oAZswAZc0AZMsAZswAZ8oAZcsAZc4AZMsAZswAZcoAZ80AZcwAZswAZssAZssAZswAZs0AZs0AZs0AZ8wAZ8wAZ8wAZ8wAZswAZcwAZs0AZcwAZswAZswAZs0AZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZswVaivDAAAARXRSTlMAAQIDBAYJDRESFhsfIiYqNUFCREtNVVZZWlxdXWNkZWZtc3V2fYSOk5eksLO5xMXJ0tPV2Nnf4OXo6evs7fDz9Pf5/f6Y2SWXAAAAy0lEQVQYGdXA11LCQACF4YNijBq7sbCWKPaOLURREPjf/5WYyRAGJrvLLXyaB3GWxZoi+IFWIL9TgBN5VRoADXntktuWzyO5B3ls9Mj11uV2C7y8AjdyCtvAwRHwtyyXOpBWl5rAuRyqKVCXroDPBdntA+1QWv0H9mT3zJgnWW0xrr8pm3sm3MlircuEzorKroG3inKLX8ClyjLgTEMXwIfKMmgFGgo78K6y+LsZa+TwN93RzItM4mAiFUziZFQwiVNNheg4cahFmlEDFzs7cwmPHM8AAAAASUVORK5CYII=");
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-format-button.ql-background,
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-background .ql-picker-label,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-label[data-value=background],
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-item[data-value=background] {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAMAAADW3miqAAAA4VBMVEUAAAAAAACAgIBVVVVAQEBVVVU5OTk7OztLS0tHR0dGRkZCQkJERERDQ0NDQ0NDQ0NDQ0NERERCQkJEREQAAAADAwMGBgZDQ0NEREQODg5ERERDQ0NFRUVERERERERERERDQ0MiIiJDQ0MmJiZEREQrKytEREREREQyMjIyMjJEREREREREREQ4ODhERERERERFRUVFRUVERERERERERERERERAQEBERERERERBQUFERERERERERERBQUFERERERERERERBQUFERERERERERERDQ0NERERERERDQ0NERERERESZD8GyAAAASnRSTlMAAQIDBAYJDRESFhsiJio1QURJS01QU1RWWVpjZGVtdXZ4fYCEiI6TnZ6ksLO3ucTFydLT193g4OLl5ebn6enq6+7w8vP39/n+/rihcb4AAADbSURBVHjazZPFDsMwEERdZkpTZmbmpszd//+grhpFSaS1e+khc1jbmrG1z7KZdSXLgvo79M9ziKCkKJIeoUPJA8AxKT6H5QGVE3dlmwJqKqaLwVdRIV1fDfVEdKGXGnoFBXQtDIwnWJp8uswd/XQWy8XD7aqD9srp2uJQ5NElVuiWGKvisLFz6Bpo3ryM+R84iXO6GoFBQ5ouAka9wyRdF0waUHSBpzl09xF0dTRmNnXu2OOiTNDtAKCg7W3jYk7QnQGObu0KvVeAJUFXU9aS/h5Sp0VFtui/s6w+XSJAbiVJ3G0AAAAASUVORK5CYII=");
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-format-button.ql-background.ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-background .ql-picker-label.ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-label[data-value=background].ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-item[data-value=background].ql-selected,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-format-button.ql-background:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker.ql-background .ql-picker-label:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker .ql-picker-label[data-value=background]:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker .ql-picker-item[data-value=background]:hover {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAMAAADW3miqAAAA5FBMVEUAAAAAAP8AgP8AVaoAgL8AZswAVdUAYL8AccYAYsQAadIAY8YAaNEAasoAZswAYsQAaNAAacsAZckAadEAZ8gAZcoAZswAZswAZMkAZM0AZcsAZ8sAZswAaM0AZ8oAZ80AZswAZc0AZMsAZswAZMsAZswAZcoAZcwAZswAZssAZssAZswAZs0AZs0AZs0AZ8wAZ8wAZ8wAZ8wAZswAZcwAZs0AZcwAZswAZswAZs0AZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZswAZsxJPDLdAAAAS3RSTlMAAQIDBAUGCAkNERIWGBkaGyImJyo1N0FCQkRFS0xNTVVWWVpjZGVtc3V2fYSOk5eksLO5xMXJ0tPV2Nnf4OXo6evs7fDz9Pf5/f60OfwzAAABG0lEQVR42s2T6VKDQBCEGyUJoqgSjcYg8dZ43/EieCUa5/3fx661qMAu7O98P4bZnq5lZlkwvXS7k1hf1BTdZFEsFpvUMU15IU7TuKiYJu9d5MODZZ8WcCBk39ZVAKcvpG+ZrgNsimIdTtV0TeBGFNewdBWORTFesUx3QcP9A8N59XT+kPWdPYavOQQVXfVYTtz6gI8jvfUsdRNWe8ApHy8z5ftgm8WhDyx8M4nKumoBd5LjVkkaAdYkz+8qpQLqtK+kwKU5XRPLP1JgNF8y3RkLjw4Us69cnMDb0qdLqR9myjEXz2brNPG2NSKQqOGPRJ5gEr8NYoT/9yHE7mfShoarovYptDw7kiWLyZTbNZBa9saK33tDWZlPK39U3ELkzhssBgAAAABJRU5ErkJggg==");
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-format-button.ql-left,
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-left .ql-picker-label,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-label[data-value=left],
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-item[data-value=left] {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkBAMAAAATLoWrAAAAElBMVEUAAABCQkJEREREREREREREREQc4xmxAAAABXRSTlMATeXo6UtNtyIAAABCSURBVCjPY2AYACAcCgaGSEKmEKFgTKEgJCERiJAiw0ACqOuR/WCKLBSMKRSE7PqB9YMwuttRnBqMKRSEGvYD6HYAD8opyeJDvUUAAAAASUVORK5CYII=");
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-format-button.ql-left.ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-left .ql-picker-label.ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-label[data-value=left].ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-item[data-value=left].ql-selected,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-format-button.ql-left:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker.ql-left .ql-picker-label:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker .ql-picker-label[data-value=left]:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker .ql-picker-item[data-value=left]:hover {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkBAMAAAATLoWrAAAAElBMVEUAAAAAZ8oAZswAZswAZswAZsxixJGvAAAABXRSTlMATeXo6UtNtyIAAABCSURBVCjPY2AYACAcCgaGSEKmEKFgTKEgJCERiJAiw0ACqOuR/WCKLBSMKRSE7PqB9YMwuttRnBqMKRSEGvYD6HYAD8opyeJDvUUAAAAASUVORK5CYII=");
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-format-button.ql-right,
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-right .ql-picker-label,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-label[data-value=right],
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-item[data-value=right] {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkBAMAAAATLoWrAAAAElBMVEUAAABCQkJEREREREREREREREQc4xmxAAAABXRSTlMATeXo6UtNtyIAAABCSURBVCjPY2AYMCAcCgaGSEKmEKFgTKEgJCERiJDiwLob2fWmyELBmEJByO4eWNejuN8QNZCRw94U3fUo7h8Q1wMAuRspyVIXC2UAAAAASUVORK5CYII=");
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-format-button.ql-right.ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-right .ql-picker-label.ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-label[data-value=right].ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-item[data-value=right].ql-selected,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-format-button.ql-right:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker.ql-right .ql-picker-label:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker .ql-picker-label[data-value=right]:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker .ql-picker-item[data-value=right]:hover {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkBAMAAAATLoWrAAAAElBMVEUAAAAAZ8oAZswAZswAZswAZsxixJGvAAAABXRSTlMATeXo6UtNtyIAAABCSURBVCjPY2AYMCAcCgaGSEKmEKFgTKEgJCERiJDiwLob2fWmyELBmEJByO4eWNejuN8QNZCRw94U3fUo7h8Q1wMAuRspyVIXC2UAAAAASUVORK5CYII=");
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-format-button.ql-center,
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-center .ql-picker-label,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-label[data-value=center],
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-item[data-value=center] {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkBAMAAAATLoWrAAAAElBMVEUAAABCQkJEREREREREREREREQc4xmxAAAABXRSTlMATeXo6UtNtyIAAABCSURBVCjPY2AYGCAcCgaGSEKmEKFgTKEgJCERiJAiw4ABqNORPWCKLBSMKRSE7PQB9oAwuuNR3BqMKRSEGvID53gA5GspyQ9EElMAAAAASUVORK5CYII=");
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-format-button.ql-center.ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-center .ql-picker-label.ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-label[data-value=center].ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-item[data-value=center].ql-selected,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-format-button.ql-center:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker.ql-center .ql-picker-label:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker .ql-picker-label[data-value=center]:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker .ql-picker-item[data-value=center]:hover {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkBAMAAAATLoWrAAAAElBMVEUAAAAAZ8oAZswAZswAZswAZsxixJGvAAAABXRSTlMATeXo6UtNtyIAAABCSURBVCjPY2AYGCAcCgaGSEKmEKFgTKEgJCERiJAiw4ABqNORPWCKLBSMKRSE7PQB9oAwuuNR3BqMKRSEGvID53gA5GspyQ9EElMAAAAASUVORK5CYII=");
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-format-button.ql-justify,
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-justify .ql-picker-label,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-label[data-value=justify],
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-item[data-value=justify] {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkBAMAAAATLoWrAAAAElBMVEUAAABCQkJEREREREREREREREQc4xmxAAAABXRSTlMATeXo6UtNtyIAAAAoSURBVCjPY2AYACAcigQMwUKmyELBmEJBYCERZCFFhoEBo64fINcDAAcQNGkJNhVcAAAAAElFTkSuQmCC");
|
||||
}
|
||||
.ql-snow.ql-toolbar .ql-format-button.ql-justify.ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker.ql-justify .ql-picker-label.ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-label[data-value=justify].ql-active,
|
||||
.ql-snow.ql-toolbar .ql-picker .ql-picker-item[data-value=justify].ql-selected,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-format-button.ql-justify:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker.ql-justify .ql-picker-label:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker .ql-picker-label[data-value=justify]:hover,
|
||||
.ql-snow.ql-toolbar:not(.ios) .ql-picker .ql-picker-item[data-value=justify]:hover {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkBAMAAAATLoWrAAAAElBMVEUAAAAAZ8oAZswAZswAZswAZsxixJGvAAAABXRSTlMATeXo6UtNtyIAAAAoSURBVCjPY2AYACAcigQMwUKmyELBmEJBYCERZCFFhoEBo64fINcDAAcQNGkJNhVcAAAAAElFTkSuQmCC");
|
||||
}
|
||||
}
|
||||
.ql-snow .ql-tooltip {
|
||||
border: 1px solid #ccc;
|
||||
box-shadow: 0px 0px 5px #ddd;
|
||||
color: #222;
|
||||
}
|
||||
.ql-snow .ql-tooltip a {
|
||||
color: #06c;
|
||||
}
|
||||
.ql-snow .ql-tooltip .input {
|
||||
border: 1px solid #ccc;
|
||||
margin: 0px;
|
||||
padding: 5px;
|
||||
}
|
||||
.ql-snow a {
|
||||
color: #06c;
|
||||
}
|
50
Examples/bower_components/quill/docs/style-guide.md
vendored
Normal file
50
Examples/bower_components/quill/docs/style-guide.md
vendored
Normal file
@ -0,0 +1,50 @@
|
||||
# Style Guide
|
||||
|
||||
Code style is very subjective but consistency is very important for a healthy codebase. Quill strives to follow good programming practices and the language specific guidelines so those will not be reproduced here. However some less obvious guidelines are listed below.
|
||||
|
||||
If there is ever uncertainty, please look at other parts of the codebase and mimic that style.
|
||||
|
||||
|
||||
### General
|
||||
|
||||
- Use two spaces for tabs
|
||||
- No trailing whitespace on any lines
|
||||
|
||||
|
||||
### Operators
|
||||
|
||||
- Always use parenthesis for function calls
|
||||
- Use brackets for one line object definitions
|
||||
|
||||
```coffeescript
|
||||
console.log('Yes') # Yes
|
||||
console.log 'No' # No
|
||||
|
||||
config = { attack: 10, defense: 10 } # Yes
|
||||
config = attack: 10, defense: 10 # No
|
||||
|
||||
# Okay
|
||||
config =
|
||||
attack: 10
|
||||
defense: 10
|
||||
```
|
||||
|
||||
|
||||
### Classes
|
||||
|
||||
- Use an explicit `this` when referencing methods
|
||||
- Use `@` when referencing instance variables
|
||||
|
||||
```coffeescript
|
||||
class Tower
|
||||
@constructor: (strength, toughness) ->
|
||||
@strength = strength # Yes
|
||||
this.toughness = toughness # No
|
||||
|
||||
this.attack() # Yes
|
||||
@defend() # No
|
||||
|
||||
attack: ->
|
||||
|
||||
defend: ->
|
||||
```
|
15
Examples/bower_components/y-array/.bower.json
vendored
Normal file
15
Examples/bower_components/y-array/.bower.json
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
"name": "y-array",
|
||||
"homepage": "https://github.com/y-js/y-array",
|
||||
"version": "0.7.5",
|
||||
"_release": "0.7.5",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "v0.7.5",
|
||||
"commit": "616d21127c3aece7c1c3619b9f7ffe2f20f03f23"
|
||||
},
|
||||
"_source": "git://github.com/y-js/y-array.git",
|
||||
"_target": "~0.7.5",
|
||||
"_originalSource": "y-array",
|
||||
"_direct": true
|
||||
}
|
3
Examples/bower_components/y-array/.bowerrc
vendored
Normal file
3
Examples/bower_components/y-array/.bowerrc
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"directory": "../"
|
||||
}
|
6
Examples/bower_components/y-array/.gitignore
vendored
Normal file
6
Examples/bower_components/y-array/.gitignore
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
/node_modules/
|
||||
bower_components
|
||||
.directory
|
||||
.c9
|
||||
.codio
|
||||
.settings
|
11
Examples/bower_components/y-array/.travis.yml
vendored
Normal file
11
Examples/bower_components/y-array/.travis.yml
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
language: node_js
|
||||
before_install:
|
||||
- "npm install -g bower coffee-script"
|
||||
- "bower install"
|
||||
node_js:
|
||||
- "0.12"
|
||||
- "0.11"
|
||||
- "0.10"
|
||||
branches:
|
||||
only:
|
||||
- master
|
92
Examples/bower_components/y-array/README.md
vendored
Normal file
92
Examples/bower_components/y-array/README.md
vendored
Normal file
@ -0,0 +1,92 @@
|
||||
|
||||
# List Type for [Yjs](https://github.com/y-js/yjs)
|
||||
|
||||
Manage list-like data with this shareable list type. You can insert and delete arbitrary objects (also custom types for Yjs) in the list type.
|
||||
|
||||
## Use it!
|
||||
Retrieve this with bower or npm.
|
||||
|
||||
##### Bower
|
||||
```
|
||||
bower install y-list --save
|
||||
```
|
||||
|
||||
and include the js library.
|
||||
|
||||
```
|
||||
<script src="./bower_components/y-list/y-list.js"></script>
|
||||
```
|
||||
|
||||
##### NPM
|
||||
```
|
||||
npm install y-list --save
|
||||
```
|
||||
and put it on the `Y` object.
|
||||
|
||||
```
|
||||
Y.List = require("y-list");
|
||||
```
|
||||
|
||||
|
||||
### List Object
|
||||
|
||||
##### Reference
|
||||
* Create
|
||||
```
|
||||
var ylist = new Y.List()
|
||||
```
|
||||
* .insert(position, content)
|
||||
* Insert content at a position
|
||||
* .insertContents(position, contents)
|
||||
* Insert a set of content at a position. This expects that contents is an array of content.
|
||||
* .push(content)
|
||||
* Insert content at the end of the list
|
||||
* .delete(position, length)
|
||||
* Delete content. The *length* parameter is optional and defaults to 1
|
||||
* .val()
|
||||
* Retrieve all content as an Array Object
|
||||
* .val(position)
|
||||
* Retrieve content from a position
|
||||
* .ref(position)
|
||||
* Retrieve a reference to the element on a *position*.
|
||||
* You can call `ref.getNext()` and `ref.getPrev()` to get the next/previous reference
|
||||
* You can call `ref.getNext(i)` and `ref.getPrev(i)` to get the i-th next/previous reference
|
||||
* You can call `ref.val()` to get the element, to which the reference points (`y.ref(1).val() === y.val(1)`)
|
||||
* .observe(f)
|
||||
* The observer is called whenever something on this list changed. (throws insert, and delete events)
|
||||
* .unobserve(f)
|
||||
* Delete an observer
|
||||
|
||||
|
||||
# A note on intention preservation
|
||||
If two users insert something at the same position concurrently, the content that was inserted by the user with the higher user-id will be to the right of the other content. In the OT world we often speak of *intention preservation*, which is very loosely defined in most cases. This type has the following notion of intention preservation: When a user inserts content *c* after a set of content *C_left*, and before a set of content *C_right*, then *C_left* will be always to the left of c, and *C_right* will be always to the right of *c*. This property will also hold when content is deleted or when a deletion is undone.
|
||||
|
||||
# A note on time complexities
|
||||
* .insert(position, content)
|
||||
* O(position)
|
||||
* .insertContents(position, contents)
|
||||
* O(position + |contents|)
|
||||
* .push(content)
|
||||
* O(1)
|
||||
* .delete(position, length)
|
||||
* O(position)
|
||||
* .val()
|
||||
* O(|ylist|)
|
||||
* .val(position)
|
||||
* O(position|)
|
||||
* Apply a delete operation from another user
|
||||
* O(1)
|
||||
* Apply an insert operation from another user
|
||||
* Yjs does not transform against operations that do not conflict with each other.
|
||||
* An operation conflicts with another operation if it intends to be inserted at the same position.
|
||||
* Overall worst case complexety: O(|conflicts|!)
|
||||
|
||||
|
||||
# Issues
|
||||
* Support moving of objects
|
||||
* Create a polymer element
|
||||
|
||||
## License
|
||||
Yjs is licensed under the [MIT License](./LICENSE.txt).
|
||||
|
||||
<kevin.jahns@rwth-aachen.de>
|
197
Examples/bower_components/y-array/y-array.es6
vendored
Normal file
197
Examples/bower_components/y-array/y-array.es6
vendored
Normal file
@ -0,0 +1,197 @@
|
||||
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
|
||||
/* global Y */
|
||||
'use strict'
|
||||
|
||||
function extend (Y) {
|
||||
class YArray {
|
||||
constructor (os, _model, idArray, valArray) {
|
||||
this.os = os
|
||||
this._model = _model
|
||||
// Array of all the operation id's
|
||||
this.idArray = idArray
|
||||
// Array of all the values
|
||||
this.valArray = valArray
|
||||
this.eventHandler = new Y.utils.EventHandler(ops => {
|
||||
var userEvents = []
|
||||
for (var i in ops) {
|
||||
var op = ops[i]
|
||||
if (op.struct === 'Insert') {
|
||||
let pos
|
||||
// we check op.left only!,
|
||||
// because op.right might not be defined when this is called
|
||||
if (op.left === null) {
|
||||
pos = 0
|
||||
} else {
|
||||
var sid = JSON.stringify(op.left)
|
||||
pos = this.idArray.indexOf(sid) + 1
|
||||
if (pos <= 0) {
|
||||
throw new Error('Unexpected operation!')
|
||||
}
|
||||
}
|
||||
this.idArray.splice(pos, 0, JSON.stringify(op.id))
|
||||
this.valArray.splice(pos, 0, op.content)
|
||||
userEvents.push({
|
||||
type: 'insert',
|
||||
object: this,
|
||||
index: pos,
|
||||
value: op.content,
|
||||
length: 1
|
||||
})
|
||||
} else if (op.struct === 'Delete') {
|
||||
let pos = this.idArray.indexOf(JSON.stringify(op.target))
|
||||
if (pos >= 0) {
|
||||
var val = this.valArray[pos]
|
||||
this.idArray.splice(pos, 1)
|
||||
this.valArray.splice(pos, 1)
|
||||
userEvents.push({
|
||||
type: 'delete',
|
||||
object: this,
|
||||
index: pos,
|
||||
value: val,
|
||||
length: 1
|
||||
})
|
||||
}
|
||||
} else {
|
||||
throw new Error('Unexpected struct!')
|
||||
}
|
||||
}
|
||||
this.eventHandler.callEventListeners(userEvents)
|
||||
})
|
||||
}
|
||||
get length () {
|
||||
return this.idArray.length
|
||||
}
|
||||
get (pos) {
|
||||
if (pos == null || typeof pos !== 'number') {
|
||||
throw new Error('pos must be a number!')
|
||||
}
|
||||
return this.valArray[pos]
|
||||
}
|
||||
toArray () {
|
||||
return this.valArray.slice()
|
||||
}
|
||||
push (contents) {
|
||||
this.insert(this.idArray.length, contents)
|
||||
}
|
||||
insert (pos, contents) {
|
||||
if (typeof pos !== 'number') {
|
||||
throw new Error('pos must be a number!')
|
||||
}
|
||||
if (!(contents instanceof Array)) {
|
||||
throw new Error('contents must be an Array of objects!')
|
||||
}
|
||||
if (contents.length === 0) {
|
||||
return
|
||||
}
|
||||
if (pos > this.idArray.length || pos < 0) {
|
||||
throw new Error('This position exceeds the range of the array!')
|
||||
}
|
||||
var mostLeft = pos === 0 ? null : JSON.parse(this.idArray[pos - 1])
|
||||
|
||||
var ops = []
|
||||
var prevId = mostLeft
|
||||
for (var i = 0; i < contents.length; i++) {
|
||||
var op = {
|
||||
left: prevId,
|
||||
origin: prevId,
|
||||
// right: mostRight,
|
||||
// NOTE: I intentionally do not define right here, because it could be deleted
|
||||
// at the time of creating this operation, and is therefore not defined in idArray
|
||||
parent: this._model,
|
||||
content: contents[i],
|
||||
struct: 'Insert',
|
||||
id: this.os.getNextOpId()
|
||||
}
|
||||
ops.push(op)
|
||||
prevId = op.id
|
||||
}
|
||||
var eventHandler = this.eventHandler
|
||||
eventHandler.awaitAndPrematurelyCall(ops)
|
||||
this.os.requestTransaction(function *() {
|
||||
// now we can set the right reference.
|
||||
var mostRight
|
||||
if (mostLeft != null) {
|
||||
mostRight = (yield* this.getOperation(mostLeft)).right
|
||||
} else {
|
||||
mostRight = (yield* this.getOperation(ops[0].parent)).start
|
||||
}
|
||||
for (var j in ops) {
|
||||
ops[j].right = mostRight
|
||||
}
|
||||
yield* this.applyCreatedOperations(ops)
|
||||
eventHandler.awaitedInserts(ops.length)
|
||||
})
|
||||
}
|
||||
delete (pos, length) {
|
||||
if (length == null) { length = 1 }
|
||||
if (typeof length !== 'number') {
|
||||
throw new Error('pos must be a number!')
|
||||
}
|
||||
if (typeof pos !== 'number') {
|
||||
throw new Error('pos must be a number!')
|
||||
}
|
||||
if (pos + length > this.idArray.length || pos < 0 || length < 0) {
|
||||
throw new Error('The deletion range exceeds the range of the array!')
|
||||
}
|
||||
if (length === 0) {
|
||||
return
|
||||
}
|
||||
var eventHandler = this.eventHandler
|
||||
var newLeft = pos > 0 ? JSON.parse(this.idArray[pos - 1]) : null
|
||||
var dels = []
|
||||
for (var i = 0; i < length; i++) {
|
||||
dels.push({
|
||||
target: JSON.parse(this.idArray[pos + i]),
|
||||
struct: 'Delete'
|
||||
})
|
||||
}
|
||||
eventHandler.awaitAndPrematurelyCall(dels)
|
||||
this.os.requestTransaction(function *() {
|
||||
yield* this.applyCreatedOperations(dels)
|
||||
eventHandler.awaitedDeletes(dels.length, newLeft)
|
||||
})
|
||||
}
|
||||
observe (f) {
|
||||
this.eventHandler.addEventListener(f)
|
||||
}
|
||||
* _changed (transaction, op) {
|
||||
if (!op.deleted) {
|
||||
if (op.struct === 'Insert') {
|
||||
var l = op.left
|
||||
var left
|
||||
while (l != null) {
|
||||
left = yield* transaction.getOperation(l)
|
||||
if (!left.deleted) {
|
||||
break
|
||||
}
|
||||
l = left.left
|
||||
}
|
||||
op.left = l
|
||||
}
|
||||
this.eventHandler.receivedOp(op)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Y.extend('Array', new Y.utils.CustomType({
|
||||
name: 'Array', // TODO: copy the name when extending the object.. (see one line above)
|
||||
class: YArray,
|
||||
struct: 'List',
|
||||
initType: function * YArrayInitializer (os, model) {
|
||||
var valArray = []
|
||||
var idArray = yield* Y.Struct.List.map.call(this, model, function (c) {
|
||||
valArray.push(c.content)
|
||||
return JSON.stringify(c.id)
|
||||
})
|
||||
return new YArray(os, model.id, idArray, valArray)
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
||||
module.exports = extend
|
||||
if (typeof Y !== 'undefined') {
|
||||
extend(Y)
|
||||
}
|
||||
|
||||
},{}]},{},[1])
|
||||
|
1
Examples/bower_components/y-array/y-array.es6.map
vendored
Normal file
1
Examples/bower_components/y-array/y-array.es6.map
vendored
Normal file
File diff suppressed because one or more lines are too long
2
Examples/bower_components/y-array/y-array.js
vendored
Normal file
2
Examples/bower_components/y-array/y-array.js
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
!function e(r,t,n){function a(s,o){if(!t[s]){if(!r[s]){var u="function"==typeof require&&require;if(!o&&u)return u(s,!0);if(i)return i(s,!0);var l=new Error("Cannot find module '"+s+"'");throw l.code="MODULE_NOT_FOUND",l}var c=t[s]={exports:{}};r[s][0].call(c.exports,function(e){var t=r[s][1][e];return a(t?t:e)},c,c.exports,e,r,t,n)}return t[s].exports}for(var i="function"==typeof require&&require,s=0;s<n.length;s++)a(n[s]);return a}({1:[function(e,r,t){"use strict";function n(e,r){if(!(e instanceof r))throw new TypeError("Cannot call a class as a function")}function a(e){var r=function(){function r(t,a,i,s){var o=this;n(this,r),this.os=t,this._model=a,this.idArray=i,this.valArray=s,this.eventHandler=new e.utils.EventHandler(function(e){var r=[];for(var t in e){var n=e[t];if("Insert"===n.struct){var a=void 0;if(null===n.left)a=0;else{var i=JSON.stringify(n.left);if(a=o.idArray.indexOf(i)+1,0>=a)throw new Error("Unexpected operation!")}o.idArray.splice(a,0,JSON.stringify(n.id)),o.valArray.splice(a,0,n.content),r.push({type:"insert",object:o,index:a,value:n.content,length:1})}else{if("Delete"!==n.struct)throw new Error("Unexpected struct!");var a=o.idArray.indexOf(JSON.stringify(n.target));if(a>=0){var s=o.valArray[a];o.idArray.splice(a,1),o.valArray.splice(a,1),r.push({type:"delete",object:o,index:a,value:s,length:1})}}}o.eventHandler.callEventListeners(r)})}return i(r,[{key:"get",value:function(e){if(null==e||"number"!=typeof e)throw new Error("pos must be a number!");return this.valArray[e]}},{key:"toArray",value:function(){return this.valArray.slice()}},{key:"push",value:function(e){this.insert(this.idArray.length,e)}},{key:"insert",value:function(e,r){if("number"!=typeof e)throw new Error("pos must be a number!");if(!(r instanceof Array))throw new Error("contents must be an Array of objects!");if(0!==r.length){if(e>this.idArray.length||0>e)throw new Error("This position exceeds the range of the array!");for(var t=0===e?null:JSON.parse(this.idArray[e-1]),n=[],a=t,i=0;i<r.length;i++){var s={left:a,origin:a,parent:this._model,content:r[i],struct:"Insert",id:this.os.getNextOpId()};n.push(s),a=s.id}var o=this.eventHandler;o.awaitAndPrematurelyCall(n),this.os.requestTransaction(regeneratorRuntime.mark(function u(){var e,r;return regeneratorRuntime.wrap(function(a){for(;;)switch(a.prev=a.next){case 0:if(null==t){a.next=5;break}return a.delegateYield(this.getOperation(t),"t0",2);case 2:e=a.t0.right,a.next=7;break;case 5:return a.delegateYield(this.getOperation(n[0].parent),"t1",6);case 6:e=a.t1.start;case 7:for(r in n)n[r].right=e;return a.delegateYield(this.applyCreatedOperations(n),"t2",9);case 9:o.awaitedInserts(n.length);case 10:case"end":return a.stop()}},u,this)}))}}},{key:"delete",value:function(e,r){if(null==r&&(r=1),"number"!=typeof r)throw new Error("pos must be a number!");if("number"!=typeof e)throw new Error("pos must be a number!");if(e+r>this.idArray.length||0>e||0>r)throw new Error("The deletion range exceeds the range of the array!");if(0!==r){for(var t=this.eventHandler,n=e>0?JSON.parse(this.idArray[e-1]):null,a=[],i=0;r>i;i++)a.push({target:JSON.parse(this.idArray[e+i]),struct:"Delete"});t.awaitAndPrematurelyCall(a),this.os.requestTransaction(regeneratorRuntime.mark(function s(){return regeneratorRuntime.wrap(function(e){for(;;)switch(e.prev=e.next){case 0:return e.delegateYield(this.applyCreatedOperations(a),"t0",1);case 1:t.awaitedDeletes(a.length,n);case 2:case"end":return e.stop()}},s,this)}))}}},{key:"observe",value:function(e){this.eventHandler.addEventListener(e)}},{key:"_changed",value:regeneratorRuntime.mark(function t(e,r){var n,a;return regeneratorRuntime.wrap(function(t){for(;;)switch(t.prev=t.next){case 0:if(r.deleted){t.next=13;break}if("Insert"!==r.struct){t.next=12;break}n=r.left;case 3:if(null==n){t.next=11;break}return t.delegateYield(e.getOperation(n),"t0",5);case 5:if(a=t.t0,a.deleted){t.next=8;break}return t.abrupt("break",11);case 8:n=a.left,t.next=3;break;case 11:r.left=n;case 12:this.eventHandler.receivedOp(r);case 13:case"end":return t.stop()}},t,this)})},{key:"length",get:function(){return this.idArray.length}}]),r}();e.extend("Array",new e.utils.CustomType({name:"Array","class":r,struct:"List",initType:regeneratorRuntime.mark(function t(n,a){var i,s;return regeneratorRuntime.wrap(function(t){for(;;)switch(t.prev=t.next){case 0:return i=[],t.delegateYield(e.Struct.List.map.call(this,a,function(e){return i.push(e.content),JSON.stringify(e.id)}),"t0",2);case 2:return s=t.t0,t.abrupt("return",new r(n,a.id,s,i));case 4:case"end":return t.stop()}},t,this)})}))}var i=function(){function e(e,r){for(var t=0;t<r.length;t++){var n=r[t];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}return function(r,t,n){return t&&e(r.prototype,t),n&&e(r,n),r}}();r.exports=a,"undefined"!=typeof Y&&a(Y)},{}]},{},[1]);
|
||||
//# sourceMappingURL=y-array.js.map
|
1
Examples/bower_components/y-array/y-array.js.map
vendored
Normal file
1
Examples/bower_components/y-array/y-array.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
37
Examples/bower_components/y-indexeddb/.bower.json
vendored
Normal file
37
Examples/bower_components/y-indexeddb/.bower.json
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
{
|
||||
"name": "y-indexeddb",
|
||||
"main": "y-indexeddb.js",
|
||||
"version": "0.7.1",
|
||||
"homepage": "http://y-js.org",
|
||||
"authors": [
|
||||
"Kevin Jahns <kevin.jahns@rwth-aachen.de>"
|
||||
],
|
||||
"description": "IndexedDB database adapter for Yjs",
|
||||
"moduleType": [
|
||||
"globals",
|
||||
"node"
|
||||
],
|
||||
"keywords": [
|
||||
"Yjs",
|
||||
"connector",
|
||||
"webrtc"
|
||||
],
|
||||
"license": "MIT",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"test",
|
||||
"tests"
|
||||
],
|
||||
"_release": "0.7.1",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "v0.7.1",
|
||||
"commit": "f84233467fbf2f15a0bb74f34902d33f2790b9e3"
|
||||
},
|
||||
"_source": "git://github.com/y-js/y-indexeddb.git",
|
||||
"_target": "~0.7.1",
|
||||
"_originalSource": "y-indexeddb",
|
||||
"_direct": true
|
||||
}
|
23
Examples/bower_components/y-indexeddb/LICENSE
vendored
Normal file
23
Examples/bower_components/y-indexeddb/LICENSE
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014
|
||||
- Kevin Jahns <kevin.jahns@rwth-aachen.de>.
|
||||
- Chair of Computer Science 5 (Databases & Information Systems), RWTH Aachen University, Germany
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
1
Examples/bower_components/y-indexeddb/README.md
vendored
Normal file
1
Examples/bower_components/y-indexeddb/README.md
vendored
Normal file
@ -0,0 +1 @@
|
||||
# IndexedDB database adapter for Yjs
|
27
Examples/bower_components/y-indexeddb/bower.json
vendored
Normal file
27
Examples/bower_components/y-indexeddb/bower.json
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
{
|
||||
"name": "y-indexeddb",
|
||||
"main": "y-indexeddb.js",
|
||||
"version": "0.7.1",
|
||||
"homepage": "http://y-js.org",
|
||||
"authors": [
|
||||
"Kevin Jahns <kevin.jahns@rwth-aachen.de>"
|
||||
],
|
||||
"description": "IndexedDB database adapter for Yjs",
|
||||
"moduleType": [
|
||||
"globals",
|
||||
"node"
|
||||
],
|
||||
"keywords": [
|
||||
"Yjs",
|
||||
"connector",
|
||||
"webrtc"
|
||||
],
|
||||
"license": "MIT",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"test",
|
||||
"tests"
|
||||
]
|
||||
}
|
189
Examples/bower_components/y-indexeddb/y-indexeddb.es6
vendored
Normal file
189
Examples/bower_components/y-indexeddb/y-indexeddb.es6
vendored
Normal file
@ -0,0 +1,189 @@
|
||||
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
|
||||
/* global Y */
|
||||
'use strict'
|
||||
|
||||
function extend (Y) {
|
||||
class Store {
|
||||
constructor (transaction, name) {
|
||||
this.store = transaction.objectStore(name)
|
||||
}
|
||||
* find (id) {
|
||||
return yield this.store.get(id)
|
||||
}
|
||||
* put (v) {
|
||||
yield this.store.put(v)
|
||||
}
|
||||
* delete (id) {
|
||||
yield this.store.delete(id)
|
||||
}
|
||||
* findWithLowerBound (start) {
|
||||
return yield this.store.openCursor(window.IDBKeyRange.lowerBound(start))
|
||||
}
|
||||
* findWithUpperBound (end) {
|
||||
return yield this.store.openCursor(window.IDBKeyRange.upperBound(end), 'prev')
|
||||
}
|
||||
* findNext (id) {
|
||||
return yield* this.findWithLowerBound([id[0], id[1] + 1])
|
||||
}
|
||||
* findPrev (id) {
|
||||
return yield* this.findWithUpperBound([id[0], id[1] - 1])
|
||||
}
|
||||
* iterate (t, start, end, gen) {
|
||||
var range = null
|
||||
if (start != null && end != null) {
|
||||
range = window.IDBKeyRange.bound(start, end)
|
||||
} else if (start != null) {
|
||||
range = window.IDBKeyRange.lowerBound(start)
|
||||
} else if (end != null) {
|
||||
range = window.IDBKeyRange.upperBound(end)
|
||||
}
|
||||
var cursorResult = this.store.openCursor(range)
|
||||
while ((yield cursorResult) != null) {
|
||||
yield* gen.call(t, cursorResult.result.value)
|
||||
cursorResult.result.continue()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
class Transaction extends Y.Transaction {
|
||||
constructor (store) {
|
||||
super(store)
|
||||
var transaction = store.db.transaction(['OperationStore', 'StateStore', 'DeleteStore'], 'readwrite')
|
||||
this.store = store
|
||||
this.ss = new Store(transaction, 'StateStore')
|
||||
this.os = new Store(transaction, 'OperationStore')
|
||||
this.ds = new Store(transaction, 'DeleteStore')
|
||||
}
|
||||
}
|
||||
class OperationStore extends Y.AbstractDatabase {
|
||||
constructor (y, opts) {
|
||||
super(y, opts)
|
||||
if (opts == null) {
|
||||
opts = {}
|
||||
}
|
||||
if (opts.namespace == null || typeof opts.namespace !== 'string') {
|
||||
throw new Error('IndexedDB: expect a string (opts.namespace)!')
|
||||
} else {
|
||||
this.namespace = opts.namespace
|
||||
}
|
||||
if (opts.idbVersion != null) {
|
||||
this.idbVersion = opts.idbVersion
|
||||
} else {
|
||||
this.idbVersion = 5
|
||||
}
|
||||
var store = this
|
||||
// initialize database!
|
||||
this.requestTransaction(function * () {
|
||||
store.db = yield window.indexedDB.open(opts.namespace, store.idbVersion)
|
||||
})
|
||||
if (opts.cleanStart) {
|
||||
this.requestTransaction(function * () {
|
||||
yield this.os.store.clear()
|
||||
yield this.ds.store.clear()
|
||||
yield this.ss.store.clear()
|
||||
})
|
||||
}
|
||||
var operationsToAdd = []
|
||||
window.addEventListener('storage', function (event) {
|
||||
if (event.key === '__YJS__' + store.namespace) {
|
||||
operationsToAdd.push(event.newValue)
|
||||
if (operationsToAdd.length === 1) {
|
||||
store.requestTransaction(function * () {
|
||||
var add = operationsToAdd
|
||||
operationsToAdd = []
|
||||
for (var i in add) {
|
||||
// don't call the localStorage event twice..
|
||||
var op = JSON.parse(add[i])
|
||||
if (op.struct !== 'Delete') {
|
||||
op = yield* this.getOperation(op.id)
|
||||
}
|
||||
yield* this.store.operationAdded(this, op, true)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}, false)
|
||||
}
|
||||
* operationAdded (transaction, op, noAdd) {
|
||||
yield* super.operationAdded(transaction, op)
|
||||
if (!noAdd) {
|
||||
window.localStorage['__YJS__' + this.namespace] = JSON.stringify(op)
|
||||
}
|
||||
}
|
||||
transact (makeGen) {
|
||||
var transaction = this.db != null ? new Transaction(this) : null
|
||||
var store = this
|
||||
|
||||
var gen = makeGen.call(transaction)
|
||||
handleTransactions(gen.next())
|
||||
|
||||
function handleTransactions (result) {
|
||||
var request = result.value
|
||||
if (result.done) {
|
||||
makeGen = store.getNextRequest()
|
||||
if (makeGen != null) {
|
||||
if (transaction == null && store.db != null) {
|
||||
transaction = new Transaction(store)
|
||||
}
|
||||
gen = makeGen.call(transaction)
|
||||
handleTransactions(gen.next())
|
||||
} // else no transaction in progress!
|
||||
return
|
||||
}
|
||||
if (request.constructor === window.IDBRequest) {
|
||||
request.onsuccess = function () {
|
||||
var res = request.result
|
||||
if (res != null && res.constructor === window.IDBCursorWithValue) {
|
||||
res = res.value
|
||||
}
|
||||
handleTransactions(gen.next(res))
|
||||
}
|
||||
request.onerror = function (err) {
|
||||
gen.throw(err)
|
||||
}
|
||||
} else if (request.constructor === window.IDBCursor) {
|
||||
request.onsuccess = function () {
|
||||
handleTransactions(gen.next(request.result != null ? request.result.value : null))
|
||||
}
|
||||
request.onerror = function (err) {
|
||||
gen.throw(err)
|
||||
}
|
||||
} else if (request.constructor === window.IDBOpenDBRequest) {
|
||||
request.onsuccess = function (event) {
|
||||
var db = event.target.result
|
||||
handleTransactions(gen.next(db))
|
||||
}
|
||||
request.onerror = function () {
|
||||
gen.throw("Couldn't open IndexedDB database!")
|
||||
}
|
||||
request.onupgradeneeded = function (event) {
|
||||
var db = event.target.result
|
||||
try {
|
||||
db.createObjectStore('OperationStore', {keyPath: 'id'})
|
||||
db.createObjectStore('DeleteStore', {keyPath: 'id'})
|
||||
db.createObjectStore('StateStore', {keyPath: 'id'})
|
||||
} catch (e) {
|
||||
console.log('Store already exists!')
|
||||
}
|
||||
}
|
||||
} else {
|
||||
gen.throw('You must not yield this type!')
|
||||
}
|
||||
}
|
||||
}
|
||||
// TODO: implement "free"..
|
||||
* destroy () {
|
||||
this.db.close()
|
||||
yield window.indexedDB.deleteDatabase(this.namespace)
|
||||
}
|
||||
}
|
||||
Y.extend('indexeddb', OperationStore)
|
||||
}
|
||||
|
||||
module.exports = extend
|
||||
if (typeof Y !== 'undefined') {
|
||||
extend(Y)
|
||||
}
|
||||
|
||||
},{}]},{},[1])
|
||||
|
1
Examples/bower_components/y-indexeddb/y-indexeddb.es6.map
vendored
Normal file
1
Examples/bower_components/y-indexeddb/y-indexeddb.es6.map
vendored
Normal file
File diff suppressed because one or more lines are too long
2
Examples/bower_components/y-indexeddb/y-indexeddb.js
vendored
Normal file
2
Examples/bower_components/y-indexeddb/y-indexeddb.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
Examples/bower_components/y-indexeddb/y-indexeddb.js.map
vendored
Normal file
1
Examples/bower_components/y-indexeddb/y-indexeddb.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
39
Examples/bower_components/y-map/.bower.json
vendored
Normal file
39
Examples/bower_components/y-map/.bower.json
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
{
|
||||
"name": "y-map",
|
||||
"version": "0.7.2",
|
||||
"homepage": "http://y-js.org",
|
||||
"authors": [
|
||||
"Kevin Jahns <kevin.jahns@rwth-aachen.de>"
|
||||
],
|
||||
"description": "Map type for Yjs",
|
||||
"main": [
|
||||
"./y-list.js",
|
||||
"./build/node/y-list.js"
|
||||
],
|
||||
"keywords": [
|
||||
"OT",
|
||||
"collaboration",
|
||||
"synchronization",
|
||||
"ShareJS",
|
||||
"Coweb",
|
||||
"concurrency"
|
||||
],
|
||||
"license": "MIT",
|
||||
"ignore": [
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"test",
|
||||
"extras",
|
||||
"test"
|
||||
],
|
||||
"_release": "0.7.2",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "v0.7.2",
|
||||
"commit": "1d85b5890ce8d76a37c5f8ad2587ca8ec7e82cbc"
|
||||
},
|
||||
"_source": "git://github.com/y-js/y-map.git",
|
||||
"_target": "~0.7.2",
|
||||
"_originalSource": "y-map",
|
||||
"_direct": true
|
||||
}
|
0
Examples/bower_components/y-map/README.md
vendored
Normal file
0
Examples/bower_components/y-map/README.md
vendored
Normal file
29
Examples/bower_components/y-map/bower.json
vendored
Normal file
29
Examples/bower_components/y-map/bower.json
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
{
|
||||
"name": "y-map",
|
||||
"version": "0.7.3",
|
||||
"homepage": "http://y-js.org",
|
||||
"authors": [
|
||||
"Kevin Jahns <kevin.jahns@rwth-aachen.de>"
|
||||
],
|
||||
"description": "Map type for Yjs",
|
||||
"main": [
|
||||
"./y-list.js",
|
||||
"./build/node/y-list.js"
|
||||
],
|
||||
"keywords": [
|
||||
"OT",
|
||||
"collaboration",
|
||||
"synchronization",
|
||||
"ShareJS",
|
||||
"Coweb",
|
||||
"concurrency"
|
||||
],
|
||||
"license": "MIT",
|
||||
"ignore": [
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"test",
|
||||
"extras",
|
||||
"test"
|
||||
]
|
||||
}
|
56
Examples/bower_components/y-map/package.json
vendored
Normal file
56
Examples/bower_components/y-map/package.json
vendored
Normal file
@ -0,0 +1,56 @@
|
||||
{
|
||||
"name": "map",
|
||||
"version": "0.7.3",
|
||||
"description": "Map Type for Yjs",
|
||||
"main": "./src/Map.js",
|
||||
"scripts": {
|
||||
"test": "node --harmony ./node_modules/.bin/gulp test",
|
||||
"lint": "./node_modules/.bin/standard"
|
||||
},
|
||||
"pre-commit": [
|
||||
"lint",
|
||||
"test"
|
||||
],
|
||||
"standard": {
|
||||
"parser": "babel-eslint",
|
||||
"ignore": [
|
||||
"build/**",
|
||||
"dist/**",
|
||||
"./y.js",
|
||||
"./y.js.map"
|
||||
]
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/y-js/map"
|
||||
},
|
||||
"keywords": [
|
||||
"Yjs",
|
||||
"OT",
|
||||
"List",
|
||||
"Array",
|
||||
"collaboration",
|
||||
"synchronization",
|
||||
"ShareJs",
|
||||
"Coweb",
|
||||
"concurrency"
|
||||
],
|
||||
"author": "Kevin Jahns <kevin.jahns@rwth-aachen.de>",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/y-js/yjs/issues"
|
||||
},
|
||||
"homepage": "http://y-js.org",
|
||||
"devDependencies": {
|
||||
"babel-eslint": "^4.1.4",
|
||||
"babel-plugin-transform-runtime": "^6.1.18",
|
||||
"babel-preset-es2015": "^6.1.18",
|
||||
"babelify": "^7.2.0",
|
||||
"gulp": "^3.9.0",
|
||||
"gulp-load-plugins": "^1.1.0",
|
||||
"gulp-prompt": "^0.1.2",
|
||||
"pre-commit": "^1.1.2",
|
||||
"run-sequence": "^1.1.4",
|
||||
"standard": "^5.3.1"
|
||||
}
|
||||
}
|
315
Examples/bower_components/y-map/y-map.es6
vendored
Normal file
315
Examples/bower_components/y-map/y-map.es6
vendored
Normal file
@ -0,0 +1,315 @@
|
||||
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
|
||||
/* global Y */
|
||||
'use strict'
|
||||
|
||||
function extend (Y /* :any */) {
|
||||
class YMap {
|
||||
/* ::
|
||||
_model: Id;
|
||||
os: Y.AbstractDatabase;
|
||||
map: Object;
|
||||
contents: any;
|
||||
opContents: Object;
|
||||
eventHandler: Function;
|
||||
*/
|
||||
constructor (os, model, contents, opContents) {
|
||||
this._model = model.id
|
||||
this.os = os
|
||||
this.map = Y.utils.copyObject(model.map)
|
||||
this.contents = contents
|
||||
this.opContents = opContents
|
||||
this.eventHandler = new Y.utils.EventHandler(ops => {
|
||||
var userEvents = []
|
||||
for (var i in ops) {
|
||||
var op = ops[i]
|
||||
var oldValue
|
||||
// key is the name to use to access (op)content
|
||||
var key = op.struct === 'Delete' ? op.key : op.parentSub
|
||||
|
||||
// compute oldValue
|
||||
if (this.opContents[key] != null) {
|
||||
let prevType = this.opContents[key]
|
||||
oldValue = () => {// eslint-disable-line
|
||||
return new Promise((resolve) => {
|
||||
this.os.requestTransaction(function *() {// eslint-disable-line
|
||||
var type = yield* this.getType(prevType)
|
||||
resolve(type)
|
||||
})
|
||||
})
|
||||
}
|
||||
} else {
|
||||
oldValue = this.contents[key]
|
||||
}
|
||||
// compute op event
|
||||
if (op.struct === 'Insert') {
|
||||
if (op.left === null) {
|
||||
if (op.opContent != null) {
|
||||
delete this.contents[key]
|
||||
if (op.deleted) {
|
||||
delete this.opContents[key]
|
||||
} else {
|
||||
this.opContents[key] = op.opContent
|
||||
}
|
||||
} else {
|
||||
delete this.opContents[key]
|
||||
if (op.deleted) {
|
||||
delete this.contents[key]
|
||||
} else {
|
||||
this.contents[key] = op.content
|
||||
}
|
||||
}
|
||||
this.map[key] = op.id
|
||||
var insertEvent
|
||||
if (oldValue === undefined) {
|
||||
insertEvent = {
|
||||
name: key,
|
||||
object: this,
|
||||
type: 'add'
|
||||
}
|
||||
} else {
|
||||
insertEvent = {
|
||||
name: key,
|
||||
object: this,
|
||||
oldValue: oldValue,
|
||||
type: 'update'
|
||||
}
|
||||
}
|
||||
userEvents.push(insertEvent)
|
||||
}
|
||||
} else if (op.struct === 'Delete') {
|
||||
if (Y.utils.compareIds(this.map[key], op.target)) {
|
||||
delete this.opContents[key]
|
||||
delete this.contents[key]
|
||||
var deleteEvent = {
|
||||
name: key,
|
||||
object: this,
|
||||
oldValue: oldValue,
|
||||
type: 'delete'
|
||||
}
|
||||
userEvents.push(deleteEvent)
|
||||
}
|
||||
} else {
|
||||
throw new Error('Unexpected Operation!')
|
||||
}
|
||||
}
|
||||
if (userEvents.length > 0) {
|
||||
this.eventHandler.callEventListeners(userEvents)
|
||||
}
|
||||
})
|
||||
}
|
||||
get (key) {
|
||||
// return property.
|
||||
// if property does not exist, return null
|
||||
// if property is a type, return a promise
|
||||
if (key == null) {
|
||||
throw new Error('You must specify key!')
|
||||
}
|
||||
if (this.opContents[key] == null) {
|
||||
return this.contents[key]
|
||||
} else {
|
||||
return new Promise((resolve) => {
|
||||
var oid = this.opContents[key]
|
||||
this.os.requestTransaction(function *() {
|
||||
var type = yield* this.getType(oid)
|
||||
resolve(type)
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
/*
|
||||
If there is a primitive (not a custom type), then return it.
|
||||
Returns all primitive values, if propertyName is specified!
|
||||
Note: modifying the return value could result in inconsistencies!
|
||||
-- so make sure to copy it first!
|
||||
*/
|
||||
getPrimitive (key) {
|
||||
if (key == null) {
|
||||
return Y.utils.copyObject(this.contents)
|
||||
} else {
|
||||
return this.contents[key]
|
||||
}
|
||||
}
|
||||
delete (key) {
|
||||
var right = this.map[key]
|
||||
if (right != null) {
|
||||
var del = {
|
||||
target: right,
|
||||
struct: 'Delete'
|
||||
}
|
||||
var eventHandler = this.eventHandler
|
||||
var modDel = Y.utils.copyObject(del)
|
||||
modDel.key = key
|
||||
eventHandler.awaitAndPrematurelyCall([modDel])
|
||||
this.os.requestTransaction(function *() {
|
||||
yield* this.applyCreatedOperations([del])
|
||||
eventHandler.awaitedDeletes(1)
|
||||
})
|
||||
}
|
||||
}
|
||||
set (key, value) {
|
||||
// set property.
|
||||
// if property is a type, return a promise
|
||||
// if not, apply immediately on this type an call event
|
||||
|
||||
var right = this.map[key] || null
|
||||
var insert /* :any */ = {
|
||||
left: null,
|
||||
right: right,
|
||||
origin: null,
|
||||
parent: this._model,
|
||||
parentSub: key,
|
||||
struct: 'Insert'
|
||||
}
|
||||
return new Promise((resolve) => {
|
||||
if (value instanceof Y.utils.CustomType) {
|
||||
// construct a new type
|
||||
this.os.requestTransaction(function *() {
|
||||
var type = yield* this.createType(value)
|
||||
insert.opContent = type._model
|
||||
insert.id = this.store.getNextOpId()
|
||||
yield* this.applyCreatedOperations([insert])
|
||||
resolve(type)
|
||||
})
|
||||
} else {
|
||||
insert.content = value
|
||||
insert.id = this.os.getNextOpId()
|
||||
var eventHandler = this.eventHandler
|
||||
eventHandler.awaitAndPrematurelyCall([insert])
|
||||
this.os.requestTransaction(function *() {
|
||||
yield* this.applyCreatedOperations([insert])
|
||||
eventHandler.awaitedInserts(1)
|
||||
})
|
||||
resolve(value)
|
||||
}
|
||||
})
|
||||
}
|
||||
observe (f) {
|
||||
this.eventHandler.addEventListener(f)
|
||||
}
|
||||
unobserve (f) {
|
||||
this.eventHandler.removeEventListener(f)
|
||||
}
|
||||
/*
|
||||
Observe a path.
|
||||
|
||||
E.g.
|
||||
```
|
||||
o.set('textarea', Y.TextBind)
|
||||
o.observePath(['textarea'], function(t){
|
||||
// is called whenever textarea is replaced
|
||||
t.bind(textarea)
|
||||
})
|
||||
|
||||
returns a Promise that contains a function that removes the observer from the path.
|
||||
*/
|
||||
observePath (path, f) {
|
||||
var self = this
|
||||
function observeProperty (events) {
|
||||
// call f whenever path changes
|
||||
for (var i = 0; i < events.length; i++) {
|
||||
var event = events[i]
|
||||
if (event.name === propertyName) {
|
||||
// call this also for delete events!
|
||||
var property = self.get(propertyName)
|
||||
if (property instanceof Promise) {
|
||||
property.then(f)
|
||||
} else {
|
||||
f(property)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (path.length < 1) {
|
||||
throw new Error('Path must contain at least one element!')
|
||||
} else if (path.length === 1) {
|
||||
var propertyName = path[0]
|
||||
var property = self.get(propertyName)
|
||||
if (property instanceof Promise) {
|
||||
property.then(f)
|
||||
} else {
|
||||
f(property)
|
||||
}
|
||||
this.observe(observeProperty)
|
||||
return Promise.resolve(function () {
|
||||
self.unobserve(f)
|
||||
})
|
||||
} else {
|
||||
var deleteChildObservers
|
||||
var resetObserverPath = function () {
|
||||
var promise = self.get(path[0])
|
||||
if (!promise instanceof Promise) {
|
||||
// its either not defined or a primitive value
|
||||
promise = self.set(path[0], Y.Map)
|
||||
}
|
||||
return promise.then(function (map) {
|
||||
return map.observePath(path.slice(1), f)
|
||||
}).then(function (_deleteChildObservers) {
|
||||
// update deleteChildObservers
|
||||
deleteChildObservers = _deleteChildObservers
|
||||
return Promise.resolve() // Promise does not return anything
|
||||
})
|
||||
}
|
||||
var observer = function (events) {
|
||||
for (var e in events) {
|
||||
var event = events[e]
|
||||
if (event.name === path[0]) {
|
||||
if (deleteChildObservers != null) {
|
||||
deleteChildObservers()
|
||||
}
|
||||
if (event.type === 'add' || event.type === 'update') {
|
||||
resetObserverPath()
|
||||
}
|
||||
// TODO: what about the delete events?
|
||||
}
|
||||
}
|
||||
}
|
||||
self.observe(observer)
|
||||
return resetObserverPath().then(
|
||||
// this promise contains a function that deletes all the child observers
|
||||
// and how to unobserve the observe from this object
|
||||
new Promise.resolve(function () { // eslint-disable-line
|
||||
if (deleteChildObservers != null) {
|
||||
deleteChildObservers()
|
||||
}
|
||||
self.unobserve(observer)
|
||||
})
|
||||
)
|
||||
}
|
||||
}
|
||||
* _changed (transaction, op) {
|
||||
if (op.struct === 'Delete') {
|
||||
var target = yield* transaction.getOperation(op.target)
|
||||
op.key = target.parentSub
|
||||
}
|
||||
this.eventHandler.receivedOp(op)
|
||||
}
|
||||
}
|
||||
Y.extend('Map', new Y.utils.CustomType({
|
||||
name: 'Map',
|
||||
class: YMap,
|
||||
struct: 'Map',
|
||||
initType: function * YMapInitializer (os, model) {
|
||||
var contents = {}
|
||||
var opContents = {}
|
||||
var map = model.map
|
||||
for (var name in map) {
|
||||
var op = yield* this.getOperation(map[name])
|
||||
if (op.opContent != null) {
|
||||
opContents[name] = op.opContent
|
||||
} else {
|
||||
contents[name] = op.content
|
||||
}
|
||||
}
|
||||
return new YMap(os, model, contents, opContents)
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
||||
module.exports = extend
|
||||
if (typeof Y !== 'undefined') {
|
||||
extend(Y)
|
||||
}
|
||||
|
||||
},{}]},{},[1])
|
||||
|
1
Examples/bower_components/y-map/y-map.es6.map
vendored
Normal file
1
Examples/bower_components/y-map/y-map.es6.map
vendored
Normal file
File diff suppressed because one or more lines are too long
2
Examples/bower_components/y-map/y-map.js
vendored
Normal file
2
Examples/bower_components/y-map/y-map.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
Examples/bower_components/y-map/y-map.js.map
vendored
Normal file
1
Examples/bower_components/y-map/y-map.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
37
Examples/bower_components/y-memory/.bower.json
vendored
Normal file
37
Examples/bower_components/y-memory/.bower.json
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
{
|
||||
"name": "y-memory",
|
||||
"main": "y-memory.js",
|
||||
"version": "0.7.0",
|
||||
"homepage": "http://y-js.org",
|
||||
"authors": [
|
||||
"Kevin Jahns <kevin.jahns@rwth-aachen.de>"
|
||||
],
|
||||
"description": "In-Memory database adapter for Yjs",
|
||||
"moduleType": [
|
||||
"globals",
|
||||
"node"
|
||||
],
|
||||
"keywords": [
|
||||
"Yjs",
|
||||
"connector",
|
||||
"webrtc"
|
||||
],
|
||||
"license": "MIT",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"test",
|
||||
"tests"
|
||||
],
|
||||
"_release": "0.7.0",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "v0.7.0",
|
||||
"commit": "04c97da664d857328524e8a873e4f40cc066125d"
|
||||
},
|
||||
"_source": "git://github.com/y-js/y-memory.git",
|
||||
"_target": "~0.7.0",
|
||||
"_originalSource": "y-memory",
|
||||
"_direct": true
|
||||
}
|
23
Examples/bower_components/y-memory/LICENSE
vendored
Normal file
23
Examples/bower_components/y-memory/LICENSE
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014
|
||||
- Kevin Jahns <kevin.jahns@rwth-aachen.de>.
|
||||
- Chair of Computer Science 5 (Databases & Information Systems), RWTH Aachen University, Germany
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
1
Examples/bower_components/y-memory/README.md
vendored
Normal file
1
Examples/bower_components/y-memory/README.md
vendored
Normal file
@ -0,0 +1 @@
|
||||
# IndexedDB database adapter for Yjs
|
27
Examples/bower_components/y-memory/bower.json
vendored
Normal file
27
Examples/bower_components/y-memory/bower.json
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
{
|
||||
"name": "y-memory",
|
||||
"main": "y-memory.js",
|
||||
"version": "0.7.1",
|
||||
"homepage": "http://y-js.org",
|
||||
"authors": [
|
||||
"Kevin Jahns <kevin.jahns@rwth-aachen.de>"
|
||||
],
|
||||
"description": "In-Memory database adapter for Yjs",
|
||||
"moduleType": [
|
||||
"globals",
|
||||
"node"
|
||||
],
|
||||
"keywords": [
|
||||
"Yjs",
|
||||
"connector",
|
||||
"webrtc"
|
||||
],
|
||||
"license": "MIT",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"test",
|
||||
"tests"
|
||||
]
|
||||
}
|
564
Examples/bower_components/y-memory/y-memory.es6
vendored
Normal file
564
Examples/bower_components/y-memory/y-memory.es6
vendored
Normal file
@ -0,0 +1,564 @@
|
||||
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
|
||||
/* global Y */
|
||||
'use strict'
|
||||
|
||||
function extend (Y) {
|
||||
require('./RedBlackTree.js')(Y)
|
||||
class Transaction extends Y.Transaction {
|
||||
constructor (store) {
|
||||
super(store)
|
||||
this.store = store
|
||||
this.ss = store.ss
|
||||
this.os = store.os
|
||||
this.ds = store.ds
|
||||
}
|
||||
}
|
||||
class Database extends Y.AbstractDatabase {
|
||||
constructor (y, opts) {
|
||||
super(y, opts)
|
||||
this.os = new Y.utils.RBTree()
|
||||
this.ds = new Y.utils.RBTree()
|
||||
this.ss = new Y.utils.RBTree()
|
||||
}
|
||||
logTable () {
|
||||
var self = this
|
||||
self.requestTransaction(function * () {
|
||||
console.log('User: ', this.store.y.connector.userId, "==============================") // eslint-disable-line
|
||||
console.log("State Set (SS):", yield* this.getStateSet()) // eslint-disable-line
|
||||
console.log("Operation Store (OS):") // eslint-disable-line
|
||||
yield* this.os.logTable() // eslint-disable-line
|
||||
console.log("Deletion Store (DS):") //eslint-disable-line
|
||||
yield* this.ds.logTable() // eslint-disable-line
|
||||
if (this.store.gc1.length > 0 || this.store.gc2.length > 0) {
|
||||
console.warn('GC1|2 not empty!', this.store.gc1, this.store.gc2)
|
||||
}
|
||||
if (JSON.stringify(this.store.listenersById) !== '{}') {
|
||||
console.warn('listenersById not empty!')
|
||||
}
|
||||
if (JSON.stringify(this.store.listenersByIdExecuteNow) !== '[]') {
|
||||
console.warn('listenersByIdExecuteNow not empty!')
|
||||
}
|
||||
if (this.store.transactionInProgress) {
|
||||
console.warn('Transaction still in progress!')
|
||||
}
|
||||
}, true)
|
||||
}
|
||||
transact (makeGen) {
|
||||
var t = new Transaction(this)
|
||||
while (makeGen !== null) {
|
||||
var gen = makeGen.call(t)
|
||||
var res = gen.next()
|
||||
while (!res.done) {
|
||||
res = gen.next(res.value)
|
||||
}
|
||||
makeGen = this.getNextRequest()
|
||||
}
|
||||
}
|
||||
* destroy () {
|
||||
super.destroy()
|
||||
delete this.os
|
||||
delete this.ss
|
||||
delete this.ds
|
||||
}
|
||||
}
|
||||
Y.extend('memory', Database)
|
||||
}
|
||||
|
||||
module.exports = extend
|
||||
if (typeof Y !== 'undefined') {
|
||||
extend(Y)
|
||||
}
|
||||
|
||||
},{"./RedBlackTree.js":2}],2:[function(require,module,exports){
|
||||
'use strict'
|
||||
|
||||
/*
|
||||
This file contains a not so fancy implemantion of a Red Black Tree.
|
||||
*/
|
||||
module.exports = function (Y) {
|
||||
class N {
|
||||
// A created node is always red!
|
||||
constructor (val) {
|
||||
this.val = val
|
||||
this.color = true
|
||||
this._left = null
|
||||
this._right = null
|
||||
this._parent = null
|
||||
if (val.id === null) {
|
||||
throw new Error('You must define id!')
|
||||
}
|
||||
}
|
||||
isRed () { return this.color }
|
||||
isBlack () { return !this.color }
|
||||
redden () { this.color = true; return this }
|
||||
blacken () { this.color = false; return this }
|
||||
get grandparent () {
|
||||
return this.parent.parent
|
||||
}
|
||||
get parent () {
|
||||
return this._parent
|
||||
}
|
||||
get sibling () {
|
||||
return (this === this.parent.left)
|
||||
? this.parent.right : this.parent.left
|
||||
}
|
||||
get left () {
|
||||
return this._left
|
||||
}
|
||||
get right () {
|
||||
return this._right
|
||||
}
|
||||
set left (n) {
|
||||
if (n !== null) {
|
||||
n._parent = this
|
||||
}
|
||||
this._left = n
|
||||
}
|
||||
set right (n) {
|
||||
if (n !== null) {
|
||||
n._parent = this
|
||||
}
|
||||
this._right = n
|
||||
}
|
||||
rotateLeft (tree) {
|
||||
var parent = this.parent
|
||||
var newParent = this.right
|
||||
var newRight = this.right.left
|
||||
newParent.left = this
|
||||
this.right = newRight
|
||||
if (parent === null) {
|
||||
tree.root = newParent
|
||||
newParent._parent = null
|
||||
} else if (parent.left === this) {
|
||||
parent.left = newParent
|
||||
} else if (parent.right === this) {
|
||||
parent.right = newParent
|
||||
} else {
|
||||
throw new Error('The elements are wrongly connected!')
|
||||
}
|
||||
}
|
||||
next () {
|
||||
if (this.right !== null) {
|
||||
// search the most left node in the right tree
|
||||
var o = this.right
|
||||
while (o.left !== null) {
|
||||
o = o.left
|
||||
}
|
||||
return o
|
||||
} else {
|
||||
var p = this
|
||||
while (p.parent !== null && p !== p.parent.left) {
|
||||
p = p.parent
|
||||
}
|
||||
return p.parent
|
||||
}
|
||||
}
|
||||
prev () {
|
||||
if (this.left !== null) {
|
||||
// search the most right node in the left tree
|
||||
var o = this.left
|
||||
while (o.right !== null) {
|
||||
o = o.right
|
||||
}
|
||||
return o
|
||||
} else {
|
||||
var p = this
|
||||
while (p.parent !== null && p !== p.parent.right) {
|
||||
p = p.parent
|
||||
}
|
||||
return p.parent
|
||||
}
|
||||
}
|
||||
rotateRight (tree) {
|
||||
var parent = this.parent
|
||||
var newParent = this.left
|
||||
var newLeft = this.left.right
|
||||
newParent.right = this
|
||||
this.left = newLeft
|
||||
if (parent === null) {
|
||||
tree.root = newParent
|
||||
newParent._parent = null
|
||||
} else if (parent.left === this) {
|
||||
parent.left = newParent
|
||||
} else if (parent.right === this) {
|
||||
parent.right = newParent
|
||||
} else {
|
||||
throw new Error('The elements are wrongly connected!')
|
||||
}
|
||||
}
|
||||
getUncle () {
|
||||
// we can assume that grandparent exists when this is called!
|
||||
if (this.parent === this.parent.parent.left) {
|
||||
return this.parent.parent.right
|
||||
} else {
|
||||
return this.parent.parent.left
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class RBTree {
|
||||
constructor () {
|
||||
this.root = null
|
||||
this.length = 0
|
||||
}
|
||||
* findNext (id) {
|
||||
return yield* this.findWithLowerBound([id[0], id[1] + 1])
|
||||
}
|
||||
* findPrev (id) {
|
||||
return yield* this.findWithUpperBound([id[0], id[1] - 1])
|
||||
}
|
||||
findNodeWithLowerBound (from) {
|
||||
if (from === void 0) {
|
||||
throw new Error('You must define from!')
|
||||
}
|
||||
var o = this.root
|
||||
if (o === null) {
|
||||
return null
|
||||
} else {
|
||||
while (true) {
|
||||
if ((from === null || Y.utils.smaller(from, o.val.id)) && o.left !== null) {
|
||||
// o is included in the bound
|
||||
// try to find an element that is closer to the bound
|
||||
o = o.left
|
||||
} else if (from !== null && Y.utils.smaller(o.val.id, from)) {
|
||||
// o is not within the bound, maybe one of the right elements is..
|
||||
if (o.right !== null) {
|
||||
o = o.right
|
||||
} else {
|
||||
// there is no right element. Search for the next bigger element,
|
||||
// this should be within the bounds
|
||||
return o.next()
|
||||
}
|
||||
} else {
|
||||
return o
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
findNodeWithUpperBound (to) {
|
||||
if (to === void 0) {
|
||||
throw new Error('You must define from!')
|
||||
}
|
||||
var o = this.root
|
||||
if (o === null) {
|
||||
return null
|
||||
} else {
|
||||
while (true) {
|
||||
if ((to === null || Y.utils.smaller(o.val.id, to)) && o.right !== null) {
|
||||
// o is included in the bound
|
||||
// try to find an element that is closer to the bound
|
||||
o = o.right
|
||||
} else if (to !== null && Y.utils.smaller(to, o.val.id)) {
|
||||
// o is not within the bound, maybe one of the left elements is..
|
||||
if (o.left !== null) {
|
||||
o = o.left
|
||||
} else {
|
||||
// there is no left element. Search for the prev smaller element,
|
||||
// this should be within the bounds
|
||||
return o.prev()
|
||||
}
|
||||
} else {
|
||||
return o
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
* findWithLowerBound (from) {
|
||||
var n = this.findNodeWithLowerBound(from)
|
||||
return n == null ? null : n.val
|
||||
}
|
||||
* findWithUpperBound (to) {
|
||||
var n = this.findNodeWithUpperBound(to)
|
||||
return n == null ? null : n.val
|
||||
}
|
||||
* iterate (t, from, to, f) {
|
||||
var o = this.findNodeWithLowerBound(from)
|
||||
while (o !== null && (to === null || Y.utils.smaller(o.val.id, to) || Y.utils.compareIds(o.val.id, to))) {
|
||||
yield* f.call(t, o.val)
|
||||
o = o.next()
|
||||
}
|
||||
return true
|
||||
}
|
||||
* logTable (from, to, filter) {
|
||||
if (filter == null) {
|
||||
filter = function () {
|
||||
return true
|
||||
}
|
||||
}
|
||||
if (from == null) { from = null }
|
||||
if (to == null) { to = null }
|
||||
var os = []
|
||||
yield* this.iterate(this, from, to, function * (o) {
|
||||
if (filter(o)) {
|
||||
var o_ = {}
|
||||
for (var key in o) {
|
||||
if (typeof o[key] === 'object') {
|
||||
o_[key] = JSON.stringify(o[key])
|
||||
} else {
|
||||
o_[key] = o[key]
|
||||
}
|
||||
}
|
||||
os.push(o_)
|
||||
}
|
||||
})
|
||||
if (console.table != null) {
|
||||
console.table(os)
|
||||
}
|
||||
}
|
||||
* find (id) {
|
||||
var n
|
||||
return (n = this.findNode(id)) ? n.val : null
|
||||
}
|
||||
findNode (id) {
|
||||
if (id == null || id.constructor !== Array) {
|
||||
throw new Error('Expect id to be an array!')
|
||||
}
|
||||
var o = this.root
|
||||
if (o === null) {
|
||||
return false
|
||||
} else {
|
||||
while (true) {
|
||||
if (o === null) {
|
||||
return false
|
||||
}
|
||||
if (Y.utils.smaller(id, o.val.id)) {
|
||||
o = o.left
|
||||
} else if (Y.utils.smaller(o.val.id, id)) {
|
||||
o = o.right
|
||||
} else {
|
||||
return o
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
* delete (id) {
|
||||
if (id == null || id.constructor !== Array) {
|
||||
throw new Error('id is expected to be an Array!')
|
||||
}
|
||||
var d = this.findNode(id)
|
||||
if (d == null) {
|
||||
throw new Error('Element does not exist!')
|
||||
}
|
||||
this.length--
|
||||
if (d.left !== null && d.right !== null) {
|
||||
// switch d with the greates element in the left subtree.
|
||||
// o should have at most one child.
|
||||
var o = d.left
|
||||
// find
|
||||
while (o.right !== null) {
|
||||
o = o.right
|
||||
}
|
||||
// switch
|
||||
d.val = o.val
|
||||
d = o
|
||||
}
|
||||
// d has at most one child
|
||||
// let n be the node that replaces d
|
||||
var isFakeChild
|
||||
var child = d.left || d.right
|
||||
if (child === null) {
|
||||
isFakeChild = true
|
||||
child = new N({id: 0})
|
||||
child.blacken()
|
||||
d.right = child
|
||||
} else {
|
||||
isFakeChild = false
|
||||
}
|
||||
|
||||
if (d.parent === null) {
|
||||
if (!isFakeChild) {
|
||||
this.root = child
|
||||
child.blacken()
|
||||
child._parent = null
|
||||
} else {
|
||||
this.root = null
|
||||
}
|
||||
return
|
||||
} else if (d.parent.left === d) {
|
||||
d.parent.left = child
|
||||
} else if (d.parent.right === d) {
|
||||
d.parent.right = child
|
||||
} else {
|
||||
throw new Error('Impossible!')
|
||||
}
|
||||
if (d.isBlack()) {
|
||||
if (child.isRed()) {
|
||||
child.blacken()
|
||||
} else {
|
||||
this._fixDelete(child)
|
||||
}
|
||||
}
|
||||
this.root.blacken()
|
||||
if (isFakeChild) {
|
||||
if (child.parent.left === child) {
|
||||
child.parent.left = null
|
||||
} else if (child.parent.right === child) {
|
||||
child.parent.right = null
|
||||
} else {
|
||||
throw new Error('Impossible #3')
|
||||
}
|
||||
}
|
||||
}
|
||||
_fixDelete (n) {
|
||||
function isBlack (node) {
|
||||
return node !== null ? node.isBlack() : true
|
||||
}
|
||||
function isRed (node) {
|
||||
return node !== null ? node.isRed() : false
|
||||
}
|
||||
if (n.parent === null) {
|
||||
// this can only be called after the first iteration of fixDelete.
|
||||
return
|
||||
}
|
||||
// d was already replaced by the child
|
||||
// d is not the root
|
||||
// d and child are black
|
||||
var sibling = n.sibling
|
||||
if (isRed(sibling)) {
|
||||
// make sibling the grandfather
|
||||
n.parent.redden()
|
||||
sibling.blacken()
|
||||
if (n === n.parent.left) {
|
||||
n.parent.rotateLeft(this)
|
||||
} else if (n === n.parent.right) {
|
||||
n.parent.rotateRight(this)
|
||||
} else {
|
||||
throw new Error('Impossible #2')
|
||||
}
|
||||
sibling = n.sibling
|
||||
}
|
||||
// parent, sibling, and children of n are black
|
||||
if (n.parent.isBlack() &&
|
||||
sibling.isBlack() &&
|
||||
isBlack(sibling.left) &&
|
||||
isBlack(sibling.right)
|
||||
) {
|
||||
sibling.redden()
|
||||
this._fixDelete(n.parent)
|
||||
} else if (n.parent.isRed() &&
|
||||
sibling.isBlack() &&
|
||||
isBlack(sibling.left) &&
|
||||
isBlack(sibling.right)
|
||||
) {
|
||||
sibling.redden()
|
||||
n.parent.blacken()
|
||||
} else {
|
||||
if (n === n.parent.left &&
|
||||
sibling.isBlack() &&
|
||||
isRed(sibling.left) &&
|
||||
isBlack(sibling.right)
|
||||
) {
|
||||
sibling.redden()
|
||||
sibling.left.blacken()
|
||||
sibling.rotateRight(this)
|
||||
sibling = n.sibling
|
||||
} else if (n === n.parent.right &&
|
||||
sibling.isBlack() &&
|
||||
isRed(sibling.right) &&
|
||||
isBlack(sibling.left)
|
||||
) {
|
||||
sibling.redden()
|
||||
sibling.right.blacken()
|
||||
sibling.rotateLeft(this)
|
||||
sibling = n.sibling
|
||||
}
|
||||
sibling.color = n.parent.color
|
||||
n.parent.blacken()
|
||||
if (n === n.parent.left) {
|
||||
sibling.right.blacken()
|
||||
n.parent.rotateLeft(this)
|
||||
} else {
|
||||
sibling.left.blacken()
|
||||
n.parent.rotateRight(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
* put (v) {
|
||||
if (v == null || v.id == null || v.id.constructor !== Array) {
|
||||
throw new Error('v is expected to have an id property which is an Array!')
|
||||
}
|
||||
var node = new N(v)
|
||||
if (this.root !== null) {
|
||||
var p = this.root // p abbrev. parent
|
||||
while (true) {
|
||||
if (Y.utils.smaller(node.val.id, p.val.id)) {
|
||||
if (p.left === null) {
|
||||
p.left = node
|
||||
break
|
||||
} else {
|
||||
p = p.left
|
||||
}
|
||||
} else if (Y.utils.smaller(p.val.id, node.val.id)) {
|
||||
if (p.right === null) {
|
||||
p.right = node
|
||||
break
|
||||
} else {
|
||||
p = p.right
|
||||
}
|
||||
} else {
|
||||
p.val = node.val
|
||||
return p
|
||||
}
|
||||
}
|
||||
this._fixInsert(node)
|
||||
} else {
|
||||
this.root = node
|
||||
}
|
||||
this.length++
|
||||
this.root.blacken()
|
||||
return node
|
||||
}
|
||||
_fixInsert (n) {
|
||||
if (n.parent === null) {
|
||||
n.blacken()
|
||||
return
|
||||
} else if (n.parent.isBlack()) {
|
||||
return
|
||||
}
|
||||
var uncle = n.getUncle()
|
||||
if (uncle !== null && uncle.isRed()) {
|
||||
// Note: parent: red, uncle: red
|
||||
n.parent.blacken()
|
||||
uncle.blacken()
|
||||
n.grandparent.redden()
|
||||
this._fixInsert(n.grandparent)
|
||||
} else {
|
||||
// Note: parent: red, uncle: black or null
|
||||
// Now we transform the tree in such a way that
|
||||
// either of these holds:
|
||||
// 1) grandparent.left.isRed
|
||||
// and grandparent.left.left.isRed
|
||||
// 2) grandparent.right.isRed
|
||||
// and grandparent.right.right.isRed
|
||||
if (n === n.parent.right && n.parent === n.grandparent.left) {
|
||||
n.parent.rotateLeft(this)
|
||||
// Since we rotated and want to use the previous
|
||||
// cases, we need to set n in such a way that
|
||||
// n.parent.isRed again
|
||||
n = n.left
|
||||
} else if (n === n.parent.left && n.parent === n.grandparent.right) {
|
||||
n.parent.rotateRight(this)
|
||||
// see above
|
||||
n = n.right
|
||||
}
|
||||
// Case 1) or 2) hold from here on.
|
||||
// Now traverse grandparent, make parent a black node
|
||||
// on the highest level which holds two red nodes.
|
||||
n.parent.blacken()
|
||||
n.grandparent.redden()
|
||||
if (n === n.parent.left) {
|
||||
// Case 1
|
||||
n.grandparent.rotateRight(this)
|
||||
} else {
|
||||
// Case 2
|
||||
n.grandparent.rotateLeft(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Y.utils.RBTree = RBTree
|
||||
}
|
||||
|
||||
},{}]},{},[1])
|
||||
|
1
Examples/bower_components/y-memory/y-memory.es6.map
vendored
Normal file
1
Examples/bower_components/y-memory/y-memory.es6.map
vendored
Normal file
File diff suppressed because one or more lines are too long
2
Examples/bower_components/y-memory/y-memory.js
vendored
Normal file
2
Examples/bower_components/y-memory/y-memory.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
Examples/bower_components/y-memory/y-memory.js.map
vendored
Normal file
1
Examples/bower_components/y-memory/y-memory.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
36
Examples/bower_components/y-richtext/.bower.json
vendored
Normal file
36
Examples/bower_components/y-richtext/.bower.json
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
{
|
||||
"name": "y-richtext",
|
||||
"version": "0.7.5",
|
||||
"authors": [
|
||||
"corentin.cadiou@linagora.com",
|
||||
"kevin.jahns@rwth-aachen.de"
|
||||
],
|
||||
"description": "Rich Text type for Yjs",
|
||||
"keywords": [
|
||||
"webrtc",
|
||||
"text",
|
||||
"edition",
|
||||
"collaborative",
|
||||
"rich text"
|
||||
],
|
||||
"license": "MIT",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"test",
|
||||
"tests"
|
||||
],
|
||||
"dependencies": {},
|
||||
"homepage": "https://github.com/y-js/y-richtext",
|
||||
"_release": "0.7.5",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "v0.7.5",
|
||||
"commit": "5a6056fa835fab93e6add70537dde4cb67e8428c"
|
||||
},
|
||||
"_source": "git://github.com/y-js/y-richtext.git",
|
||||
"_target": "~0.7.5",
|
||||
"_originalSource": "y-richtext",
|
||||
"_direct": true
|
||||
}
|
25
Examples/bower_components/y-richtext/LICENSE.txt
vendored
Normal file
25
Examples/bower_components/y-richtext/LICENSE.txt
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015
|
||||
- Corentin Cadiou <corentin.cadiou@linagora.com>
|
||||
- Kevin Jahns <kevin.jahns@rwth-aachen.de>
|
||||
- Linagora
|
||||
- Veeting.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
59
Examples/bower_components/y-richtext/Readme.md
vendored
Normal file
59
Examples/bower_components/y-richtext/Readme.md
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
|
||||
# Rich Text type for [Yjs](https://github.com/y-js/richtext)
|
||||
|
||||
This type strongly resembles the [rich text](https://github.com/ottypes/rich-text) format for operational transformation. Under the hood, however, several mechanisms ensure that the intentions of your changes are preserved. Furthermore, you can transform the actions on the document in the rich text format back and forth, and, therefore, you can bind this type to any rich text editor that supports the widely used rich text format.
|
||||
|
||||
|
||||
## Use it!
|
||||
Retrieve this with bower or npm.
|
||||
|
||||
##### Bower
|
||||
```
|
||||
bower install y-richtext --save
|
||||
```
|
||||
|
||||
and include the js library.
|
||||
|
||||
```
|
||||
<script src="./bower_components/y-richtext/y-richtext.js"></script>
|
||||
```
|
||||
|
||||
##### NPM
|
||||
```
|
||||
npm install y-richtext --save
|
||||
```
|
||||
and put it on the `Y` object.
|
||||
|
||||
```
|
||||
Y.RichText = require("y-richtext");
|
||||
```
|
||||
|
||||
|
||||
### RichText Object
|
||||
|
||||
##### Reference
|
||||
* Create
|
||||
```
|
||||
var yrichtext = new Y.RichText()
|
||||
```
|
||||
* Create
|
||||
```
|
||||
var yrichtext = new Y.RichText(ot_delta)
|
||||
```
|
||||
* .bind(editor)
|
||||
* Bind this type to an rich text editor. (Currently, only QuillJs is supported)
|
||||
|
||||
|
||||
# A note on intention preservation
|
||||
This type has several mechanisms to ensure that the intention of your actions are preserved. For example:
|
||||
* If two users fix a word concurrently, only one change will prevail. A classical example is that two users want to correct the word "missplled". If two users correct it at the same time (or they merge after they corrected it offline), the result in operation transformation algorithms would be "misspeelled". This type will ensure that the result is "misspelled"
|
||||
* When a user inserts content *c* after a set of content *C_left*, and before a set of content *C_right*, then *C_left* will be always to the left of c, and *C_right* will be always to the right of *c*. This property will also hold when content is deleted or when a deletion is undone.
|
||||
|
||||
## Contribution
|
||||
We thank [Veeting](https://www.veeting.com/) and [Linagora](https://www.linagora.com/) who sponsored this work, and agreed to publish it as Open Source.
|
||||
|
||||
## License
|
||||
Yjs and the RichText type are licensed under the [MIT License](./LICENSE.txt).
|
||||
|
||||
- Corentin Cadiou <corentin.cadiou@linagora.com>
|
||||
- Kevin Jahns <kevin.jahns@rwth-aachen.de>
|
25
Examples/bower_components/y-richtext/bower.json
vendored
Normal file
25
Examples/bower_components/y-richtext/bower.json
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
{
|
||||
"name": "y-richtext",
|
||||
"version": "0.7.6",
|
||||
"authors": [
|
||||
"corentin.cadiou@linagora.com",
|
||||
"kevin.jahns@rwth-aachen.de"
|
||||
],
|
||||
"description": "Rich Text type for Yjs",
|
||||
"keywords": [
|
||||
"webrtc",
|
||||
"text",
|
||||
"edition",
|
||||
"collaborative",
|
||||
"rich text"
|
||||
],
|
||||
"license": "MIT",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"test",
|
||||
"tests"
|
||||
],
|
||||
"dependencies": {}
|
||||
}
|
503
Examples/bower_components/y-richtext/y-richtext.es6
vendored
Normal file
503
Examples/bower_components/y-richtext/y-richtext.es6
vendored
Normal file
@ -0,0 +1,503 @@
|
||||
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
|
||||
/* global Y */
|
||||
'use strict'
|
||||
|
||||
function extend (Y) {
|
||||
Y.requestModules(['Array']).then(function () {
|
||||
class YRichtext extends Y.Array['class'] {
|
||||
constructor (os, _model, idArray, valArray) {
|
||||
super(os, _model, idArray, valArray)
|
||||
this._length = 0
|
||||
this.instances = []
|
||||
for (var i = 0, v = valArray[i]; i < valArray.length; i++) {
|
||||
if (typeof v === 'string') {
|
||||
this._length++
|
||||
}
|
||||
}
|
||||
var self = this
|
||||
this.observe(function (events) {
|
||||
for (var i = 0, event = events[i]; i < events.length; i++) {
|
||||
if (event.type === 'insert') {
|
||||
if (typeof event.value === 'string') {
|
||||
self._length++
|
||||
}
|
||||
} else if (event.type === 'delete') {
|
||||
if (typeof event.value === 'string') {
|
||||
self._length--
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
get length () {
|
||||
return this._length
|
||||
}
|
||||
toString () {
|
||||
return this.valArray.map(function (v) {
|
||||
if (typeof v === 'string') {
|
||||
return v
|
||||
}
|
||||
}).join('')
|
||||
}
|
||||
toOTOps () {
|
||||
var ops = []
|
||||
var op = {
|
||||
insert: [],
|
||||
attributes: {}
|
||||
}
|
||||
function createNewOp () {
|
||||
var attrs = {}
|
||||
// copy attributes
|
||||
for (var name in op.attributes) {
|
||||
attrs[name] = op.attributes[name]
|
||||
}
|
||||
op = {
|
||||
insert: [],
|
||||
attributes: attrs
|
||||
}
|
||||
}
|
||||
var i = 0
|
||||
for (; i < this.valArray.length; i++) {
|
||||
let v = this.valArray[i]
|
||||
if (v.constructor === Array) {
|
||||
if (op.insert.length > 0) {
|
||||
op.insert = op.insert.join('')
|
||||
ops.push(op)
|
||||
createNewOp()
|
||||
}
|
||||
if (v[1] === null) {
|
||||
delete op.attributes[v[0]]
|
||||
} else {
|
||||
op.attributes[v[0]] = v[1]
|
||||
}
|
||||
} else {
|
||||
op.insert.push(v)
|
||||
}
|
||||
}
|
||||
if (op.insert.length > 0) {
|
||||
op.insert = op.insert.join('')
|
||||
ops.push(op)
|
||||
}
|
||||
return ops
|
||||
}
|
||||
insert (pos, content) {
|
||||
var curPos = 0
|
||||
var selection = {}
|
||||
for (var i = 0; i < this.valArray.length; i++) {
|
||||
if (curPos === pos) {
|
||||
break
|
||||
}
|
||||
var v = this.valArray[i]
|
||||
if (typeof v === 'string') {
|
||||
curPos++
|
||||
} else if (v.constructor === Array) {
|
||||
if (v[1] === null) {
|
||||
delete selection[v[0]]
|
||||
} else {
|
||||
selection[v[0]] = v[1]
|
||||
}
|
||||
}
|
||||
}
|
||||
super.insert(i, content.split(''))
|
||||
return selection
|
||||
}
|
||||
delete (pos, length) {
|
||||
/*
|
||||
let x = to be deleted string
|
||||
let s = some string
|
||||
let * = some selection
|
||||
E.g.
|
||||
sss*s***x*xxxxx***xx*x**ss*s
|
||||
|---delete-range--|
|
||||
delStart delEnd
|
||||
|
||||
We'll check the following
|
||||
* is it possible to delete some of the selections?
|
||||
1. a dominating selection to the right could be the same as the selection (curSel) to delStart
|
||||
2. a selections could be overwritten by another selection to the right
|
||||
*/
|
||||
var curPos = 0
|
||||
var curSel = {}
|
||||
var endPos = pos + length
|
||||
if (length <= 0) return
|
||||
var delStart // relative to valArray
|
||||
var delEnd // ..
|
||||
var v, i // helper variable for elements of valArray
|
||||
|
||||
for (delStart = 0, v = this.valArray[delStart]; curPos < pos && delStart < this.valArray.length; v = this.valArray[++delStart]) {
|
||||
if (typeof v === 'string') {
|
||||
curPos++
|
||||
} else if (v.constructor === Array) {
|
||||
curSel[v[0]] = v[1]
|
||||
}
|
||||
}
|
||||
for (delEnd = delStart, v = this.valArray[delEnd]; curPos < endPos && delEnd < this.valArray.length; v = this.valArray[++delEnd]) {
|
||||
if (typeof v === 'string') {
|
||||
curPos++
|
||||
}
|
||||
}
|
||||
if (delEnd === this.valArray.length) {
|
||||
// yay, you can delete everything without checking
|
||||
for (i = delEnd - 1, v = this.valArray[i]; i >= delStart; v = this.valArray[--i]) {
|
||||
super.delete(i, 1)
|
||||
}
|
||||
} else {
|
||||
if (typeof v === 'string') {
|
||||
delEnd--
|
||||
}
|
||||
var rightSel = {}
|
||||
for (i = delEnd, v = this.valArray[i]; i >= delStart; v = this.valArray[--i]) {
|
||||
if (v.constructor === Array) {
|
||||
if (rightSel[v[0]] === undefined) {
|
||||
if (v[1] === curSel[v[0]]) {
|
||||
// case 1.
|
||||
super.delete(i, 1)
|
||||
}
|
||||
rightSel[v[0]] = v[1]
|
||||
} else {
|
||||
// case 2.
|
||||
super.delete(i, 1)
|
||||
}
|
||||
} else if (typeof v === 'string') {
|
||||
// always delete the strings
|
||||
super.delete(i, 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
1. get selection attributes from position $from
|
||||
(name it antiAttrs, and we'll use it to make sure that selection ends in antiAttrs)
|
||||
2. Insert selection $attr, if necessary
|
||||
3. Between from and to, we'll delete all selections that do not match $attr.
|
||||
Furthermore, we'll update antiAttrs, if necessary
|
||||
4. In the end well insert a selection that makes sure that selection($to) ends in antiAttrs
|
||||
*/
|
||||
select (from, to, attrName, attrValue) {
|
||||
if (from == null || to == null || attrName == null || attrValue === undefined) {
|
||||
throw new Error('You must define four parameters')
|
||||
} else {
|
||||
var step2i
|
||||
var step2sel
|
||||
var antiAttrs = [attrName, null]
|
||||
var curPos = 0
|
||||
var i = 0
|
||||
// 1. compute antiAttrs
|
||||
for (; i < this.valArray.length; i++) {
|
||||
let v = this.valArray[i]
|
||||
if (curPos === from) {
|
||||
break
|
||||
}
|
||||
if (v.constructor === Array) {
|
||||
if (v[0] === attrName) {
|
||||
antiAttrs[1] = v[1]
|
||||
}
|
||||
} else if (typeof v === 'string') {
|
||||
curPos++
|
||||
}
|
||||
}
|
||||
// 2. Insert attr
|
||||
if (antiAttrs[1] !== attrValue) {
|
||||
// we'll execute this later
|
||||
step2i = i
|
||||
step2sel = [attrName, attrValue]
|
||||
}
|
||||
|
||||
// 3. update antiAttrs, modify selection
|
||||
var deletes = []
|
||||
for (; i < this.valArray.length; i++) {
|
||||
let v = this.valArray[i]
|
||||
if (curPos === to) {
|
||||
break
|
||||
}
|
||||
if (v.constructor === Array) {
|
||||
if (v[0] === attrName) {
|
||||
antiAttrs[1] = v[1]
|
||||
deletes.push(i)
|
||||
}
|
||||
} else if (typeof v === 'string') {
|
||||
curPos++
|
||||
}
|
||||
}
|
||||
// actually delete the found selections
|
||||
// also.. we have to delete from right to left (so that the positions dont change)
|
||||
for (var j = deletes.length - 1; j >= 0; j--) {
|
||||
var del = deletes[j]
|
||||
super.delete(del, 1)
|
||||
// update i, rel. to
|
||||
if (del < i) {
|
||||
i--
|
||||
}
|
||||
if (del < step2i) {
|
||||
step2i--
|
||||
}
|
||||
}
|
||||
// 4. Update selection to match antiAttrs
|
||||
// never insert, if not necessary
|
||||
// 1. when it is the last position ~ i < valArray.length)
|
||||
// 2. when a similar attrName already exists between i and the next character
|
||||
if (antiAttrs[1] !== attrValue && i < this.valArray.length) { // check 1.
|
||||
var performStep4 = true
|
||||
var v
|
||||
for (j = i, v = this.valArray[j]; j < this.valArray.length && v.constructor === Array; v = this.valArray[++j]) {
|
||||
if (v[0] === attrName) {
|
||||
performStep4 = false // check 2.
|
||||
if (v[1] === attrValue) {
|
||||
super.delete(j, 1)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
if (performStep4) {
|
||||
var sel = [attrName, antiAttrs[1]]
|
||||
super.insert(i, [sel])
|
||||
}
|
||||
}
|
||||
if (step2i != null) {
|
||||
super.insert(step2i, [step2sel])
|
||||
// if there are some selections to the left of step2sel, delete them if possible
|
||||
// * have same attribute name
|
||||
// * no insert between step2sel and selection
|
||||
for (j = step2i - 1, v = this.valArray[j]; j >= 0 && v.constructor === Array; v = this.valArray[--j]) {
|
||||
if (v[0] === attrName) {
|
||||
super.delete(j, 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
bind (quill) {
|
||||
this.instances.push(quill)
|
||||
var self = this
|
||||
|
||||
// this function makes sure that either the
|
||||
// quill event is executed, or the yjs observer is executed
|
||||
var token = true
|
||||
function mutualExcluse (f) {
|
||||
if (token) {
|
||||
token = false
|
||||
try {
|
||||
f()
|
||||
} catch (e) {
|
||||
token = true
|
||||
throw new Error(e)
|
||||
}
|
||||
token = true
|
||||
}
|
||||
}
|
||||
|
||||
quill.setContents(this.toOTOps())
|
||||
|
||||
quill.on('text-change', function (delta) {
|
||||
mutualExcluse(function () {
|
||||
var pos = 0
|
||||
var name // helper variable
|
||||
for (var i = 0; i < delta.ops.length; i++) {
|
||||
var op = delta.ops[i]
|
||||
if (op.insert != null) {
|
||||
var attrs = self.insert(pos, op.insert)
|
||||
// create new selection
|
||||
for (name in op.attributes) {
|
||||
if (op.attributes[name] !== attrs[name]) {
|
||||
self.select(pos, pos + op.insert.length, name, op.attributes[name])
|
||||
}
|
||||
}
|
||||
// not-existence of an attribute in op.attributes denotes
|
||||
// that we have to unselect (set to null)
|
||||
for (name in attrs) {
|
||||
if (op.attributes == null || attrs[name] !== op.attributes[name]) {
|
||||
self.select(pos, pos + op.insert.length, name, null)
|
||||
}
|
||||
}
|
||||
pos += op.insert.length
|
||||
}
|
||||
if (op.delete != null) {
|
||||
self.delete(pos, op.delete)
|
||||
}
|
||||
if (op.retain != null) {
|
||||
var afterRetain = pos + op.retain
|
||||
if (afterRetain > self.length) {
|
||||
var diff = afterRetain - self.length
|
||||
var enters = ''
|
||||
while (diff !== 0) {
|
||||
diff--
|
||||
enters += '\n'
|
||||
}
|
||||
for (name in op.attributes) {
|
||||
quill.formatText(self.length, self.length + op.retain, name, null)
|
||||
// quill.deleteText(self.length, self.length + op.retain)
|
||||
}
|
||||
quill.insertText(self.length, enters, op.attributes)
|
||||
self.insert(self.length, enters)
|
||||
}
|
||||
for (name in op.attributes) {
|
||||
self.select(pos, pos + op.retain, name, op.attributes[name])
|
||||
}
|
||||
pos = afterRetain
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
this.observe(function (events) {
|
||||
mutualExcluse(function () {
|
||||
var v // helper variable
|
||||
var curSel // helper variable (current selection)
|
||||
for (var i = 0; i < events.length; i++) {
|
||||
var event = events[i]
|
||||
if (event.type === 'insert') {
|
||||
if (typeof event.value === 'string') {
|
||||
var position = 0
|
||||
var insertSel = {}
|
||||
for (var l = event.index - 1; l >= 0; l--) {
|
||||
v = self.valArray[l]
|
||||
if (typeof v === 'string') {
|
||||
position++
|
||||
} else if (v.constructor === Array && typeof insertSel[v[0]] === 'undefined') {
|
||||
insertSel[v[0]] = v[1]
|
||||
}
|
||||
}
|
||||
quill.insertText(position, event.value, insertSel)
|
||||
} else if (event.value.constructor === Array) {
|
||||
// a new selection is created
|
||||
// find left selection that matches newSel[0]
|
||||
curSel = null
|
||||
var newSel = event.value
|
||||
// denotes the start position of the selection
|
||||
// (without the selection objects)
|
||||
var selectionStart = 0
|
||||
for (var j = event.index - 1; j >= 0; j--) {
|
||||
v = self.valArray[j]
|
||||
if (v.constructor === Array) {
|
||||
// check if v matches newSel
|
||||
if (newSel[0] === v[0]) {
|
||||
// found a selection
|
||||
// update curSel and go to next step
|
||||
curSel = v[1]
|
||||
break
|
||||
}
|
||||
} else if (typeof v === 'string') {
|
||||
selectionStart++
|
||||
}
|
||||
}
|
||||
// make sure to decrement j, so we correctly compute selectionStart
|
||||
for (; j >= 0; j--) {
|
||||
v = self.valArray[j]
|
||||
if (typeof v === 'string') {
|
||||
selectionStart++
|
||||
}
|
||||
}
|
||||
// either a selection was found {then curSel was updated}, or not (then curSel = null)
|
||||
if (newSel[1] === curSel) {
|
||||
// both are the same. not necessary to do anything
|
||||
return
|
||||
}
|
||||
// now find out the range over which newSel has to be created
|
||||
var selectionEnd = selectionStart
|
||||
for (var k = event.index + 1; k < self.valArray.length; k++) {
|
||||
v = self.valArray[k]
|
||||
if (v.constructor === Array) {
|
||||
if (v[0] === newSel[0]) {
|
||||
// found another selection with same attr name
|
||||
break
|
||||
}
|
||||
} else if (typeof v === 'string') {
|
||||
selectionEnd++
|
||||
}
|
||||
}
|
||||
// create a selection from selectionStart to selectionEnd
|
||||
if (selectionStart !== selectionEnd) {
|
||||
quill.formatText(selectionStart, selectionEnd, newSel[0], newSel[1])
|
||||
}
|
||||
}
|
||||
} else if (event.type === 'delete') {
|
||||
if (typeof event.value === 'string') { // TODO: see button. add || `event.length > 1`
|
||||
// only if these conditions are true, we have to actually check if we have to delete sth.
|
||||
// Then we have to check if between pos and pos + event.length are selections:
|
||||
// delete till pos + (event.length - number of selections)
|
||||
var pos = 0
|
||||
for (var u = 0; u < event.index; u++) {
|
||||
v = self.valArray[u]
|
||||
if (typeof v === 'string') {
|
||||
pos++
|
||||
}
|
||||
}
|
||||
var delLength = event.length
|
||||
/* TODO!!
|
||||
they do not exist anymore.. so i can't query. you have to query over event.value(s) - but that not yet implemented
|
||||
for (; i < event.index + event.length; i++) {
|
||||
if (self.valArray[i].constructor === Array) {
|
||||
delLength--
|
||||
}
|
||||
}*/
|
||||
quill.deleteText(pos, pos + delLength)
|
||||
} else if (event.value.constructor === Array) {
|
||||
curSel = null
|
||||
var from = 0
|
||||
var x
|
||||
for (x = event.index - 1; x >= 0; x--) {
|
||||
v = self.valArray[x]
|
||||
if (v.constructor === Array) {
|
||||
if (v[0] === event.value[0]) {
|
||||
curSel = v[1]
|
||||
break
|
||||
}
|
||||
} else if (typeof v === 'string') {
|
||||
from++
|
||||
}
|
||||
}
|
||||
for (; x >= 0; v = self.valArray[--x]) {
|
||||
if (typeof v === 'string') {
|
||||
from++
|
||||
}
|
||||
}
|
||||
var to = from
|
||||
for (x = event.index; x < self.valArray.length; x++) {
|
||||
v = self.valArray[x]
|
||||
if (v.constructor === Array) {
|
||||
if (v[0] === event.value[0]) {
|
||||
break
|
||||
}
|
||||
} else if (typeof v === 'string') {
|
||||
to++
|
||||
}
|
||||
}
|
||||
if (curSel !== event.value[1] && from !== to) {
|
||||
quill.formatText(from, to, event.value[0], curSel)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
quill.editor.checkUpdate()
|
||||
})
|
||||
})
|
||||
}
|
||||
* _changed () {
|
||||
this.instances.forEach(function (quill) {
|
||||
quill.editor.checkUpdate()
|
||||
})
|
||||
yield* Y.Array.class.prototype._changed.apply(this, arguments)
|
||||
}
|
||||
}
|
||||
Y.extend('Richtext', new Y.utils.CustomType({
|
||||
name: 'Richtext',
|
||||
class: YRichtext,
|
||||
struct: 'List',
|
||||
initType: function * YTextInitializer (os, model) {
|
||||
var valArray = []
|
||||
var idArray = yield* Y.Struct.List.map.call(this, model, function (c) {
|
||||
valArray.push(c.content)
|
||||
return JSON.stringify(c.id)
|
||||
})
|
||||
return new YRichtext(os, model.id, idArray, valArray)
|
||||
}
|
||||
}))
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = extend
|
||||
if (typeof Y !== 'undefined') {
|
||||
extend(Y)
|
||||
}
|
||||
|
||||
},{}]},{},[1])
|
||||
|
2
Examples/bower_components/y-richtext/y-richtext.js
vendored
Normal file
2
Examples/bower_components/y-richtext/y-richtext.js
vendored
Normal file
File diff suppressed because one or more lines are too long
37
Examples/bower_components/y-text/.bower.json
vendored
Normal file
37
Examples/bower_components/y-text/.bower.json
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
{
|
||||
"name": "y-text",
|
||||
"version": "0.7.1",
|
||||
"homepage": "http://y-js.org",
|
||||
"authors": [
|
||||
"Kevin Jahns <kevin.jahns@rwth-aachen.de>"
|
||||
],
|
||||
"description": "Text type for Yjs",
|
||||
"main": "./src/Text.js",
|
||||
"keywords": [
|
||||
"OT",
|
||||
"collaboration",
|
||||
"synchronization",
|
||||
"ShareJS",
|
||||
"Coweb",
|
||||
"concurrency"
|
||||
],
|
||||
"license": "MIT",
|
||||
"ignore": [
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"test",
|
||||
"extras",
|
||||
"test"
|
||||
],
|
||||
"devDependencies": {},
|
||||
"_release": "0.7.1",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "v0.7.1",
|
||||
"commit": "bdb6553994226703504875431c56436704b3af57"
|
||||
},
|
||||
"_source": "git://github.com/y-js/y-text.git",
|
||||
"_target": "~0.7.1",
|
||||
"_originalSource": "y-text",
|
||||
"_direct": true
|
||||
}
|
3
Examples/bower_components/y-text/.bowerrc
vendored
Normal file
3
Examples/bower_components/y-text/.bowerrc
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"directory": "../"
|
||||
}
|
6
Examples/bower_components/y-text/.gitignore
vendored
Normal file
6
Examples/bower_components/y-text/.gitignore
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
/node_modules/
|
||||
bower_components
|
||||
.directory
|
||||
.c9
|
||||
.codio
|
||||
.settings
|
11
Examples/bower_components/y-text/.travis.yml
vendored
Normal file
11
Examples/bower_components/y-text/.travis.yml
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
language: node_js
|
||||
before_install:
|
||||
- "npm install -g bower coffee-script"
|
||||
- "bower install"
|
||||
node_js:
|
||||
- "0.12"
|
||||
- "0.11"
|
||||
- "0.10"
|
||||
branches:
|
||||
only:
|
||||
- master
|
27
Examples/bower_components/y-text/bower.json
vendored
Normal file
27
Examples/bower_components/y-text/bower.json
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
{
|
||||
"name": "y-text",
|
||||
"version": "0.7.2",
|
||||
"homepage": "http://y-js.org",
|
||||
"authors": [
|
||||
"Kevin Jahns <kevin.jahns@rwth-aachen.de>"
|
||||
],
|
||||
"description": "Text type for Yjs",
|
||||
"main": "./src/Text.js",
|
||||
"keywords": [
|
||||
"OT",
|
||||
"collaboration",
|
||||
"synchronization",
|
||||
"ShareJS",
|
||||
"Coweb",
|
||||
"concurrency"
|
||||
],
|
||||
"license": "MIT",
|
||||
"ignore": [
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"test",
|
||||
"extras",
|
||||
"test"
|
||||
],
|
||||
"devDependencies": {}
|
||||
}
|
291
Examples/bower_components/y-text/y-text.es6
vendored
Normal file
291
Examples/bower_components/y-text/y-text.es6
vendored
Normal file
@ -0,0 +1,291 @@
|
||||
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
|
||||
/* global Y */
|
||||
'use strict'
|
||||
|
||||
function extend (Y) {
|
||||
Y.requestModules(['Array']).then(function () {
|
||||
class YText extends Y.Array['class'] {
|
||||
constructor (os, _model, idArray, valArray) {
|
||||
super(os, _model, idArray, valArray)
|
||||
this.textfields = []
|
||||
}
|
||||
toString () {
|
||||
return this.valArray.join('')
|
||||
}
|
||||
insert (pos, content) {
|
||||
super.insert(pos, content.split(''))
|
||||
}
|
||||
bind (textfield, domRoot) {
|
||||
domRoot = domRoot || window; // eslint-disable-line
|
||||
if (domRoot.getSelection == null) {
|
||||
domRoot = window;// eslint-disable-line
|
||||
}
|
||||
|
||||
// don't duplicate!
|
||||
for (var t in this.textfields) {
|
||||
if (this.textfields[t] === textfield) {
|
||||
return
|
||||
}
|
||||
}
|
||||
var creatorToken = false
|
||||
|
||||
var word = this
|
||||
textfield.value = this.toString()
|
||||
this.textfields.push(textfield)
|
||||
var createRange, writeRange, writeContent
|
||||
if (textfield.selectionStart != null && textfield.setSelectionRange != null) {
|
||||
createRange = function (fix) {
|
||||
var left = textfield.selectionStart
|
||||
var right = textfield.selectionEnd
|
||||
if (fix != null) {
|
||||
left = fix(left)
|
||||
right = fix(right)
|
||||
}
|
||||
return {
|
||||
left: left,
|
||||
right: right
|
||||
}
|
||||
}
|
||||
writeRange = function (range) {
|
||||
writeContent(word.toString())
|
||||
textfield.setSelectionRange(range.left, range.right)
|
||||
}
|
||||
writeContent = function (content) {
|
||||
textfield.value = content
|
||||
}
|
||||
} else {
|
||||
createRange = function (fix) {
|
||||
var range = {}
|
||||
var s = domRoot.getSelection()
|
||||
var clength = textfield.textContent.length
|
||||
range.left = Math.min(s.anchorOffset, clength)
|
||||
range.right = Math.min(s.focusOffset, clength)
|
||||
if (fix != null) {
|
||||
range.left = fix(range.left)
|
||||
range.right = fix(range.right)
|
||||
}
|
||||
var editedElement = s.focusNode
|
||||
if (editedElement === textfield || editedElement === textfield.childNodes[0]) {
|
||||
range.isReal = true
|
||||
} else {
|
||||
range.isReal = false
|
||||
}
|
||||
return range
|
||||
}
|
||||
|
||||
writeRange = function (range) {
|
||||
writeContent(word.toString())
|
||||
var textnode = textfield.childNodes[0]
|
||||
if (range.isReal && textnode != null) {
|
||||
if (range.left < 0) {
|
||||
range.left = 0
|
||||
}
|
||||
range.right = Math.max(range.left, range.right)
|
||||
if (range.right > textnode.length) {
|
||||
range.right = textnode.length
|
||||
}
|
||||
range.left = Math.min(range.left, range.right)
|
||||
var r = document.createRange(); // eslint-disable-line
|
||||
r.setStart(textnode, range.left)
|
||||
r.setEnd(textnode, range.right)
|
||||
var s = window.getSelection(); // eslint-disable-line
|
||||
s.removeAllRanges()
|
||||
s.addRange(r)
|
||||
}
|
||||
}
|
||||
writeContent = function (content) {
|
||||
var contentArray = content.replace(new RegExp('\n', 'g'), ' ').split(' ');// eslint-disable-line
|
||||
textfield.innerText = ''
|
||||
for (var i in contentArray) {
|
||||
var c = contentArray[i]
|
||||
textfield.innerText += c
|
||||
if (i !== contentArray.length - 1) {
|
||||
textfield.innerHTML += ' '
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
writeContent(this.toString())
|
||||
|
||||
this.observe(function (events) {
|
||||
for (var e in events) {
|
||||
var event = events[e]
|
||||
if (!creatorToken) {
|
||||
var oPos, fix
|
||||
if (event.type === 'insert') {
|
||||
oPos = event.index
|
||||
fix = function (cursor) {// eslint-disable-line
|
||||
if (cursor <= oPos) {
|
||||
return cursor
|
||||
} else {
|
||||
cursor += 1
|
||||
return cursor
|
||||
}
|
||||
}
|
||||
var r = createRange(fix)
|
||||
writeRange(r)
|
||||
} else if (event.type === 'delete') {
|
||||
oPos = event.index
|
||||
fix = function (cursor) {// eslint-disable-line
|
||||
if (cursor < oPos) {
|
||||
return cursor
|
||||
} else {
|
||||
cursor -= 1
|
||||
return cursor
|
||||
}
|
||||
}
|
||||
r = createRange(fix)
|
||||
writeRange(r)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
// consume all text-insert changes.
|
||||
textfield.onkeypress = function (event) {
|
||||
if (word.is_deleted) {
|
||||
// if word is deleted, do not do anything ever again
|
||||
textfield.onkeypress = null
|
||||
return true
|
||||
}
|
||||
creatorToken = true
|
||||
var char
|
||||
if (event.keyCode === 13) {
|
||||
char = '\n'
|
||||
} else if (event.key != null) {
|
||||
if (event.charCode === 32) {
|
||||
char = ' '
|
||||
} else {
|
||||
char = event.key
|
||||
}
|
||||
} else {
|
||||
char = window.String.fromCharCode(event.keyCode); // eslint-disable-line
|
||||
}
|
||||
if (char.length > 1) {
|
||||
return true
|
||||
} else if (char.length > 0) {
|
||||
var r = createRange()
|
||||
var pos = Math.min(r.left, r.right, word.length)
|
||||
var diff = Math.abs(r.right - r.left)
|
||||
word.delete(pos, diff)
|
||||
word.insert(pos, char)
|
||||
r.left = pos + char.length
|
||||
r.right = r.left
|
||||
writeRange(r)
|
||||
}
|
||||
event.preventDefault()
|
||||
creatorToken = false
|
||||
return false
|
||||
}
|
||||
textfield.onpaste = function (event) {
|
||||
if (word.is_deleted) {
|
||||
// if word is deleted, do not do anything ever again
|
||||
textfield.onpaste = null
|
||||
return true
|
||||
}
|
||||
event.preventDefault()
|
||||
}
|
||||
textfield.oncut = function (event) {
|
||||
if (word.is_deleted) {
|
||||
// if word is deleted, do not do anything ever again
|
||||
textfield.oncut = null
|
||||
return true
|
||||
}
|
||||
event.preventDefault()
|
||||
}
|
||||
//
|
||||
// consume deletes. Note that
|
||||
// chrome: won't consume deletions on keypress event.
|
||||
// keyCode is deprecated. BUT: I don't see another way.
|
||||
// since event.key is not implemented in the current version of chrome.
|
||||
// Every browser supports keyCode. Let's stick with it for now..
|
||||
//
|
||||
textfield.onkeydown = function (event) {
|
||||
creatorToken = true
|
||||
if (word.is_deleted) {
|
||||
// if word is deleted, do not do anything ever again
|
||||
textfield.onkeydown = null
|
||||
return true
|
||||
}
|
||||
var r = createRange()
|
||||
var pos = Math.min(r.left, r.right, word.toString().length)
|
||||
var diff = Math.abs(r.left - r.right)
|
||||
if (event.keyCode != null && event.keyCode === 8) { // Backspace
|
||||
if (diff > 0) {
|
||||
word.delete(pos, diff)
|
||||
r.left = pos
|
||||
r.right = pos
|
||||
writeRange(r)
|
||||
} else {
|
||||
if (event.ctrlKey != null && event.ctrlKey) {
|
||||
var val = word.toString()
|
||||
var newPos = pos
|
||||
var delLength = 0
|
||||
if (pos > 0) {
|
||||
newPos--
|
||||
delLength++
|
||||
}
|
||||
while (newPos > 0 && val[newPos] !== ' ' && val[newPos] !== '\n') {
|
||||
newPos--
|
||||
delLength++
|
||||
}
|
||||
word.delete(newPos, pos - newPos)
|
||||
r.left = newPos
|
||||
r.right = newPos
|
||||
writeRange(r)
|
||||
} else {
|
||||
if (pos > 0) {
|
||||
word.delete(pos - 1, 1)
|
||||
r.left = pos - 1
|
||||
r.right = pos - 1
|
||||
writeRange(r)
|
||||
}
|
||||
}
|
||||
}
|
||||
event.preventDefault()
|
||||
creatorToken = false
|
||||
return false
|
||||
} else if (event.keyCode != null && event.keyCode === 46) { // Delete
|
||||
if (diff > 0) {
|
||||
word.delete(pos, diff)
|
||||
r.left = pos
|
||||
r.right = pos
|
||||
writeRange(r)
|
||||
} else {
|
||||
word.delete(pos, 1)
|
||||
r.left = pos
|
||||
r.right = pos
|
||||
writeRange(r)
|
||||
}
|
||||
event.preventDefault()
|
||||
creatorToken = false
|
||||
return false
|
||||
} else {
|
||||
creatorToken = false
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Y.extend('Text', new Y.utils.CustomType({
|
||||
name: 'Text',
|
||||
class: YText,
|
||||
struct: 'List',
|
||||
initType: function * YTextInitializer (os, model) {
|
||||
var valArray = []
|
||||
var idArray = yield* Y.Struct.List.map.call(this, model, function (c) {
|
||||
valArray.push(c.content)
|
||||
return JSON.stringify(c.id)
|
||||
})
|
||||
return new YText(os, model.id, idArray, valArray)
|
||||
}
|
||||
}))
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = extend
|
||||
if (typeof Y !== 'undefined') {
|
||||
extend(Y)
|
||||
}
|
||||
|
||||
},{}]},{},[1])
|
||||
|
1
Examples/bower_components/y-text/y-text.es6.map
vendored
Normal file
1
Examples/bower_components/y-text/y-text.es6.map
vendored
Normal file
File diff suppressed because one or more lines are too long
2
Examples/bower_components/y-text/y-text.js
vendored
Normal file
2
Examples/bower_components/y-text/y-text.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
Examples/bower_components/y-text/y-text.js.map
vendored
Normal file
1
Examples/bower_components/y-text/y-text.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
37
Examples/bower_components/y-webrtc/.bower.json
vendored
Normal file
37
Examples/bower_components/y-webrtc/.bower.json
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
{
|
||||
"name": "y-webrtc",
|
||||
"main": "y-webrtc.js",
|
||||
"version": "0.7.1",
|
||||
"homepage": "http://y-js.org",
|
||||
"authors": [
|
||||
"Kevin Jahns <kevin.jahns@rwth-aachen.de>"
|
||||
],
|
||||
"description": "WebRTC connector for Yjs",
|
||||
"moduleType": [
|
||||
"globals",
|
||||
"node"
|
||||
],
|
||||
"keywords": [
|
||||
"Yjs",
|
||||
"connector",
|
||||
"webrtc"
|
||||
],
|
||||
"license": "MIT",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"test",
|
||||
"tests"
|
||||
],
|
||||
"_release": "0.7.1",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "v0.7.1",
|
||||
"commit": "8620167b9feceaf4940b6fd0a7be60243e362420"
|
||||
},
|
||||
"_source": "git://github.com/y-js/y-webrtc.git",
|
||||
"_target": "~0.7.1",
|
||||
"_originalSource": "y-webrtc",
|
||||
"_direct": true
|
||||
}
|
70
Examples/bower_components/y-webrtc/README.md
vendored
Normal file
70
Examples/bower_components/y-webrtc/README.md
vendored
Normal file
@ -0,0 +1,70 @@
|
||||
# WebRTC Connector for [Yjs](https://github.com/y-js/yjs)
|
||||
|
||||
|
||||
It propagates document updates directly to all users via WebRTC. While WebRTC is not the most reliable connector, messages are propagated with almost no delay.
|
||||
|
||||
* Very fast message propagation (not noticeable)
|
||||
* Very easy to use
|
||||
* Very little server load (you still have to set up a [signaling server](http://www.html5rocks.com/en/tutorials/webrtc/infrastructure/))
|
||||
* Not suited for a large amount of collaborators
|
||||
* WebRTC is not supported in all browsers, and some have troubles communicating with each other
|
||||
|
||||
We provide you with a free signaling server (it is used by default), but in production you should set up your own signaling server. You could use the [signalmaster](https://github.com/andyet/signalmaster) from &yet, which is very easy to set up.
|
||||
|
||||
## Use it!
|
||||
Retrieve this with bower or npm, and use it as a js library or as a custom polymer element.
|
||||
|
||||
##### NPM
|
||||
```
|
||||
npm install y-webrtc --save
|
||||
```
|
||||
and put it on the `Y` object.
|
||||
|
||||
```
|
||||
Y.WebRTC = require("y-webrtc");
|
||||
```
|
||||
|
||||
##### Bower
|
||||
```
|
||||
bower install y-webrtc --save
|
||||
```
|
||||
|
||||
##### Polymer
|
||||
On the website you find a bunch of examples on how you can use Yjs as polymer element.
|
||||
```
|
||||
<link rel="import" href="../y-webrtc/y-webrtc.html">
|
||||
<y-webrtc connector={{connector}} room="my-room-name"></y-webrtc>
|
||||
```
|
||||
|
||||
### Create the connection object
|
||||
This connector uses [SimpleWebRTC](https://simplewebrtc.com/) as an underlaying WebRTC framework, which supports the concept of rooms.
|
||||
|
||||
```
|
||||
var options = {};
|
||||
var conn = new Y.WebRTC("my_room_name", options); // will connect to the default signaling server
|
||||
```
|
||||
|
||||
On the options object you can put the following properties:
|
||||
* url (optional)
|
||||
* Set the url of your signaling server. E.g. url = "https://yatta.ninja:8888" (which is the default endpoint)
|
||||
* debug (optional)
|
||||
* Whether to enable debugging mode (defaults to false)
|
||||
|
||||
# Start Hacking
|
||||
This connector is also a nice starting point to build your own connector. The only 75 SLOCs of code are pretty well documented and understandable. If you have any troubles, don't hesitate to ask me for help!
|
||||
|
||||
### Directory Structure
|
||||
* lib/
|
||||
* Source files
|
||||
* build/browser
|
||||
* Unminified, but [browserified](http://browserify.org/) source files
|
||||
* build/node
|
||||
* npm modules
|
||||
|
||||
|
||||
## License
|
||||
Yjs is licensed under the [MIT License](./LICENSE.txt).
|
||||
|
||||
<kevin.jahns@rwth-aachen.de>
|
||||
|
||||
|
27
Examples/bower_components/y-webrtc/bower.json
vendored
Normal file
27
Examples/bower_components/y-webrtc/bower.json
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
{
|
||||
"name": "y-webrtc",
|
||||
"main": "y-webrtc.js",
|
||||
"version": "0.7.2",
|
||||
"homepage": "http://y-js.org",
|
||||
"authors": [
|
||||
"Kevin Jahns <kevin.jahns@rwth-aachen.de>"
|
||||
],
|
||||
"description": "WebRTC connector for Yjs",
|
||||
"moduleType": [
|
||||
"globals",
|
||||
"node"
|
||||
],
|
||||
"keywords": [
|
||||
"Yjs",
|
||||
"connector",
|
||||
"webrtc"
|
||||
],
|
||||
"license": "MIT",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"test",
|
||||
"tests"
|
||||
]
|
||||
}
|
11656
Examples/bower_components/y-webrtc/y-webrtc.es6
vendored
Normal file
11656
Examples/bower_components/y-webrtc/y-webrtc.es6
vendored
Normal file
File diff suppressed because one or more lines are too long
1
Examples/bower_components/y-webrtc/y-webrtc.es6.map
vendored
Normal file
1
Examples/bower_components/y-webrtc/y-webrtc.es6.map
vendored
Normal file
File diff suppressed because one or more lines are too long
6
Examples/bower_components/y-webrtc/y-webrtc.js
vendored
Normal file
6
Examples/bower_components/y-webrtc/y-webrtc.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
Examples/bower_components/y-webrtc/y-webrtc.js.map
vendored
Normal file
1
Examples/bower_components/y-webrtc/y-webrtc.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
37
Examples/bower_components/y-websockets-client/.bower.json
vendored
Normal file
37
Examples/bower_components/y-websockets-client/.bower.json
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
{
|
||||
"name": "y-websockets-client",
|
||||
"main": "y-websockets-client.js",
|
||||
"version": "0.7.10",
|
||||
"homepage": "http://y-js.org",
|
||||
"authors": [
|
||||
"Kevin Jahns <kevin.jahns@rwth-aachen.de>"
|
||||
],
|
||||
"description": "Websockets connector for Yjs (browser/node client)",
|
||||
"moduleType": [
|
||||
"globals",
|
||||
"node"
|
||||
],
|
||||
"keywords": [
|
||||
"Yjs",
|
||||
"connector",
|
||||
"websockets"
|
||||
],
|
||||
"license": "MIT",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"test",
|
||||
"tests"
|
||||
],
|
||||
"_release": "0.7.10",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "v0.7.10",
|
||||
"commit": "b5ce42502dae6ad3cb0bf7b1d5a615af91876f1c"
|
||||
},
|
||||
"_source": "git://github.com/y-js/y-websockets-client.git",
|
||||
"_target": "~0.7.10",
|
||||
"_originalSource": "y-websockets-client",
|
||||
"_direct": true
|
||||
}
|
1
Examples/bower_components/y-websockets-client/README.md
vendored
Normal file
1
Examples/bower_components/y-websockets-client/README.md
vendored
Normal file
@ -0,0 +1 @@
|
||||
# Websockets Connector for [Yjs](https://github.com/y-js/yjs)
|
27
Examples/bower_components/y-websockets-client/bower.json
vendored
Normal file
27
Examples/bower_components/y-websockets-client/bower.json
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
{
|
||||
"name": "y-websockets-client",
|
||||
"main": "y-websockets-client.js",
|
||||
"version": "0.7.11",
|
||||
"homepage": "http://y-js.org",
|
||||
"authors": [
|
||||
"Kevin Jahns <kevin.jahns@rwth-aachen.de>"
|
||||
],
|
||||
"description": "Websockets connector for Yjs (browser/node client)",
|
||||
"moduleType": [
|
||||
"globals",
|
||||
"node"
|
||||
],
|
||||
"keywords": [
|
||||
"Yjs",
|
||||
"connector",
|
||||
"websockets"
|
||||
],
|
||||
"license": "MIT",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"test",
|
||||
"tests"
|
||||
]
|
||||
}
|
54
Examples/bower_components/y-websockets-client/package.json
vendored
Normal file
54
Examples/bower_components/y-websockets-client/package.json
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
{
|
||||
"name": "y-websockets-client",
|
||||
"version": "0.7.1",
|
||||
"description": "Websockets connector for Yjs (browser/node client)",
|
||||
"main": "./src/Websockets-client.js",
|
||||
"scripts": {
|
||||
"test": "node --harmony ./node_modules/.bin/gulp test",
|
||||
"lint": "./node_modules/.bin/standard"
|
||||
},
|
||||
"pre-commit": [
|
||||
"lint",
|
||||
"test"
|
||||
],
|
||||
"standard": {
|
||||
"parser": "babel-eslint",
|
||||
"ignore": [
|
||||
"build/**",
|
||||
"dist/**"
|
||||
]
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/y-js/y-websockets-client.git"
|
||||
},
|
||||
"keywords": [
|
||||
"Yjs",
|
||||
"Connector"
|
||||
],
|
||||
"author": "Kevin Jahns <kevin.jahns@rwth-aachen.de>",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/y-js/y-websockets-client/issues"
|
||||
},
|
||||
"homepage": "http://y-js.org",
|
||||
"dependencies": {
|
||||
"socket.io-client": "^1.3.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-eslint": "^4.1.4",
|
||||
"babel-plugin-transform-runtime": "^6.1.18",
|
||||
"babel-preset-es2015": "^6.1.18",
|
||||
"babel-runtime": "^6.1.18",
|
||||
"babelify": "^7.2.0",
|
||||
"fs": "0.0.2",
|
||||
"gulp": "^3.9.0",
|
||||
"gulp-load-plugins": "^1.1.0",
|
||||
"gulp-prompt": "^0.1.2",
|
||||
"http": "0.0.0",
|
||||
"pre-commit": "^1.1.2",
|
||||
"run-sequence": "^1.1.4",
|
||||
"socket.io": "^1.3.7",
|
||||
"standard": "^5.3.1"
|
||||
}
|
||||
}
|
7340
Examples/bower_components/y-websockets-client/y-websockets-client.es6
vendored
Normal file
7340
Examples/bower_components/y-websockets-client/y-websockets-client.es6
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
Examples/bower_components/y-websockets-client/y-websockets-client.es6.map
vendored
Normal file
1
Examples/bower_components/y-websockets-client/y-websockets-client.es6.map
vendored
Normal file
File diff suppressed because one or more lines are too long
4
Examples/bower_components/y-websockets-client/y-websockets-client.js
vendored
Normal file
4
Examples/bower_components/y-websockets-client/y-websockets-client.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
Examples/bower_components/y-websockets-client/y-websockets-client.js.map
vendored
Normal file
1
Examples/bower_components/y-websockets-client/y-websockets-client.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
29
Examples/bower_components/yjs/.bower.json
vendored
Normal file
29
Examples/bower_components/yjs/.bower.json
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
{
|
||||
"name": "yjs",
|
||||
"version": "0.7.6",
|
||||
"homepage": "y-js.org",
|
||||
"authors": [
|
||||
"Kevin Jahns <kevin.jahns@rwth-aachen.de>"
|
||||
],
|
||||
"description": "A Framework that enables Real-Time collaboration on arbitrary data structures.",
|
||||
"main": "y.js",
|
||||
"keywords": [
|
||||
"OT",
|
||||
"collaboration",
|
||||
"synchronization",
|
||||
"sharejs",
|
||||
"coweb",
|
||||
"concurrency"
|
||||
],
|
||||
"license": "MIT",
|
||||
"_release": "0.7.6",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "v0.7.6",
|
||||
"commit": "eee80e1755379a2f39e9d0ed780bf29975256575"
|
||||
},
|
||||
"_source": "git://github.com/y-js/yjs.git",
|
||||
"_target": "~0.7.6",
|
||||
"_originalSource": "yjs",
|
||||
"_direct": true
|
||||
}
|
8
Examples/bower_components/yjs/.gitignore
vendored
Normal file
8
Examples/bower_components/yjs/.gitignore
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
node_modules
|
||||
Examples/bower_components
|
||||
.directory
|
||||
.codio
|
||||
.settings
|
||||
.jshintignore
|
||||
.jshintrc
|
||||
.validate.json
|
18
Examples/bower_components/yjs/Examples/Chat/index.html
vendored
Normal file
18
Examples/bower_components/yjs/Examples/Chat/index.html
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<style>
|
||||
#chat p span {
|
||||
color: blue;
|
||||
}
|
||||
</style>
|
||||
<div id="chat"></div>
|
||||
<form id="chatform">
|
||||
<input name="username" type="text" style="width:15%;">
|
||||
<input name="message" type="text" style="width:60%;">
|
||||
<input type="submit" value="Send">
|
||||
</form>
|
||||
<script src="../bower_components/yjs/y.js"></script>
|
||||
<script src="./index.js"></script>
|
||||
</body>
|
||||
</html>
|
75
Examples/bower_components/yjs/Examples/Chat/index.js
vendored
Normal file
75
Examples/bower_components/yjs/Examples/Chat/index.js
vendored
Normal file
@ -0,0 +1,75 @@
|
||||
/* @flow */
|
||||
/* global Y */
|
||||
|
||||
// initialize a shared object. This function call returns a promise!
|
||||
Y({
|
||||
db: {
|
||||
name: 'memory'
|
||||
},
|
||||
connector: {
|
||||
name: 'websockets-client',
|
||||
room: 'chat-example'
|
||||
// debug: true,
|
||||
// url: 'http://127.0.0.1:2345'
|
||||
},
|
||||
sourceDir: '/bower_components',
|
||||
share: {
|
||||
chat: 'Array'
|
||||
}
|
||||
}).then(function (y) {
|
||||
window.y = y
|
||||
// This functions inserts a message at the specified position in the DOM
|
||||
function appendMessage(message, position) {
|
||||
var p = document.createElement('p')
|
||||
var uname = document.createElement('span')
|
||||
uname.appendChild(document.createTextNode(message.username + ": "))
|
||||
p.appendChild(uname)
|
||||
p.appendChild(document.createTextNode(message.message))
|
||||
document.querySelector('#chat').insertBefore(p, chat.children[position] || null)
|
||||
}
|
||||
// This function makes sure that only 7 messages exist in the chat history.
|
||||
// The rest is deleted
|
||||
function cleanupChat () {
|
||||
var len
|
||||
while ((len = y.share.chat.length) > 7) {
|
||||
y.share.chat.delete(0)
|
||||
}
|
||||
}
|
||||
// Insert the initial content
|
||||
y.share.chat.toArray().forEach(appendMessage)
|
||||
cleanupChat()
|
||||
|
||||
// whenever content changes, make sure to reflect the changes in the DOM
|
||||
y.share.chat.observe(function (events) {
|
||||
for (var i = 0; i < events.length; i++) {
|
||||
if (events[i].type === 'insert') {
|
||||
appendMessage(events[i].value, events[i].index)
|
||||
} else if (events[i].type === 'delete') {
|
||||
chat.children[events[i].index].remove()
|
||||
}
|
||||
}
|
||||
// concurrent insertions may result in a history > 7, so cleanup here
|
||||
cleanupChat()
|
||||
})
|
||||
document.querySelector('#chatform').onsubmit = function (event) {
|
||||
// the form is submitted
|
||||
var message = {
|
||||
username: this.querySelector("[name=username]").value,
|
||||
message: this.querySelector("[name=message]").value
|
||||
}
|
||||
if (message.username.length > 0 && message.message.length > 0) {
|
||||
if (y.share.chat.length > 6) {
|
||||
// If we are goint to insert the 8th element, make sure to delete first.
|
||||
y.share.chat.delete(0)
|
||||
}
|
||||
// Here we insert a message in the shared chat type.
|
||||
// This will call the observe function (see line 40)
|
||||
// and reflect the change in the DOM
|
||||
y.share.chat.push([message])
|
||||
this.querySelector("[name=message]").value = ""
|
||||
}
|
||||
// Do not send this form!
|
||||
event.preventDefault()
|
||||
return false
|
||||
}
|
||||
})
|
23
Examples/bower_components/yjs/Examples/Jigsaw/index.html
vendored
Normal file
23
Examples/bower_components/yjs/Examples/Jigsaw/index.html
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style type="text/css">
|
||||
.draggable {
|
||||
cursor: move;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<svg id="puzzle-example" width="100%" viewBox="0 0 800 800">
|
||||
<g>
|
||||
<path d="M 311.76636,154.23389 C 312.14136,171.85693 318.14087,184.97998 336.13843,184.23047 C 354.13647,183.48047 351.88647,180.48096 354.88599,178.98096 C 357.8855,177.48096 368.38452,170.35693 380.00806,169.98193 C 424.61841,168.54297 419.78296,223.6001 382.25757,223.6001 C 377.75806,223.6001 363.51001,219.10107 356.38599,211.97656 C 349.26196,204.85254 310.64185,207.10254 314.76636,236.34863 C 316.34888,247.5708 324.08374,267.90723 324.84595,286.23486 C 325.29321,296.99414 323.17603,307.00635 321.58911,315.6377 C 360.11353,305.4585 367.73462,304.30518 404.00513,312.83936 C 410.37915,314.33887 436.62573,310.21436 421.25269,290.3418 C 405.87964,270.46924 406.25464,248.34717 417.12817,240.84814 C 428.00171,233.34912 446.74976,228.84961 457.99829,234.09912 C 469.24683,239.34814 484.61987,255.84619 475.24585,271.59424 C 465.87231,287.34229 452.74878,290.7168 456.49829,303.84033 C 460.2478,316.96387 479.74536,320.33838 500.74292,321.83789 C 509.70142,322.47803 527.97192,323.28467 542.10864,320.12939 C 549.91821,318.38672 556.92212,315.89502 562.46753,313.56396 C 561.40796,277.80664 560.84888,245.71729 560.3606,241.97314 C 558.85278,230.41455 542.49536,217.28564 525.86499,223.2251 C 520.61548,225.1001 519.86548,231.84912 505.24243,232.59912 C 444.92798,235.69238 462.06958,143.26709 525.86499,180.48096 C 539.52759,188.45068 575.19409,190.7583 570.10913,156.85889 C 567.85962,141.86035 553.98608,102.86523 553.98608,102.86523 C 553.98608,102.86523 477.23755,111.82227 451.99878,91.991699 C 441.50024,83.74292 444.87476,69.494629 449.37427,61.245605 C 453.87378,52.996582 465.12231,46.622559 464.74731,36.123779 C 463.02563,-12.086426 392.96704,-10.902832 396.5061,36.873535 C 397.25562,46.997314 406.62964,52.621582 410.75415,60.495605 C 420.00757,78.161377 405.50024,96.073486 384.50757,99.490723 C 377.36206,100.65381 349.17505,102.65332 320.39429,102.23486 C 319.677,102.22461 318.95923,102.21143 318.24194,102.19775 C 315.08423,120.9751 311.55688,144.39697 311.76636,154.23389 z " style="fill:#f2c569;stroke:#000000" id="path2502"/>
|
||||
<path d="M 500.74292,321.83789 C 479.74536,320.33838 460.2478,316.96387 456.49829,303.84033 C 452.74878,290.7168 465.87231,287.34229 475.24585,271.59424 C 484.61987,255.84619 469.24683,239.34814 457.99829,234.09912 C 446.74976,228.84961 428.00171,233.34912 417.12817,240.84814 C 406.25464,248.34717 405.87964,270.46924 421.25269,290.3418 C 436.62573,310.21436 410.37915,314.33887 404.00513,312.83936 C 367.73462,304.30518 360.11353,305.4585 321.58911,315.6377 C 320.56372,321.21484 319.75854,326.2207 320.01538,330.46191 C 320.76538,342.83545 329.3894,385.95508 327.8894,392.7041 C 326.3894,399.45312 313.64136,418.20117 297.89331,407.32715 C 282.14526,396.45361 276.52075,393.4541 265.27222,394.5791 C 254.02368,395.70361 239.77563,402.07812 239.77563,419.32568 C 239.77563,436.57373 250.27417,449.69727 268.64673,447.82227 C 287.36353,445.9126 317.92163,423.11035 325.63989,452.69678 C 330.1394,469.94434 330.51392,487.19238 330.1394,498.44092 C 329.95825,503.87646 326.09985,518.06592 322.16089,531.28125 C 353.2854,532.73682 386.47095,531.26611 394.2561,529.93701 C 430.30933,523.78174 429.31909,496.09766 412.62866,477.44385 C 406.25464,470.31934 401.75513,455.32129 405.87964,444.82275 C 414.07056,423.97314 458.8064,422.17773 473.37134,438.82324 C 483.86987,450.82178 475.99585,477.44385 468.49683,482.69287 C 453.52222,493.17529 457.22485,516.83008 473.37134,528.06201 C 504.79126,549.91943 572.35913,535.56152 572.35913,535.56152 C 572.35913,535.56152 567.85962,498.06592 567.48462,471.81934 C 567.10962,445.57275 589.60669,450.07227 593.3562,450.07227 C 597.10571,450.07227 604.22974,455.32129 609.47925,459.4458 C 614.72876,463.57031 618.85327,469.94434 630.85181,470.69434 C 677.43726,473.60596 674.58813,420.7373 631.97632,413.32666 C 623.35229,411.82666 614.72876,416.32617 603.10522,424.57519 C 591.48169,432.82422 577.23315,425.32519 570.10913,417.45117 C 566.07788,412.99561 563.8479,360.16406 562.46753,313.56396 C 556.92212,315.89502 549.91821,318.38672 542.10864,320.12939 C 527.97192,323.28467 509.70142,322.47803 500.74292,321.83789 z " style="fill:#f3f3d6;stroke:#000000" id="path2504"/>
|
||||
<path d="M 240.52563,141.86035 C 257.60327,159.6499 243.94507,188.68799 214.65356,190.22949 C 185.09448,191.78516 164.66675,157.17822 190.28589,136.61621 C 200.49585,128.42139 198.05786,114.12158 179.78296,106.98975 C 154.4187,97.091553 90.54419,107.73975 90.54419,107.73975 C 90.54419,107.73975 100.88794,135.11328 101.41772,168.48242 C 101.79272,192.104 68.796875,189.47949 63.172607,186.85498 C 57.54834,184.23047 45.924805,173.73145 37.675781,173.73145 C -14.411865,173.73145 -10.013184,245.84375 39.925537,232.22412 C 48.174316,229.97461 56.42334,220.97559 68.796875,222.47559 C 81.17041,223.9751 87.544434,232.59912 87.544434,246.09766 C 87.544434,252.51709 87.0354,281.24268 86.340576,312.87012 C 119.15894,313.67676 160.60962,314.46582 170.03442,313.58887 C 186.15698,312.08936 195.90601,301.59033 188.40698,293.3418 C 180.90796,285.09277 156.16089,256.59619 179.03296,239.34814 C 201.90503,222.10059 235.65112,231.84912 239.77563,247.22217 C 243.90015,262.59521 240.52563,273.46924 234.90112,279.09326 C 229.27661,284.71777 210.52905,298.96582 221.40259,308.71484 C 232.27661,318.46338 263.77222,330.83691 302.39282,320.71338 C 309.58862,318.82715 315.92114,317.13525 321.58911,315.6377 C 323.17603,307.00635 325.29321,296.99414 324.84595,286.23486 C 324.08374,267.90723 316.34888,247.5708 314.76636,236.34863 C 310.64185,207.10254 349.26196,204.85254 356.38599,211.97656 C 363.51001,219.10107 377.75806,223.6001 382.25757,223.6001 C 419.78296,223.6001 424.61841,168.54297 380.00806,169.98193 C 368.38452,170.35693 357.8855,177.48096 354.88599,178.98096 C 351.88647,180.48096 354.13647,183.48047 336.13843,184.23047 C 318.14087,184.97998 312.14136,171.85693 311.76636,154.23389 C 311.55688,144.39697 315.08423,120.9751 318.24194,102.19775 C 290.37524,101.67725 262.46069,98.968262 254.39868,97.991211 C 233.38013,95.443359 217.17456,117.53662 240.52563,141.86035 z " style="fill:#bebcdb;stroke:#000000" id="path2506"/>
|
||||
<path d="M 325.63989,452.69678 C 317.92163,423.11035 287.36353,445.9126 268.64673,447.82227 C 250.27417,449.69727 239.77563,436.57373 239.77563,419.32568 C 239.77563,402.07812 254.02368,395.70361 265.27222,394.5791 C 276.52075,393.4541 282.14526,396.45361 297.89331,407.32715 C 313.64136,418.20117 326.3894,399.45313 327.8894,392.7041 C 329.3894,385.95508 320.76538,342.83545 320.01538,330.46191 C 319.75855,326.2207 320.56372,321.21484 321.58911,315.6377 C 315.92114,317.13525 309.58862,318.82715 302.39282,320.71338 C 263.77222,330.83691 232.27661,318.46338 221.40259,308.71484 C 210.52905,298.96582 229.27661,284.71777 234.90112,279.09326 C 240.52563,273.46924 243.90015,262.59521 239.77563,247.22217 C 235.65112,231.84912 201.90503,222.10059 179.03296,239.34814 C 156.16089,256.59619 180.90796,285.09277 188.40698,293.3418 C 195.90601,301.59033 186.15698,312.08936 170.03442,313.58887 C 160.60962,314.46582 119.15894,313.67676 86.340576,312.87012 C 85.573975,347.74561 84.581299,386.15088 83.794922,402.07812 C 82.295166,432.44922 109.29175,422.32568 115.66577,420.82568 C 122.04028,419.32568 126.16479,409.57715 143.03735,408.45215 C 185.9231,405.59326 186.09985,466.69629 144.16235,467.69482 C 128.41431,468.06982 113.79126,451.19678 108.16675,447.44727 C 102.54272,443.69775 87.919433,442.94775 83.794922,457.9458 C 82.01709,464.41113 78.118652,481.65137 78.098144,496.18994 C 78.071045,515.38037 82.295166,531.81201 82.295166,531.81201 C 82.295166,531.81201 105.54224,526.5625 149.41187,526.5625 C 193.28149,526.5625 199.65552,547.93506 194.78101,558.80859 C 189.90649,569.68213 181.28296,568.93213 179.40796,583.18066 C 172.7063,634.11133 253.34106,631.08203 249.14917,584.68018 C 247.96948,571.62354 237.16528,571.66699 232.27661,557.68359 C 222.17944,528.80273 244.64966,523.56299 257.39819,524.68799 C 263.59351,525.23437 290.95679,529.73389 320.75757,531.21582 C 321.22437,531.23877 321.69312,531.25928 322.16089,531.28125 C 326.09985,518.06592 329.95825,503.87646 330.1394,498.44092 C 330.51392,487.19238 330.1394,469.94434 325.63989,452.69678 z " style="fill:#d3ea9d;stroke:#000000" id="path2508"/>
|
||||
</g>
|
||||
</svg>
|
||||
<script src="../bower_components/yjs/y.js"></script>
|
||||
<script src="../bower_components/d3/d3.js"></script>
|
||||
<script src="./index.js"></script>
|
||||
</body>
|
||||
</html>
|
70
Examples/bower_components/yjs/Examples/Jigsaw/index.js
vendored
Normal file
70
Examples/bower_components/yjs/Examples/Jigsaw/index.js
vendored
Normal file
@ -0,0 +1,70 @@
|
||||
/* @flow */
|
||||
/* global Y, d3 */
|
||||
|
||||
// initialize a shared object. This function call returns a promise!
|
||||
Y({
|
||||
db: {
|
||||
name: 'memory'
|
||||
},
|
||||
connector: {
|
||||
name: 'websockets-client',
|
||||
room: 'Puzzle-example2'
|
||||
// debug: true,
|
||||
// url: 'http://127.0.0.1:2345'
|
||||
},
|
||||
sourceDir: '/bower_components',
|
||||
share: {
|
||||
piece1: 'Map',
|
||||
piece2: 'Map',
|
||||
piece3: 'Map',
|
||||
piece4: 'Map'
|
||||
}
|
||||
}).then(function (y) {
|
||||
var origin // mouse start position - translation of piece
|
||||
var drag = d3.behavior.drag()
|
||||
.on('dragstart', function (params) {
|
||||
// get the translation of the element
|
||||
var translation = d3.select(this).attr('transform').slice(10,-1).split(',').map(Number)
|
||||
// mouse coordinates
|
||||
var mouse = d3.mouse(this.parentNode)
|
||||
origin = {
|
||||
x: mouse[0] - translation[0],
|
||||
y: mouse[1] - translation[1]
|
||||
}
|
||||
})
|
||||
.on("drag", function(){
|
||||
var mouse = d3.mouse(this.parentNode)
|
||||
var x = mouse[0] - origin.x // =^= mouse - mouse at dragstart + translation at dragstart
|
||||
var y = mouse[1] - origin.y
|
||||
d3.select(this).attr("transform", "translate(" + x + "," + y + ")")
|
||||
})
|
||||
.on('dragend', function (piece, i) {
|
||||
// save the current translation of the puzzle piece
|
||||
var mouse = d3.mouse(this.parentNode)
|
||||
var x = mouse[0] - origin.x
|
||||
var y = mouse[1] - origin.y
|
||||
piece.set('translation', {x: x, y: y})
|
||||
})
|
||||
|
||||
var data = [y.share.piece1, y.share.piece2, y.share.piece3, y.share.piece4]
|
||||
var pieces = d3.select(document.querySelector("#puzzle-example")).selectAll("path").data(data)
|
||||
|
||||
pieces
|
||||
.classed('draggable', true)
|
||||
.attr("transform", function (piece) {
|
||||
var translation = piece.get('translation') || {x: 0, y: 0}
|
||||
return "translate(" + translation.x + "," + translation.y + ")"
|
||||
}).call(drag)
|
||||
|
||||
data.forEach(function(piece){
|
||||
piece.observe(function () {
|
||||
// whenever a property of a piece changes, update the translation of the pieces
|
||||
pieces
|
||||
.transition()
|
||||
.attr("transform", function (piece) {
|
||||
var translation = piece.get('translation') || {x: 0, y: 0}
|
||||
return "translate(" + translation.x + "," + translation.y + ")"
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
145
Examples/bower_components/yjs/Examples/Quill/index.html
vendored
Normal file
145
Examples/bower_components/yjs/Examples/Quill/index.html
vendored
Normal file
@ -0,0 +1,145 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" href="../bower_components/quill/dist/quill.snow.css" />
|
||||
<style>
|
||||
#quill {
|
||||
border: 1px solid gray;
|
||||
box-shadow: 0px 0px 10px gray;
|
||||
}
|
||||
#toolbar {
|
||||
border-bottom: 1px solid gray;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="quill">
|
||||
<!-- Create the toolbar container -->
|
||||
<div id="toolbar" class="toolbar">
|
||||
<span class="ql-format-group">
|
||||
<select title="Font" class="ql-font">
|
||||
<option value="sans-serif" selected="">Sans Serif</option>
|
||||
<option value="serif">Serif</option>
|
||||
<option value="monospace">Monospace</option>
|
||||
</select>
|
||||
<select title="Size" class="ql-size">
|
||||
<option value="10px">Small</option>
|
||||
<option value="13px" selected="">Normal</option>
|
||||
<option value="18px">Large</option>
|
||||
<option value="32px">Huge</option>
|
||||
</select>
|
||||
</span>
|
||||
<span class="ql-format-group">
|
||||
<span title="Bold" class="ql-format-button ql-bold"></span>
|
||||
<span class="ql-format-separator"></span>
|
||||
<span title="Italic" class="ql-format-button ql-italic"></span>
|
||||
<span class="ql-format-separator"></span>
|
||||
<span title="Underline" class="ql-format-button ql-underline"></span>
|
||||
<span class="ql-format-separator"></span>
|
||||
<span title="Strikethrough" class="ql-format-button ql-strike"></span>
|
||||
</span>
|
||||
<span class="ql-format-group">
|
||||
<select title="Text Color" class="ql-color">
|
||||
<option value="rgb(0, 0, 0)" label="rgb(0, 0, 0)" selected=""></option>
|
||||
<option value="rgb(230, 0, 0)" label="rgb(230, 0, 0)"></option>
|
||||
<option value="rgb(255, 153, 0)" label="rgb(255, 153, 0)"></option>
|
||||
<option value="rgb(255, 255, 0)" label="rgb(255, 255, 0)"></option>
|
||||
<option value="rgb(0, 138, 0)" label="rgb(0, 138, 0)"></option>
|
||||
<option value="rgb(0, 102, 204)" label="rgb(0, 102, 204)"></option>
|
||||
<option value="rgb(153, 51, 255)" label="rgb(153, 51, 255)"></option>
|
||||
<option value="rgb(255, 255, 255)" label="rgb(255, 255, 255)"></option>
|
||||
<option value="rgb(250, 204, 204)" label="rgb(250, 204, 204)"></option>
|
||||
<option value="rgb(255, 235, 204)" label="rgb(255, 235, 204)"></option>
|
||||
<option value="rgb(255, 255, 204)" label="rgb(255, 255, 204)"></option>
|
||||
<option value="rgb(204, 232, 204)" label="rgb(204, 232, 204)"></option>
|
||||
<option value="rgb(204, 224, 245)" label="rgb(204, 224, 245)"></option>
|
||||
<option value="rgb(235, 214, 255)" label="rgb(235, 214, 255)"></option>
|
||||
<option value="rgb(187, 187, 187)" label="rgb(187, 187, 187)"></option>
|
||||
<option value="rgb(240, 102, 102)" label="rgb(240, 102, 102)"></option>
|
||||
<option value="rgb(255, 194, 102)" label="rgb(255, 194, 102)"></option>
|
||||
<option value="rgb(255, 255, 102)" label="rgb(255, 255, 102)"></option>
|
||||
<option value="rgb(102, 185, 102)" label="rgb(102, 185, 102)"></option>
|
||||
<option value="rgb(102, 163, 224)" label="rgb(102, 163, 224)"></option>
|
||||
<option value="rgb(194, 133, 255)" label="rgb(194, 133, 255)"></option>
|
||||
<option value="rgb(136, 136, 136)" label="rgb(136, 136, 136)"></option>
|
||||
<option value="rgb(161, 0, 0)" label="rgb(161, 0, 0)"></option>
|
||||
<option value="rgb(178, 107, 0)" label="rgb(178, 107, 0)"></option>
|
||||
<option value="rgb(178, 178, 0)" label="rgb(178, 178, 0)"></option>
|
||||
<option value="rgb(0, 97, 0)" label="rgb(0, 97, 0)"></option>
|
||||
<option value="rgb(0, 71, 178)" label="rgb(0, 71, 178)"></option>
|
||||
<option value="rgb(107, 36, 178)" label="rgb(107, 36, 178)"></option>
|
||||
<option value="rgb(68, 68, 68)" label="rgb(68, 68, 68)"></option>
|
||||
<option value="rgb(92, 0, 0)" label="rgb(92, 0, 0)"></option>
|
||||
<option value="rgb(102, 61, 0)" label="rgb(102, 61, 0)"></option>
|
||||
<option value="rgb(102, 102, 0)" label="rgb(102, 102, 0)"></option>
|
||||
<option value="rgb(0, 55, 0)" label="rgb(0, 55, 0)"></option>
|
||||
<option value="rgb(0, 41, 102)" label="rgb(0, 41, 102)"></option>
|
||||
<option value="rgb(61, 20, 102)" label="rgb(61, 20, 102)"></option>
|
||||
</select>
|
||||
<span class="ql-format-separator"></span>
|
||||
<select title="Background Color" class="ql-background">
|
||||
<option value="rgb(0, 0, 0)" label="rgb(0, 0, 0)"></option>
|
||||
<option value="rgb(230, 0, 0)" label="rgb(230, 0, 0)"></option>
|
||||
<option value="rgb(255, 153, 0)" label="rgb(255, 153, 0)"></option>
|
||||
<option value="rgb(255, 255, 0)" label="rgb(255, 255, 0)"></option>
|
||||
<option value="rgb(0, 138, 0)" label="rgb(0, 138, 0)"></option>
|
||||
<option value="rgb(0, 102, 204)" label="rgb(0, 102, 204)"></option>
|
||||
<option value="rgb(153, 51, 255)" label="rgb(153, 51, 255)"></option>
|
||||
<option value="rgb(255, 255, 255)" label="rgb(255, 255, 255)" selected=""></option>
|
||||
<option value="rgb(250, 204, 204)" label="rgb(250, 204, 204)"></option>
|
||||
<option value="rgb(255, 235, 204)" label="rgb(255, 235, 204)"></option>
|
||||
<option value="rgb(255, 255, 204)" label="rgb(255, 255, 204)"></option>
|
||||
<option value="rgb(204, 232, 204)" label="rgb(204, 232, 204)"></option>
|
||||
<option value="rgb(204, 224, 245)" label="rgb(204, 224, 245)"></option>
|
||||
<option value="rgb(235, 214, 255)" label="rgb(235, 214, 255)"></option>
|
||||
<option value="rgb(187, 187, 187)" label="rgb(187, 187, 187)"></option>
|
||||
<option value="rgb(240, 102, 102)" label="rgb(240, 102, 102)"></option>
|
||||
<option value="rgb(255, 194, 102)" label="rgb(255, 194, 102)"></option>
|
||||
<option value="rgb(255, 255, 102)" label="rgb(255, 255, 102)"></option>
|
||||
<option value="rgb(102, 185, 102)" label="rgb(102, 185, 102)"></option>
|
||||
<option value="rgb(102, 163, 224)" label="rgb(102, 163, 224)"></option>
|
||||
<option value="rgb(194, 133, 255)" label="rgb(194, 133, 255)"></option>
|
||||
<option value="rgb(136, 136, 136)" label="rgb(136, 136, 136)"></option>
|
||||
<option value="rgb(161, 0, 0)" label="rgb(161, 0, 0)"></option>
|
||||
<option value="rgb(178, 107, 0)" label="rgb(178, 107, 0)"></option>
|
||||
<option value="rgb(178, 178, 0)" label="rgb(178, 178, 0)"></option>
|
||||
<option value="rgb(0, 97, 0)" label="rgb(0, 97, 0)"></option>
|
||||
<option value="rgb(0, 71, 178)" label="rgb(0, 71, 178)"></option>
|
||||
<option value="rgb(107, 36, 178)" label="rgb(107, 36, 178)"></option>
|
||||
<option value="rgb(68, 68, 68)" label="rgb(68, 68, 68)"></option>
|
||||
<option value="rgb(92, 0, 0)" label="rgb(92, 0, 0)"></option>
|
||||
<option value="rgb(102, 61, 0)" label="rgb(102, 61, 0)"></option>
|
||||
<option value="rgb(102, 102, 0)" label="rgb(102, 102, 0)"></option>
|
||||
<option value="rgb(0, 55, 0)" label="rgb(0, 55, 0)"></option>
|
||||
<option value="rgb(0, 41, 102)" label="rgb(0, 41, 102)"></option>
|
||||
<option value="rgb(61, 20, 102)" label="rgb(61, 20, 102)"></option>
|
||||
</select>
|
||||
</span>
|
||||
<span class="ql-format-group">
|
||||
<span title="List" class="ql-format-button ql-list"></span>
|
||||
<span class="ql-format-separator"></span>
|
||||
<span title="Bullet" class="ql-format-button ql-bullet"></span>
|
||||
<span class="ql-format-separator"></span>
|
||||
<select title="Text Alignment" class="ql-align">
|
||||
<option value="left" label="Left" selected=""></option>
|
||||
<option value="center" label="Center"></option>
|
||||
<option value="right" label="Right"></option>
|
||||
<option value="justify" label="Justify"></option>
|
||||
</select>
|
||||
</span>
|
||||
<span class="ql-format-group">
|
||||
<span title="Link" class="ql-format-button ql-link"></span>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- Create the editor container -->
|
||||
<div id="editor">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Include the Quill library -->
|
||||
<script src="../bower_components/quill/dist/quill.js"></script>
|
||||
<script src="../bower_components/yjs/y.es6"></script>
|
||||
<script src="./index.js"></script>
|
||||
</body>
|
||||
</html>
|
32
Examples/bower_components/yjs/Examples/Quill/index.js
vendored
Normal file
32
Examples/bower_components/yjs/Examples/Quill/index.js
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
/* global Y, Quill */
|
||||
|
||||
// initialize a shared object. This function call returns a promise!
|
||||
|
||||
Y({
|
||||
db: {
|
||||
name: 'memory'
|
||||
},
|
||||
connector: {
|
||||
name: 'websockets-client',
|
||||
room: 'richtext-example18',
|
||||
debug: true
|
||||
//url: 'http://127.0.0.1:2345'
|
||||
},
|
||||
sourceDir: '/bower_components',
|
||||
share: {
|
||||
richtext: 'Richtext' // y.share.richtext is of type Y.Richtext
|
||||
}
|
||||
}).then(function (y) {
|
||||
window.yquill = y
|
||||
|
||||
// create quill element
|
||||
window.quill = new Quill('#editor', {
|
||||
modules: {
|
||||
'toolbar': { container: '#toolbar' },
|
||||
'link-tooltip': true
|
||||
},
|
||||
theme: 'snow'
|
||||
})
|
||||
// bind quill to richtext type
|
||||
y.share.richtext.bind(window.quill)
|
||||
})
|
8
Examples/bower_components/yjs/Examples/Textarea/index.html
vendored
Normal file
8
Examples/bower_components/yjs/Examples/Textarea/index.html
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<textarea style="width:80%;" rows=40 id="textfield" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"></textarea>
|
||||
<script src="../bower_components/yjs/y.js"></script>
|
||||
<script src="./index.js"></script>
|
||||
</body>
|
||||
</html>
|
24
Examples/bower_components/yjs/Examples/Textarea/index.js
vendored
Normal file
24
Examples/bower_components/yjs/Examples/Textarea/index.js
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
/* global Y */
|
||||
|
||||
// initialize a shared object. This function call returns a promise!
|
||||
Y({
|
||||
db: {
|
||||
name: 'memory'
|
||||
},
|
||||
connector: {
|
||||
name: 'websockets-client',
|
||||
room: 'Textarea-example-dev'
|
||||
// debug: true
|
||||
// url: 'http://127.0.0.1:2345'
|
||||
},
|
||||
sourceDir: '/bower_components',
|
||||
share: {
|
||||
textarea: 'Text' // y.share.textarea is of type Y.Text
|
||||
}
|
||||
}).then(function (y) {
|
||||
window.y = y
|
||||
|
||||
// bind the textarea to a shared text element
|
||||
y.share.textarea.bind(document.getElementById('textfield'))
|
||||
// thats it..
|
||||
})
|
15
Examples/bower_components/yjs/Examples/bower.json
vendored
Normal file
15
Examples/bower_components/yjs/Examples/bower.json
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
"name": "yjs-examples",
|
||||
"version": "0.0",
|
||||
"homepage": "y-js.org",
|
||||
"authors": [
|
||||
"Kevin Jahns <kevin.jahns@rwth-aachen.de>"
|
||||
],
|
||||
"description": "Examples for yjs",
|
||||
"license": "MIT",
|
||||
"ignore": [],
|
||||
"dependencies": {
|
||||
"yjs": "../",
|
||||
"y-webrtc": "~0.6.4"
|
||||
}
|
||||
}
|
23
Examples/bower_components/yjs/LICENSE
vendored
Normal file
23
Examples/bower_components/yjs/LICENSE
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014
|
||||
- Kevin Jahns <kevin.jahns@rwth-aachen.de>.
|
||||
- Chair of Computer Science 5 (Databases & Information Systems), RWTH Aachen University, Germany
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
147
Examples/bower_components/yjs/README.md
vendored
Normal file
147
Examples/bower_components/yjs/README.md
vendored
Normal file
@ -0,0 +1,147 @@
|
||||
|
||||
# 
|
||||
|
||||
Yjs is a framework for optimistic concurrency control and automatic conflict resolution on shared data types. The framework implements a new OT-like concurrency algorithm and provides similar functionality as [ShareJs] and [OpenCoweb]. Yjs was designed to handle concurrent actions on arbitrary complex data types like Text, Json, and XML. We provide a tutorial and some applications for this framework on our [homepage](http://y-js.org/).
|
||||
|
||||
**NOTE** This project is currently migrating. So there may exist some information that is not true anymore..
|
||||
|
||||
You can create you own shared types easily. Therefore, you can take matters into your own hand by defining the meaning of the shared types and ensure that it is valid, while Yjs ensures data consistency (everyone will eventually end up with the same data). We already provide data types for
|
||||
|
||||
| Name | Description |
|
||||
|----------|-------------------|
|
||||
|[map](https://github.com/y-js/y-map) | Add, update, and remove properties of an object. Included in Yjs|
|
||||
|[array](https://github.com/y-js/y-array) | A shared linked list implementation |
|
||||
|[selections](https://github.com/y-js/y-selections) | Manages selections on types that use linear structures (e.g. the y-array type). Select a range of elements, and assign meaning to them.|
|
||||
|[xml](https://github.com/y-js/y-xml) | An implementation of the DOM. You can create a two way binding to Browser DOM objects|
|
||||
|[text](https://github.com/y-js/y-text) | Collaborate on text. Supports two way binding to textareas, input elements, or HTML elements (e.g. *h1*, or *p*)|
|
||||
|[richtext](https://github.com/y-js/y-richtext) | Collaborate on rich text. Supports two way binding to several editors|
|
||||
|
||||
Unlike other frameworks, Yjs supports P2P message propagation and is not bound to a specific communication protocol. Therefore, Yjs is extremely scalable and can be used in a wide range of application scenarios.
|
||||
|
||||
We support several communication protocols as so called *Connectors*. You can create your own connector too - read [this wiki page](https://github.com/y-js/yjs/wiki/Custom-Connectors). Currently, we support the following communication protocols:
|
||||
|
||||
|Name | Description |
|
||||
|----------------|-----------------------------------|
|
||||
|[xmpp](https://github.com/y-js/y-xmpp) | Propagate updates in a XMPP multi-user-chat room ([XEP-0045](http://xmpp.org/extensions/xep-0045.html))|
|
||||
|[webrtc](https://github.com/y-js/y-webrtc) | Propagate updates Browser2Browser via WebRTC|
|
||||
|[test](https://github.com/y-js/y-test) | A Connector for testing purposes. It is designed to simulate delays that happen in worst case scenarios|
|
||||
|
||||
|
||||
You can use Yjs client-, and server- side. You can get it as via npm, and bower. We even provide polymer elements for Yjs!
|
||||
|
||||
The advantages over similar frameworks are support for
|
||||
* .. P2P message propagation and arbitrary communication protocols
|
||||
* .. arbitrary complex data types
|
||||
* .. offline editing: Changes are stored persistently and only relevant changes are propagated on rejoin
|
||||
* .. AnyUndo: Undo *any* action that was executed in constant time (coming..)
|
||||
* .. Intention Preservation: When working on Text, the intention of your changes are preserved. This is particularily important when working offline. Every type has a notion on how we define Intention Preservation on it.
|
||||
|
||||
## Use it!
|
||||
You can find a tutorial, and examples on the [website](http://y-js.org). Furthermore, the [github wiki](https://github.com/y-js/yjs/wiki) offers more information about how you can use Yjs in your application.
|
||||
|
||||
Either clone this git repository, install it with [bower](http://bower.io/), or install it with [npm](https://www.npmjs.org/package/yjs).
|
||||
|
||||
### Bower
|
||||
```
|
||||
bower install y-js/yjs
|
||||
```
|
||||
Then you include the libraries directly from the installation folder.
|
||||
```
|
||||
<script src="./bower_components/yjs/y.js"></script>
|
||||
```
|
||||
|
||||
### Npm
|
||||
```
|
||||
npm install yjs --save
|
||||
```
|
||||
|
||||
And use it like this with *npm*:
|
||||
```
|
||||
Y = require("yjs");
|
||||
```
|
||||
|
||||
# Y()
|
||||
In order to create an instance of Y, you need to have a connection object (instance of a Connector). Then, you can create a shared data type like this:
|
||||
```
|
||||
var y = new Y(connector);
|
||||
```
|
||||
|
||||
|
||||
# Y.Map
|
||||
Yjs includes only one type by default - the Y.Map type. It mimics the behaviour of a javascript Object. You can create, update, and remove properies on the Y.Map type. Furthermore, you can observe changes on this type as you can observe changes on Javascript Objects with [Object.observe](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/observe) - an ECMAScript 7 proposal which is likely to become accepted by the committee. Until then, we have our own implementation.
|
||||
|
||||
|
||||
##### Reference
|
||||
* Create
|
||||
```
|
||||
var map = y.set("new_map", Y.Map).then(function(map){
|
||||
map // is my map type
|
||||
});
|
||||
```
|
||||
* Every instance of Y is an Y.Map
|
||||
```
|
||||
var y = new Y(options);
|
||||
```
|
||||
* .get(name)
|
||||
* Retrieve the value of a property. If the value is a type, `.get(name)` returns a promise
|
||||
* .set(name, value)
|
||||
* Set/update a property. `value` may be a primitive type, or a custom type definition (e.g. `Y.Map`)
|
||||
* .delete(name)
|
||||
* Delete a property
|
||||
* .observe(observer)
|
||||
* The `observer` is called whenever something on this object changes. Throws *add*, *update*, and *delete* events
|
||||
* .observePath(path, observer)
|
||||
* `path` is an array of property names. `observer` is called when the property under `path` is set, deleted, or updated
|
||||
* .unobserve(f)
|
||||
* Delete an observer
|
||||
|
||||
# A note on intention preservation
|
||||
When users create/update/delete the same property concurrently, only one change will prevail. Changes on different properties do not conflict with each other.
|
||||
|
||||
# A note on time complexities
|
||||
* .get(name)
|
||||
* O(1)
|
||||
* .set(name, value)
|
||||
* O(1)
|
||||
* .delete(name)
|
||||
* O(1)
|
||||
* Apply a delete operation from another user
|
||||
* O(1)
|
||||
* Apply an update operation from another user (set/update a property)
|
||||
* Yjs does not transform against operations that do not conflict with each other.
|
||||
* An operation conflicts with another operation if it changes the same property.
|
||||
* Overall worst case complexety: O(|conflicts|!)
|
||||
|
||||
# Status
|
||||
Yjs is a work in progress. Different versions of the *y-* repositories may not work together. Just drop me a line if you run into troubles.
|
||||
|
||||
## Get help
|
||||
There are some friendly people on [](https://gitter.im/y-js/yjs?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) who may help you with your problem, and answer your questions.
|
||||
|
||||
Please report _any_ issues to the [Github issue page](https://github.com/y-js/yjs/issues)! I try to fix them very soon, if possible.
|
||||
|
||||
## Changelog
|
||||
### 1.0.0
|
||||
This is a complete rewrite of the 0.5 version of Yjs. Since Yjs 1.0 it is possible to work asynchronously on a persistent database, which enables offline support.
|
||||
* Switched to semver versioning
|
||||
* Requires a promise implementation in environment (es6 promises suffice, included in all the major browsers). Otherwise you have to include a polyfill
|
||||
* Y.Object has been renamed to Y.Map
|
||||
* Y.Map exchanges `.val(name [, value])` in favor of `.set(name, value)` and `.get(name)`
|
||||
* Y.Map `.get(name)` returns a promise, if the value is a custom type
|
||||
* The Connector definition slightly changed (I'll update the wiki)
|
||||
* The Type definitions completely changed, so you have to rewrite them (I'll rewrite the article in the wiki)
|
||||
* Support for several packaging systems
|
||||
* Flowtype
|
||||
|
||||
|
||||
## Contribution
|
||||
I created this framework during my bachelor thesis at the chair of computer science 5 [(i5)](http://dbis.rwth-aachen.de/cms), RWTH University. Since December 2014 I'm working on Yjs as a part of my student worker job at the i5.
|
||||
|
||||
## License
|
||||
Yjs is licensed under the [MIT License](./LICENSE.txt).
|
||||
|
||||
<yjs@dbis.rwth-aachen.de>
|
||||
|
||||
[ShareJs]: https://github.com/share/ShareJS
|
||||
[OpenCoweb]: https://github.com/opencoweb/coweb/wiki
|
||||
|
19
Examples/bower_components/yjs/bower.json
vendored
Normal file
19
Examples/bower_components/yjs/bower.json
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "yjs",
|
||||
"version": "0.7.7",
|
||||
"homepage": "y-js.org",
|
||||
"authors": [
|
||||
"Kevin Jahns <kevin.jahns@rwth-aachen.de>"
|
||||
],
|
||||
"description": "A Framework that enables Real-Time collaboration on arbitrary data structures.",
|
||||
"main": "y.js",
|
||||
"keywords": [
|
||||
"OT",
|
||||
"collaboration",
|
||||
"synchronization",
|
||||
"sharejs",
|
||||
"coweb",
|
||||
"concurrency"
|
||||
],
|
||||
"license": "MIT"
|
||||
}
|
2386
Examples/bower_components/yjs/y.es6
vendored
Normal file
2386
Examples/bower_components/yjs/y.es6
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
Examples/bower_components/yjs/y.es6.map
vendored
Normal file
1
Examples/bower_components/yjs/y.es6.map
vendored
Normal file
File diff suppressed because one or more lines are too long
3
Examples/bower_components/yjs/y.js
vendored
Normal file
3
Examples/bower_components/yjs/y.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
Examples/bower_components/yjs/y.js.map
vendored
Normal file
1
Examples/bower_components/yjs/y.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "yjs",
|
||||
"version": "0.7.7",
|
||||
"version": "0.8.1",
|
||||
"homepage": "y-js.org",
|
||||
"authors": [
|
||||
"Kevin Jahns <kevin.jahns@rwth-aachen.de>"
|
||||
|
114
y.es6
114
y.es6
@ -1909,34 +1909,8 @@ module.exports = function (Y/* :any */) {
|
||||
})
|
||||
return ss
|
||||
}
|
||||
* getOperations (startSS) {
|
||||
// TODO: use bounds here!
|
||||
if (startSS == null) {
|
||||
startSS = {}
|
||||
}
|
||||
var ops = []
|
||||
|
||||
var endSV = yield* this.getStateVector()
|
||||
for (var endState of endSV) {
|
||||
var user = endState.user
|
||||
if (user === '_') {
|
||||
continue
|
||||
}
|
||||
var startPos = startSS[user] || 0
|
||||
|
||||
yield* this.os.iterate(this, [user, startPos], [user, Number.MAX_VALUE], function * (op) {
|
||||
ops.push(op)
|
||||
})
|
||||
}
|
||||
var res = []
|
||||
for (var op of ops) {
|
||||
var o = yield* this.makeOperationReady(startSS, op)
|
||||
res.push(o)
|
||||
}
|
||||
return res
|
||||
}
|
||||
/*
|
||||
Here, we make op executable for the receiving user.
|
||||
Here, we make all missing operations executable for the receiving user.
|
||||
|
||||
Notes:
|
||||
startSS: denotes to the SV that the remote user sent
|
||||
@ -1971,7 +1945,92 @@ module.exports = function (Y/* :any */) {
|
||||
(startSS or currSS.. ?)
|
||||
-> Could be necessary when I turn GC again.
|
||||
-> Is a bad(ish) idea because it requires more computation
|
||||
|
||||
What we do:
|
||||
* Iterate over all missing operations.
|
||||
* When there is an operation, where the right op is known, send this op all missing ops to the left to the user
|
||||
* I explained above what we have to do with each operation. Here is how we do it efficiently:
|
||||
1. Go to the left until you find either op.origin, or a known operation (let o denote current operation in the iteration)
|
||||
2. Found a known operation -> set op.left = o, and send it to the user. stop
|
||||
3. Found o = op.origin -> set op.left = op.origin, and send it to the user. start again from 1. (set op = o)
|
||||
4. Found some o -> set o.right = op, o.left = o.origin, send it to the user, continue
|
||||
*/
|
||||
* getOperations (startSS) {
|
||||
// TODO: use bounds here!
|
||||
if (startSS == null) {
|
||||
startSS = {}
|
||||
}
|
||||
var send = []
|
||||
|
||||
var endSV = yield* this.getStateVector()
|
||||
for (var endState of endSV) {
|
||||
var user = endState.user
|
||||
if (user === '_') {
|
||||
continue
|
||||
}
|
||||
var startPos = startSS[user] || 0
|
||||
|
||||
yield* this.os.iterate(this, [user, startPos], [user, Number.MAX_VALUE], function * (op) {
|
||||
op = Y.Struct[op.struct].encode(op)
|
||||
if (op.struct !== 'Insert') {
|
||||
send.push(op)
|
||||
} else if (op.right == null || op.right[1] < (startSS[op.right[0]] || 0)) {
|
||||
// case 1. op.right is known
|
||||
var o = op
|
||||
// Remember: ?
|
||||
// -> set op.right
|
||||
// 1. to the first operation that is known (according to startSS)
|
||||
// 2. or to the first operation that has an origin that is not to the
|
||||
// right of op.
|
||||
// For this we maintain a list of ops which origins are not found yet.
|
||||
var missing_origins = [op]
|
||||
var newright = op.right
|
||||
while (true) {
|
||||
if (o.left == null) {
|
||||
op.left = null
|
||||
send.push(op)
|
||||
if (!Y.utils.compareIds(o.id, op.id)) {
|
||||
o = Y.Struct[op.struct].encode(o)
|
||||
o.right = missing_origins[missing_origins.length - 1].id
|
||||
send.push(o)
|
||||
}
|
||||
break
|
||||
}
|
||||
o = yield* this.getOperation(o.left)
|
||||
// we set another o, check if we can reduce $missing_origins
|
||||
while (missing_origins.length > 0 && Y.utils.compareIds(missing_origins[missing_origins.length - 1].origin, o.id)) {
|
||||
missing_origins.pop()
|
||||
}
|
||||
if (o.id[1] < (startSS[o.id[0]] || 0)) {
|
||||
// case 2. o is known
|
||||
op.left = o.id
|
||||
send.push(op)
|
||||
break
|
||||
} else if (Y.utils.compareIds(o.id, op.origin)) {
|
||||
// case 3. o is op.origin
|
||||
op.left = op.origin
|
||||
send.push(op)
|
||||
op = Y.Struct[op.struct].encode(o)
|
||||
op.right = newright
|
||||
if (missing_origins.length > 0) {
|
||||
console.log('This should not happen .. :( please report this')
|
||||
}
|
||||
missing_origins = [op]
|
||||
} else {
|
||||
// case 4. send o, continue to find op.origin
|
||||
var s = Y.Struct[op.struct].encode(o)
|
||||
s.right = missing_origins[missing_origins.length - 1].id
|
||||
s.left = s.origin
|
||||
send.push(s)
|
||||
missing_origins.push(o)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
return send
|
||||
}
|
||||
/* this is what we used before.. use this as a reference..
|
||||
* makeOperationReady (startSS, op) {
|
||||
op = Y.Struct[op.struct].encode(op)
|
||||
op = Y.utils.copyObject(op)
|
||||
@ -1995,6 +2054,7 @@ module.exports = function (Y/* :any */) {
|
||||
op.left = op.origin
|
||||
return op
|
||||
}
|
||||
*/
|
||||
}
|
||||
Y.Transaction = TransactionInterface
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user