Gmail label column resizer

User script that allows the labels column in Gmail to be resized

  1. // ==UserScript==
  2. // @name Gmail label column resizer
  3. // @namespace http://www.codecouch.com/
  4. // @description User script that allows the labels column in Gmail to be resized
  5. // @include http://mail.google.com/*
  6. // @include https://mail.google.com/*
  7. // @match http://mail.google.com/*
  8. // @match https://mail.google.com/*
  9. // @version 1.2
  10. // @history 1.2 Allow 10 seconds for the Gmail Greasemonkey API to load, Chrome & GM userscripts now share same code
  11. // @history 1.1 Stopped duplicate grab bars and added more URL matching
  12. // @history 1.0 Initial version
  13. // @grant none
  14. // ==/UserScript==
  15.  
  16. var addGmailResizerToPage = function() {
  17.  
  18. function loadGmailResizer() {
  19. // Insert code here...
  20.  // Use the Gmail Greasemonkey API to reliably find the 2 main elements (the left- and right-hand columns). You do not need Greasemonkey installed
  21. // to use this API. See http://code.google.com/p/gmail-greasemonkey/wiki/GmailGreasemonkey10API for details (note: the documentation is out of date)
  22. //
  23. // Load the API. It will run our callback function when loaded, passing a GmailAPI object
  24. gmonkey.load(2, function(o) {
  25. /*
  26. Set up variables. To keep the code size down, some are re-used. There should be no global namespace pollution
  27.  
  28. i initially points to the parent element of the left-hand nav, ultimately points to the parent element of the grab bar
  29. l initially used as a loop counter, ultimately points to the element that is resized to change the left-hand column width
  30. r initially used as a temporary loop variable, ultimately points to the style object of the element that is resized in the right-hand column
  31. c initially points to the parent element of the active view, then parent element of all columns, then used to hold the width of columns 3-n (if present)
  32. d this points to the document in the frame we use
  33. b this points to the body
  34. t this is used to calculate the top coordinate of the grab bar
  35. x this holds the initial x delta between mouse click and left-hand column width
  36. w initially used to point to the left-hand and main column elements, then during dragging, this holds the new width of the left-hand column
  37. n initially holds pointers to all the columns elements, then the left-hand nav, then holds the string 'addEventListener'
  38. g this points to the grab bar element
  39. Q this holds the string 'querySelector'
  40. W this holds the string 'width'
  41. U used for many things, most notably holding the strings 'parentNode', 'childNodes', and 'cssText'
  42. P this holds the string 'px'
  43. S this holds the string 'style'
  44. k this is the function that sets the width of the right-hand column
  45. */
  46.  
  47. var i=o.getNavPaneElement(), l, r, c=o.getActiveViewElement(), d=c.ownerDocument, b=d.body, t=0, x, w, n, g, Q='querySelector', W='width', U='parentNode', P='px', S='style', k=function() { r[W]=b[o]-l[o]-c+P; };
  48.  
  49. // Update c and i to point to their intended elements
  50. while(c.compareDocumentPosition(i)&2) c=c[U];
  51. while(i[U]!=b) i=i[U];
  52.  
  53. // Update n to hold pointers to all the column elements (even if more than 2 are present), and w to point to just the first 2
  54. n=c[U='childNodes'], w=[n[0], n[1]];
  55.  
  56. // Detect if a table has been used for layout (this happens with some of the Gmail labs, e.g. Right-side chat). If present, find the first
  57. // element that is controlling the cell's width by finding the first element that has an explicit non-zero width style set. This isn't a
  58. // perfect detection method (working with all the child nodes might be better), but it's better than nothing, and works at the moment :-)
  59. if(c.cells)
  60. for(o in w) { // Loop over the first two table cells
  61. for(l in r=w[o][U]) // Find all of the cell's child elements and loop over them
  62. if(parseInt(r[l][S][W])) { // If the current child element has a non-zero style width explicitly set...
  63. w[o]=r[l]; // ... then assume it is the width-controlling element, and store in in the current item in w
  64. break; // There's no point in continuing to check the children (doing a "When a stranger calls")
  65. }
  66. }
  67.  
  68. // Update l and r to point to their intended elements, and determine how much space is taken up
  69. // by any other columns (if present) by subtracting the label & main columns widths from the body width
  70. l=w[0], r=w[1][S], c=b[o='offsetWidth']-l[o]-w[1][o];
  71.  
  72. // Create the grab bar, and insert it into the page
  73. g=i.appendChild(d.createElement('div'));
  74.  
  75. // Copy the inline style from the "Compose" button. At present, the only inline style is a browser-specific user-select style used to prevent text selection.
  76. // This is applied to the right-hand column while dragging is underway to stop the text being selected. It is removed afterwards so that text can be copied.
  77. // This approach keeps the code size down, as the Gmail code handles the browser detection so I don't have to deal with vendor prefixes.
  78. // Store the inline style in a property called 'cssText2' of the right-hand column's style object
  79. n=l[Q]('[role^=n]');
  80. r[(U='cssText')+2]=n[Q]('[role]')[S][U];
  81.  
  82. // Calculate the top position for the grab bar
  83. while(t+=n.offsetTop, n=n.offsetParent);
  84.  
  85. // Style the grab bar
  86. g[S][U] = W + ':4px;position:absolute;z-index:1;left:' + (l[o]-5) + 'px;top:' + t + 'px;bottom:0;cursor:ew-resize;cursor:col-resize;background:url(data:image/gif;base64,R0lGODlhAwAEAIAAAL+/v////yH5BAAAAAAALAAAAAADAAQAAAIERGKnVwA7)';
  87.  
  88. // Add a resize event to the window to update the size of the right-hand column when the window is resized
  89. // While Gmail does this anyway, it doesn't take into account any size change to the left-hand column
  90. top[n='addEventListener']('resize', k, 0);
  91.  
  92. // Add mouse event listeners. mousedown is added to the grab bar, mousemove and mouseup to the document
  93. g[n]('mousedown', function(e) {
  94. // Only trigger with the LMB on grab bar. Stores initial x coord and width of left-hand column
  95. // Save a copy of the existing right-hand column style so we can restore it later, then disable text selection
  96. // Call e.preventDefault() to stop a native drag operation from starting (this happens a lot in Fx)
  97. e.which==1 && (x=l[o]-e.pageX, r[U+3]=r[U], r[U]+=r[U+2], e.preventDefault());
  98. }, 0);
  99.  
  100. d[n]('mousemove', function(e) {
  101. // If we have the mouse button pressed, work out the x delta then update the column widths and the grab bar position
  102. x && (w=e.pageX+x, l[S][W]=w+P, g[S].left=w-5+P, k());
  103. }, 0);
  104.  
  105. d[n]('mouseup', function(e) {
  106. // If the LMB is released, stop the mousemove code from running and restore the right-hand column style
  107. // k() needs to be called again, as restoring the style could alter the width
  108. e.which==1 && (x=0, r[U]=r[U+3], k());
  109. }, 0);
  110. });
  111.  
  112. };
  113.  
  114. // Test for the presence of the Gmail Greasemonkey API once per second. Give up if not present after 10 seconds
  115. var loadCount = 0;
  116. function testForGmonkey() {
  117. loadCount++;
  118. if (loadCount == 10) clearInterval(timerHandle);
  119. if (typeof(gmonkey) == 'object' && 'load' in gmonkey) {
  120. clearInterval(timerHandle);
  121.  
  122. // Only load the resizer code if it hasn't already been run (stops multiple grab bars from appearing)
  123. if ('loadedGmailResizer' in top) return;
  124. top.loadedGmailResizer = true;
  125. loadGmailResizer();
  126. }
  127. };
  128. var timerHandle = setInterval(testForGmonkey, 1000);
  129.  
  130. };
  131. s = document.createElement('script');
  132. s.type = 'text/javascript';
  133. s.textContent = '(' + addGmailResizerToPage.toString() + ')()';
  134. document.body.appendChild(s);

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址