Comparing version 1.0.0-beta.3 to 1.0.0-beta.4
@@ -20,27 +20,25 @@ import extend from 'extend'; | ||
delta() { | ||
return new Delta().insert(this.value(), this.formats()).insert('\n', this.attributes.values()); | ||
return new Delta().insert(this.value(), extend(this.formats(), this.attributes.values())); | ||
} | ||
formatAt(index, length, format, value) { | ||
if (index + length === this.length()) { | ||
let attribute = Parchment.query(format, Parchment.Scope.ATTRIBUTE); | ||
if (attribute != null) { | ||
this.attributes.attribute(attribute, value); | ||
} | ||
if (length <= 1) return; | ||
format(name, value) { | ||
let attribute = Parchment.query(name, Parchment.Scope.BLOCK_ATTRIBUTE); | ||
if (attribute != null) { | ||
this.attributes.attribute(attribute, value); | ||
} | ||
this.format(format, value); | ||
} | ||
formatAt(index, length, name, value) { | ||
this.format(name, value); | ||
} | ||
insertAt(index, value, def) { | ||
if (typeof value === 'string' && value.startsWith('\n')) { | ||
let block = Parchment.create('block'); | ||
if (typeof value === 'string' && value.endsWith('\n')) { | ||
let block = Parchment.create(Block.blotName); | ||
this.parent.insertBefore(block, index === 0 ? this : this.next); | ||
block.insertAt(0, value.slice(1)); | ||
block.insertAt(0, value.slice(0, -1)); | ||
} else { | ||
super.insertAt(index, value, def); | ||
} | ||
} | ||
length() { | ||
return super.length() + NEWLINE_LENGTH; | ||
} | ||
} | ||
@@ -47,0 +45,0 @@ BlockEmbed.scope = Parchment.Scope.BLOCK_BLOT; |
@@ -25,2 +25,7 @@ import Parchment from 'parchment'; | ||
detach() { | ||
// super.detach() will also clear domNode.__blot | ||
if (this.parent != null) this.parent.children.remove(this); | ||
} | ||
format(name, value) { | ||
@@ -65,2 +70,6 @@ if (this._length !== 0) { | ||
let range = this.selection.getNativeRange(); | ||
// Link format will insert text outside of anchor tag | ||
while (this.domNode.lastChild != null && this.domNode.lastChild !== this.textNode) { | ||
this.domNode.parentNode.insertBefore(this.domNode.lastChild, this.domNode); | ||
} | ||
if (this.textNode.data !== Cursor.CONTENTS) { | ||
@@ -75,3 +84,10 @@ let native = this.selection.getNativeRange(); | ||
if (range != null && range.start.node === textNode && range.end.node === textNode) { | ||
this.selection.setNativeRange(textNode, Math.max(0, range.start.offset - 1), textNode, Math.max(0, range.end.offset - 1)); | ||
// optimize() might move the cursor after our restore | ||
let [start, end] = [range.start.offset, range.end.offset].map(function(offset) { | ||
return Math.max(0, Math.min(textNode.data.length, offset - 1)); | ||
}); | ||
setTimeout(() => { | ||
// optimize() might move selection after us | ||
this.selection.setNativeRange(textNode, start, textNode, end); | ||
}, 1); | ||
} | ||
@@ -78,0 +94,0 @@ } |
@@ -33,3 +33,4 @@ import Parchment from 'parchment'; | ||
super.deleteAt(index, length); | ||
if (last != null && first !== last && firstOffset > 0) { | ||
if (last != null && first !== last && firstOffset > 0 && | ||
!(first instanceof BlockEmbed) && !(last instanceof BlockEmbed)) { | ||
let lastChild = first.children.tail; | ||
@@ -36,0 +37,0 @@ last.moveChildren(first); |
@@ -0,1 +1,29 @@ | ||
# 1.0.0-beta.4 | ||
Weekly beta preview release. | ||
### Breaking Changes | ||
- Headers no longer generates id attribute [#700](https://github.com/quilljs/quill/issues/700) | ||
- Add Control+Y hotkey on Windows [#705](https://github.com/quilljs/quill/issues/705) | ||
- BlockEmbed Blots are now length 1 and represented in a Delta the same as an inline embed | ||
- value() used to return object and newline, newline is now removed | ||
- formats used to be attributed on the newline character, it is now attributed on the object | ||
### Features | ||
- Enter on empty and indented list removes indent [#707](https://github.com/quilljs/quill/issues/707) | ||
- Allow base64 images to be inserted via APIs [#721](https://github.com/quilljs/quill/issues/721) | ||
### Bug Fixes | ||
- Fix typing after clearing inline format [#703](https://github.com/quilljs/quill/issues/703) | ||
- Correctly position Bubble tooltip when selecting multiple lines [#706](https://github.com/quilljs/quill/issues/706) | ||
- Fix typing after link format [#708](https://github.com/quilljs/quill/issues/708) | ||
- Fix loss of selection on using link tooltip [#709](https://github.com/quilljs/quill/issues/709) | ||
- Fix `setSelection(null)` [#722](https://github.com/quilljs/quill/issues/722) | ||
Thank you [@benbro](https://github.com/benbro), [@brynjagr](https://github.com/brynjagr), and [@sachinrekhi](https://github.com/sachinrekhi) for contributions to this release. | ||
# 1.0.0-beta.3 | ||
@@ -10,3 +38,2 @@ | ||
### Features | ||
@@ -17,3 +44,2 @@ | ||
### Bug Fixes | ||
@@ -20,0 +46,0 @@ |
@@ -52,6 +52,4 @@ import Delta from 'rich-text/lib/delta'; | ||
this.scroll.insertAt(index, key, op.insert[key]); | ||
// Block embeds themselves already represent newline | ||
if (Parchment.query(key, Parchment.Scope.BLOCK) != null) { | ||
consumeNextNewline = true; | ||
} | ||
} else { | ||
return index; | ||
} | ||
@@ -58,0 +56,0 @@ } |
@@ -238,5 +238,9 @@ import './polyfill'; | ||
setSelection(index, length = 0, source = Emitter.sources.API) { | ||
[index, length, , source] = overload(index, length, source); | ||
this.selection.setRange(new Range(index, length), source); | ||
setSelection(index, length, source) { | ||
if (index == null) { | ||
this.selection.setRange(null, length || Quill.sources.API); | ||
} else { | ||
[index, length, , source] = overload(index, length, source); | ||
this.selection.setRange(new Range(index, length), source); | ||
} | ||
this.selection.scrollIntoView(); | ||
@@ -243,0 +247,0 @@ } |
@@ -27,3 +27,3 @@ import Parchment from 'parchment'; | ||
this.lastRange = this.savedRange = new Range(0, 0); | ||
['keyup', 'mouseup', 'touchend', 'touchleave', 'focus', 'blur'].forEach((eventName) => { | ||
['keyup', 'mouseup', 'mouseleave', 'touchend', 'touchleave', 'focus', 'blur'].forEach((eventName) => { | ||
this.root.addEventListener(eventName, () => { | ||
@@ -37,3 +37,3 @@ // When range used to be a selection and user click within the selection, | ||
if (delta.length() > 0) { | ||
setTimeout(this.update.bind(this, Emitter.sources.SILENT), 1); | ||
this.update(Emitter.sources.SILENT); | ||
} | ||
@@ -44,7 +44,6 @@ }); | ||
if (native == null) return; | ||
if (native.start.node === this.cursor.textNode) return; // cursor.restore() will handle | ||
// TODO unclear if this has negative side effects | ||
this.emitter.once(Emitter.events.SCROLL_UPDATE, () => { | ||
try { | ||
// Check crash condition in FF https://bugzilla.mozilla.org/show_bug.cgi?id=1270235 | ||
if (native.start.node.parentNode == null || native.end.node.parentNode == null) return; | ||
this.setNativeRange(native.start.node, native.start.offset, native.end.node, native.end.offset); | ||
@@ -210,2 +209,5 @@ } catch (ignored) {} | ||
debug.info('setNativeRange', startNode, startOffset, endNode, endOffset); | ||
if (startNode != null && (this.root.parentNode == null || startNode.parentNode == null || endNode.parentNode == null)) { | ||
return; | ||
} | ||
let selection = document.getSelection(); | ||
@@ -212,0 +214,0 @@ if (selection == null) return; |
@@ -8,15 +8,2 @@ import Block from '../blots/block'; | ||
} | ||
optimize() { | ||
super.optimize(); | ||
let text = this.domNode.textContent.toLowerCase(); | ||
let id = text.replace(/[^a-z0-9]+/g, '-').replace(/^\-/, '').replace(/\-$/, ''); | ||
if (this.domNode.id !== id) { | ||
if (id.length === 0) { | ||
this.domNode.removeAttribute('id'); | ||
} else { | ||
this.domNode.id = id; | ||
} | ||
} | ||
} | ||
} | ||
@@ -23,0 +10,0 @@ Header.blotName = 'header'; |
import Embed from '../blots/embed'; | ||
import Link from '../formats/link'; | ||
import Link, { sanitize } from '../formats/link'; | ||
@@ -19,3 +19,3 @@ | ||
static sanitize(url) { | ||
return Link.sanitize(url); | ||
return sanitize(url, ['http', 'https', 'data']) ? url : '//:0'; | ||
} | ||
@@ -22,0 +22,0 @@ |
@@ -18,10 +18,3 @@ import Inline from '../blots/inline'; | ||
static sanitize(url) { | ||
let anchor = document.createElement('a'); | ||
anchor.href = url; | ||
let protocol = anchor.href.slice(0, anchor.href.indexOf(':')); | ||
if (['http', 'https', 'mailto'].indexOf(protocol) > -1) { | ||
return url; | ||
} else { | ||
return this.SANITIZED_URL; | ||
} | ||
return sanitize(url, ['http', 'https', 'mailto']) ? url : this.SANITIZED_URL; | ||
} | ||
@@ -40,2 +33,10 @@ | ||
export default Link; | ||
function sanitize(url, protocols) { | ||
let anchor = document.createElement('a'); | ||
anchor.href = url; | ||
let protocol = anchor.href.slice(0, anchor.href.indexOf(':')); | ||
return protocols.indexOf(protocol) > -1; | ||
} | ||
export { Link as default, sanitize }; |
@@ -22,2 +22,5 @@ import Parchment from 'parchment'; | ||
this.quill.keyboard.addBinding({ key: 'Z', shortKey: true, shiftKey: true }, this.redo.bind(this)); | ||
if (/Win/i.test(navigator.platform)) { | ||
this.quill.keyboard.addBinding({ key: 'Y', shortKey: true }, this.redo.bind(this)); | ||
} | ||
} | ||
@@ -24,0 +27,0 @@ |
@@ -190,4 +190,7 @@ import clone from 'clone'; | ||
{ collapsed: true, format: ['list'], empty: true }, | ||
function(range) { | ||
function(range, context) { | ||
this.quill.format('list', false); | ||
if (context.format.indent) { | ||
this.quill.format('indent', false); | ||
} | ||
} | ||
@@ -239,5 +242,6 @@ ], | ||
Object.keys(context.format).forEach((name) => { | ||
if (lineFormats[name] == null && !Array.isArray(context.format[name])) { | ||
this.quill.format(name, context.format[name], Quill.sources.USER); | ||
} | ||
if (lineFormats[name] != null) return; | ||
if (Array.isArray(context.format[name])) return; | ||
if (name === 'link') return; | ||
this.quill.format(name, context.format[name], Quill.sources.USER); | ||
}); | ||
@@ -244,0 +248,0 @@ } |
@@ -23,8 +23,6 @@ import Parchment from 'parchment'; | ||
format(name, value) { | ||
if (name === this.statics.blotName && !value) { | ||
this.domNode.textContent = this.domNode.textContent; | ||
this.attach(); | ||
} | ||
super.format(name, value); | ||
replaceWith(block) { | ||
this.domNode.textContent = this.domNode.textContent; | ||
this.attach(); | ||
super.replaceWith(block); | ||
} | ||
@@ -31,0 +29,0 @@ |
@@ -28,3 +28,2 @@ import extend from 'extend'; | ||
this.container.classList.add('ql-toolbar'); | ||
this.container.classList.toggle('ios', /iPhone|iPad/i.test(navigator.userAgent)); | ||
this.controls = []; | ||
@@ -40,6 +39,4 @@ this.handlers = {}; | ||
this.quill.on(Quill.events.SCROLL_OPTIMIZE, () => { | ||
setTimeout(() => { | ||
let [range, ] = this.quill.selection.getRange(); // quill.getSelection triggers update | ||
this.update(range); | ||
}, 1); | ||
let [range, ] = this.quill.selection.getRange(); // quill.getSelection triggers update | ||
this.update(range); | ||
}); | ||
@@ -71,3 +68,2 @@ } | ||
input.addEventListener(eventName, (e) => { | ||
this.quill.focus(); | ||
let value; | ||
@@ -86,2 +82,3 @@ if (input.tagName === 'SELECT') { | ||
} | ||
this.quill.focus(); | ||
if (this.handlers[format] != null) { | ||
@@ -88,0 +85,0 @@ this.handlers[format].call(this, value); |
{ | ||
"name": "quill", | ||
"version": "1.0.0-beta.3", | ||
"version": "1.0.0-beta.4", | ||
"description": "Cross browser rich text editor", | ||
@@ -38,3 +38,3 @@ "author": "Jason Chen <jhchen7@gmail.com>", | ||
"extend": "~3.0.0", | ||
"parchment": "1.0.0-beta.5", | ||
"parchment": "1.0.0-beta.6", | ||
"rich-text": "~3.0.0" | ||
@@ -44,19 +44,18 @@ }, | ||
"async": "^1.5.2", | ||
"babel-core": "^6.7.6", | ||
"babel-core": "^6.9.1", | ||
"babel-loader": "^6.2.4", | ||
"babel-plugin-transform-es2015-modules-commonjs": "^6.7.4", | ||
"babel-preset-es2015": "^6.6.0", | ||
"babel-plugin-transform-es2015-modules-commonjs": "^6.8.0", | ||
"babel-preset-es2015": "^6.9.0", | ||
"css-loader": "~0.23.1", | ||
"extract-text-webpack-plugin": "^1.0.1", | ||
"html-loader": "~0.4.3", | ||
"http-proxy": "^1.13.2", | ||
"http-proxy": "^1.13.3", | ||
"istanbul-instrumenter-loader": "~0.2.0", | ||
"jasmine-core": "^2.4.1", | ||
"karma": "~0.13.22", | ||
"karma-chrome-launcher": "~0.2.3", | ||
"karma-coverage": "~0.5.5", | ||
"karma-jasmine": "~0.3.8", | ||
"karma-sauce-launcher": "~0.3.1", | ||
"lodash": "^4.10.0", | ||
"protractor": "^3.2.2", | ||
"karma-chrome-launcher": "^1.0.1", | ||
"karma-coverage": "^1.0.0", | ||
"karma-jasmine": "^1.0.2", | ||
"karma-sauce-launcher": "^1.0.0", | ||
"lodash": "^4.13.1", | ||
"quill-docs": "quilljs/quilljs.github.io.git#1.0", | ||
@@ -67,4 +66,7 @@ "style-loader": "~0.13.1", | ||
"ts-loader": "~0.8.2", | ||
"typescript": "^1.8.9", | ||
"typescript": "^1.8.10", | ||
"uglify-js": "^2.6.2", | ||
"wdio-jasmine-framework": "^0.2.1", | ||
"webdriver-manager": "^10.0.2", | ||
"webdriverio": "^4.0.9", | ||
"webpack": "^1.13.1", | ||
@@ -83,7 +85,12 @@ "webpack-dev-server": "^1.14.1" | ||
"build": "webpack --config _develop/webpack.config.js --devtool hidden-source-map; rm dist/quill; rm dist/quill.bubble; rm dist/quill.snow; rm dist/*.css.map", | ||
"build:release": "./_develop/release.sh", | ||
"build:release": "./_develop/scripts/release.sh", | ||
"start": "npm run build; foreman start -f _develop/procfile", | ||
"test": "npm run build; karma start _develop/karma.config.js", | ||
"test": "npm run test:unit", | ||
"test:all": "npm run test:unit; npm run test:functional", | ||
"test:functional": "./_develop/scripts/webdriver.sh", | ||
"test:unit": "npm run build; karma start _develop/karma.config.js", | ||
"test:coverage": "webpack --config _develop/webpack.coverage.js; karma start _develop/karma.config.js --reporters coverage", | ||
"travis": "karma start _develop/karma.config.js --reporters dots,saucelabs" | ||
"travis": "karma start _develop/karma.config.js --reporters dots,saucelabs", | ||
"webdriver:start": "webdriver-manager start", | ||
"webdriver:update": "webdriver-manager update" | ||
}, | ||
@@ -90,0 +97,0 @@ "keywords": [ |
30
quill.js
@@ -11,6 +11,6 @@ import Quill from './core'; | ||
import { BackgroundStyle as Background } from './formats/background'; | ||
import { ColorStyle as Color } from './formats/color'; | ||
import { FontClass as Font } from './formats/font'; | ||
import { SizeClass as Size } from './formats/size'; | ||
import { BackgroundClass, BackgroundStyle } from './formats/background'; | ||
import { ColorClass, ColorStyle } from './formats/color'; | ||
import { FontClass, FontStyle } from './formats/font'; | ||
import { SizeClass, SizeStyle } from './formats/size'; | ||
@@ -46,2 +46,14 @@ import Bold from './formats/bold'; | ||
Quill.register({ | ||
'attributors/class/background': BackgroundClass, | ||
'attributors/class/color': ColorClass, | ||
'attributors/class/font': FontClass, | ||
'attributors/class/size': SizeClass, | ||
'attributors/style/background': BackgroundStyle, | ||
'attributors/style/color': ColorStyle, | ||
'attributors/style/font': FontStyle, | ||
'attributors/style/size': SizeStyle | ||
}, true); | ||
Quill.register({ | ||
'formats/align': Align, | ||
@@ -51,6 +63,6 @@ 'formats/direction': Direction, | ||
'formats/background': Background, | ||
'formats/color': Color, | ||
'formats/font': Font, | ||
'formats/size': Size, | ||
'formats/background': BackgroundStyle, | ||
'formats/color': ColorStyle, | ||
'formats/font': FontClass, | ||
'formats/size': SizeClass, | ||
@@ -89,5 +101,5 @@ 'formats/blockquote': Blockquote, | ||
'ui/link-tooltip': LinkTooltip | ||
}); | ||
}, true); | ||
module.exports = Quill; |
@@ -5,2 +5,3 @@ import Emitter from '../core/emitter'; | ||
import icons from '../ui/icons'; | ||
import { Range } from '../core/selection'; | ||
import Tooltip from '../ui/tooltip'; | ||
@@ -35,3 +36,12 @@ | ||
this.tooltip.root.style.width = this.tooltip.root.offsetWidth + 'px'; | ||
this.tooltip.position(this.quill.getBounds(range)); | ||
let lines = this.quill.scroll.lines(range.index, range.length); | ||
if (lines.length === 1) { | ||
this.tooltip.position(this.quill.getBounds(range)); | ||
} else { | ||
let lastLine = lines[lines.length - 1]; | ||
let index = lastLine.offset(this.quill.scroll); | ||
let length = Math.min(lastLine.length() - 1, range.index + range.length - index); | ||
let bounds = this.quill.getBounds(new Range(index, length)); | ||
this.tooltip.position(bounds); | ||
} | ||
} else if (document.activeElement !== input) { | ||
@@ -38,0 +48,0 @@ this.tooltip.hide(); |
@@ -67,3 +67,3 @@ import Emitter from '../core/emitter'; | ||
this.quill.on(Emitter.events.SELECTION_CHANGE, update) | ||
.on(Emitter.events.TEXT_CHANGE, update); | ||
.on(Emitter.events.SCROLL_OPTIMIZE, update); | ||
document.body.addEventListener('click', (e) => { | ||
@@ -70,0 +70,0 @@ pickers.forEach(function(picker) { |
@@ -109,3 +109,3 @@ import DropdownIcon from '../assets/icons/dropdown.svg'; | ||
if (this.select.selectedIndex > -1) { | ||
let item = this.container.querySelector('.ql-picker-options').children[this.select.selectedIndex] | ||
let item = this.container.querySelector('.ql-picker-options').children[this.select.selectedIndex]; | ||
option = this.select.options[this.select.selectedIndex]; | ||
@@ -112,0 +112,0 @@ this.selectItem(item); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
611317
13451
29
+ Addedparchment@1.0.0-beta.6(transitive)
- Removedparchment@1.0.0-beta.5(transitive)
Updatedparchment@1.0.0-beta.6