Selectively fire change events in CKEditor - ckeditor

I am writing a plugin that uses a dialog box.
I notice that clicking the toolbar button to open the dialog box fires a change event on the editor. Is there anyway to disable this event when opening the dialog box?
The plugin modifies the content using setAttribute(), removeAttribute(), and removeStyles(). Is there anyway to have calls to these methods fire a change event?
After more investigation, I discovered 2 issues (which I think relates to using YUI's App Framework), which might be the cause of the unexpected behaviour.
To reproduce: http://jsfiddle.net/c3tqk/
Problem 1:
1. Select part of the first paragraph (text) and click the Edit Link button.
2. Select part of the second paragraph (link) and click the Edit Link button. Check the console and notice a change event is fired.
Problem 2:
1. Select ex in the first paragraph and click the Bold button.
2. Deselect and select the x in the first paragraph and click the Bold button. Notice that the change event is fired twice.

You can always fire an event manually though it's not usually recommended. Use CKEDITOR.event.fire:
element.setAttribute( 'foo', 'bar' );
editor.fire( 'change' );
A better idea is to use editor#saveSnapshot event, which creates undo snapshots (your change becomes officially undoable, that's pretty cool) and fires editor#change automatically, if needed:
element.setAttribute( 'foo', 'bar' );
editor.fire( 'saveSnapshot' );
You can also interrupt existing events as they get fired and make sure no other listeners are called. Simply use CKEDITOR.event.on listener with low priority.
editor.on( 'change', function( evt ) {
if ( some condition ) {
evt.stop();
// ...or...
evt.cancel();
}
}, editor, null, -999 ); // by default listeners have priority=10
See CKEDITOR.eventInfo.stop and CKEDITOR.eventInfo.cancel. They're slightly different.
It might be tricky to get why the event is fired as you click to open the dialog box (and to create the right rule), but it feels quite possible. I couldn't reproduce it though (tried latest Chrome and FF); change was fired only when typing or executing commands (like Bold, Link, etc.). If you provided some extra info about your setup (versions of CKEditor and the browser, editor config and the name of the dialog), it would be much easier to debug.

Related

Can I detect if an element (button) is "clickable" in my rspecs?

Context: In my rspec (using Ruby and Capybara)
I click on a link to test an action in my app: adding a branch to my app.
A modal window opens, where I select the branch, and then I click a "submit" button to add the branch to my app. After clicking "submit" the modal window is closed.
The rspecs continues by clicking "Save" in the main screen, to save the state of the application (and effectively saving adding the branch).
Problem: The rspec is failing because (seemingly) it is trying to click the "Save" button on the main screen while the modal window that is used to select the branch is still present. The test doesn't complain that it can't find the "Save" button component, but that it can't be clicked.
The error in the log is:
[...]Save</button> is not clickable at point (692, 23). Other element would receive the click[...]
A gotcha: this rspec passes correctly on some environments, like when it is run against my local server, but it fails when it is executed by our automation server. Thus, this test has been tagged as "flaky".
Potential solutions: Things we have tried so far:
Play around our "clicks configuration", making sure we are on "ready state" and that the modal window is gone. We failed with this, since we kept hitting the same error.
Implement a "wait". We added a loop to sleep for a bit while the modal window seemed to exist
XYZ.add_new_branch_name(#branch_name)
while Utilities.element_visible?(:xpath, myElement)
sleep(0.5)
end
XYZ.save
The while condition checks if the "submit" button of the modal window exists. The element_visible function uses
find(method,element).visible?
but I'm not sure if find should already take into account that the button may exist and be visible but not be clickable.
Since this still fails, in spite of all our effort to make sure that the modal is gone before we attempt to click on the "save" button, I want tot ask:
Is there a proper way to detect if an element behind a modal window is clickable or not using rspecs?
find only cares about "visibility", not "clickability" (and different drivers may have slightly different interpretations of "visibility"). The reason for the flakiness you're seeing is most likely speed of the machine running the tests which affects the timing of the modal animating away. The best way to solve this issue is to disable animations in the test mode (how you do that is dependent on exactly what library and/or CSS you're using for the animations). The other way is to do as you're doing - checking that the modal has disappeared before clicking the 'Save' button, however you should just be using the Capybara provided methods (which include waiting/retrying behavior) rather than writing your own loop for that.
expect(page).not_to have_css('css selector of the modal') # RSpec version
assert_no_css('css selector of the modal') # minitest version
After looking at the mouse position from your error, one other potential issue you may be having is with screen size and scrolling. If the page requires to be scrolled to get to the 'Save' button and (692, 23) would put the button behind a fixed header (you should be able to verify that by taking a screenshot before the button click attempt) then it may not be possible for whatever driver you're using to click the button. In that case you'd need to use execute_script to scroll the page to a different location so the button is not covered on the page and/or increase the "browser" size so scrolling isn't necessary in the test.
I had a similar problem and solved it by writing my own click_on_with_wait helper function:
def click_on_with_wait(text, wait_time: Capybara.default_max_wait_time)
success = false
(wait_time * 10).round.times do
click_on text
success = true
break
rescue Selenium::WebDriver::Error::WebDriverError
sleep(0.1)
end
# Try clicking one last time, so that the error will get raised if it still doesn't work
click_on text unless success
end
This will try to click on the element. If it's still hidden by the modal, the function will wait 100ms and then try again, until the given wait_time is reached.
Using Rails, I put it in system_spec_helpers.rb so that I can simply replace click_on 'Submit Form' with click_on_with_wait 'Submit Form'.

Handsontable edit on mobile device

i know that handsontable is not mobile friendly but is there a workaround that we can edit on mobile devices with the newest version?
Regards
I use Handsontable version 0.25.1, but I imagine the situation is still the same at the very latest release.
My experience is only with iPad device (iOS 9); I cannot speak about all mobile devices.
I found the rendering acceptable. But if you tap a cell to edit nothing happens, which is rather limiting! I made just two small changes to rectify:
Tracing all of this right down in handsontable.full.js, the logic in onCellMouseDown() is testing for event.button === 0 (i.e. left mouse button) to start setting up for recognising the double click to activate the mobile text editor. On a touch device, they are explicitly calling their onMouseDown/Move/Up() from their onTouchStart/Move/End(), passing the mouse events the event structure received for the touch event. However, touch events' event structure does not have a button member, so that is undefined, causing bad behaviour.
Directly setting passed-in event.button = 0 before passing to mouse event handlers solves this. Put in line:
event.button = 0; // set as left mouse button
into onTouchStart() [prior to call to onMouseDown(event), around line 1326] & onTouchEnd() [prior to call to onMouseUp(event), around line 1368].
Now tapping into a cell correctly allows editing. It brings up their MobileTextEditor. Which I did not like for a number of reasons, including the fact that often it appears behind the on-screen keyboard so the user does not even know it is there! I changed their Handsontable.TextCell [around line 4346] so that the editor: line now reads:
editor: (isMobileBrowser() && Handsontable.useMobileEditor) ? getEditorConstructor('mobile') : getEditorConstructor('text'), // only use mobile editor if explicitly called for
So it uses the standard in-place text editor, which I prefer, unless you go hot.updateSettings({useMobileEditor: true}).

wxPython Enter Button Event

I've seen plenty of information about this topic, but not the answer to this question exactly. I have the opposite problem of most. I want to prevent the Enter button from clicking a button when the button has focus. And to do this, I don't want to simply disable the button from accepting an Enter button press, but rather I want to conditionally capture the Enter button press in a callback method. Right now, I have bound the following event to all widgets in my python program:
parent.Bind(wx.EVT_CHAR, self.CharInputCallback)
The EVT_CHAR event is actually thrown when the enter button is pressed and I'm able to get the callback in my callback method. My problem is that the enter button's functionality of virtually clicking a button still goes through, despite purposely not skipping the event (which would forward on the event). Since this is happening, and I'm sure my callback method is not forwarding the event along (I've tested this by capturing characters going to a text box) I suspect that the enter button throws an additional event that I'm not capturing. I've tried binding and capturing the additional following events to prevent the "virtual click" from the enter button:
parent.Bind(wx.EVT_TEXT_ENTER, self.CharInputCallback)
parent.Bind(wx.EVT_KEY_UP, self.CharInputCallback)
parent.Bind(wx.EVT_KEY_DOWN, self.CharInputCallback)
Yet when I press enter, the button in focus is still clicked. To summarize, is there an additional event being thrown when I press the enter button? If so, which event in particular is "virtually clicking" the button? Most forums I've found have discussed how to recognize when the enter button is pressed, but I want to recognize it and disable it's default action when a button is in focus.
I tried binding all those events to different handlers and I also bound EVT_BUTTON. It appears that EVT_BUTTON always fires BEFORE the key and char events do. If you don't want your button to be clicked, then you'll probably have to either disable it, use a different widget (maybe one of the generic buttons) or create your own. I would also ask on the wxPython mailing list to see if they have any suggestions.
The only way to order the events in wxPython that I'm aware of is to use wx.CallAfter or wx.CallLater. I'm not sure how you'd use that in this context though.
The event that causes enter to click a button is the key up event. My code for my callback was messed up slightly. Capturing the key up event and not skipping it prevent the enter button from clicking a button in focus. On Windows 7 anyways.

