How to set responsive images with CKEditor 5? - ckeditor

Using the Simple Upload Adapter, according to the CKEditor 5 documentation upon a successful image upload, the server should return either:
This for a single image:
{
default: 'http://example.com/images/image–default-size.png'
}
Or this for multiple (i.e. for the srcset attribute)
{
default: 'http://example.com/images/image–default-size.png',
'160': 'http://example.com/images/image–size-160.image.png',
'500': 'http://example.com/images/image–size-500.image.png',
'1000': 'http://example.com/images/image–size-1000.image.png',
'1052': 'http://example.com/images/image–default-size.png'
}
For starters the documentation is incorrect as per this SO post, so I'm not surprised this doesn't work. But does anyone know what response format CKEditor 5 is expecting for it to correctly insert/build the srcset attribute? It does take the default key but seems to ignore the others!

Inside of the _initListeners function of the upload adapter you will find that the Promise only resolves with the following:
resolve( {
default: response.url
} );
The solution - change the Promise to resolve the following:
resolve( response.urls );
Note, in this example the response object may have either keys url or urls.
I ended up using the following as I ignore null keys in my server responses.
if ( response.hasOwnProperty( 'url' ) ) {
resolve( {
default: response.url
} );
} else if ( response.hasOwnProperty( 'urls' ) ) {
resolve( response.urls );
}
As a sidenote, if you've read through the other SO post I referred to, I would also recommend removing this (see commented section):
if ( !response /** || !response.uploaded */ ) {
return reject( response && response.error && response.error.message ? response.error.message : genericError );
}
I'm not a fan of using arbitrary flags in response, if the upload failed then I would rather see a HTTP status code indicating it, I can't see any reason why we need to return 200 and { "uploaded" : false }

Related

React Redux dispatch getting called multiple times

MERN Stack application with Login and Register working properly.
On opening dashboard ("/" path), it dispatches "getWallets" 3 times, instead of 1:
Dashboard.jsx :
useEffect(() => {
if (isError) {
console.log(message)
}
if (!user) {
navigate("/login")
}
else {
dispatch(getWallets())
}
return () => {
dispatch(reset())
}
}, [user, navigate, isError, message, dispatch])
It also dispatches "getWalletData" 9 times instead of one (since I only have 1 wallet atm).
TestWalletsData.jsx (component inserted on Dashboard.jsx):
useEffect(() => {
if (isError) {
console.log(message)
}
if (wallets.length > 0 && walletsData.length <= wallets.length) {
wallets.forEach(wallet => {
dispatch(getWalletData(wallet))
dispatch(reset())
})
}
return () => {
dispatch(reset())
}
}, [wallets, wallets.length, walletsData, isError, message, dispatch])
At this point the application is running ok since I don't permit another object to get pushed to the state if it's already there , but since I'm using a limited rate API to get wallets data this isn't the road I want to path.
I'm assuming the issue arrives with the re-rendering of components and the wrong use of useEffect, but I just don't know how to fix it.
I've tried setting the environment to production as suggested by this comment but everything stays the same. https://stackoverflow.com/a/72301433/14399239
PS: Never worked with React Redux or Redux for that matter before trying it out on this project. Tried to follow a tutorial logic and apply it on my use case but having serious difficulties.
EDIT
Managed to solve the issue by removing the React.StrictMode !

Remove particular type of error from Datadog

Currently, I see error status for all the authentication errors and it feels like a lot of extra noise in the total errors chart. I looked at https://github.com/DataDog/dd-trace-js/pull/909 and tried to use the custom execute provided for graphql
import ddTrace from 'dd-trace'
let tracer = ddTrace.init({
debug: false
}) // initialized in a different file to avoid hoisting.
tracer.use('graphql', {
hooks: {
execute: (span, args, res) => {
if (res && res.errors && res.errors[0] && res.errors[0].status !== 403) {
span?.setTag('error', res.errors)
}
}
}
})
export default tracer
But still, res with only 403 error is going into error status. Please help me with how can I achieve this.
Update: I found this bit of code in the tracing client repo:
tracer.use('graphql', {
hooks: {
execute: (span, args, res) => {
if (res?.errors?.[0]?.status === 403) { // assuming "status" is a number
span?.setTag('error', null) // remove any error set by the tracer
}
}
}
})
https://github.com/DataDog/dd-trace-js/issues/1249
maybe it would help
Old message:
Never mind. seems like my solution is only for express, graphql doesn't support that property
You probably want to just modify the validateStatus property in the http module:
Callback function to determine if there was an error. It should take a status code as its only parameter and return true for success or false for errors
https://datadoghq.dev/dd-trace-js/interfaces/plugins.http.html#validatestatus
As an example you should be able to mark 403s as not be errors with something like this:
const tracer = require('dd-trace').init();
tracer.use('express', {
validateStatus: code => code < 400 && code != 403
})

