Jira Wiki Whitespace

Mimic non-wiki style whitespace for description and comments

  1. // ==UserScript==
  2. // @name Jira Wiki Whitespace
  3. // @namespace http://mailerdaemon.home.comcast.net
  4. // @description Mimic non-wiki style whitespace for description and comments
  5. // @include *jira*/browse/*-*
  6. // @version 1.3
  7. // @unwrap
  8. // ==/UserScript==
  9.  
  10. GM_addStyle("div#description_full p, div.action-body ul, div.action-body ol, div.action-body blockquote { margin-bottom: 0;}");
  11.  
  12. if(x = $X("//div[@id='description_full']"))
  13. {
  14. //jira wraps the description in spaces, we need to remove them or they will trouble us later.
  15. if(x.firstChild.nodeType == x.TEXT_NODE) x.firstChild.data = x.firstChild.data.replace(/^\n /, "");
  16. if(x.lastChild.nodeType == x.TEXT_NODE) x.lastChild.data = x.lastChild.data.replace(/\n $/, "");
  17. rep = String.fromCharCode(32,160);
  18. $Z("//div[@id='description_full' or (@class='action-body' and not(@id='changehistory'))]/descendant-or-self::*[not(ancestor-or-self::pre) and text()]", function(r)
  19. {
  20. for( var i=0; i < r.childNodes.length; i++ )
  21. if(r.childNodes[i].nodeType == r.TEXT_NODE)
  22. {
  23. p = r.childNodes[i];
  24. span = document.createElement("span");
  25. span.innerHTML = p.data.replace(/ /g, rep).replace(/&/g, "&amp;").replace(/\</g, "&lt;").replace(/\>/g, "&gt;").replace(/([^\n])(?=\n)/g, "$1<br/>");
  26. p.parentNode.replaceChild(span, p);
  27. }
  28. });
  29. }
  30.  
  31. function $X(_xpath, node){//to search in a frame, you must traverse the .contentDocument or .contentWindow attribute.
  32. var doc = (node)?(node.ownerDocument || node):(node = document);
  33. return doc.evaluate(_xpath, node, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null).snapshotItem(0);
  34. }
  35. /*function $Y(_xpath, node){
  36. var doc = (node)?(node.ownerDocument || node):(node = document);
  37. return doc.evaluate(_xpath, node, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
  38. }*/
  39. function $Z(_xpath, func, node){
  40. var doc = (node)?(node.ownerDocument || node):(node = document);
  41. var res = doc.evaluate(_xpath, node, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
  42. var args = Array.prototype.slice.call(arguments, 3);
  43. var i = 0;
  44. for (; i < res.snapshotLength; ++i)
  45. func.apply(func, [res.snapshotItem(i), i].concat(args));
  46. return i;
  47. }
  48. /*function insertAfter(insert, after){return after.parentNode.insertBefore(insert, after.nextSibling);}
  49. function insertBefore(insert, before){return before.parentNode.insertBefore(insert, before);}
  50. function remove(r){return r.parentNode.removeChild(r);}
  51. /**/function replace(old, New){return old.parentNode.replaceChild(New,old);}