Home

can double-click be made to work for word-select in 'Output' pane? triple-click for line-select?

Another behavior that's been present in LINQPad 4, still present in LINQPad 5.0.4, just reporting in case it's fixable during beta. :)

AFAICT the Output pane is a hosted instance of IE, but double-clicking on words in IE windows seems to work fine for doing word-select , but it doesn't work (does nothing) in the Output pane.

If I do a 'view source' from the output pane, save that to a file, then open the file in IE, double-click and triple-click work.

If I go to about:blank in IE, F12 to modify the source to be the same as what's in the output pane source, the double-click and triple-click work.

I can still click-drag for selecting like 'normal' but since double-click and triple-click seem to work fine in an instance of IE, I was hoping maybe this is just an IE setting during its hosting that could be changed?

Thanks!

Comments

  • It's this problem:

    https://connect.microsoft.com/VisualStudio/feedback/details/792884/windows-forms-webbrowser-on-usercontrol-with-ie-10-installed-breaks-double-click-text-select#tabs

    I've tried all the workarounds, but nothing seems to work reliably. If you can give me something that works, I'll take a look.
  • Using the Work_Around_Applied_To_Project.zip file attached to the bug, I narrowed the issue down to setting AllowWebBrowserDrop and ScriptErrorsSuppressed only after adding the webbrowser control to its parent usercontrol. If you set them before the webbrowser is added to the parent usercontrol, then the double/triple-click behavior breaks.

    One workaround is not to set them at all (leaving them as their defaults of AllowWebBrowserDrop = true and ScriptErrorsSuppressed = false), but assuming that's not a viable option, then setting them after the parent.Controls.Add(webBrowser) seems to work.

    This is going based on the repro sln attached to the bug, so if you've already tried that and it doesn't work for you, do you have a different repro sln I could try?

    Thanks, Joe!
  • edited July 2015
    The difficulty is that I've tried leaving these properties unset, but the bug remains. I don't believe that workaround is reliable.
  • Since doing so works for the repro attached to the bug, any chance you have a repro you can share the source for? There might be a different property that's in the same 'needs to be set after adding to parent control' set (as a guess) that the repro attached to the bug happens to not touch. I'm happy to try and figure out a workaround if you have a repro I can play with. :)

    Thanks!
  • I'm guessing you've already noticed this, but BrowseDriversForm and BrowseSamplesForm both set ScriptErrorsSuppressed = true and both have double/triple click working fine. The OutputWebBrowser ctor setting AllowWebBrowserDrop = false seems to be the only place setting that particular property AFAICT
  • I have tried to isolate it, but it's not easy. It could take the best part of a day to get a repro.

    I was hoping for a workaround like this:
    http://stackoverflow.com/a/25400426/46223
  • well, I happened to be using the old 4.31 version today and noticed that double-clicking in its Results window worked just fine! This was before the introduction of the data grids AFAICT.

    If there's an archive of LINQPad versions I could download I can try to bisect it down to a particular version where double-click stopped working? Not sure if that's of any value, but would be happy to do so if it helps isolate the bug and leads to a fix. :smile:
  • @JoeAlbahari - see my previous comment - I forgot to add the @ mention and wasn't sure if it notifies you on discussions you had already commented on or not. :smile:
  • That's interesting. When I run v4.31, I get the same behavior as the latest version, i.e., I cannot double-click results. This makes me concerned that if I find a "fix", it may not work for everyone.

    If someone with expertise in Javascript could come up with a simple and reliable bit of JS - or something involving the IE DOM, that would be the safest solution. It only has to work with IE.
  • edited August 2015
    I have had a go at creating some JS that will select the word under the cursor on double click and the paragraph under the cursor on triple click.
    Note a small caveat: that the "double click speed" is set as part of the script, and won't use the system setting from Windows...

    Tested on IE11, also works on Firefox; untested on Chrome.

    // function to get mouse position relative to the container
    var getMousePosition = function (container, mouseEvent) {
    var currentObject = container;
    var currentLeft = 0;
    var currentTop = 0;
    while (currentObject != document.body) {
    currentLeft += currentObject.offsetLeft;
    currentTop += currentObject.offsetTop;
    currentObject = currentObject.offsetParent;
    }
    return {
    x: mouseEvent.pageX - currentLeft,
    y: mouseEvent.pageY - currentTop
    }
    }

    var clickCounter;
    var clickPosition;
    var resetClick = function () {
    clickCounter = 0;
    clickPosition = {
    x: null,
    y: null
    };
    };
    resetClick();
    var clickTimer;

    // function to wait for the next click, and reset click details if time elapses
    var conserveClick = function (mousePosition) {
    clickPosition = mousePosition;
    clearTimeout(clickTimer);
    clickTimer = setTimeout(resetClick, 250); // NOTE: that this does mean that the double click speed is defined by the javascript, NOT the system settings...
    clickCounter++;
    };

    var findClickedText = function (parentElement, x, y, paragraph) {
    var range = document.createRange();
    for (var child = 0; child < parentElement.childNodes.length; child++) {
    var textElement = parentElement.childNodes[child];

    var texts = paragraph ? [textElement.textContent] : textElement.textContent.split(/\W/);
    var start = 0;
    for (var index in texts) {
    var check = texts[index];
    var end = start + check.length;
    range.setStart(textElement, start);
    range.setEnd(textElement, end);
    var rects = range.getClientRects(); // don't use getBoundingClientRect as text could wrap
    var clickedRect = isClickInRects(rects);
    if (clickedRect) {
    return [check, start, clickedRect, range, textElement];
    }
    start = end + 1;
    }
    }

    function isClickInRects (rects) {
    for (var index in rects) {
    var rect = rects[index];
    if (rect.left < x && rect.right > x && rect.top < y && rect.bottom > y) {
    return rect;
    }
    }
    return false;
    }
    return null;
    };

    var selectTextAtPosition = function (all, position) {
    var element = document.elementFromPoint(position.x, position.y);
    var result = findClickedText(element, position.x, position.y, all);
    if (result != null) {
    var selection = window.getSelection();
    selection.removeAllRanges();
    selection.addRange(result[3]);
    }
    };

    document.body.addEventListener('click', function (event) {

    // get the current mouse position
    var mousePosition = getMousePosition(document.body, event);

    // if first click or position has not changed
    if (clickCounter == 0 || (clickPosition.x == mousePosition.x && clickPosition.y == mousePosition.y)) {
    conserveClick(mousePosition);

    if (clickCounter > 1 && clickCounter < 4)
    selectTextAtPosition(clickCounter == 3, clickPosition);
    }
    });
    Edit: Forgot to mention, for testing, I used the following CSS to prevent the browser's default selection behavior:

    body {
    -moz-user-select: none;
    -webkit-user-select: none;
    -ms-user-select: none;
    user-select: none;
    -o-user-select: none;
    }
Sign In or Register to comment.