GithubHelp home page GithubHelp logo

killercodemonkey / ngx-quill Goto Github PK

View Code? Open in Web Editor NEW
1.8K 26.0 257.0 17.62 MB

Angular (>=2) components for the Quill Rich Text Editor

License: MIT License

TypeScript 98.66% JavaScript 1.34%
quill-editor ngx-quill quill quilljs rich-text-editor rich-text angular angular-x wysiwyg ng

ngx-quill's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ngx-quill's Issues

How to focus the editor?

Is there any way to focus the text field with this module? I noticed that Quill has a .focus() method, but I don't know if I can use it or how to do it.

Throw 'Unexpected token export' when import the module

system: OSX 10.12.4
angular: 2.4.1
code:

import { QuillModule } from 'ngx-quill';
console.log('QuillModule', QuillModule);

errors:

Uncaught SyntaxError: Unexpected token export
es5-shim.js?hash=adc3c62…:17 Uncaught TypeError: Cannot read property 'meteorInstall' of undefined
    at es5-shim.js?hash=adc3c62…:17
    at es5-shim.js?hash=adc3c62…:2789
(anonymous) @ es5-shim.js?hash=adc3c62…:17
(anonymous) @ es5-shim.js?hash=adc3c62…:2789
promise.js?hash=db5ea3b…:17 Uncaught TypeError: Cannot read property 'meteorInstall' of undefined
    at promise.js?hash=db5ea3b…:17
    at promise.js?hash=db5ea3b…:581
(anonymous) @ promise.js?hash=db5ea3b…:17
(anonymous) @ promise.js?hash=db5ea3b…:581
ecmascript-runtime.js?hash=361600e…:17 Uncaught TypeError: Cannot read property 'meteorInstall' of undefined
    at ecmascript-runtime.js?hash=361600e…:17
    at ecmascript-runtime.js?hash=361600e…:4630
(anonymous) @ ecmascript-runtime.js?hash=361600e…:17
(anonymous) @ ecmascript-runtime.js?hash=361600e…:4630
babel-runtime.js?hash=542c082…:17 Uncaught TypeError: Cannot read property 'meteorInstall' of undefined
    at babel-runtime.js?hash=542c082…:17
    at babel-runtime.js?hash=542c082…:160
(anonymous) @ babel-runtime.js?hash=542c082…:17
(anonymous) @ babel-runtime.js?hash=542c082…:160
random.js?hash=31dadb9…:18 Uncaught TypeError: Cannot read property 'meteorInstall' of undefined
    at random.js?hash=31dadb9…:18
    at random.js?hash=31dadb9…:355
(anonymous) @ random.js?hash=31dadb9…:18
(anonymous) @ random.js?hash=31dadb9…:355
mongo-id.js?hash=345d169…:19 Uncaught TypeError: Cannot read property 'Random' of undefined
    at mongo-id.js?hash=345d169…:19
    at mongo-id.js?hash=345d169…:142
(anonymous) @ mongo-id.js?hash=345d169…:19
(anonymous) @ mongo-id.js?hash=345d169…:142
geojson-utils.js?hash=b204c7d…:17 Uncaught TypeError: Cannot read property 'meteorInstall' of undefined
    at geojson-utils.js?hash=b204c7d…:17
    at geojson-utils.js?hash=b204c7d…:439
(anonymous) @ geojson-utils.js?hash=b204c7d…:17
(anonymous) @ geojson-utils.js?hash=b204c7d…:439
minimongo.js?hash=66cc6ab…:23 Uncaught TypeError: Cannot read property 'MongoID' of undefined
    at minimongo.js?hash=66cc6ab…:23
    at minimongo.js?hash=66cc6ab…:3917
(anonymous) @ minimongo.js?hash=66cc6ab…:23
(anonymous) @ minimongo.js?hash=66cc6ab…:3917
check.js?hash=63d7478…:17 Uncaught TypeError: Cannot read property 'meteorInstall' of undefined
    at check.js?hash=63d7478…:17
    at check.js?hash=63d7478…:613
(anonymous) @ check.js?hash=63d7478…:17
(anonymous) @ check.js?hash=63d7478…:613
retry.js?hash=1e40961…:18 Uncaught TypeError: Cannot read property 'Random' of undefined
    at retry.js?hash=1e40961…:18
    at retry.js?hash=1e40961…:110
(anonymous) @ retry.js?hash=1e40961…:18
(anonymous) @ retry.js?hash=1e40961…:110
ddp-common.js?hash=d42359b…:17 Uncaught TypeError: Cannot read property 'check' of undefined
    at ddp-common.js?hash=d42359b…:17
    at ddp-common.js?hash=d42359b…:493
(anonymous) @ ddp-common.js?hash=d42359b…:17
(anonymous) @ ddp-common.js?hash=d42359b…:493
reload.js?hash=628b069…:18 Uncaught TypeError: Cannot read property 'Symbol' of undefined
    at reload.js?hash=628b069…:18
    at reload.js?hash=628b069…:309
(anonymous) @ reload.js?hash=628b069…:18
(anonymous) @ reload.js?hash=628b069…:309
ddp-client.js?hash=bc32a16…:17 Uncaught TypeError: Cannot read property 'check' of undefined
    at ddp-client.js?hash=bc32a16…:17
    at ddp-client.js?hash=bc32a16…:4983
