Created
January 28, 2012 12:52
-
-
Save quietlynn/1694195 to your computer and use it in GitHub Desktop.
[DEPRECATED] Google+ Toolkit
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Google+ Toolkit => Handle Google+ DOM more easily. | |
Copyright (C) 2012 Jingqin Lynn | |
This program is free software: you can redistribute it and/or modify | |
it under the terms of the GNU General Public License as published by | |
the Free Software Foundation, either version 3 of the License, or | |
(at your option) any later version. | |
This program is distributed in the hope that it will be useful, | |
but WITHOUT ANY WARRANTY; without even the implied warranty of | |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
GNU General Public License for more details. | |
You should have received a copy of the GNU General Public License | |
along with this program. If not, see <http://www.gnu.org/licenses/>. | |
*/ | |
// ==UserScript== | |
// @name Google+ Toolkit | |
// @namespace http://project.quietmusic.org/j/ | |
// @description Handle Google+ DOM more easily. | |
// @match https://plus.google.com/* | |
// @require https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js | |
// ==/UserScript== | |
(function(){ | |
//Use the <base> element to detect Google+ main page. | |
var base = document.querySelector('base'); | |
if (!base) return; | |
if (!base.href.match(/^https:\/\/plus\.google\.com(\/u\/\d+)?\/?/)) return; | |
//Chrome V8 don't support unsafeWindow. Time for a hack. | |
if (window == unsafeWindow) { | |
var span = document.createElement('span'); | |
span.setAttribute('onclick', 'return window;'); | |
unsafeWindow = span.onclick(); | |
} | |
//For shorter code. | |
var win = unsafeWindow; | |
win.ext = win.ext || {}; | |
if (win.ext.toolkit) { | |
return; | |
} else { | |
win.ext.toolkit = {}; | |
} | |
win.ext.toolkitCallback = win.ext.toolkitCallback || []; | |
win.ext.toolkit.onjQueryLoaded = function($) { | |
//For those who prefer jQuery plugins. | |
$.gplus = win.ext; | |
win.ext.toolkitReady = true; | |
//XPath plugin | |
(function($) { | |
var xpathTypes = { | |
'any': XPathResult.ANY_TYPE, | |
'number': XPathResult.NUMBER_TYPE, | |
'string': XPathResult.STRING_TYPE, | |
'boolean': XPathResult.BOOLEAN_TYPE, | |
'iterator': XPathResult.UNORDERED_NODE_ITERATOR_TYPE, | |
'ordered_iterator': XPathResult.ORDERED_NODE_ITERATOR_TYPE, | |
'snapshot': XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, | |
'ordered_snapshot': XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, | |
'single': XPathResult.ANY_UNORDERED_NODE_TYPE, | |
'first' : XPathResult.FIRST_ORDERED_NODE_TYPE, | |
}; | |
var iterateXPathResult = function(callback) { | |
var node; | |
var i = 0; | |
while (node = this.iterateNext()) { | |
callback(i, node); | |
i++; | |
} | |
}; | |
$.xpath = function jQueryXPathPlugin(expr, opt_context, opt_type, opt_nsResolver) { | |
if(typeof(opt_type) != 'number') { | |
if(!opt_type) opt_type = 'any'; | |
opt_type = xpathTypes[opt_type]; | |
} | |
var result = document.evaluate(expr, opt_context || document, opt_nsResolver || null, opt_type, null); | |
switch (result.resultType) { | |
case XPathResult.NUMBER_TYPE: | |
return result.numberValue; | |
case XPathResult.STRING_TYPE: | |
return result.stringValue; | |
case XPathResult.BOOLEAN_TYPE: | |
return result.booleanValue; | |
case XPathResult.UNORDERED_NODE_ITERATOR_TYPE: | |
case XPathResult.ORDERED_NODE_ITERATOR_TYPE: | |
var nodes = []; | |
var node = null; | |
while (node = result.iterateNext()) { | |
nodes.push(node); | |
} | |
return $(nodes); | |
return result; | |
case XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE: | |
case XPathResult.ORDERED_NODE_SNAPSHOT_TYPE: | |
var nodes = []; | |
var node = null; | |
for (var i = 0; i < result.snapshotLength; i++) { | |
nodes.push(result.snapshotItem(i)); | |
} | |
return $(nodes); | |
case XPathResult.ANY_UNORDERED_NODE_TYPE: | |
case XPathResult.FIRST_ORDERED_NODE_TYPE: | |
return $(result.singleNodeValue); | |
default: | |
return result; | |
} | |
result.each = eachResult; | |
return result; | |
}; | |
$.prototype.xpath = function jQueryXPathPlugin(expr, opt_type, opt_nsResolver) { | |
return $.xpath(expr, this[0], opt_type, opt_nsResolver); | |
} | |
})($); | |
//Dynamic selection plugin. Selects nodes matching the selector that are present or added later. | |
(function($) { | |
$.prototype.dynamicSelect = function (selector, callback) { | |
var foreach = function(_, e) { callback(e); }; | |
$(selector, this).each(foreach); | |
var handler = function(e) { | |
if(!e) e = event; | |
if(e.target instanceof Element) { | |
if($(e.target).is(selector)) callback(e.target); | |
$(selector, e.target).each(foreach); | |
} | |
}; | |
for(var i = 0; i < this.length; i++) { | |
this[i].addEventListener('DOMNodeInserted', handler, false); | |
} | |
return handler; | |
}; | |
$.prototype.stopDynamicSelect = function(handler) { | |
for(var i = 0; i < this.length; i++) { | |
this[i].removeEventListener('DOMNodeInserted', handler, false); | |
} | |
}; | |
if ($.xpath) { | |
$.prototype.dynamicXPath = function(expr, callback, opt_type, opt_nsResolver) { | |
var foreach = function(_, e) { callback(e); }; | |
this.xpath(expr, opt_type, opt_nsResolver).each(foreach); | |
var handler = function(e) { | |
if(!e) e = event; | |
$.xpath(expr, e.target, opt_type, opt_nsResolver).each(foreach); | |
}; | |
for(var i = 0; i < this.length; i++) { | |
this[i].addEventListener('DOMNodeInserted', handler, false); | |
} | |
return handler; | |
}; | |
$.prototype.stopDynamicXPath = $.prototype.stopDynamicSelect; | |
} | |
})($); | |
//Do the callbacks. | |
var callbacks = win.ext.toolkitCallback; | |
for (var i = 0; i < callbacks.length; i++) { | |
callbacks[i]($); | |
} | |
}; | |
if (typeof(jQuery) != 'undefined') win.jQuery = jQuery; | |
if (typeof(win.jQuery) == 'undefined') { | |
//Load jQuery from Google CDN | |
var script = document.createElement('script'); | |
script.type = 'text/javascript'; | |
script.src = 'https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js'; | |
//jQuery is not ready yet when the 'load' event of the <script> is dispatched. | |
//Appending another script block can ensure jQuery is defined. | |
var cb = document.createElement('script'); | |
cb.type = 'text/javascript'; | |
cb.textContent = 'jQuery.noConflict();window.ext.toolkit.onjQueryLoaded(jQuery);'; | |
script.addEventListener('load', function() { | |
document.head.appendChild(cb); | |
}); | |
document.head.appendChild(script); | |
} else { | |
win.ext.toolkit.onjQueryLoaded(win.jQuery); | |
} | |
//Some helper functions. | |
win.ext.doClick = function(target) { | |
var e; | |
e = document.createEvent('MouseEvents'); | |
e.initEvent('mousedown', true, true); | |
target.dispatchEvent(e); | |
e = document.createEvent('MouseEvents'); | |
e.initEvent('click', true, true); | |
target.dispatchEvent(e); | |
e = document.createEvent('MouseEvents'); | |
e.initEvent('mouseup', true, true); | |
target.dispatchEvent(e); | |
return target; | |
}; | |
win.ext.doKeypress = function (target) { | |
var e = document.createEvent('KeyboardEvent'); | |
e.initEvent('keypress', true, true, win, 0, 0, 0, 0, 0, 'e'.charCodeAt(0)); | |
target.dispatchEvent(e); | |
return target; | |
}; | |
win.ext.getLangCode = function () { | |
var langCode = null; | |
//Parse query string to get language code | |
var queryStringMatch = location.toString().match(/[\?&]hl=([a-zA-Z\-]+)/); | |
if(queryStringMatch) { | |
langCode = queryStringMatch[1]; | |
} else { | |
//Parse HTML tag. ('<html lang="xx-YY">') | |
var htmlLang = document.documentElement.getAttribute("lang"); | |
//Get browser language. | |
var browserLang = win.navigator.language; | |
if(browserLang && browserLang.indexOf(htmlLang) == 0) { | |
//If there is no conflict, the browser language should be more detailed. | |
langCode = browserLang; | |
} else { | |
//If there is a conflict, the HTML 'lang' attribute has advantage. | |
langCode = htmlLang; | |
} | |
//Not able to find the language code. | |
if(!langCode) langCode = ''; | |
} | |
return langCode.toLowerCase(); | |
}; | |
win.ext.isInFrame = function() { | |
return win.top !== win.self; | |
}; | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment