0

I am developing a Firefox add-on. I need to highlight elements in a webpage using the element's XPath. I am able to highlight it. The problem is the elements are appearing in a distorted way. They are loosing their alignment. Please concentrate on How I am adding display property to parent element that is causing issue for me in the elementHover function.

Please find below is code that I have tried:

$(document).on('mouseenter', 'span[name=element-span]', function() {
    var xpath = $(this).next('input').val();
    $(this).closest("li").addClass("hovered");
    browser.tabs.executeScript(tempTabId, {
        code: "var css = '.highlistelement{" + "outline:2px solid #F70B0B !important;" + "border:2px solid red !important;" +
        "-webkit-box-shadow:0 0 0 2px #F70B0B !important, 0 0 0 2px #F70B0B !important;" + "}'," +
        "head = document.getElementsByTagName('head')[0],style = document.createElement('style');" + "style.type = 'text/css';" +
        "if (style.styleSheet){style.styleSheet.cssText = css;} " + "else {style.appendChild(document.createTextNode(css));" + "}head.appendChild(style);"
    });
    browser.tabs.executeScript(tempTabId, {
        code: "var css = '.block{" + "display:inline-block  !important;" +"};"
    });
    browser.tabs.executeScript(tempTabId, {
        code: "var css = '.displayBlock{" + "display:inline-block !important;" +"}',"+
        "head = document.getElementsByTagName('head')[0],style = document.createElement('style');" + "style.type = 'text/css';" +
        "if (style.styleSheet){style.styleSheet.cssText = css;} " + "else {style.appendChild(document.createTextNode(css));" + "}head.appendChild(style);"
    });
    browser.tabs.executeScript(tempTabId, {
        code: elementHover(xpath, "highlistelement","displayBlock","block")
    });
});

function elementHover(xpath, highlightClass,displayClass,blockClass) {
    var str = 'var path="' + xpath + '";' +
        'var iterator = document.evaluate(path, document, null, XPathResult.UNORDERED_NODE_ITERATOR_TYPE, null); ' +
        'try {' +
        'var thisNode = iterator.iterateNext();' +
        'while (thisNode) {' +
        'thisNode.classList.add("' + highlightClass + '");' +
        'pnode=thisNode.parentNode;'+
        ' while(pnode){'+
        'if(pnode.style.getPropertyValue("display")==="none")'+
        '{'+
        'pnode.classList.add("'+blockClass+'");' +
        '}' +
        'else if(pnode.style.getPropertyValue("display")==="block"){' +
        'pnode.style.display="block"' +
         '}'+
        'else if(pnode.style.getPropertyValue("display")==="inline-block"){' +
        'pnode.style.display="inline-block"' +
        '}'+
        'else if(pnode.style.getPropertyValue("display")==="flex"){' +
        'pnode.style.display="flex"' +
        '}'+
        'else if(pnode.style.getPropertyValue("display")==="inline"){' +
        'pnode.style.display="inline"' +
        '}'+
        'else if(pnode.style.getPropertyValue("display")==="inline-flex"){' +
        'pnode.style.display="inline-flex"' +
        '}'+
        'else if(pnode.style.getPropertyValue("display")==="inline-table"){' +
        'pnode.style.display="inline-table"' +
        '}'+
        'else if(pnode.style.getPropertyValue("display")==="list-item"){' +
        'pnode.style.display="list-item"' +
        '}'+
        'else if(pnode.style.getPropertyValue("display")==="run-in"){' +
        'pnode.style.display="run-in"' +
        '}'+
        'else if(pnode.style.getPropertyValue("display")==="table"){' +
        'pnode.style.display="table"' +
        '}'+
        'else if(pnode.style.getPropertyValue("display")==="table-caption"){' +
        'pnode.style.display="table-caption"' +
        '}'+
        'else if(pnode.style.getPropertyValue("display")==="table-column-group"){' +
        'pnode.style.display="table-column-group"' +
        '}'+
        'else if(pnode.style.getPropertyValue("display")==="table-header-group"){' +
        'pnode.style.display="table-header-group"' +
        '}'+
        'else if(pnode.style.getPropertyValue("display")==="table-footer-group"){' +
        'pnode.style.display="table-header-group"' +
        '}'+
        'else if(pnode.style.getPropertyValue("display")==="table-row-group"){' +
        'pnode.style.display="table-row-group"' +
        '}'+
        'else if(pnode.style.getPropertyValue("display")==="table-cell"){' +
        'pnode.style.display="table-cell"' +
        '}'+
        'else if(pnode.style.getPropertyValue("display")==="table-column"){' +
        'pnode.style.display="table-cell"' +
        '}'+
        'else if(pnode.style.getPropertyValue("display")==="table-row"){' +
        'pnode.style.display="table-row"' +
        '}'+
        'else if(pnode.style.getPropertyValue("display")==="initial"){' +
        'pnode.style.display="initial"' +
        '}'+
        'else if(pnode.style.getPropertyValue("display")==="inherit"){' +
        'pnode.style.display="inherit"' +
        '}'+
        'else if(pnode.style.getPropertyValue("display")==="")' +
        '{'+
        'pnode.classList.add("'+displayClass+'");' +
        'var evObj = document.createEvent("Events");'+
        ' evObj.initEvent("mouseover", true, false);'+
        'pnode.dispatchEvent(evObj);'+
        '}else  if(pnode.style.getPropertyValue("visibility")==="hidden")'+
        '{'+
        'pnode.style.visibility = "visible";' +
        '}' +
        'thisNode.scrollIntoView(true);' +
        'pnode=pnode.parentNode;'+
        '}' +
        'thisNode = iterator.iterateNext();' +
        '}' +
        '} catch (e) {' +
        '}';
    return str;
}