vuepress build docs get ReferenceError: pageMeta is not defined?

vuepress dev docs is ok, but vuepress build docs get the following error, why?
...
...
✔ Client
Compiled successfully in 22.59s
✔ Server
Compiled successfully in 15.41s
wait Rendering static HTML...
error Error rendering /404.html: false
undefined
...
...
ReferenceError: pageMeta is not defined
...
...
tl;dr You need to downgrade vue-router which is installed as part of vuepress to match ~3.1.3.
I've basically encountered the same error when trying to implement some VuePress theme.
AFAICT the pageMeta is related to VuePress rendering pages on server-side (SSR). It's used in a template using triple curly braces and there are parts of vuepress-generated code assigning data for this markup to be replaced with properly. Since I didn't touch any SSR-related stuff in VuePress I'm quite sure I haven't done anything causing this particular issue explicitly.
So I've tried to disable parts of my code to locate the fragment which is causing this misbehaviour. It turns out the obvious culprit is vue-router.
I'm applying a navigation guard on vue-router instance exposed in enhanceApp.js of VuePress. Inside that guard I put code complying with existing documentation for vue-router. Essentially, I am redirecting some requests due to optionally existing redirection tables or frontmatter information.
In vuepress dev this code is working, but generating errors in browser console. Those errors are about an unhandled promise rejection due to aborting initially requested routing transition in favour of starting another one which seems an eligible intention on using vue-router.
does not work:
export default function( context ) {
const { router, siteData: { pages, themeConfig = {} } } = context;
router.beforeEach( handleRedirects );
function handleRedirects( to, from, next ) {
const numPages = pages.length;
for ( let i = 0; i < numPages; i++ ) {
const { path, frontmatter } = pages[i];
if ( path === to.path && frontmatter.redirect ) {
if ( from.path === frontmatter.redirect ) {
next( false );
} else {
next( frontmatter.redirect );
}
return;
}
}
const redirections = themeConfig.redirect || {};
if ( redirections.hasOwnProperty( to.path ) ) {
next( redirections[to.path] );
return;
}
next();
}
}
does work:
export default function( context ) {
const { router, siteData: { pages, themeConfig = {} } } = context;
router.beforeEach( handleRedirects );
function handleRedirects( to, from, next ) {
const numPages = pages.length;
for ( let i = 0; i < numPages; i++ ) {
const { path, frontmatter } = pages[i];
if ( path === to.path && frontmatter.redirect ) {
if ( from.path === frontmatter.redirect ) {
next( false );
} else {
next(); // <--- omitting passed target
}
return;
}
}
const redirections = themeConfig.redirect || {};
if ( redirections.hasOwnProperty( to.path ) ) {
next(); // <--- omitting passed target
return;
}
next();
}
}
Just to be clear: The latter one makes vuepress build succeed, but the result isn't functional with regards to properly handling redirects.
IMHO the issue is with vue-router for rejecting some promise I didn't start here. One might claim it is with vuepress for failing to adopt a change in API by handling rejected routing transitions properly. But this is also true for SSR (look at third code example given there).
As a solution, you could try downgrading vue-router to versions prior to 3.2.0. In my case, vuepress is properly asking for version ^3.1.3. However, due to semantic versioning, this selector is covering latest 3.4.3 as well.
Thus concluding, there is a breaking change in vue-router, which has been introduced with minor release version 3.2.0. Because of that vue-router isn't complying with semantic versioning.
IMHO, this change of behaviour isn't quite eligible at all for code using vue-router should not have to care about how routing is proceeding unless it leads to some valid target. Thus, code asking to switch route shouldn't cause a rejection that must be handled. This feedback might be optional, but right now it is sort of mandatory.

