Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Other SVG (eg: Font Awesome) #31

Closed
kl3sk opened this issue Mar 6, 2019 · 12 comments
Closed

Other SVG (eg: Font Awesome) #31

kl3sk opened this issue Mar 6, 2019 · 12 comments
Labels
resolution:resolved This issue was already resolved (e.g. by another ticket). type:question

Comments

@kl3sk
Copy link

kl3sk commented Mar 6, 2019

Following this doc evrething works as expected.

Now I want to create a custom plugin fowling this doc

As long as I use ckeditor SVG to add to the toolbar it works, but when I want to use fa's one it doesn't.

I tried to modify vue.config.js without success.

@kl3sk kl3sk changed the title Other SVG (eg fontaawesom) Other SVG (eg: Font Awesome) Mar 6, 2019
@jodator
Copy link

jodator commented Mar 6, 2019

@kl3sk Quick question: where do you put the SVG icon? The icons from CKEditor 5 are put in specific folders in order to raw-loader and not Vue's loader would load them:

// vue.config.js as in first linked docs:
config.module
	.rule( 'cke-svg' )
	.test( /ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/ )
	.use( 'raw-loader' )
	.loader( 'raw-loader' );

The trick part here is that Vue uses other loader then CKEditor 5 for SVGs. This code tests for CKEditor 5 icons located under theme/icons in every ckeditor5-package. So if you put it in you plugin you should add a .test() condition to match your icons and add it to the cke-svg and check if they are loaded then.

I'd try with something like this:

config.module
	.rule( 'cke-svg' )
	.test( /ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/ )
	.test( /my-plugin[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/ )         // <- added
	.use( 'raw-loader' )
	.loader( 'raw-loader' );

@kl3sk
Copy link
Author

kl3sk commented Mar 6, 2019

@jodator thanks for your answer.

I try to add like this

config.module
	.rule( 'cke-svg' )
        .test( /ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/ )
        .test(/fontawesome-[^/\\]+[/\\]svgs[/\\](solid|regular|brand)[/\\][^/\\]+\.svg$/)
        .use( 'raw-loader' )
        .loader( 'raw-loader' )

Edit:
Here is a part of the error

 error  in ./node_modules/@ckeditor/ckeditor5-image/theme/icons/image_placeholder.svg

Module parse failed: Unexpected token (1:0)
You may need an appropriate loader to handle this file type.
> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 700 250"><rect rx="4"/></svg>

 @ ./node_modules/@ckeditor/ckeditor5-image/src/imageupload/imageuploadprogress.js 21:0-75 54:72-92
 @ ./node_modules/@ckeditor/ckeditor5-image/src/imageupload.js
 @ ./node_modules/cache-loader/dist/cjs.js??ref--12-0!./node_modules/babel-loader/lib!./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader/lib??vue-loader-options!./src/views/Document/Document.vue?vue&type=script&lang=js&
 @ ./src/views/Document/Document.vue?vue&type=script&lang=js&
 @ ./src/views/Document/Document.vue
 @ ./src/router.js
 @ ./src/main.js
 @ multi (webpack)-dev-server/client?http://192.168.121.62:8080/sockjs-node (webpack)/hot/dev-server.js ./src/main.js

@jodator
Copy link

jodator commented Mar 6, 2019

It must be something with the paths, I've used vue icon from FA and used in one of manual tests (no Vue integration and loaded from default location):

selection_221

I don't recall exactly what part of path was checked but double check them for typos ;)

Also adding another rule with one test might help (I don't recall how this API worked TBH):

config.module
	.rule( 'my-svg' )
	// start with direct path (ie inside your project)
        .test( /last\/part\/of\/path\/to\/icon.svg$/ )
        .use( 'raw-loader' )
        .loader( 'raw-loader' )

Edit: The error show that the loader didn't kick in so probably the path is wrong or the test should be written differently.

@kl3sk
Copy link
Author

kl3sk commented Mar 6, 2019

Ok i'll try to check my path. But @fortawesome/fontawesome-free/svgs/solid/search.svg (for example) seem good because I test the regex.

BTW I tried to create an other rule too.

@kl3sk
Copy link
Author

kl3sk commented Mar 6, 2019

With this rule:

    config.module
      .rule('my-svg')
      .test(/fontawesome-free\/svgs\/solid\/search\.svg$/)
      .use('raw-loader')
      .loader('raw-loader')

and this import:

import imageIcon from '@fortawesome/fontawesome-free/svgs/solid/search.svg'

I have still the error.

May I've made a typo I didn't saw ?

EDIT:
I have this in my console too

 TypeError: "svg is null"

EDIT2:

Erreur d’analyse XML : mal formé -> XML parsing error: incorrectly formed

@jodator
Copy link

jodator commented Mar 6, 2019

Alrighty:

you have two options (noted in the docs)

a) clear the rules (if you don't have other SVGs)

	chainWebpack: config => {
		const svgRule = config.module.rule( 'svg' );

		svgRule.uses.clear();
		svgRule.use( 'raw-loader' ).loader( 'raw-loader' );
	}

Option b) leave other svg intact

	chainWebpack: config => {
		const svgRule = config.module.rule( 'svg' );

		svgRule.exclude.add(__dirname + "/node_modules/@ckeditor");
		svgRule.exclude.add(__dirname + "/node_modules/@fortawesome");       // ! this

		config.module
		 	.rule( 'cke-svg' )
// beautify this or use another rule 
		 	.test( /ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg|svgs\/brands\/vuejs\.svg$/ )
		 	.use( 'raw-loader' )
		 	.loader( 'raw-loader' )
// add .rule( 'my-svg' ) below with one `test()` call per svg path.
	}

the app:

<template>
	<div id="app">
		<ckeditor :editor="editor" v-model="editorData" :config="editorConfig"></ckeditor>
	</div>
</template>

<script>
	import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classiceditor';

	import EssentialsPlugin from '@ckeditor/ckeditor5-essentials/src/essentials';
	import BoldPlugin from '@ckeditor/ckeditor5-basic-styles/src/bold';
	import ItalicPlugin from '@ckeditor/ckeditor5-basic-styles/src/italic';
	import LinkPlugin from '@ckeditor/ckeditor5-link/src/link';
	import ParagraphPlugin from '@ckeditor/ckeditor5-paragraph/src/paragraph';

	import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
	import ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview';

	import vueIcon from '@fortawesome/fontawesome-free/svgs/brands/vuejs.svg'
	// import vueIcon from '@ckeditor/ckeditor5-basic-styles/theme/icons/bold.svg'

	class MyPlugin extends Plugin {
		init() {
			this.editor.ui.componentFactory.add( 'vuebutton', locale => {
				const buttonView = new ButtonView( locale );

				buttonView.set( {
					label: 'Vue icon',
					tooltip: true,
					withText: true,
					icon: vueIcon
				} );

				this.listenTo( buttonView, 'execute', () => {
					// eslint-disable-next-line
					console.log('uga')
				} );

				return buttonView;
			} );
		}
	}

	export default {
		name: 'app',
		data() {
			return {
				editor: ClassicEditor,
				editorData: '<p>Content of the editor.</p>',
				editorConfig: {
					plugins: [
						EssentialsPlugin,
						BoldPlugin,
						ItalicPlugin,
						LinkPlugin,
						ParagraphPlugin,
						MyPlugin
					],

					toolbar: {
						items: [
							'bold',
							'italic',
							'link',
							'undo',
							'redo',
							'vuebutton'
						]
					}
				}
			};
		}
	};
</script>

ps.: Don't forget to start & stop dev server since it needs to reload webpack config.

and works with Vue like this:

selection_222

@jodator jodator added pending:feedback This issue is blocked by necessary feedback. type:question labels Mar 6, 2019
@kl3sk
Copy link
Author

kl3sk commented Mar 6, 2019

I read the docs, and I tried both solutions.

The first work but my others SVG doesn't works any more, so I jump to the other solution and even with your sample it does the same.

I ever try your solution without any working code.

edit: BTW I reload my dev server each time :)

