Is it possible to set turn the default spell checker on by default. Without clicking the button in the toolbar each time?
I am using the default browser spell checker functionality in the browser.
setup: function (ed) {
ed.addCommand('mceSpellCheckRuntime', function() {
t = ed.plugins.spellchecker;
if (t.mceSpellCheckRuntimeTimer) {
window.clearTimeout(t.mceSpellCheckRuntimeTimer);
}
t.mceSpellCheckRuntimeTimer = window.setTimeout(function() {
t._done();
t._sendRPC('checkWords', [t.selectedLang, t._getWords()], function(r) {
if (r.length > 0) {
t.active = 1;
t._markWords(r);
ed.nodeChanged();
}
});
}, 3000); //3 seconds
});
ed.onInit.add(function(ed){
ed.pasteAsPlainText = true;
ed.execCommand('mceSpellCheckRuntime');
});
ed.onKeyUp.add(function(ed, e) {
ed.execCommand('mceSpellCheckRuntime');
});
},
Its quiet possible........:)
Try the below code.......
ed.onInit.add(function(ed, e) {
setTimeout(function () {
tinyMCE.activeEditor.controlManager.setActive('spellchecker', true); tinymce.execCommand('mceSpellCheck', true);
}, 1);
});
Nope, this is not possible due to the fact that there are so many possibilities of using a spellchecker in tinymce. The user may however define on which events the spellchecker should check (that's what you already did).
Working solution for TinyMCE 3
Create a helper function to improve UX:
function delay(fn, ms) {
let timer = 0
return function(...args) {
clearTimeout(timer)
timer = setTimeout(fn.bind(this, ...args), ms || 0)
}
}
Register a new command within TinyMCE Spell Checker plugin:
ed.addCommand('mceSpellCheckAuto', function() {
if (t.active) {
t._removeWords();
ed.nodeChanged();
t._sendRPC('checkWords', [t.selectedLang, t._getWords()], function(r) {
if (r.length > 0) {
t._markWords(r);
ed.nodeChanged();
}
});
}
});
Call your new command from a keyPress event:
ed.onKeyPress.add(delay(function() {
tinymce.execCommand('mceSpellCheckAuto', true);
}, 500));
Related
The following code can be used to install the program in the PWA:
var fab = document.querySelector('#fab');
var deferredPrompt;
fab.addEventListener('click', function () {
if (deferredPrompt) {
deferredPrompt.prompt();
deferredPrompt.userChoice.then(function (choice) {
if (choice.outcome === 'dismissed') {
console.log('installation was cancelled');
} else {
console.log('User Added To Home Screen');
}
});
deferredPrompt = null;
}
});
//********************************************************************
window.addEventListener('beforeinstallprompt', function (event) {
console.log('beforeinstallprompt run .');
event.preventDefault();
deferredPrompt = event;
return false;
});
now for Uninstall:
It can only be removed from the browser
Now my question is here:
Is it possible to create a code such as manual installation (mentioned above) that the user can uninstall the program without the need to use the browser tool?
Thank you all for your answers
I am using external buttons for am charts export. when i enter into annotations mode and do export, the chart gets exported with annotations. But when the chart gets reloaded , the annotations mode does not revert back.
Could somebody let me know how to go back from annotations to normal mode.
if (chart.export.drawing.buffer.enabled === true) {
// Exporting the annotated chart with out "
//chart.export.capture"
chart.export.toPNG({}, function (data) {
chartimage.postImageData(data, chart_image_name)
});
} else {
chart.export.capture({
// action: "draw"
}, function () {
this.toPNG({
}, function (data) {
images.push({
"image": data,
"fit": [523.28, 769.89]
});
pending--;
if (pending === 0) {
chart.export.toPNG({
content: images
}, function (data) {
chartimage.postImageData(data, chart_image_name)
});
}
});
});
}
}
To exit from Annotation mode, simply use Export plugin's internal API method done():
chart["export"].drawing.handler.done();
BTW, export keyword is reserved and will result in errors on some browsers. It's better to access Export instance via named key: chart["export"].toPNG() versus chart.export.toPNG().
Please find the workaround below..
First capture the events for set and cancel annotations using menu reviewer
menuReviver: function (item, li) {
if (item.format === "XLSX" || item.format === "JSON") {
li.style.display = "none";
}
$(li).click(function () {
if (item.action == "draw") {
$("#chart_annotations").val(1);
}
if (item.action == "cancel") {
$("#chart_annotations").val(0);
}
});
return li;
}
Now while exporting the chart image use $("#chart_annotations").val() value as a
flag whether to export annotated chart or a normal chart. Please find the code below...
if (window.fabric) {
if ($("#chart_annotations").val() == 1) {
chart.export.toPNG({}, function (data) {
chartimage.postImageData(data, chart_image_name)
});
} else {
chart.export.capture({
//action: "change"
}, function () {
this.toPNG({
}, function (data) {
images.push({
"image": data,
"fit": [523.28, 769.89]
});
pending--;
if (pending === 0) {
chart.export.toPNG({
content: images
}, function (data) {
//post the image data using ajax
chartimage.postImageData(data, chart_image_name)
});
}
});
});
}
Hi i implemented a Messagebox in a for loop, but i know the messagebox works asynchron.
I want that the programm wait for every loop to the desicion of the user.
onBook: function(oEvent) {
var that = this;
for (var i = 0; i < Items.length; i++){
function message(innerArg) {
sap.m.MessageBox.confirm(
"Text", {
icon : sap.m.MessageBox.Icon.INFORMATION,
title : "Really",
actions : [ sap.m.MessageBox.Action.YES,
sap.m.MessageBox.Action.NO ],
onClose : function(oAction) {
if (oAction === sap.m.MessageBox.Action.NO) {
delete(i);
}else{
}
}
});
}
message(i);
}
that.do(oEvent);
The programm jumps in the "do" method before a user action is done
Edit:
for (var i = 0; i < Items.length; i++){
(function (innerArg) {
sap.m.MessageBox.confirm(
"Delete?", {
icon : sap.m.MessageBox.Icon.INFORMATION,
title : "Delete",
actions : [ sap.m.MessageBox.Action.YES,
sap.m.MessageBox.Action.NO ],
onClose : function(oAction) {
if (oAction === sap.m.MessageBox.Action.NO) {
delete(innerArg)
}}
});
})(i);
}
that.Save(oEvent);
When the box is open the entries are booked because the programm goes to the save method without wating of user action Whats wrong ?
Ah, the asynchronous-function-in-a-synchronous-loop anti-pattern ;-)
You can try using closures:
for (var i = 0; i < items; i++) {
// use self-executing function here
(function(innerArg) {
sap.m.MessageBox.confirm(
"Text", {
onClose: function(oAction) {
if (oAction === sap.m.MessageBox.Action.NO) {
// here I want to do something
console.log("Value: ", innerArg);
}
}
}
);
})(i);
}
EDIT: Update with Promises
Based on your updated question, I have provided a more-or-less sorta-kinda working example (it may not work flawless, but it should show the design pattern you should follow)
You wrap the message box responses into a Promise resolve, and store these into an array. You then feed that array to Promise.all() in order to proceed with your save functionality
processData: function() {
var promises = [],
self = this;
for (var i = 0; i < items; i++) {
promises.push(this.doMessageboxAction(i));
}
Promise.all(promises).then(function(aData) {
aData.forEach(function(oData) {
self.save(oData);
});
}).catch(function(err) {
console.log(err);
});
}
doMessageboxAction: function(item) {
return new Promise(function(resolve, reject) {
sap.m.MessageBox.confirm(
"Text", {
onClose: function(oAction) {
if (oAction === sap.m.MessageBox.Action.NO) {
//do something
//etc
resolve(item); // or some other variable
}
else {
//do something else
//etc
resolve(item); // or some other variable
}
}
}
);
});
}
i have simple dropdown, and i need to hide (fadeout) it by clicking on the document
this is my jquery code:
var expandCheckbox = $('.filterShow'),
formCheckbox = $('.checkboxWrap');
expandCheckbox.click(function(e) {
e.preventDefault();
if ($(this).hasClass('active')) {
$(this).removeClass('active');
$(formCheckbox).fadeOut(200);
} else {
$(this).addClass('active');
$(formCheckbox).fadeIn(100);
}
});
$('body').not('.filterShow, .checkboxWrap').click(function() {
$(formCheckbox).fadeOut(100);
});
SEE JSFIDDLE
Remove "e.preventDefault" which has no use here, add "return false" to prevent event propagation to its parent, use "document" instead of "body" as the selector for fading the dropdownlist upon clicking anywhere on the document.
$(document).ready(function(){
expandCheckbox = $('.filterShow'),
formCheckbox = $('.checkboxWrap');
expandCheckbox.click(function (e) {
if ($(this).hasClass('active')) {
$(this).removeClass('active');
formCheckbox.fadeOut(200);
} else {
$(this).addClass('active');
formCheckbox.fadeIn(100);
}
return false;
});
$(document).click(function (e) {
if (expandCheckbox.hasClass('active')) {
expandCheckbox.removeClass('active');
formCheckbox.fadeOut(200);
}
return false;
});
formCheckbox.find('input:checkbox').click(function (e) {
e.stopPropagation();
});
});
I could not found any examples with this scenario so here we go:
I want the user choose a directory, load all files inside it, change them, and save this file overriding it or saving a new file in that same directory without asking where he want to save.
I don't know how to list the files of the directory
I don't know how to save a file in a directory without prompting the filechooser window
I believe it is possible because I see something similar here (last paragraph):
http://www.developer.com/lang/using-the-file-api-outside-the-sandbox-in-chrome-packaged-apps.html
Any answer will be appreciated, Thank you
EDIT: Thanks to Chris Johnsen for giving me this great answer:
var fileHandler = function() {
var _entry = null;
this.open = function(cb) {
chrome.fileSystem.chooseEntry({
type: 'openDirectory'
}, function(dirEntry) {
if (!dirEntry || !dirEntry.isDirectory) {
cb && cb(null);
return;
}
_entry = dirEntry;
listDir(_entry, cb);
});
};
this.save = function(filename, source) {
chrome.fileSystem.getWritableEntry(_entry, function(entry) {
entry.getFile(filename, {
create: true
}, function(entry) {
entry.createWriter(function(writer) {
writer.onwrite = function() {
writer.onwrite = null;
writer.truncate(writer.position);
};
writer.write(new Blob([source], {
type: 'text/javascript'
}));
});
});
});
};
this.saveAs = function(filename, source) {
chrome.fileSystem.chooseEntry({
type: 'openDirectory'
}, function(entry) {
chrome.fileSystem.getWritableEntry(entry, function(entry) {
entry.getFile(filename, {
create: true
}, function(entry) {
entry.createWriter(function(writer) {
writer.onwrite = function() {
writer.onwrite = null;
writer.truncate(writer.position);
};
writer.write(new Blob([source], {
type: 'text/javascript'
}));
});
});
});
});
};
var listDir = function(dirent, cb, listing) {
if (listing === undefined) {
listing = [];
}
var reader = dirent.createReader();
var read_some = reader.readEntries.bind(reader, function(ents) {
if (ents.length === 0) {
return cb && cb(listing);
}
var process_some = function(ents, i) {
for (; i < ents.length; i++) {
listing.push(ents[i]);
if (ents[i].isDirectory) {
return listDir(ents[i], process_some.bind(null, ents, i + 1), listing);
}
}
read_some();
};
process_some(ents, 0);
}, function() {
console.error('error reading directory');
});
read_some();
};
};
Your save method should work fine (mostly, see below) for your second requirement (write to a code-chosen filename without another user prompt), but there are a couple of bugs in open (at least as presented in the question):
Inside the chooseEntry callback, this !== fileHandler because the callback is invoked with a different this (probably the background page’s window object).
You can work around this in several ways:
Use fileHandler instead of this (if you are not using it as any kind of prototype).
Use .bind(this) to bind each of your callback functions to the same context.
Use var self = this; at the top of open and use self.entry (et cetera) in the callbacks.
You may want to call cb for the success case. Maybe you have another way of postponing calls to (e.g.) fileHandler.save (clicking on some element to trigger the save?), but adding something like
⋮
cb && cb(self.entry);
⋮
after self.entry = dirEntry makes it easy to (e.g.) chain open and save:
fileHandler.open(function(ent) {
fileHandler.save('newfile','This is the text\nto save in the (possibly) new file.');
});
There is a latent bug in save: if you ever overwrite an existing file, then you will want to call writer.truncate() (unless you always write more bytes than the file originally held).
⋮
writer.onwrite = function() {
writer.onwrite = null;
writer.truncate(writer.position);
};
writer.write(…);
⋮
It looks like you have a good start on the file listing part. If you want to reference the list of files later, then you might want to save them in your object instead of just logging them; this can get a bit hairy if you want to recurse into subdirectories (and also not assume that readEntries returns everything for its first call).
function list_dir(dirent, cb, listing) {
if (listing === undefined) listing = [];
var reader = dirent.createReader();
var read_some = reader.readEntries.bind(reader, function(ents) {
if (ents.length === 0)
return cb && cb(listing);
process_some(ents, 0);
function process_some(ents, i) {
for(; i < ents.length; i++) {
listing.push(ents[i]);
if (ents[i].isDirectory)
return list_dir(ents[i], process_some.bind(null, ents, i + 1), listing);
}
read_some();
}
}, function() {
console.error('error reading directory');
});
read_some();
}
You could use it in the open callback (assuming you add its success callback) like this:
fileHandler.open(function(ent) {
ent && list_dir(ent, function(listing) {
fileHandler.listing = listing;
console.log('listing', fileHandler.listing.map(function(ent){return ent.fullPath}).join('\n'));
fileHandler.save('a_dir/somefile','This is some data.');
});
});