Preventing line breaks - ENTER keypresses. Instead - fire custom event - aloha-editor

I'd like to use Aloha to WYSIWYG-edit single-line headlines.
For that I need to intercept ENTER keypress (to prevent line-break) and fire custom save event.
Is there a way to do that?
Thanks!

Here's what worked for me on "hotfix" branch:
Aloha.bind('aloha-smart-content-changed', function(e, data) {
value = data.editable.getContents();
// save it to database.
});
Aloha.bind('aloha-command-will-execute', function(e, data) {
if (data.commandId == 'insertlinebreak') {
data.preventDefault = true;
}
});
More info here:
https://github.com/alohaeditor/Aloha-Editor/issues/1502

Related

Detect react event from Tampermonkey

I'm enhancing a React front end with Tampermonkey , by adding highlights to show cursor location in a grid, and allowing users to directly enter data , rather than then enter data.
After 2 or 3 cursor moves or data entry the grid refreshes or updates - no page change - and looses the highlighting I set up.
I'd like to catch the refresh/update and reset the highlighting.
I'm a noob..
The network tab shows post events so I tried https://jsbin.com/dixelocazo/edit?js,console
var open = window.XMLHttpRequest.prototype.open,
send = window.XMLHttpRequest.prototype.send;
to try and use POST events to detect the refresh. No joy !
I also looked at ajax events.
No luck :(
Can someone point me in the right direction here ?
Once I catch the event, I can then reset the highlighting to fix the problem
Since normally the userscripts run in a sandbox, JavaScript functions or objects cannot be used directly by default, here's what you can do:
Disable the sandbox:
// #grant none
You won't be able to use any GM functions, though.
Run in the page context via unsafeWindow:
const __send = unsafeWindow.XMLHttpRequest.prototype.send;
unsafeWindow.XMLHttpRequest.prototype.send = function () {
this.addEventListener('loadend', e => {
console.log('intercepted', e);
}, {once: true});
__send.apply(this, arguments);
};
Use MutationObserver to detect changes in page DOM:
const observer = new MutationObserver(mutations => {
const matched = [];
for (const {addedNodes} of mutations) {
for (const n of addedNodes) {
if (!n.tagName)
continue;
if (n.matches('.prey:not(.my-highlight)')) {
matched.push(n);
} else if (n.firstElementChild) {
matched.push(...n.querySelectorAll('.prey:not(.my-highlight)'));
}
}
}
// process the matched elements
for (const el of matched) {
el.classList.add('my-highlight');
}
});
observer.observe(document.querySelector('.surviving-ancestor') || document.body, {
subtree: true,
childList: true,
});
.surviving-ancestor means the element that isn't replaced/recreated by the page script. In devtools element inspector it's the one that isn't highlighted temporarily during DOM updates.
See also Performance of MutationObserver.

Trigger other key rather than original key using angularjs

I am try to trigger " ` " keyCode = 192 when I press " enter " keyCode = 13. I am trying below code but it is not working in contenteditable div. Any idea?
And how to $apply this?
$scope.pressKey = function(event){
if(event.keyCode == 13){
event.preventDefault();
var e=angular.element.Event('keydown');
console.log(e);
e.which=192;
$('#regularDot').trigger(e);
}
<div id="regularDot" ng-keypress="pressKey($event)" class="wf-loading"
ng-model="regularDot" contenteditable="true" n></div>
Don't use pure JS methods like KeyboardEvent() it has cross browser support issues, use jQuery instead.
Now angular.element has basic support of jquery but it does not support Event() method which you used. So best approach is having jquery library in your codebase (with its script tag attached before angularjs in index.html). Then change your code to as follows:
$scope.pressKey = function(event) {
if (event.keyCode == 13) {
event.preventDefault();
var e = jQuery.Event('keypress');
console.log(e);
e.which = 192;
e.keyCode = 192;
$timeout(function() {
$('#regularDot').trigger(e);
});
} else if(event.keyCode == 192){
console.log("Newly triggered event catched with keyCode " + event.keyCode);
}
}
Here I've made just few changes like adding trigger method inside $timeout so that it'll wait small time to complete the preventDefault of previously triggered event before setting (triggering) new event, and doing $apply also. I've changed newly triggered event type to keypress instead of keydown so that after triggering event you'll be able to handle it using ng-keypress on that element (with id regularDot).
Similar plunker example to refer.

fireEvent('click') not working in IE11 - Extjs

I am planning to trigger a click event programatically when user presses a spacebar key. I have been used fireEvent('click') it is working for chrome, but It is not working for IE-11. I also tried, dispatchEvent for IE but it is throwing an error: "element does not support method or property dispatchEvent". Please follow below code.
onCustomRender: function(thisEl, args){
var fetchTrigger = thisEl.getTrigger('fetchID
fetchTrigger.el.on('keydown',function(e,thisEl){
if (e.keyCode === 32) {
//fetchTrigger.el.fireEvent('click'); //this is working in chrome //not working in IE and did not throwing error.
var evObj = document.createEvent('MouseEvents');
evObj.initEvent('click', true, false);
fetchTrigger.el.dispatchEvent(evObj);
}
});
}
Please Help
Thanks in Advance
First of all you have syntax error in the code you provided...
Calling the function directly is easiest (as Evan said) but if you want to keep the logic in the controller you can fire events. Else you need some ugly code to get the controller first, then call the method...
I don't like fireing events and attaching listeners on the 'Ext.dom.Element' if you don't have to. Just use your ext elements..
Here is what I would do:
onCustomRender: function(thisEl, args){
var fetchTrigger = thisEl.getTrigger('fetchID');
fetchTrigger.on('keydown',function(trigger, e){
if (e.keyCode === 32) {
trigger.fireEvent('click', trigger);
}
});
}
Or even better, use the controller:
implement listeners
init: function () {
this.control({
'#fetchID': { //you can optimize the componentQuery
keydown: this.onTriggerKeyDown,
click: this.onTriggerClick
}
});
},
and methods like this:
onTriggerKeyDown: function(trigger, e){
if (e.keyCode === 32) {
this.onTriggerClick(trigger);
}
},
onTriggerClick: function(trigger) {
//do you thing!
}

Check form for changes in AngularJS

I have an HTML page built using AngularJS. The page has a form containing a number of fields.
I have a Save, Back and Cancel button. When you click the back button I would like to be able to tell if changes have been made to the field and prompt the question "Would you like to save your changes?".
If you click the Cancel button, I want to ignore any changes made and go back to the previous page. How can this be achieved in Angular?
fYou can use "$locationChangeStart" https://docs.angularjs.org/api/ng/service/$location
$scope.$on('$locationChangeStart', function(event, newURL) {
if (newURL.lastIndexOf("#/") >= 0) {
$scope.locationToMove = newURL.substring(newURL.lastIndexOf("#/") + 1); // here you can store the location to move for future use
} else {
$scope.locationToMove = "/";
}
if ($scope.form.$dirty && !goToBack && !saved) {
$scope.displayConfirmationModel = true; // any alerts you want to show here
event.preventDefault();
}
else {
// you can move to that location
}
});
In the if you can check any change condition , its just for example I have given. You can do this for any location change , but if you want to do this on cancel or back button then you can have the same condition on the button click method and check for change .i.e if the form filed is dirty.

backbone.js fire one of touch/mouse event on same function

I have a Backbone View with events for mobile and desktop version:
events: {
"touchstart .button": "action1",
"mousedown .button": "action1",
"touchend .button": "action2",
"mouseup .button": "action2",
}
I want only one of the event fired when touched from my mobile device. Currently in one of my mobile device, action1 is fired twice.
I have tried using a custom method from this solution, but somehow in Android 2.3 the custom method for touchend after touchstart won't be fired, but using pure "touchend" would be fired instead.
Thus I'm thinking if Backbone.js can prevent "mouseup" from being fired if "touchend" is being fired.
Another approach, which feels slightly less hacky to me:
I like to test for touch events and set a global variable upon initialization of the application.
MyApp.clickEvent = ('ontouchstart' in window) ? "touchstart" : "mousedown";
Then in my views I perform something like:
events: function() {
var _events = {};
_events[MyApp.clickEvent + " .button"] = "action1";
return _events;
}
One hacky solution would be to use the underscore.js function throttle to make it so that the function can be called only once per x milliseconds. Check the documentation here to see if it suits your needs.
The final solution would be:
action1: _.throttle(function(params) {
// Do what you do here
}, 400); // The timeframe within which the function can be called just once.
You can define a function to determine touch devices like:
function is_touch_device() {
try {
document.createEvent("TouchEvent");
return true;
} catch (e) {
return false;
}
}
this function is from another thread What's the best way to detect a 'touch screen' device using JavaScript?
then use it in events:
events: function() {
if(is_touch_device) {
return {
/// touch events
}
} else {
return {
/// mouse events
}
}
}
if they are exactly the same dehrg answer would be a less redundant one

Resources