(anonymous) @ ddp-client.js?hash=bc32a16…:17
(anonymous) @ ddp-client.js?hash=bc32a16…:4983
ddp.js?hash=25dc3f4…:14 Uncaught TypeError: Cannot read property 'DDP' of undefined
    at ddp.js?hash=25dc3f4…:14
    at ddp.js?hash=25dc3f4…:27
(anonymous) @ ddp.js?hash=25dc3f4…:14
(anonymous) @ ddp.js?hash=25dc3f4…:27
allow-deny.js?hash=c9344ef…:18 Uncaught TypeError: Cannot read property 'LocalCollection' of undefined
    at allow-deny.js?hash=c9344ef…:18
    at allow-deny.js?hash=c9344ef…:536
(anonymous) @ allow-deny.js?hash=c9344ef…:18
(anonymous) @ allow-deny.js?hash=c9344ef…:536
mongo.js?hash=c4281c0…:17 Uncaught TypeError: Cannot read property 'AllowDeny' of undefined
    at mongo.js?hash=c4281c0…:17
    at mongo.js?hash=c4281c0…:909
(anonymous) @ mongo.js?hash=c4281c0…:17
(anonymous) @ mongo.js?hash=c4281c0…:909
xolvio_cleaner.js?hash=a137467…:17 Uncaught TypeError: Cannot read property 'Mongo' of undefined
    at xolvio_cleaner.js?hash=a137467…:17
    at xolvio_cleaner.js?hash=a137467…:102
(anonymous) @ xolvio_cleaner.js?hash=a137467…:17
(anonymous) @ xolvio_cleaner.js?hash=a137467…:102
practicalmeteor_chai.js?hash=92e20bf…:17 Uncaught TypeError: Cannot read property 'Symbol' of undefined
    at practicalmeteor_chai.js?hash=92e20bf…:17
    at practicalmeteor_chai.js?hash=92e20bf…:5639
(anonymous) @ practicalmeteor_chai.js?hash=92e20bf…:17
(anonymous) @ practicalmeteor_chai.js?hash=92e20bf…:5639
practicalmeteor_sinon.js?hash=b2d5a9f…:17 Uncaught TypeError: Cannot read property 'chai' of undefined
    at practicalmeteor_sinon.js?hash=b2d5a9f…:17
    at practicalmeteor_sinon.js?hash=b2d5a9f…:6256
(anonymous) @ practicalmeteor_sinon.js?hash=b2d5a9f…:17
(anonymous) @ practicalmeteor_sinon.js?hash=b2d5a9f…:6256
hwillson_stub-collections.js?hash=fd53027…:17 Uncaught TypeError: Cannot read property 'Mongo' of undefined
    at hwillson_stub-collections.js?hash=fd53027…:17
    at hwillson_stub-collections.js?hash=fd53027…:106
(anonymous) @ hwillson_stub-collections.js?hash=fd53027…:17
(anonymous) @ hwillson_stub-collections.js?hash=fd53027…:106
webapp.js?hash=3026d45…:18 Uncaught TypeError: Cannot read property 'meteorInstall' of undefined
    at webapp.js?hash=3026d45…:18
    at webapp.js?hash=3026d45…:70
(anonymous) @ webapp.js?hash=3026d45…:18
(anonymous) @ webapp.js?hash=3026d45…:70
livedata.js?hash=7cf1831…:14 Uncaught TypeError: Cannot read property 'DDP' of undefined
    at livedata.js?hash=7cf1831…:14
    at livedata.js?hash=7cf1831…:31
(anonymous) @ livedata.js?hash=7cf1831…:14
(anonymous) @ livedata.js?hash=7cf1831…:31
autoupdate.js?hash=1fd9cf3…:19 Uncaught TypeError: Cannot read property 'Retry' of undefined
    at autoupdate.js?hash=1fd9cf3…:19
    at autoupdate.js?hash=1fd9cf3…:206
(anonymous) @ autoupdate.js?hash=1fd9cf3…:19
(anonymous) @ autoupdate.js?hash=1fd9cf3…:206
barbatus_typescript-runtime.js?hash=7df7215…:17 Uncaught TypeError: Cannot read property 'meteorInstall' of undefined
    at barbatus_typescript-runtime.js?hash=7df7215…:17
    at barbatus_typescript-runtime.js?hash=7df7215…:215
(anonymous) @ barbatus_typescript-runtime.js?hash=7df7215…:17
(anonymous) @ barbatus_typescript-runtime.js?hash=7df7215…:215
global-imports.js?hash=4c0db35…:3 Uncaught TypeError: Cannot read property 'Mongo' of undefined
    at global-imports.js?hash=4c0db35…:3
(anonymous) @ global-imports.js?hash=4c0db35…:3
app.js?hash=151d68c…:1 Uncaught ReferenceError: meteorInstall is not defined
    at app.js?hash=151d68c…:1
(anonymous) @ app.js?hash=151d68c…:1

onContentChanged - triggers when item is removed from array

I have a problem regarding the onContentChanged method.

In my project I have a array of quill editors. And a user can add a new editor instance to the array and delete one from the array. But when the user delete a editor from the array the onContentChanged method is triggered.