ionic 2 caching images

I am writing an ionic 2 application, and want to cache images.
After long searching on the web I found these references:
https://gist.github.com/ozexpert/d95677e1fe044e6173ef59840c9c484e
https://github.com/chrisben/imgcache.js/blob/master/js/imgcache.js
I implemented the given solution, but i see that the ImgCache module does not behave as expected - the ImgCache.isCached callback is never called.
Any idea or other good solution for caching images in ionic 2?
======== UPDATE ==========
Here is the directive code I use:
import { Directive, ElementRef, Input } from '#angular/core';
import ImgCache from 'imgcache.js';
#Directive({
selector: '[image-cache]'
})
export class ImageCacheDirective {
constructor (
private el: ElementRef
) {
// init
}
ngOnInit() {
// This message is shown in console
console.log('ImageCacheDirective *** ngOnInit: ', this.el.nativeElement.src);
this.el.nativeElement.crossOrigin = "Anonymous"; // CORS enabling
ImgCache.isCached(this.el.nativeElement.src, (path: string, success: any) => {
// These message are never printed
console.log('path - '+ path);
console.log('success - '+ success);
if (success) {
// already cached
console.log('already cached so using cached');
ImgCache.useCachedFile(this.el.nativeElement);
} else {
// not there, need to cache the image
console.log('not there, need to cache the image - ' + this.el.nativeElement.src);
ImgCache.cacheFile(this.el.nativeElement.src, () => {
console.log('cached file');
// ImgCache.useCachedFile(el.nativeElement);
});
}
});
}
}
In app.nodule.es I do:
import { ImageCacheDirective } from '../components/image-cache-directive/image-cache-directive';
and then in home.html:
<img src="http://localhost/ionic-test/img/timeimg.php" image-cache>
It's late but probably this is the solution:
1. Install cordova FileTransfer:
ionic plugin add cordova-plugin-file-transfer --save
2. Init ImgCache when the deviceready event of cordova fires. In src/app/app.component.ts add these methods (or integrate them with your initializeApp() method - this method comes up with a default project start):
initImgCache() {
// activated debug mode
ImgCache.options.debug = true;
ImgCache.options.chromeQuota = 100 * 1024 * 1024; // 100 MB
ImgCache.init(() => { },
() => { console.log('ImgCache init: error! Check the log for errors'); });
}
initializeApp() {
this.platform.ready().then(() => {
this.initImgCache();
// Okay, so the platform is ready and our plugins are available.
// Here you can do any higher level native things you might need.
StatusBar.styleDefault();
Splashscreen.hide();
});
}
Another option is to use a dedicated cache manager for ionic. instead of implementing everything on your own.
Here are 2 options :
1. A generic cache implementation :https://github.com/Nodonisko/ionic-cache
2. This one is better for images: https://github.com/BenBBear/ionic-cache-src
EDIT:
This is not a "link only" answer.. it tells the user to use a ready made implementations instead of trying to implement from scratch.

How can I save Material with a envMap property?

My Material has a envMap. I call Material.toJSON() to save it to localStorage.
There is an error reported ,saying
Texture.js:124 Uncaught TypeError: Failed to execute 'drawImage' on 'CanvasRenderingContext2D': The provided value is not of type '(HTMLImageElement or HTMLVideoElement or HTMLCanvasElement or ImageBitmap)'.
I debugged it, found the image is an array which is not the correct type.
Here is my question,how can I save my material with an envMap property correctly?
[Update]: I've posted this as an issue which you can reference here.
I just ran into this problem as well. I fixed it by modifying the THREE.js source as follows.
In the getDataURL function inside of toJSON, there is a section that assigns meta.images[ img ] paths to the data URLs of your envMap.
Here's my fix [starts at line 22134, rev 79]:
if ( meta.images[ image.uuid ] === undefined ) {
/* ADD THIS PART */
if (image instanceof Array && image.length > 1) {
meta.images[ image.uuid ] = {
uuid: image.uuid,
url: image.map((val) => { getDataURL(val) })
};
} else {
meta.images[ image.uuid ] = {
uuid: image.uuid,
url: getDataURL( image )
};
}
}

Resources