@jodator
Copy link

jodator commented Mar 6, 2019

Check the svgRule.exclude.add(__dirname + "/node_modules/@fortawesome"); part. If you use some Font Awesome SVGs for CKEditor 5 and some for other code of Vue app you might need to copy some of them to other location to be usable with CKEditor 5 icons (`raw-loader). I don't see any easy fix for this.

ps.: @kl3sk you can post your solution if you mange to make this working :)

@kl3sk
Copy link
Author

kl3sk commented Mar 6, 2019

Yes i'll do if i find.

An other clue, I use a custom build, maybe it is the problem ?

@kl3sk
Copy link
Author

kl3sk commented Mar 7, 2019

Ok, after some search and tries I finally understand the problem.

Long answer:

As @jodator said, in a VueJs project, it used it own loader (for SVG in this case) and Ckeditor its own.
I said earlier I test two solutions proposed by Ckeditor docs. The first work for Ckeditor and no more for my project, in fact because this solution reset the SVG loader my Vue app is not able any more to load SVG.

After this, I follow the second solution.
I try to load an other rule in webpack-chain and/or modify the .test function inside the Ckeditor's one.
Nothing will work ! In fact fontawesome package was ever loader inside my Vue app so for any reason can't be loaded twice with an other loader. This is the reason why it doesn't work.

The solution was copying my font to an other location and add a rule to load it through Ckeditor's loader aka: raw-loader.

Short answer:

  • Copy your font elsewere
my/custom/folder
  • Exclude it from the svgRules :
svgRule.exclude.add(path.join(__dirname, 'my/custom/folder'))
  • Create an new rule to load it
config.module
      .rule('cke-plugin-browser')
      .test(/my[/\\]custom[/\\]folder[/\\][^/\\]+\.svg$/)
      .use('raw-loader')
      .loader('raw-loader')

Idea

I don't know if it possible but, why not use Vue loader when ckeditor-vue is used ?

Despite this last question, I close this issue because solved for me.

@kl3sk kl3sk closed this as completed Mar 7, 2019
@Mgsy Mgsy added resolution:solved and removed pending:feedback This issue is blocked by necessary feedback. labels Mar 7, 2019
@jodator
Copy link

jodator commented Mar 7, 2019

I don't know if it possible but, why not use Vue loader when ckeditor-vue is used ?

AFAIR the vue uses file-loader which just outputs URI to a file. In CKE5 we're bundling the SVG contents into the package. We're using raw-loader to load SVG contents and then use it to create an icon.

@kl3sk
Copy link
Author

kl3sk commented Mar 7, 2019

It could maybe be added to the docs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
resolution:resolved This issue was already resolved (e.g. by another ticket). type:question
Projects
None yet
Development

No branches or pull requests

4 participants