And that is causing some side effects in my project. Because every time onContentChanged is triggered I save the data to the database. And when I delete a editor from my array, onContentChanged will add it back ;-(

Is there a way to change the behavior of onContentChanged so it's only watching the content of the current instance of the editor?

Prepend protocol to inserted links

Is there a way to prepend protocol to inserted links or make all link absolute?
For example, if user enters google.com as a link Quill generates link with href="google.com" which opens it incorrectly as a relative link.

Thanks

Can you please give an exam,ple of how to configure the Toolbar?

Could you please give an exmple of how to configure the toolbar? I have added it to my module but not sure where the configuration goes, thanks

{```

toolbar: [
['bold', 'italic', 'underline', 'strike'], // toggled buttons
['blockquote', 'code-block'],
...
['link', 'image', 'video'] // link and image, video
]
};

Build Error 1.3.3

I dialed back to 1.3.1 and everything is fine, so I'm thinking there might be an issue with a later release. (fyi ... I am not an AoT user)

node error;
build 06-Jul-2017 15:55:14 ERROR in [at-loader] ./node_modules/ngx-quill/src/quill-editor.component.ts:109:7
build 06-Jul-2017 15:55:14 TS2345: Argument of type '{ modules: any; placeholder: string; readOnly: boolean; theme: string; formats: string[]; bounds:...' is not assignable to parameter of type 'QuillOptionsStatic'.
build 06-Jul-2017 15:55:14 Object literal may only specify known properties, and 'bounds' does not exist in type 'QuillOptionsStatic'.

Responsive Toolbar Collapse

Feature Request

It would be nice if we could collapse the toolbar under a hamburger button to not take up so much room on small screens.

Loading external fonts

Hello,

I'm having issues on loading external fonts.
Html:

<quill-editor [(ngModel)]="HTML_DATA" [style]="{'height' : '100%'}" [modules]="configEditor">

On my config object I've add:

configEditor: {} = {
    toolbar: [
      ['bold', 'italic', 'underline', 'strike'],       
      [{ 'list': 'ordered'}, { 'list': 'bullet' }],
      [{ 'header': [1, 2, 3, 4, 5, 6, false] }],
      [{ 'color': [] }, { 'background': [] }],         
      [{ 'font': [ 'Aref Ruqaa', 'Mirza', 'Roboto'] }],
      [{ 'align': [] }],
      ['clean'],                   
    ]
  };

loaded the google font on index.html
<link href="https://fonts.googleapis.com/css?family=Aref+Ruqaa|Mirza|Roboto" rel="stylesheet">

and added some css on the component:

#editor-container {
    font-family: "Aref Ruqaa";
    font-size: 18px;
    height: 375px;
  }
 
  #toolbar-container .ql-font span[data-label="Aref Ruqaa"]::before {
    font-family: "Aref Ruqaa";
  }

  #toolbar-container .ql-font span[data-label="Mirza"]::before {
    font-family: "Mirza";
  }

  #toolbar-container .ql-font span[data-label="Roboto"]::before {
    font-family: "Roboto";
  }
  
  .ql-font-mirza {
    font-family: "Mirza";
  }

  .ql-font-roboto {
    font-family: "Roboto";
  }

I'm doing anything wrong? It's possible to load fonts with this directive? The documentation is a little bit confusing. The only working example that I can see is in regular js.

https://codepen.io/quill/pen/gLBYam

Thanks.

onContentChange() Debounce option

Would be nice to set a x number of seconds to debounce the onContentChange function.

So when you want to save data to your back end, you can write it every x seconds.

AOT Build Error with angular 4

When try AOT Build with Angular 4, I got the flowing error:

Unexpected value 'QuillModule in /Projects/angular-seed/node_modules/ngx-quill/in
dex.d.ts' imported by the module 'AppModule in /Projects/angular-seed/src/app/app
.module.ts'. Please add a @NgModule annotation.

Here is my app.modules.ts:

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { HttpModule, JsonpModule } from '@angular/http';

import { NgbModule } from '@ng-bootstrap/ng-bootstrap';

import { QuillModule } from 'ngx-quill';

import { AppComponent }   from './app.component';
import { RouteComponents, AppRoutes } from './app.routes';

@NgModule({
    declarations: [
        AppComponent,
        RouteComponents
    ],
    imports: [
        BrowserModule,
        BrowserAnimationsModule,
        CommonModule,
        FormsModule,
        ReactiveFormsModule,
        HttpModule,
        JsonpModule,
        NgbModule,
        QuillModule,
        AppRoutes
    ],
    bootstrap: [AppComponent]
})
export class AppModule {}

and my package.json

{
  "name": "angular-seed",
  "version": "1.0.0",
  "description": "angular seed app",
  "main": "index.html",
  "scripts": {
    "sass": "node-sass --recursive --source-map true --source-map-contents --output src src ",
    "sass:w": "npm run sass -- --watch",
    "build": "npm run tsc && npm run sass",
    "start": "npm run clean && npm run build && concurrently \"npm run tsc:w\" \"npm run sass:w\" \"npm run gulp:dev\"",
    "gulp:dev": "gulp dev",
    "gulp:serve": "gulp serve",
    "clean": "rm -rf dist && find src -name \\*.js -type f -delete && find src -name \\*.js.map -type f -delete && find src -name \\*.ngfactory.ts -type f -delete && find src -name \\*.css -type f -delete && find src -name \\*.css.map -type f -delete && find src -name \\*.shim.ts -type f -delete && find src -name \\*.ngsummary.json -type f -delete && find src -name \\*.ngstyle.ts -type f -delete",
    "ngc": "ngc --project tsconfig-aot.json",
    "tsc": "tsc --project tsconfig.json",
    "tsc:w": "npm run tsc -- --watch",
    "tsc-aot": "tsc -p tsconfig-aot.json",
    "rollup": "rollup -c rollup.config.js",
    "build-aot": "npm run build && npm run ngc && npm run tsc-aot && npm run rollup"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/beginor/angular-seed.git"
  },
  "keywords": ["angular", "seed", "gulp", "systemjs"],
  "author": "beginor",
  "license": "MIT",
  "bugs": {
    "url": "https://github.com/beginor/angular-seed/issues"
  },
  "homepage": "https://github.com/beginor/angular-seed#readme",
  "dependencies": {
    "@angular/animations": "^4.2.5",
    "@angular/common": "^4.2.5",
    "@angular/compiler": "^4.2.5",
    "@angular/core": "^4.2.5",
    "@angular/forms": "^4.2.5",
    "@angular/http": "^4.2.5",
    "@angular/platform-browser": "^4.2.5",
    "@angular/platform-browser-dynamic": "^4.2.5",
    "@angular/router": "^4.2.5",
    "core-js": "^2.4.1",
    "reflect-metadata": "^0.1.10",
    "rxjs": "~5.4.1",
    "systemjs": "^0.20.14",
    "zone.js": "^0.8.12",
    "bootstrap": "^4.0.0-alpha.6",
    "@ng-bootstrap/ng-bootstrap": "^1.0.0-alpha.26",
    "font-awesome": "^4.7.0",
    "web-animations-js": "^2.2.5",
    "quill": "^1.2.6",
    "ngx-quill": "^1.3.3"
  },
  "devDependencies": {
    "@angular/compiler-cli": "^4.2.5",
    "@angular/platform-server": "^4.2.5",
    "@types/core-js": "~0.9.42",
    "@types/node": "~8.0.6",
    "concurrently": "^3.5.0",
    "gulp": "^3.9.1",
    "gulp-connect": "^5.0.0",
    "http-proxy-middleware": "0.17.4",
    "node-sass": "^4.5.3",
    "rollup": "^0.43.0",
    "rollup-plugin-commonjs": "^8.0.2",
    "rollup-plugin-node-resolve": "^3.0.0",
    "rollup-plugin-uglify": "^2.0.1",
    "typescript": "~2.3.4",
    "@types/web-animations-js": "^2.2.4",
    "@types/quill":"^0.0.31"
  }
}

Using Grammarly Breaks Quill

  1. What is Grammarly
  2. Download Chrome Extension
  3. Visit Demo Page
  4. Attempt to use Quill while Grammarly is enabled.

When Grammarly is enabled on a page that uses the ngx-quill Editor the editor is rendered basically useless, making selecting text impossible and inserting text into the middle of a sentence impossible. The editor I'm using to write this isn't having problems so I know it's possible to correct this issue.

Grammarly is used by a huge amount of people just wanted to let you know about this. So more devs can adopt Quill without worry of users not being able to use the editor.

AOT Build Error - Cannot find quill.module.js

Hello,

Everything works well when using JIT with ionic serve, but when I try to compile with "ionic build --release --prod", then I get this error when loading my app in the browser:

main.js:93 Uncaught Error: Module build failed: Error: ENOENT: no such file or directory, open '/Users/etc/app/node_modules/ngx-quill/src/quill.module.js'

There's a related issue commenting on how Node Modules are typically pre built here: ionic-team/ionic-app-scripts#632

If you have any advice then I'd really appreciate it. Here below are my system details.

Thank you
Tom


ionic info:

Cordova CLI: 6.3.1
Ionic Framework Version: 2.2.0
Ionic CLI Version: 2.2.1
Ionic App Lib Version: 2.2.0
Ionic App Scripts Version: 1.2.2
ios-deploy version: 1.9.1
ios-sim version: 5.0.3
OS: macOS Sierra
Node Version: v6.9.1
Xcode version: Xcode 8.3.2 Build version 8E2002

package.json excerpt:

"dependencies": {
"@angular/common": "2.4.8",
"@angular/compiler": "2.4.8",
"@angular/compiler-cli": "2.4.8",
"@angular/core": "2.4.8",
"@angular/forms": "2.4.8",
"@angular/http": "2.4.8",
"@angular/platform-browser": "2.4.8",
"@angular/platform-browser-dynamic": "2.4.8",
"@angular/platform-server": "2.4.8",
"@ionic-native/core": "^3.4.4",
"@ionic-native/onesignal": "^3.4.4",
"@ionic/storage": "2.0.0",
"cropperjs": "^0.8.1",
"intl": "^1.2.4",
"ionic-angular": "2.2.0",
"ionic-native": "2.4.1",
"ionicons": "3.0.0",
"moment": "^2.14.1",
"ng2-password-strength-bar": "^1.1.2",
"ng2-resource-rest": "1.12.2",
"rxjs": "5.0.1",
"sw-toolbox": "3.4.0",
"zone.js": "0.7.2"
},
"devDependencies": {
"@ionic/app-scripts": "1.2.2",
"typescript": "2.0.9"
},

Source code has linting errors

Hi again,

When I include the SRC version, my AngularCLI (with strict linting) includes any issues found in the ngx-quill node module:

I am not sure why it is doing it but no other node modules do this (my linting is set to exclude Node Modules). Perhaps it is something to do with the fact that it is using the source?

error on compiling with angular-cli (1.0.0-rc.0)

When trying to use ngx-quill with angular-cli (1.0.0-rc.0) and angular (4.0.0-rc.2) I get an error on compiling regarding quill.module.ts

ERROR in Error encountered resolving symbol values statically. Calling function 'makeDecorator', function calls are not supported. Consider replacing the function or lambda with a reference to an exported function

Integrating with Directives?

Wondered if there was anyway to integrate the editor with directives? I've been trying to use this example for auto including link tags on regex match but instead trying to auto include some directive or locator for Angular2 to use. Tried adding attributes like [custom] or adding custom tags to tie certain words to angular hooks but just constantly get "[Parchment] Cannot insert custom into block," 'custom' is whatever I try build either the attribute/blot/embed/inline/etc. Wondered if this was actually possible, or just incompatible.

Is there a way to "clean" text as it is pasted in?

I do not have the Clean button enabled in the toolbar. Many users copy and paste rich HTML (From Word etC) into the textbox and then they can't remove the formatting.

Is there a way to clean it on paste? (ie. it removes all formatting and then they can reformat as they want?)

Thanks

Include 'tslint.json' into .npmignore

when using ngx-quill as dependency in angular 2+ (in my case ^4.0.0) and try to run ´ng lint´ then you will get the following error:

Failed to load /Users/foo/projects/bar/node_modules/ngx-quill/tslint.json: Could not find custom rule directory: /Users/foo/projects/bar/node_modules/ngx-quill/node_modules/codelyzer

The tslint.json is needed for development but not as part of the distribution.

So, please add 'tslint.json' into .npmignore and publish a new version ... THX

I need the index.js

Hi,

I am using Angular-seed project which is using SystemJS. It requires the index.js instead of index.ts. For example, the ng2-ckeditor is doing the same thing - wrapping the ckeditor. And I could get it working with my Angular-seed project. Can you add tsconfig.json and do the same thing to in your project?

Regards
Cheng

Triggering clipboard with initial model value

It seems like when a new instance of quill-editor is created it triggers an event on the clipboard.
This behavior doesn't happen in the original version of quilljs. AI looked into the code and seems like you're using pasteHTML to insert the initial value, which makes it trigger the clipboard.

Context: On my application I'm listening for content that is pasted into the editor so I can clean up the content being pasted, the problem is that every time a new instance of quill-editor is created, it triggers a clipboard event which ends up changing the format of the value being passed by ngModel.

Here's a code example:

    /// this should be triggered ONLY when a new text is pasted from the clipboard.
    quill.clipboard.addMatcher(Node.ELEMENT_NODE, (node, delta) => {
      return new Delta().insert(node.textContent);
    });

cc: @EunusHosen

custom toolbar

Hello,

I m trying to use custom toolbar and it s not working.
Can you give me some direction how to use it?

many thanks

Uncaught Error: Expected 'styles' to be an array of strings.

Hi.

I've just downloaded your component and im trying to make it work. I've added the component to my appModule as explained in the ReadMe file.

i get this error when trying to transpile my code:

angular 2/angular-seed/angular-webpack/node_modules/ng2-quill-editor/quillEditor.component.ts:81:57
Property 'assign' does not exist on type 'ObjectConstructor'.

i also get a bunch of errors, like this one:

Uncaught Error: Expected 'styles' to be an array of strings.
at assertArrayOfStrings (eval at (http://localhost:8081/vendor.js:95:2)

Most of the errors occur in the vendor.ts file.

I had to set the "noImplicitAny": false to false to avoid a whole bunch of other errors regarding implicitly type any.

Is there any fix to these errors? Am i missing something?

I'm running with typescript version 2.0.10 - angular version ~2.2.0

Kind regards Chris

Error: Unexpected value 'QuillModule' imported by the module 'AppModule' at d

I've been trying to get Quill working in my Angular 2 project and I can't figure out this error from ngx-quill. I followed the instructions for the systemjs.config file, added import { QuillModule } from 'ngx-quill'; to my app.module file, added it to the Imports, added "ngx-quill": "1.0.0" to my packages.json file and "@types/quill": "^0.0.29" to devDependencies.

Any idea what this console error means?
Error: Unexpected value 'QuillModule' imported by the module 'AppModule' at d

unexpected actions

hi, the does the demo work for you? I checked your live demo and the editor behaves very buggy. the cursor randomly goes to the beginning of the text, some spaces are removed and there happen a huge number of selectionaction event on the background.

Ability to add custom toolbar options through quill-editor-toolbar to existing toolbar

I'm trying to add additional options to the toolbar which contains syntax highlighting option. In other words, something like this does not work

<quill-editor [(ngModel)]="title"
              [maxLength]="5"
              [minLength]="3"
              [required]="true"
              [modules]="{syntax:true,toolbar: [['code-block']]}"
              (onContentChanged)="onContentChanged($event);">

  <div quill-editor-toolbar>
    <span class="ql-formats">
      <button class="btn-primary">save</button>
    </span>
  </div>

</quill-editor>

Is there a workaround for something like this?

Configurable block tag (div, paragraph)

Any ideas on how to implement the solution found here in an Angular 2 project? I'm not fond of the <p><br></p> line on enter. I think the output should look the same as what's shown in the editor.

Angular universal

Hi,

ngx-quill breaks universal

for example this line
var elem = document.createElement('div');

cause
ReferenceError: document is not defined

Support for reactive forms (formControl)

First of all, thanks for your work on this great plugin! It works nicely with template driven forms.

I would, however, also like to use it with reactive forms. Thus i need to use "formControl" instead of "ngModel".

It appears that this is not fully supported(?)

My specific problem is that I am not able to use the "patchValue" method (of FormGroup) to insert content into the quill editor. The editor window remains empty after patching.

Entering new content by hand, and saving it, works fine however.

Please correct me if I'm mistaken.

Thanks!

How to add custom handler

Hi, first of all, thank you for this cool package :).

So, here is my issue: I need to add a custom handler for the images (I don't want the image to be stored in base 64)

How can I add a custom handler ?

Reset the quill editor

I'm using angular 4 + reactive forms and bringing rich text in from my api. On initialization the quill editor puts the rich text in exact how I want, but if I overwrite the initialized editor it will strip all my markup inside the opening p and closing /p tags. How can I make every patchValue replace the editor body with exactly what I want it to from the api?

Setting modules input results in error

Setting modules input causes error quill Cannot import modules/0. Are you sure it was registered? .
My exaple is:
<quill-editor formControlName="journalEntry" modules="{toolbar: [['bold', 'italic', 'underline', 'strike']]}") </quill-editor>

Thank you

Compiling with ng build --aot throws "can't find symbol KeyRegistry exported from module"

Using AngularCLI and trying to build in AOT mode, I get this error: "can't find symbol KeyRegistry exported from module". Honestly at this stage I have no idea what this means or why - I am raising it here in the hope that someone knows what this means - I will post back here if I can figure out the issue

>ng build --aot
  0% compilingcan't resolve module C:/Git/QueMesaAdmin/QueMesaAdminApp/node_modules/ngx-quill/node_modules/@angular/core/src/di/reflective_key.d.ts from C:/Git/QueMesaAdmin/QueMesaAdminApp/node_modules/ngx-quill/node_modules/@angular/core/src/di/reflective_key.d.ts
can't find symbol KeyRegistry exported from module C:/Git/QueMesaAdmin/QueMesaAdminApp/node_modules/ngx-quill/node_modules/@angular/core/src/di/reflective_key.d.ts
Error: can't find symbol KeyRegistry exported from module C:/Git/QueMesaAdmin/QueMesaAdminApp/node_modules/ngx-quill/node_modules/@angular/core/src/di/reflective_key.d.ts
    at ReflectorHost.findDeclaration (C:\Users\chuckj\src\angular\modules\@angular\compiler-cli\src\reflector_host.ts:200:15)
    at C:\Users\chuckj\src\angular\modules\@angular\compiler-cli\src\codegen.ts:179:44
    at Array.forEach (native)

Register new module ImageResize

I'm trying to add a new module in the editor to show image size and can resize it.

I found this module for the Quill editor but I am not able to add it in ngx-quill when it returns the editor in onEditorCreated ()

Component.js
onEditorCreated(quill) { this.editor = quill; this.editor.register('modules/ImageResize',ImageResize); console.log('quill is ready! this is current quill instance object', quill); }

`/**
 * Custom module for quilljs to allow user to resize <img> elements
 * (Works on Chrome, Edge, Safari and replaces Firefox's native resize behavior)
 * @see https://quilljs.com/blog/building-a-custom-module/
 */ 
export class ImageResize {
 
	constructor(quill, options = {}) {
		// save the quill reference and options
		this.quill = quill;
		this.options = options;

		// bind handlers to this instance
		this.handleClick = this.handleClick.bind(this);
		this.handleMousedown = this.handleMousedown.bind(this);
		this.handleMouseup = this.handleMouseup.bind(this);
		this.handleDrag = this.handleDrag.bind(this);
		this.checkImage = this.checkImage.bind(this);

		// track resize handles
		this.boxes = [];

		// disable native image resizing on firefox
		document.execCommand('enableObjectResizing', false, 'false');

		// respond to clicks inside the editor
		this.quill.root.addEventListener('click', this.handleClick, false);
	}

	handleClick(evt) {
		if (evt.target && evt.target.tagName && evt.target.tagName.toUpperCase() == 'IMG') {
			if (this.img === evt.target) {
				// we are already focused on this image
				return;
			}
			if (this.img) {
				// we were just focused on another image
				this.hide();
			}
			// clicked on an image inside the editor
			this.show(evt.target);
		}
		else if (this.img) {
			// clicked on a non image
			this.hide();
		}
	}

	show(img) {
		// keep track of this img element
		this.img = img;
		this.showResizers();
		this.showSizeDisplay();
		// position the resize handles at the corners
		const rect = this.img.getBoundingClientRect();
		this.positionBoxes(rect);
		this.positionSizeDisplay(rect);
	}

	hide() {
		this.hideResizers();
		this.hideSizeDisplay();
		this.img = undefined;
	}

	showResizers() {
		// prevent spurious text selection
		this.setUserSelect('none');
		// add 4 resize handles
		this.addBox('nwse-resize'); // top left
		this.addBox('nesw-resize'); // top right
		this.addBox('nwse-resize'); // bottom right
		this.addBox('nesw-resize'); // bottom left
		// listen for the image being deleted or moved
		document.addEventListener('keyup', this.checkImage, true);
		this.quill.root.addEventListener('input', this.checkImage, true);
	}

	hideResizers() {
		// stop listening for image deletion or movement
		document.removeEventListener('keyup', this.checkImage);
		this.quill.root.removeEventListener('input', this.checkImage);
		// reset user-select
		this.setUserSelect('');
		this.setCursor('');
		// remove boxes
		this.boxes.forEach(box => document.body.removeChild(box));
		// release memory
		this.dragBox = undefined;
		this.dragStartX = undefined;
		this.preDragWidth = undefined;
		this.boxes = [];
	}

	addBox(cursor) {
		// create div element for resize handle
		const box = document.createElement('div');
		// apply styles
		const styles = {
			position: 'absolute',
			height: '12px',
			width: '12px',
			backgroundColor: 'white',
			border: '1px solid #777',
			boxSizing: 'border-box',
			opacity: '0.80',
			cursor: cursor,
		};
		this.extend(box.style, styles, this.options.handleStyles || {});
		// listen for mousedown on each box
		box.addEventListener('mousedown', this.handleMousedown, false);
		// add drag handle to document
		document.body.appendChild(box);
		// keep track of drag handle
		this.boxes.push(box);
	}

	extend(destination, ...sources) {
		sources.forEach(source => {
			for (let prop in source) {
				if (source.hasOwnProperty(prop)) {
					destination[prop] = source[prop];
				}
			}
		});
		return destination;
	}

	positionBoxes(rect) {
		// set the top and left for each drag handle
		[
			{left: rect.left - 6, top: rect.top - 6},               // top left
			{left: rect.left + rect.width - 6, top: rect.top - 6},               // top right
			{left: rect.left + rect.width - 6, top: rect.top + rect.height - 6}, // bottom right
			{left: rect.left - 6, top: rect.top + rect.height - 6}, // bottom left
		].forEach((pos, idx) => {
			this.extend(this.boxes[idx].style, {
				top: Math.round(pos.top + window.pageYOffset) + 'px',
				left: Math.round(pos.left + window.pageXOffset) + 'px',
			});
		});
	}

	handleMousedown(evt) {
		// note which box
		this.dragBox = evt.target;
		// note starting mousedown position
		this.dragStartX = evt.clientX;
		// store the width before the drag
		this.preDragWidth = this.img.width || this.img.naturalWidth;
		// set the proper cursor everywhere
		this.setCursor(this.dragBox.style.cursor);
		// listen for movement and mouseup
		document.addEventListener('mousemove', this.handleDrag, false);
		document.addEventListener('mouseup', this.handleMouseup, false);
	}

	handleMouseup() {
		// reset cursor everywhere
		this.setCursor('');
		// stop listening for movement and mouseup
		document.removeEventListener('mousemove', this.handleDrag);
		document.removeEventListener('mouseup', this.handleMouseup);
	}

	handleDrag(evt) {
		if (!this.img) {
			// image not set yet
			return;
		}
		// update image size
		if (this.dragBox == this.boxes[0] || this.dragBox == this.boxes[3]) {
			// left-side resize handler; draging right shrinks image
			this.img.width = Math.round(this.preDragWidth - evt.clientX - this.dragStartX);
		}
		else {
			// right-side resize handler; draging right enlarges image
			this.img.width = Math.round(this.preDragWidth + evt.clientX - this.dragStartX);
		}
		// reposition the drag handles around the image
		const rect = this.img.getBoundingClientRect();
		this.positionBoxes(rect);
		this.positionSizeDisplay(rect);
	}

	setUserSelect(value) {
		[
			'userSelect',
			'mozUserSelect',
			'webkitUserSelect',
			'msUserSelect'
		].forEach(prop => {
			// set on contenteditable element and <html>
			this.quill.root.style[prop] = value;
			document.documentElement.style[prop] = value;
		});
	}

	setCursor(value) {
		[
			document.body,
			this.img,
			this.quill.root
		].forEach(el => el.style.cursor = value);
	}

	checkImage() {
		if (this.img) {
			this.hide();
		}
	}

	showSizeDisplay() {
		if (!this.options.displaySize) {
			return;
		}
		this.display = document.createElement('div');
		// apply styles
		const styles = {
			position: 'absolute',
			font: '12px/1.0 Arial, Helvetica, sans-serif',
			padding: '4px 8px',
			textAlign: 'center',
			backgroundColor: 'white',
			color: '#333',
			border: '1px solid #777',
			boxSizing: 'border-box',
			opacity: '0.80',
			cursor: 'default',
		};
		this.extend(this.display.style, styles, this.options.displayStyles || {});
		document.body.appendChild(this.display);
	}

	hideSizeDisplay() {
		document.body.removeChild(this.display);
		this.display = undefined;
	}

	positionSizeDisplay(rect) {
		if (!this.display || !this.img) {
			return;
		}
		const size = this.getCurrentSize();
		this.display.innerHTML = size.join(' &times; ');
		if (size[0] > 120 && size[1] > 30) {
			// position on top of image
			const dispRect = this.display.getBoundingClientRect();
			this.extend(this.display.style, {
				left: Math.round(rect.left + rect.width + window.pageXOffset - dispRect.width - 8) + 'px',
				top: Math.round(rect.top + rect.height + window.pageYOffset - dispRect.height - 8) + 'px',
			});
		}
		else {
			// position off bottom right
			this.extend(this.display.style, {
				left: Math.round(rect.left + rect.width + window.pageXOffset + 8) + 'px',
				top: Math.round(rect.top + rect.height + window.pageYOffset + 8) + 'px',
			});
		}
	}

	getCurrentSize() {
		return [
			this.img.width,
			Math.round(this.img.width / this.img.naturalWidth * this.img.naturalHeight),
		];
	}

}
`

Someone know how to ?

Will not compile with "noImplicitAny"

Line 93 in "quill-editor.component.ts" throws an error when compiled with Typescripts "noImplicitAny" flag set.

"[ts] Element implicitly has an 'any' type because type 'Object' has no index signature."

The code:

if (toolbarElem) {
  modules['toolbar'] = toolbarElem; // Throws error
}

Error 413 Payload Too Large

Hi, when I upload a image to the content, the error bellow happens:

Response {_body: "↵↵↵<meta char…s/cors/lib/index.js:185:7)↵↵↵", status: 413, ok: false, statusText: "Payload Too Large", headers: Headers, …}
headers
:
Headers {_headers: Map(12), _normalizedNames: Map(12)} ok : false
status : 413
statusText : "Payload Too Large"
type : 2
url :
"http://www.adrianabartolomucci.com.br/api/servicos/59370f9d6993d8381cd31694"
_body
:
"↵↵↵↵<title>Error</title>↵↵↵

Error: request entity too large
   at readStream (/home/adrianabartolomucci/apps_nodejs/node_modules/body-parser/node_modules/raw-body/index.js:196:17)
   at getRawBody (/home/adrianabartolomucci/apps_nodejs/node_modules/body-parser/node_modules/raw-body/index.js:106:12)
   at read (/home/adrianabartolomucci/apps_nodejs/node_modules/body-parser/lib/read.js:76:3)
   at jsonParser (/home/adrianabartolomucci/apps_nodejs/node_modules/body-parser/lib/types/json.js:127:5)
   at Layer.handle [as handle_request] (/home/adrianabartolomucci/apps_nodejs/node_modules/express/lib/router/layer.js:95:5)
   at trim_prefix (/home/adrianabartolomucci/apps_nodejs/node_modules/express/lib/router/index.js:317:13)
   at /home/adrianabartolomucci/apps_nodejs/node_modules/express/lib/router/index.js:284:7
   at Function.process_params (/home/adrianabartolomucci/apps_nodejs/node_modules/express/lib/router/index.js:335:12)
   at next (/home/adrianabartolomucci/apps_nodejs/node_modules/express/lib/router/index.js:275:10)
   at /home/adrianabartolomucci/apps_nodejs/app.js:43:5
   at Layer.handle [as handle_request] (/home/adrianabartolomucci/apps_nodejs/node_modules/express/lib/router/layer.js:95:5)
   at trim_prefix (/home/adrianabartolomucci/apps_nodejs/node_modules/express/lib/router/index.js:317:13)
   at /home/adrianabartolomucci/apps_nodejs/node_modules/express/lib/router/index.js:284:7
   at Function.process_params (/home/adrianabartolomucci/apps_nodejs/node_modules/express/lib/router/index.js:335:12)
   at next (/home/adrianabartolomucci/apps_nodejs/node_modules/express/lib/router/index.js:275:10)
   at cors (/home/adrianabartolomucci/apps_nodejs/node_modules/cors/lib/index.js:185:7)
↵↵↵"
proto
:
Body

Cursor moving to beginning of line

ngx-quilltest

As seen above, whenever I first initiate the quill editor (with a null, '', or database value), the cursor automatically moves to the front and starts placing characters in front of it.

quill version: "ngx-quill": "^1.3.3" (I've confirmed that 1.33 is installed by using the npm list --depth=0 command

HTML:
<quill-editor formControlName="answer" (onEditorCreated)="setFocus($event)"></quill-editor>

The setFocus method is the same as you have in your demo.

Any insights as to why this is happening? If you need more information, please let me know.

Registration of quill-image-resize-module fails

I have been trying to register an image resize module (https://github.com/kensnyder/quill-image-resize-module) with Quill. But as soon as Quill.register('modules/imageResize', ImageResize); is called, I get the following error: TypeError: Cannot read property 'imports' of undefined

I created a plunker that shows the issue:
https://plnkr.co/edit/IrSndtpRKSXG324zArN7?p=preview

I don't really know if this is really an issue or if I'm simply mistaking something in the configuration. I have had a look at the examples provided and other issues but have not been able to resolve this problem. Hence, any help would be deeply appreciated as the ability to resize images is something quite handy to have.

Thank you very much.

Where do I get quill.snow.css from?

Hi again,

I don't want to use the Quill CDN for quill.snow.css and would like to reference it from the Node modules in my angualar-cli json file so it is packaged in WebPack. However, I can't seem to find it in ngx-quill or quill - where can I find it?

Syntax highlighter

Hi
This might be the wrong place for my question but here goes...

I have added angular2-highlight-js and it works very well inside quill.

But when I want to display syntax highlighted code outside quill I am not able to get it working.
On the element i set:
highlight-js-content=".highlight"
This is according to the docs in highlight. But quill saves it:
<pre class="ql-syntax" spellcheck="false">

Any idea on how I can make this work?

In advance thank you.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.