Skip to content

Instantly share code, notes, and snippets.

@quietlynn
Created January 28, 2012 12:52
Show Gist options
  • Save quietlynn/1694195 to your computer and use it in GitHub Desktop.
Save quietlynn/1694195 to your computer and use it in GitHub Desktop.
[DEPRECATED] Google+ Toolkit
/*
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