I'm trying to use Letters as the main collaborative text editor for one of our projects. But, I'm unable to run even a simple demo.
This is my "index.html" test page:
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="letters.js"></script>
<meta charset="UTF-8">
<script type="text/javascript">
function load() {
Letters.create( document.body, {
cloudServices: {
tokenUrl: '<Development token URL from https://dashboard.ckeditor.com>',
uploadUrl: '<Upload URL from https://dashboard.ckeditor.com>',
documentId: 'cats'
},
title: 'Cats',
body: `<p>Cats are awesome.</p>`
} )
.then( letters => {
console.log( letters.getTitle() );
console.log( letters.getBody() );
});
}
</script>
</head>
<body onload="load()">
</body>
</html>
There's also a "letters.js" file, but I couldn't even find a download link for Letters. I had to look at the demo page source to find it. If anyone knows an official link, please tell me.
When I open this file (locally or within a web server), nothing happens. The console shows this messages:
Logging on browser console. See `cloudServices._logUrl` configuration. Object { message: "letters-restarteditor: Restart.", level: "error", stackTrace: "value#file:///home/(...)/letters.js:1:1018463\n", data: {...} } letters.js:1:47910
Logging on browser console. See `cloudServices._logUrl` configuration. Object { message: "letters-restarteditor: Restart.", level: "error", stackTrace: "value#file:///home/(...)/letters.js:1:1018463\n", data: {...} } letters.js:1:47910
Logging on browser console. See `cloudServices._logUrl` configuration. Object { message: "letters-restarteditor: Switched to offline mode. Too many restarts.", level: "error", stackTrace: "value#file:///home/(...)/letters.js:1:1018463\n", data: {...} } letters.js:1:47910
Does anyone knows what can be happening? Is "Letters" a stable and reliable tool to use in a big project? Being built over CKEditor5, is CKEditor5 a stable and reliable tool? Or I should better stick with CKEditor4?
Thanks in advance!
There has been no official release of Letters so far, that's why tere is no download link for it. The documentation was published for people who are trying Letters in a private beta program.
I have a good news though, next week there will be a free trial officially available with valid download links, updated documentation, which should work just fine. Within the next few days after offering the trial we will also document on how to customize Letters, add/remove plugins and so on.
As of the end of April 2018, you can sign up to Letters and try it out. For the quick start guide check https://docs.ckeditor.com/letters/latest/guides/integration/quick-start.html
Related
I am using GWT with Bootstrap3 and Openlayers Map. I have implemented my own OSM Map server.
My application does not start without internet connection. I need guidance.
I followed the instructions in boostrap3 V1.0.2 for offline applications.
However I only got a blank screen.
Starting with the Firefox debugger I got the following message in the console:
Uncaught ReferenceError: OpenLayers is not defined
<anonymous> http://www.openstreetmap.org/openlayers/OpenStreetMap.js:7
Starting with Google Chrome I get the following warning
[Deprecation] Application Cache API manifest selection is deprecated and will be removed in M85, around August 2020. See https://www.chromestatus.com/features/6192449487634432 for more details.
followed by
GET http://www.openlayers.org/api/OpenLayers.js net::ERR_INTERNET_DISCONNECTED
and
localhost/:1 Application Cache Error event: Invalid or missing manifest origin trial token: http://localhost:8090/simaso/simasoweb/appcache.manifest
Here is my basic setup
SiMaSoWeb.gwt.xml:
...
<inherits name='com.google.gwt.json.JSON'/>
<inherits name="com.google.web.bindery.autobean.AutoBean"/>
<inherits name="org.gwtbootstrap3.extras.cachemanifest.Offline"/>
...
<add-linker name="offline" />
SiMaSoWeb.html:
<!doctype html>
<html manifest="simasoweb/appcache.manifest">
<head>
<title>Sirene</title>
<script type="text/javascript" language="javascript" src="simasoweb/simasoweb.nocache.js"></script>
<script src="http://www.openlayers.org/api/OpenLayers.js"></script>
<script src="http://www.openstreetmap.org/openlayers/OpenStreetMap.js"></script>
<link type="text/css" rel="stylesheet" href="SiMaSoWeb.css">
....
</html>
In ...\simasoweb\appcache.manifest I find:
CACHE MANIFEST
# Version: 1599380329409.0.6297069797290025
CACHE:
AF4477772D0DB53A10ABCF74A5AE0C4D.cache.js
fonts/fontawesome-webfont.woff
clear.cache.gif
fonts/FontAwesome.otf
css/bootstrap-notify-custom.min.cache.css
7192594CA2F468C2F793523022719FA0.cache.js
...
css/font-awesome-4.7.0.min.cache.css
NETWORK:
*
Finally
I compile all this . Resources seem to be included in the war file ..
Needless to say that with internet connection, only in the first 1-2 seconds of starting, all is running fine ..
As per the Google Chrome warning you included, App Cache is a deprecated standard and is being removed. It has already been removed from non-secure contexts.
You should be using Service Workers instead to cache resources for offline use. You may have to write your own linker or maybe you can use gwt-serviceworker-linker.
Thanks to ELEVATE I managed to move from AppCache to ServiceWorker. However the Openlayers couldnt be fixed this way. So here is what solved the issues:
ServiceWorker
I am still using Java 8
I upgraded to GWT 2.9
I added to .gwt.xml
<inherits name="org.realityforge.gwt.serviceworker.Linker"/>
<inherits name="elemental2.dom.Dom"/>
<inherits name="elemental2.promise.Promise"/>
<inherits name="jsinterop.base.Base"/>
...
and
<add-linker name="serviceworker"/>
<extend-configuration-property name="serviceworker_static_files" value="./"/>
<extend-configuration-property name="serviceworker_static_files" value="../SiMaSoWeb.html"/>
In my entry JAVA-routine right at the start of my onModuleLod I added
import static elemental2.dom.DomGlobal.*;
import elemental2.dom.DomGlobal;
public void onModuleLoad() {
...
initStatic();
...
and later in that module
public void initStatic() {
if ( null != navigator.serviceWorker )
{
navigator.serviceWorker.register("simasoweb/"+ GWT.getModuleName() + "-sw.js" ).then( registration -> {
console.log( "ServiceWorker registration successful with scope: " + registration.getScope() );
// Every minute attempt to update the serviceWorker. If it does update
// then the "controllerchange" event will fire.
DomGlobal.setInterval( v -> registration.update(), 60000 );
return null;
}, error -> {
console.log( "ServiceWorker registration failed: ", error );
return null;
} );
navigator.serviceWorker.addEventListener( "controllerchange", e -> {
// This fires when the service worker controlling this page
// changes, eg a new worker has skipped waiting and become
// the new active worker.
console.log( "ServiceWorker updated ", e );
} );
}
}
}
I had issues with accesing the right files in my gwt - war directory. Therefore I updated the navigator.serviceWorker.register... command.
Very useful was the google inherent debugger with CTRL+SHIFT+I. In the 'console'-tab you find the messages - red means bad - solve it!
As external jar libraries I had to include
elemental2-core
elemental2-dom
elemental2-promise
base
Now the openlayers issues... Needless to say that there might be a much more elegant way and further more, you need an offline-map, which I have rendered myself and available (150GB for Germany!).
In the HTML file
Note that I opened the openlayers and openstreetmap .js files in a browser copied them in a file and copied them into my war directory in the subdirectory src. Again the browser debugger can help find directory issues.
<script type="text/javascript" language="javascript" src="simasoweb/simasoweb.nocache.js"></script>
<script src="src/OpenLayers.js"></script>
<script src="src/OpenStreetMap.js"></script>
Copy hard
I downloaded the gwt-openlayers demo project GWT-OpenLayers-master.zip
and copied all files in GWT-OpenLayers-master\gwt-openlayers-showcase\src\main\resources\org\gwtopenmaps\demo\openlayers\public\openlayers into my ...war\src\ directory where my openlayers.js files lie.
Finally I am not sure if the service-worker point 1-3 really helped.
I use Sentry to track client-side errors. However, I loaded my web app in the Edge browser today only to find a blank page. Edge raised a TextEncoder is not defined error because one of the libraries in my bundle referenced TextEncoder which it does not support. Sentry did not report the error because the error occurred before Sentry was initialized.
I use vue-cli to create a Vue project with Sentry being initialized near the top of the main file:
import { init } from '#sentry/browser';
import { environment } from '#/constants';
import { Vue as VueIntegration } from '#sentry/integrations';
export default function(Vue) {
const debug = environment !== 'production';
init({
dsn: 'redacted',
environment,
debug,
integrations: [new VueIntegration({ Vue, logErrors: debug })],
});
}
I've been thinking of initializing Sentry manually with a script tag near the start of the <body> tag. However, the fact that I use the VueIntegration plugin complicates things. Would it be safe to initialize Sentry twice? Once before the main bundle loads and once as I'm doing in the example above?
I noticed there's something in the docs about managing multiple Sentry clients but I'm not sure if that's relevant to my specific case.
One idea I have is just a barebones window.onerror hook before anything else loads but I'm not really sure how to interact with Sentry without pulling in their #sentry/browser package. Ideally I would just communicate with their service using a simple XHR request and my DSN.
My question is what is the recommended way to track errors that occur before Sentry is initialized in the main JS bundle?
I ended up solving it by adding a barebones window.onerror hook that loads inline before the main bundle arrives. The error is immediately sent to our API and then to our Slack #alerts channel. I added rate limiting so people dont abuse it (too much).
index.html (generated by vue-cli except for the new script tag):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
/>
<title>App title</title>
</head>
<body>
<script>
// This gives us basic error tracking until the main app bundle loads and
// initializes Sentry. Allows us to catch errors that would surface before
// Sentry has a chance to catch them like Edge's `TextEncoder is not defined`.
(function() {
function sendBasicClientError(message, error) {
var xhr = new XMLHttpRequest();
var domain =
window.location.hostname === 'localhost'
? 'http://localhost:5000'
: 'https://example.com';
xhr.open('POST', domain + '/api/v1/basic_client_errors');
xhr.setRequestHeader(
'Content-Type',
'application/vnd.api+json; charset=utf-8'
);
xhr.send(
JSON.stringify({
data: {
type: 'basic_client_error',
attributes: {
error_message: 'Init error: ' + message + ' ' + navigator.userAgent,
error: error
? JSON.parse(
JSON.stringify(error, Object.getOwnPropertyNames(error))
)
: null,
},
},
})
);
}
window.onerror = function(message, filename, lineno, colno, error) {
sendBasicClientError(
message + ' ' + filename + ':' + lineno + ':' + colno,
error
);
};
})();
</script>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
Right before Sentry loads we clear the hook:
// Clears the simple `window.onerror` from `index.html` so that Sentry can
// take over now that it's ready.
window.onerror = () => {};
init({
dsn: 'redacted',
environment,
debug,
integrations: [new VueIntegration({ Vue, logErrors: debug })],
});
Rails controller:
module Api
module V1
class BasicClientErrorsController < ApplicationController
def create
# Can comment out if not using the `pundit` gem.
skip_authorization
# We use `sidekiq` and `slack-ruby-client` gems here.
# Substitute whatever internal error tracking tool you use.
SlackNotifierWorker.perform_async(
basic_client_error_params[:error_message],
'#alerts'
)
head :accepted
end
private
def basic_client_error_params
# We use the `restful-jsonapi` gem to parse the JSON:API format.
restify_param(:basic_client_error).require(:basic_client_error).permit(
:error_message
)
end
end
end
end
Rate limiting with the rack-attack gem:
Rack::Attack.throttle('limit public basic client errors endpoint', limit: 1, period: 60.seconds.to_i) do |req|
req.ip if req.path.end_with?('/basic_client_errors') && req.post?
end
Have you tried this Laxy loading Sentry ?
It's mentioned here that if you set data-lazy to no, or use forceLoad, it'll try to fetch Sentry SDK as soon as possible.
This issue should be handled by the loader, as mentioned here :
Current limitations
Because we inject our SDK asynchronously, we will only monitor global errors and unhandled promise for you until the SDK is fully loaded. That means that we might miss breadcrumbs during the download.
For example, a user clicking on a button on your website is making an XHR request. We will not miss any errors, only breadcrumbs and only up until the SDK is fully loaded. You can reduce this time by manually calling forceLoad or set data-lazy="no".
I'm trying to write a casperJS program that can navigate and download PDFs. If I can grab an actual URL corresponding to the PDF it's pretty straight-forward, but that isn't always the case. To test this, I've been working with this simple example locally:
<html>
<head>
</head>
<body>
<h1 class="page-title">Hello</h1>
<a id='1' href="test.pdf" target="_blank">one</a>
</body>
</html>
Basic casper:
casper.start('file:///opt/templates/templates/src/main/resources/casperjs/example.html').then(function() {
this.echo('started')
});
casper.then(function() {
this.waitForSelector('a', function() {
this.click('a');
});
});
casper.wait(1000, function() {
this.echo(JSON.stringify(this.popups[0]));
});
casper.run();
When I run this, the (only) popup that's present is a blank HTML page that never loads. It's also worth noting that if you test this without the 'target="_blank"' (i.e. the PDF opens in the same tab), the 'resource.received' event will be emitted (with null content type), but loading the resource will fail:
[warning] [phantom] Loading resource failed with status=fail: file:///opt/templates/templates/src/main/resources/casperjs/test.pdf
Is there any good way to handle links that will open/download PDFs in some generic way? You can hook into 'navigation.requested' perhaps and download there, but I don't think there's a wonderful way to figure out that the nav is for a PDF (the URL may not always have file extension).
Does any one know how to integrate linked In Login method with chrome extension?
I am trying to integrate Login in with linked in my chrome extension but have no idea how to do it. i tried this code but it says:
<script type="text/javascript" src="//platform.linkedin.com/in.js">
api_key: xxxxxxxxxxxxx
onLoad: onLinkedInLoad
authorize: true
</script>
<script type="text/javascript">
function onLinkedInLoad() {
IN.Event.on(IN, "auth", getProfileData);
}
function getProfileData() {
IN.API.Profile("me").result(ShowProfileData);
}
function ShowProfileData(profiles) {
var member = profiles.values[0];
var id=member.id;
}
</script>
<script type="in/Login"></script>
Failed to load resource: net::ERR_FILE_NOT_FOUND
I believe you have likely spelled the resource incorrectly. I just ran into the same issue because I was trying to call the file oauth.js but in my directory I had spelled it ouath.js. Double check all your spelling and the paths that you are using to find files.
I am using the blueimp fileupload basic plugin in my project. It all works well in Safari, Firefox, Chrome but there is a problem with Internet Explorer 9 and below:
The start callback gets called and in the network tab of developer tools I see the ajax call being executed. However the file is never being upload (I checked on the server, too) and the call eventually ends up in a 408 request timeout.
Any hints on what could be the reason?
Here are my relevant code parts:
<input class="input-file" id="fileupload" name="files[]" data-url="/app_dev.php/backend/ajax/upload/wish/1850cf918a43d42" type="file">
<script type="text/javascript" src="js/jquery/jquery-1.8.2.min.js"></script>
<script type="text/javascript" src="js/uploader/vendor/jquery.ui.widget.js"></script>
<script type="text/javascript" src="js/uploader/jquery.fileupload.js"></script>
<script type="text/javascript" src="js/uploader/jquery.iframe-transport.js"></script>
<script>
$(document).ready(function() {
$('#fileupload').fileupload({
dataType: 'json',
dropZone: null,
start: function (e, data){
console.log('start'); //fires in all browsers = fine
},
progress: function (e, data){
console.log('progress'); //fires in Safari, FF, Chrome = fine
},
done: function (e, data) {
console.log('done'); //never getting here in IE cause file doesn't get uploaded.
}
});
</script>
Problem fixed!
There were two issues. One had to do with local network settings.
The other was to implement the correct handling of content type negotiation. See https://github.com/blueimp/jQuery-File-Upload/wiki/Setup for more details.
Just my 5 ยข:
I had a very hard time trying to make it work with pretty links! Following dumps were totally empty!
var_dump($_FILES);
var_dump($_POST);
var_dump($_GET);
So:
$('#fileupload').fileupload({
url: 'http://code.dev/products/postUpload' // <--- remove trailing slash!!!
});