How can I make a Jeditable (jQuery) span activate editing on more than one event?

For the jQuery extension Jeditable, one of the parameters that can be specified is which DOM event will turn a div/span/... into a text input/textarea/...
I would like to have more than one event serve as a trigger; that is, I would like either a click event or a contextmenu event to turn a span into an in-place edit area.
Is there a graceful way to do this without forking Jeditable?
--edit--
An example of code specifying the event is below. The parameter is optional, defaulting to a regular click.
$(".edit_rightclick").editable("/ajax/save",
{
cancel: "Cancel",
submit: "OK",
tooltip: "Right click to edit.",
event: "contextmenu",
});
Calling twice, once for the regular click event with the event unspecified, and one for the contextmenu event (right-click if there are no switched mouse buttons or anything like that) does not seem to produce the intended effect of an element becoming editable in place on a click from either mouse button.
I'm taking the lack of answers so far to mean that it's impossible, or rather it would require changes to Jeditable or jQuery that would include headaches for the developer, possible code smells, etc.

Firebug: How to inspect elements changing with mouse movements?

Sometimes I need to inspect elements that are only showing up on a page if you put mouse over some area. The problem is that if you start moving mouse towards firebug console in order to see the changes, mouse-out event is triggered and all changes I am trying to inspect disappear. How to deal with such cases?
Basically I am looking for something that would either:
Switch to firebug console without moving a mouse (using keyboard shortcuts maybe? But I can't figure out how to use firebug with keyboard only)
Have an ability to "freeze" the page so your mouse movements don't trigger any events anymore.
Thanks.
HTML Tooltip (Firebug)
Select the element with the inspector or in the DOM. Go to the "Styles" tab in firebug and click to the small arrow on the tab and select ":hover" (also available ":active"). The state will remain on "hover" and you can select other elements to make them hover.
HTML Tooltip (Firefox developer tools)
Click the button to see three checkboxes, which you can use to set the :hover, :active and :focus pseudo-classes for the selected element
This feature can also be accessed from the popup menu in the HTML view.
If you set one of these pseudo-classes for a node, an orange dot appears in the markup view next to all nodes to which the pseudo-class has been applied:
JQuery Tooltip
Open the console and enter jQuery('.css-class').trigger('mouseover')
Regular Javascript Tooltip
Open the console and enter document.getElementById('yourId').dispatchEvent(new Event('mouseover'));
The style panel in Firebug has a dropdown menu where you can choose the :active or :hover state.
You can also start the debugger on a timer. Enter this command into the console:
setTimeout(function(){ debugger; }, 10000);
This will give you 10 seconds to use the mouse and make the page look the way you want in order to inspect it. When the debugger starts, the page will freeze, and you'll be able to explore the elements in the developer tool tab, without the DOM changing or responding to any additional mouse events.
I think you can also do this :
Choose Firebugs Inspect mode
Hover over the item that pops up the element you wish to inspect and then use the Tab key several times to make Firebug active (I found it tricky to see when Firebug was the active component but nothing like trial and error - when I saw that Firefoxes Find Toolbar was active I'd then Shift + Tab backwards twice to get into Firebug.
Then I'd use the L/R arrow keys to contract/expand elements and U/D arrow keys to navigate through Firebugs console
Worked for me anyway!
For Jquery UI tooltip I finally set up a long delay for the hiding of the element so I have time to inspect it before it's deleted. For example, I used this to inspect the tooltip:
$( document ).tooltip({ hide: {duration: 100000 } });
instead of:
$( document ).tooltip();
You could insert a breakpoint at the start of the mouseout event handler. Its code won't be executed until you allow it to continue, and you can use the DOM inspector and so forth while execution is stopped.
Firebug's hotkey for inspecting elements is Ctrl + Shift + C (Windows/Linux).
Go here for a list of all Firebug keyboard shortcuts.
For the bootstrap tooltip:
$(document ).tooltip({delay: { show: 0, hide: 100000 }});
While selecting :hover in the CSS menu might be nice if you only want to inspect some CSS code, it doesn't work if whatever you want to inspect is changed using JavaScript.
A simple hack in this case is to open Firebug in a different window (top right corner of the Firebug bar) than move your mouse at the desired location and drag and drop something from there out of the browser window. Now you can inspect whatever in the Firebug window. Just don't move your mouse back into the browser window.
For Javascript events such as Mouse over.
Open Firebug/Inspect an element.
Click on the element before the mouseover event, e.g. click on a div. It will turn blue to show it is selected.
Put your mouse over the element and don't move it from this point forward.
Use your ↑/↓ arrow keys to manoeuvre in Firebug.
Use your ←/→ arrow keys to expand/contract code with + or -.
Double tap Tab to get to the CSS pane.
Use the arrow keys to navigate. Use shift and arrow keys to select text. Ctrl & C to copy.
Hold Shift and double tap Tab to get back to the HTML pane.
I'd like to chip in with my preferred method. Putting this little snippet in your console allows you to start the debugger at any time with a simple keypress on your keyboard (F8 is used in this example)
document.addEventListener("keydown", (event) => {if (event.key == 'F8') {debugger}});
You can also use a keycode if you prefer:
document.addEventListener("keydown", (event) => {if (event.keyCode == 119) {debugger}});
I found that Chrome does work a bit differently than Firefox. In particular, menus that close when the mouse is clicked outside of the menu remain open when inspecting them in Chrome (and they close when inspecting them with Firebug). So the advice is to try to use a different development tool in a different browser to see if it makes a difference.
Open console:
If you have javascript based tooltip, find applicable elements in console with appropriate selector. like below and confirm you able to find appropriate element with selectors.
$('your selector')
Write above javascript and Press enter. you will have list of elements.
Now e.g. If library added event on mouseenter enter following script:
$('your selector').mouseenter()
Press enter.
This way you can simulate mouse movement events without actual mouse. and can use actual mouse pointer to investigate thing in debugger tool.
This is an extremely old question by now, but I've found an answer that directly answers the "freeze the browser" portion of the question.
Control + Alt + B. This is "break on mutate". Which means, when you are hovering over an element with firebug engaged (Control + Shift + C), that when the HTML attributes would change, instead they hit a breakpoint, allowing you to easily navigate around to examine for paths, etc.

Resources