fixed bower & added dependencies & cleanup
This commit is contained in:
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": {}
|
||||
}
|
||||
529
Examples/bower_components/y-richtext/y-richtext.es6
vendored
Normal file
529
Examples/bower_components/y-richtext/y-richtext.es6
vendored
Normal file
@@ -0,0 +1,529 @@
|
||||
(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, _content) {
|
||||
super(os, _model, _content)
|
||||
this.instances = []
|
||||
}
|
||||
_destroy () {
|
||||
for (var i = this.instances.length - 1; i >= 0; i--) {
|
||||
this.unbindQuill(this.instances[i].editor)
|
||||
}
|
||||
super._destroy()
|
||||
}
|
||||
get length () {
|
||||
/*
|
||||
TODO: I must not use observe to compute the length.
|
||||
But since I inherit from Y.Array, I can't set observe
|
||||
the changes at the right momet (for that I would require direct access to EventHandler).
|
||||
This is the most elegant solution, for now.
|
||||
But at some time you should re-write Y.Richtext more elegantly!!
|
||||
*/
|
||||
return this.toString().length
|
||||
}
|
||||
toString () {
|
||||
return this._content.map(function (v) {
|
||||
if (typeof v.val === 'string') {
|
||||
return v.val
|
||||
}
|
||||
}).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._content.length; i++) {
|
||||
let v = this._content[i].val
|
||||
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._content.length; i++) {
|
||||
if (curPos === pos) {
|
||||
break
|
||||
}
|
||||
var v = this._content[i].val
|
||||
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 _content
|
||||
var delEnd // ..
|
||||
var v, i // helper variable for elements of _content
|
||||
|
||||
for (delStart = 0; curPos < pos && delStart < this._content.length; delStart++) {
|
||||
v = this._content[delStart].val
|
||||
if (typeof v === 'string') {
|
||||
curPos++
|
||||
} else if (v.constructor === Array) {
|
||||
curSel[v[0]] = v[1]
|
||||
}
|
||||
}
|
||||
for (delEnd = delStart; curPos < endPos && delEnd < this._content.length; delEnd++) {
|
||||
v = this._content[delEnd].val
|
||||
if (typeof v === 'string') {
|
||||
curPos++
|
||||
}
|
||||
}
|
||||
if (delEnd === this._content.length) {
|
||||
// yay, you can delete everything without checking
|
||||
for (i = delEnd - 1; i >= delStart; i--) {
|
||||
v = this._content[i].val
|
||||
super.delete(i, 1)
|
||||
}
|
||||
} else {
|
||||
if (typeof v === 'string') {
|
||||
delEnd--
|
||||
}
|
||||
var rightSel = {}
|
||||
for (i = delEnd; i >= delStart; i--) {
|
||||
v = this._content[i].val
|
||||
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._content.length; i++) {
|
||||
let v = this._content[i].val
|
||||
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._content.length; i++) {
|
||||
let v = this._content[i].val
|
||||
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 < _content.length)
|
||||
// 2. when a similar attrName already exists between i and the next character
|
||||
if (antiAttrs[1] !== attrValue && i < this._content.length) { // check 1.
|
||||
var performStep4 = true
|
||||
var v
|
||||
for (j = i; j < this._content.length; j++) {
|
||||
v = this._content[j].val
|
||||
if (v.constructor !== Array) {
|
||||
break
|
||||
}
|
||||
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; j >= 0; j--) {
|
||||
v = this._content[j].val
|
||||
if (v.constructor !== Array) {
|
||||
break
|
||||
}
|
||||
if (v[0] === attrName) {
|
||||
super.delete(j, 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
bind () {
|
||||
this.bindQuill.apply(this, arguments)
|
||||
}
|
||||
unbindQuill (quill) {
|
||||
var i = this.instances.findIndex(function (binding) {
|
||||
return binding.editor === quill
|
||||
})
|
||||
if (i >= 0) {
|
||||
var binding = this.instances[i]
|
||||
this.unobserve(binding.yCallback)
|
||||
binding.editor.off('text-change', binding.quillCallback)
|
||||
this.instances.splice(i, 1)
|
||||
}
|
||||
}
|
||||
bindQuill (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())
|
||||
|
||||
function quillCallback (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) {
|
||||
let additionalContent = quill.getText(self.length)
|
||||
quill.insertText(self.length, additionalContent)
|
||||
// quill.deleteText(self.length + additionalContent.length, quill.getLength())
|
||||
for (name in op.attributes) {
|
||||
quill.formatText(self.length + additionalContent.length, self.length + additionalContent.length * 2, name, null)
|
||||
// quill.deleteText(self.length, self.length + op.retain)
|
||||
}
|
||||
self.insert(self.length, additionalContent)
|
||||
// op.attributes = null
|
||||
}
|
||||
for (name in op.attributes) {
|
||||
self.select(pos, pos + op.retain, name, op.attributes[name])
|
||||
quill.formatText(pos, pos + op.retain, name, op.attributes[name])
|
||||
}
|
||||
pos = afterRetain
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
quill.on('text-change', quillCallback)
|
||||
|
||||
function yCallback (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._content[l].val
|
||||
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._content[j].val
|
||||
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._content[j].val
|
||||
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._content.length; k++) {
|
||||
v = self._content[k].val
|
||||
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._content[u].val
|
||||
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._content[i].val.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._content[x].val
|
||||
if (v.constructor === Array) {
|
||||
if (v[0] === event.value[0]) {
|
||||
curSel = v[1]
|
||||
break
|
||||
}
|
||||
} else if (typeof v === 'string') {
|
||||
from++
|
||||
}
|
||||
}
|
||||
for (; x >= 0; x--) {
|
||||
v = self._content[x].val
|
||||
if (typeof v === 'string') {
|
||||
from++
|
||||
}
|
||||
}
|
||||
var to = from
|
||||
for (x = event.index; x < self._content.length; x++) {
|
||||
v = self._content[x].val
|
||||
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()
|
||||
})
|
||||
}
|
||||
this.observe(yCallback)
|
||||
this.instances.push({
|
||||
editor: quill,
|
||||
yCallback: yCallback,
|
||||
quillCallback: quillCallback
|
||||
})
|
||||
}
|
||||
* _changed () {
|
||||
this.instances.forEach(function (instance) {
|
||||
instance.editor.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 _content = yield* Y.Struct.List.map.call(this, model, function (c) {
|
||||
return {
|
||||
id: JSON.stringify(c.id),
|
||||
val: c.content
|
||||
}
|
||||
})
|
||||
return new YRichtext(os, model.id, _content)
|
||||
}
|
||||
}))
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = extend
|
||||
if (typeof Y !== 'undefined') {
|
||||
extend(Y)
|
||||
}
|
||||
|
||||
},{}]},{},[1])
|
||||
|
||||
1
Examples/bower_components/y-richtext/y-richtext.es6.map
vendored
Normal file
1
Examples/bower_components/y-richtext/y-richtext.es6.map
vendored
Normal file
File diff suppressed because one or more lines are too long
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
1
Examples/bower_components/y-richtext/y-richtext.js.map
vendored
Normal file
1
Examples/bower_components/y-richtext/y-richtext.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user