ปรับความกว้าง คอลัมน์ซ้ายของ Gmail

พอดีอยากได้ left column ของ Gmail ให้กว้างๆ หน่อย เพราะว่ามี Label ที่ชื่อยาว แล้วมันมองไม่เห็นเลขจำนวน Unread. ก็เลยไปเสิร์ซหาดู พบ UserScripts ในอันดับแรกๆ เลย.  Feature ใช้ได้เลย มันจำความกว้างที่เราตั้งไว้ ไว้ใน cookie ด้วย ถ้าเรามีการเปิดหน้า Gmail ใหม่ มันก็จะปรับความกว้างไว้ให้เลย.

อ้างอิงจากที่นี่
http://www.codecouch.com/2013/04/resizing-the-left-hand-labels-column-in-gmail-an-update-to-save-the-column-width/

Source Code ของ UserScripts เผื่อเว็บที่อ้างอิงมาเข้าไม่ได้แล้ว

// ==UserScript==
// @name           Gmail label column resizer
// @namespace      http://www.codecouch.com/
// @description    User script that allows the labels column in Gmail to be resized
// @include        http://mail.google.com/*
// @include        https://mail.google.com/*
// @match          http://mail.google.com/*
// @match          https://mail.google.com/*
// @version        1.2
// @history        1.2 Allow 10 seconds for the Gmail Greasemonkey API to load, Chrome & GM userscripts now share same code
// @history        1.1 Stopped duplicate grab bars and added more URL matching
// @history        1.0 Initial version
// @grant          none
// ==/UserScript==
 
var addGmailResizerToPage = function() {
 
	function loadGmailResizer() {
		// @version        1.3
		// @history        1.3 Store label column width in a cookie (and set on load), update Greasemonkey API check frequency
		// @history        1.2 Allow 10 seconds for the Gmail Greasemonkey API to load, Chrome & GM userscripts now share same code
		// @history        1.1 Stopped duplicate grab bars and added more URL matching
		// @history        1.0 Initial version
		 
		// Use the Gmail Greasemonkey API to reliably find the 2 main elements (the left- and right-hand columns). You do not need Greasemonkey installed 
		// to use this API. See http://code.google.com/p/gmail-greasemonkey/wiki/GmailGreasemonkey10API for details (note: the documentation is out of date)
		//
		// Load the API. It will run our callback function when loaded, passing a GmailAPI object
		gmonkey.load(2, function(o) {
			/*
				Set up variables. To keep the code size down, some are re-used. There should be no global namespace pollution
		 
				i		initially points to the parent element of the left-hand nav, ultimately points to the parent element of the grab bar
				l		initially used as a loop counter, ultimately points to the element that is resized to change the left-hand column width
				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
				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)
				d		this points to the document in the frame we use
				b		this points to the body
				t		this is used to calculate the top coordinate of the grab bar
				x		this holds the initial x delta between mouse click and left-hand column width
				w		initially used to point to the left-hand and main column elements. During dragging, holds the new width of the left-hand column. On load, holds the saved width (if any)
				n		initially holds pointers to all the columns elements, then the left-hand nav, then holds the string 'addEventListener'
				g		this points to the grab bar element
				Q		this holds the string 'querySelector'
				W		this holds the string 'width'
				U		used for many things, most notably holding the strings 'parentNode', 'childNodes', and 'cssText'
				P		this holds the string 'px'
				S		this holds the string 'style'
				k		this is the function that sets the width of the right-hand column
			*/		
		 
			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; };
		 
			// Update c and i to point to their intended elements
			while(c.compareDocumentPosition(i)&2) c=c[U];
			while(i[U]!=b) i=i[U];
		 
			// 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
			n=c[U='childNodes'], w=[n[0], n[1]];
		 
			// 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
			// 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
			// perfect detection method (working with all the child nodes might be better), but it's better than nothing, and works at the moment :-)
			if(c.cells)
				for(o in w) {						// Loop over the first two table cells
					for(l in r=w[o][U])				// Find all of the cell's child elements and loop over them
						if(parseInt(r[l][S][W])) {		// If the current child element has a non-zero style width explicitly set...
							w[o]=r[l];			// ... then assume it is the width-controlling element, and store in in the current item in w
							break;				// There's no point in continuing to check the children (doing a "When a stranger calls")
						}
				}
		 
			// Update l and r to point to their intended elements, and determine how much space is taken up
			// by any other columns (if present) by subtracting the label & main columns widths from the body width
			l=w[0], r=w[1][S], c=b[o='offsetWidth']-l[o]-w[1][o];
		 
			// Create the grab bar, and insert it into the page
			g=i.appendChild(d.createElement('div'));
		 
			// 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.
			// 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.
			// 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.
			// Store the inline style in a property called 'cssText2' of the right-hand column's style object
			n=l[Q]('[role^=n]');
			r[(U='cssText')+2]=n[Q]('[role]')[S][U];
		 
			// Calculate the top position for the grab bar
			while(t+=n.offsetTop, n=n.offsetParent);
		 
			// Style the grab bar
			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)';
		 
			// Add a resize event to the window to update the size of the right-hand column when the window is resized
			// While Gmail does this anyway, it doesn't take into account any size change to the left-hand column
			top[n='addEventListener']('resize', k, 0);
		 
			// Add mouse event listeners. mousedown is added to the grab bar, mousemove and mouseup to the document
			g[n]('mousedown', function(e) {
				// Only trigger with the LMB on grab bar. Stores initial x coord and width of left-hand column
				// Save a copy of the existing right-hand column style so we can restore it later, then disable text selection
				// Call e.preventDefault() to stop a native drag operation from starting (this happens a lot in Fx)
				e.which==1 && (x=l[o]-e.pageX, r[U+3]=r[U], r[U]+=r[U+2], e.preventDefault());
			}, 0);
		 
			d[n]('mousemove', function(e) {
				// If we have the mouse button pressed, work out the x delta then update the column widths and the grab bar position
				x && (w=e.pageX+x, l[S][W]=w+P, g[S].left=w-5+P, k());
			}, 0);
		 
			d[n]('mouseup', function(e) {
				// If the LMB is released, stop the mousemove code from running and restore the right-hand column style
				// k() needs to be called again, as restoring the style could alter the width
				// Also save the label column width into a cookie
				e.which==1 && (x=0, r[U]=r[U+3], d.cookie='labelWidth='+w+'; expires=Fri, 31 Dec 9999 23:59:59 GMT"', k());
			}, 0);
		 
			// If the label column width has been previously saved, use it to set the initial width
			w = parseInt(d.cookie.replace(/(?:(?:^|.*;\s*)labelWidth\s*\=\s*((?:[^;](?!;))*[^;]?).*)|.*/, '$1'), 10);
			if (!isNaN(w)) l[S][W]=w+P, g[S].left=w-5+P, k();
		});
 
	};
 
	// Test for the presence of the Gmail Greasemonkey API once per second. Give up if not present after 10 seconds
	var loadCount = 0;
	function testForGmonkey() {
		loadCount++;
		if (loadCount == 10) clearInterval(timerHandle);
		if (typeof(gmonkey) == 'object' && 'load' in gmonkey) {
			clearInterval(timerHandle);
 
			// Only load the resizer code if it hasn't already been run (stops multiple grab bars from appearing)
			if ('loadedGmailResizer' in top) return;
			top.loadedGmailResizer = true;
			loadGmailResizer();
		}
	};
	var timerHandle = setInterval(testForGmonkey, 1000);
 
};
s = document.createElement('script');
s.type = 'text/javascript';
s.textContent = '(' + addGmailResizerToPage.toString() + ')()';
document.body.appendChild(s);