Please find the sample image below to understand the issue:

enter image description here

Please observe the image. When I highlight the "Gmail" text, the remaining two links are moved to next line.

Makyen
  • 31,849
  • 12
  • 86
  • 121
  • Please put your longer code in a separate file, not as long mult-iline strings. It is much easier to understand if the code is in another properly formatted file. If you are going to put the code in a multi-line string, then at least have if formatted such that it reads with normal indenting. – Makyen Jan 27 '17 at 05:06
  • Possible duplicate of [How to give border to any element using css without adding border-width to the whole width of element?](http://stackoverflow.com/questions/2748637/how-to-give-border-to-any-element-using-css-without-adding-border-width-to-the-w) – Makyen Jan 27 '17 at 06:06
  • Please [edit] the question to be on-topic: include a **complete** [mcve] that *duplicates the problem*. Including a *manifest.json*, some of the background/content/popup scripts/HTML. Questions seeking debugging help ("**why isn't this code working?**") must include: ►the desired behavior, ►a specific problem or error *and* ►the shortest code necessary to reproduce it **in the question itself**. Questions without a clear problem statement are not useful to other readers. See: "**How to create a [mcve]**", [What topics can I ask about here?](http://stackoverflow.com/help/on-topic), and [ask]. – Makyen Jan 27 '17 at 07:02
  • If you already understand that changing the `display` style for the element's ancestors is causing the problem you are interested in, why are you still changing the `display` style? I must admit, given the amount of code you have devoted to changing the ancestor's `display` style, I had assumed that the layout changes resulting from the change to the `display` style were desired. – Makyen Jan 27 '17 at 07:50

1 Answers1

0

The styles you are applying change the layout. You change the size size of the box the element in which you are interested, and you change the value of the display style for all of its parents.

Adding a border changes the size of the displayed element

Specifically, you are adding a border: border:2px solid red !important;.

Prior to applying your style, the box model is a 34×24 box:

Box prior to border

After adding the border, the box is 38×28 (2 extra pixels on each side).

After adding border

If you don't want the layout to change, then make sure that the styles you add don't change the size of the box the element is displayed in. In this case, because you also apply the style outline:2px solid #F70B0B !important;, you could get a very similar effect by just not using the border:2px solid red !important; style.

Below is a quick example showing how adding a border changes the size of the element vs. an outline that does not. The border or outline is added upon hover.

.borderOnHover:hover {
  border:2px solid red !important;
}
.outlineOnHover:hover {
  outline:2px solid #F70B0B !important;
}
<span class="borderOnHover">Border changes the size</span>
<span>Other Text</span>
<br/>
<br/>
<span class="outlineOnHover">Outline does not change the size</span>
<span>Other Text</span>
<br/>

Changing the display property for all ancestors

Your code also runs through changing the display property on all of the element's ancestors. What each is changed to depends on what its previous value is. You do this by either changing the display attribute, or adding the displayBlock class. You also add the block class, but you never define the block class, so it has no effect. In order to not affect the layout, you will need to not change the display property for the element or any of its ancestors.

Your block CSS class is never created. You assign the text to the variable css, but then the value of the variable is immediately changed to the text for your displayBlock class, which is then added as a <style>.

Makyen
  • 31,849
  • 12
  • 86
  • 121
  • Thanks for your efforts. But it doesn't solved my issue. – Narayana Bojja Jan 27 '17 at 06:32
  • @Narayana, I have updated this to mention that you should not change the `display` style for any of the ancestors of the element, or the element. I had not previously mentioned it because you clearly are going to considerable trouble to change that style on all ancestors. Given that level of effort, I had assumed that it was something you were really wanting to change. However, it is certainly changing the layout. If you are wanting the the layout not to change at all, then you need to not be changing that style, at all on any elements. – Makyen Jan 27 '17 at 07:36
  • Thanks for your reply. If I don't change display property of parent elements , I am not able to highlight pop-up's elements. Is there a way to highlight elements inside pop-up without changing display property ? – Narayana Bojja Jan 27 '17 at 09:24
  • @Narayana, you are going to need to be much more specific than that to communicate what you are desiring. What popup, specifically, are you referring to? Are you asking about a popup for your extension? I, or anyone else, are going to need explicit examples of what you are concerned about. – Makyen Jan 27 '17 at 10:09