home *** CD-ROM | disk | FTP | other *** search
- if (typeof(Function.bind) == "undefined") {
- Function.prototype.bind = function(object) {
- var __ars = arguments, __me = this;
- return function(arguments) {
- arguments = [arguments];
- for (var i = 0, len = __ars.length; ++i < len;)
- arguments.push(__ars[i]);
- return __me.apply(object, arguments);
- }
- }
- }
-
- /** ================================================================================ **/
-
- function getNCRndStr() {
- return "ncrnd=" + (100000 + Math.floor(Math.random() * 899999));
- }
-
- /** ================================================================================ **/
- var G_Profiler = {
- add: function(aObject, aFunctionName) {
- var orig = aObject[aFunctionName];
-
- aObject[aFunctionName] = function() {
- let startTime = Date.now();
- let result = orig.apply(this, arguments);
-
- if (gYaSearchService)
- gYaSearchService.log("_profile_ [" + aFunctionName + "]: " + (Date.now() - startTime) + " msec.");
-
- return result;
- }
- }
- }
-
- /** ================================================================================ **/
-
- var G_DateUtils = {
- get releasedTime() {
- delete this.releasedTime;
-
- var versionStr = gYaSearchService.version;
- var versionDate = new Date(parseInt(versionStr.substr(0,4), 10),
- parseInt(versionStr.substr(4,2), 10) - 1,
- parseInt(versionStr.substr(6,2), 10)).getTime();
-
- this.releasedTime = versionDate > 0 ? versionDate : null;
-
- if (!this.releasedTime)
- gYaSearchService.log("Invalid nsIYaSearch::version value");
-
- return this.releasedTime;
- },
-
- _lastServerTimeUpdate: 0,
-
- get serverTime() {
- var res = gYaSearchService.getCharPref("yasearch.general.server.time");
- return Math.max(0, gYaSearchService.parseIntFromStr(res));
- },
-
- set serverTime(aValue) {
- if (aValue && aValue > this.releasedTime) {
- gYaSearchService.setCharPref("yasearch.general.server.time", aValue);
- this._lastServerTimeUpdate = Date.now();
- }
- },
-
- updateServerTimeValue: function(aResponse) {
- if (Math.abs(this._lastServerTimeUpdate - Date.now()) < DAY_SECS / 4)
- return;
-
- this.serverTime = this.getTimeFromHttpResponse(aResponse);
- },
-
- getTimeFromHttpResponse: function(aResponse, aValidate) {
- var result = this.getDateFromHttpResponse(aResponse, aValidate);
- return result ? result.getTime() : null;
- },
-
- getDateFromHttpResponse: function(aResponse, aValidate) {
- var result = null;
-
- try {
- var serverDate = new Date(aResponse.target.getResponseHeader("Date"));
-
- if (serverDate != "Invalid Date" && serverDate.getTime() > 0)
- serverDate = new Date(serverDate.getTime() +
- serverDate.getTimezoneOffset() * 60 * 1000 +
- 3 * 60 * 60 * 1000);
-
- if (serverDate != "Invalid Date" && serverDate.getTime() > 0)
- res = serverDate;
- } catch(e) {}
-
- return res;
- }
- }
-
- /** ================================================================================ **/
-
- var G_ObserverServiceWrapper = {
- _observerService: Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService),
-
- addObserver: function(aObject, aTopic) {
- return this._observerService.addObserver(aObject, aTopic, false);
- },
-
- removeObserver: function(aObject, aTopic) {
- return this._observerService.removeObserver(aObject, aTopic, false);
- }
- };
-
- /** ================================================================================ **/
-
- function G_Timer(aCallback, aDelay, aRepeating, aMaxTimes) {
- this.callback = aCallback;
- this.repeating = !!aRepeating;
-
- this.maxTimes = (typeof aMaxTimes == "number" && aMaxTimes > 0) ? aMaxTimes : null;
- this.timesCounter = 0;
-
- this.timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
- var type = aRepeating ? this.timer.TYPE_REPEATING_SLACK : this.timer.TYPE_ONE_SHOT;
-
- G_ObserverServiceWrapper.addObserver(this, "xpcom-shutdown");
-
- this.timer.initWithCallback(this, aDelay, type);
- }
-
- G_Timer.prototype = {
- observe: function(aSubject, aTopic, aData) {
- if (aTopic === "xpcom-shutdown")
- this.cancel();
- },
-
- cancel: function() {
- if (!this.timer)
- return;
-
- this.timer.cancel();
- this.timer = null;
- this.callback = null;
-
- G_ObserverServiceWrapper.removeObserver(this, "xpcom-shutdown");
- },
-
- notify: function(timer) {
- var result = this.callback();
-
- this.timesCounter++;
-
- if (!this.repeating || (this.maxTimes && this.timesCounter >= this.maxTimes))
- this.cancel();
-
- return result;
- },
-
- set delay(val) {
- if (this.timer)
- this.timer.delay = val;
- },
-
- QueryInterface: function(iid) {
- if (iid.equals(Ci.nsISupports) ||
- iid.equals(Ci.nsITimerCallback) ||
- iid.equals(Ci.nsIObserver))
- return this;
-
- throw Components.results.NS_ERROR_NO_INTERFACE;
- }
- }
-
- /** ================================================================================ **/
-
- function G_TimedHTTPRequester(aPrefName, aURL, aFileName, aResponseCallback,
- aResponseExpiredDays, aRequestExpiredMinutes) {
-
- G_ObserverServiceWrapper.addObserver(this, "profile-before-change");
-
- this.request = null;
- this.prefName = "yasearch.general.lastUpdate." + aPrefName;
- this.url = aURL;
- this.fileName = aFileName;
- this.callback = aResponseCallback;
- this.responseExpiredTime = DAY_SECS * (aResponseExpiredDays || 14);
- this.requestExpiredTime = MIN_SEC * (aRequestExpiredMinutes || 60);
-
- this.timer = new G_Timer(this.checkURL.bind(this), Math.floor(Math.random() * MIN_SEC * 10));
- }
-
- G_TimedHTTPRequester.prototype = {
- observe: function(aSubject, aTopic, aData) {
- if (aTopic === "profile-before-change")
- this.cancel();
- },
-
- cancel: function() {
- if (this.timer) {
- this.timer.cancel();
- this.timer = null;
- }
-
- if (this.request && this.request.channel.isPending())
- this.request.channel.cancel(Components.results.NS_BINDING_ABORTED);
-
- this.callback = null;
- },
-
- get prefArray() {
- var pref = (gYaSearchService.getCharPref(this.prefName) || "").split("|");
- return (pref.length == 2) ? pref : [0,0];
- },
-
- getFromPref: function(aType) {
- var res = 0;
-
- switch (aType) {
- case "request":
- res = this.prefArray[0];
- break;
- case "response":
- res = this.prefArray[1];
- break;
- }
-
- return (new Date(parseInt(res, 10))).valueOf() || 0;
- },
-
- putToPref: function(aType) {
- var pref = this.prefArray;
-
- switch (aType) {
- case "request":
- pref[0] = Date.now();
- break;
- case "response":
- pref[1] = Date.now();
- break;
- }
-
- gYaSearchService.setCharPref(this.prefName, pref.join("|"));
- },
-
- get requestTime() {
- return this.getFromPref("request");
- },
-
- set requestTime() {
- this.putToPref("request");
- return this.requestTime;
- },
-
- get responseTime() {
- return this.getFromPref("response");
- },
-
- set responseTime() {
- this.putToPref("response");
- return this.responseTime;
- },
-
- get isResponseGood() {
- return this.responseTime > (Date.now() - this.responseExpiredTime);
- },
-
- get isRequestGood() {
- return this.requestTime > (Date.now() - this.requestExpiredTime);
- },
-
- checkURL: function() {
- if (this.isResponseGood || this.isRequestGood)
- return;
-
- this.requestTime = true;
-
- if (this.isRequestGood !== true)
- return;
-
- this.request = gYaSearchService.xmlHttpRequest(this.url, { callbackFunc: this.checkURLCallback.bind(this) });
- },
-
- checkURLCallback: function(aReq) {
- if (!gYaSearchService.isReqError(aReq)) {
- this.responseTime = true;
-
- var callbackResult = this.callback(gYaSearchService.safeUnicode(aReq.target.responseText));
-
- if (callbackResult) {
- var file = gYaSearchService.getYandexDir();
- file.append(this.fileName);
-
- if (!file.exists() || !file.isFile()) {
- try {
- file.create(Ci.nsIFile.NORMAL_FILE_TYPE, 0755);
- } catch(e) {}
- }
-
- if (file.exists() && file.isFile() && file.isWritable())
- gYaSearchService.writeFile(file, callbackResult);
- }
- }
-
- this.request = null;
- },
-
- QueryInterface: function(iid) {
- if (iid.equals(Ci.nsISupports) ||
- iid.equals(Ci.nsIObserver))
- return this;
-
- throw Components.results.NS_ERROR_NO_INTERFACE;
- }
- }
-
- function G_HTTPFileWrapper(aFileName, aXMLRootTagName) {
- this.fileName = aFileName;
- this.xmlRootTagName = aXMLRootTagName || null;
- }
-
- G_HTTPFileWrapper.prototype = {
- getFile: function(aPlace) {
- var file = null;
-
- switch (aPlace) {
- case "saved":
- file = gYaSearchService.getYandexDir();
- break;
-
- case "default":
- file = gYaSearchService.getContentDir();
- file.append("services");
- break;
-
- default:
- throw new Error("G_HTTPFileWrapper.getFile() wrong arguments");
- }
-
- file.append(this.fileName);
-
- return file;
- },
-
- getFileContent: function(aPlace) {
- var file = this.getFile(aPlace);
- if (!(file && file.exists() && file.isFile() && file.isReadable()))
- return null;
-
- return gYaSearchService.safeE4Xml(gYaSearchService.readFile(file), null, this.xmlRootTagName);
- },
-
- get defaultContent() {
- return this.getFileContent("default");
- },
-
- get savedContent() {
- return this.getFileContent("saved");
- },
-
- get anyContent() {
- return this.savedContent || this.defaultContent;
- },
-
- get mergedContent() {
- var defaultContent = this.defaultContent;
- var savedContent = this.savedContent;
-
- if (!savedContent)
- return defaultContent;
-
- var savedRootTagName = savedContent.name().toString();
- var defaultRootTagName = defaultContent.name().toString();
-
- if (savedRootTagName !== defaultRootTagName)
- return defaultContent;
-
- for each (var tag in defaultContent.*) {
- var tagName = tag.name().toString();
-
- for each (var attrName in ["id", "name"]) {
- var attrValue = tag["@" + attrName].toString();
-
- if (attrValue && !savedContent[tagName].(function::attribute(attrName) == attrValue)[0]) {
- savedContent[tagName] += tag;
- break;
- }
- }
- }
-
- return savedContent[0] || defaultContent;
- }
- }
-
- /** ================================================================================ **/
- function G_HashTable() {
- this._hash = null;
- this.clear();
- }
-
- G_HashTable.prototype = {
- clear: function() {
- this._hash = {__proto__: null};
- },
-
- put: function(key, value) {
- this._hash[key] = value;
- },
-
- get: function(key) {
- return this._hash[key];
- },
-
- remove: function(key) {
- delete this._hash[key];
- },
-
- __iterator__: function() {
- for (let [key, value] in Iterator(this._hash))
- yield [key, value];
- },
-
- get keys() {
- let keys = [];
- for (let [key,] in this)
- keys.push(key);
- return keys;
- },
-
- get values() {
- let values = [];
- for (let [,value] in this)
- values.push(value);
- return values;
- }
- };
-
- /** ================================================================================ **/
-
- const gYaURLInfo = {
- _data: { __proto__: null },
-
- CY_STATE_UNKNOWN: 1,
- CY_STATE_REQUEST: 2,
- CY_STATE_ERROR: 4,
- CY_STATE_RESPONSE: 8,
-
- BLOGGERS_STATE_UNKNOWN: 1,
- BLOGGERS_STATE_TIMED_REQUEST: 2,
- BLOGGERS_STATE_REQUEST: 4,
- BLOGGERS_STATE_ERROR: 8,
- BLOGGERS_STATE_RESPONSE: 16,
-
- getURL: function(aURI) {
- if (typeof(aURI) == "string")
- aURI = gYaSearchService.makeURI(aURI);
-
- if (aURI) {
- try {
- if (/^https?$/.test(aURI.scheme) && aURI.host.length > 3) {
- return {
- prePath: aURI.prePath.replace(/(:\/\/)(.+@)/, "$1"),
- path: aURI.path,
- nonQueryPath: aURI.path.split(/\?|#/)[0],
- toString: function() {
- return this.prePath + this.path;
- }
- };
- }
- } catch(e) {}
- }
-
- return null;
- },
-
- clear: function() {
- this._data = { __proto__: null };
- },
-
- _cleanupTimer: (function() {
- let cleanup = {
- notify: function() {
- if (!gYaURLInfo)
- return;
-
- let data = gYaURLInfo._data,
- minAccessTime = Date.now() - (MIN_SEC * 60);
-
- for (let prop in data)
- if (data[prop]._lastAccessTime < minAccessTime)
- delete data[prop];
- }
- };
-
- let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
- timer.initWithCallback(cleanup, MIN_SEC * 60, Ci.nsITimer.TYPE_REPEATING_SLACK);
- return timer;
- })(),
-
- _setupData: function(aURL) {
- let url = this.getURL(aURL);
- if (!url)
- return [];
-
- if (!this._data[url.prePath]) {
- this._data[url.prePath] = {
- bloggers: { __proto__: null },
- cy: { __proto__: null }
- }
- }
-
- let data = this._data[url.prePath];
- data._lastAccessTime = Date.now();
-
- return [url, data];
- },
-
- getCYAndBloggers: function(aURL) {
- let [url, data] = this._setupData(aURL);
- if (!(url && data))
- return [];
-
- return [data.cy[url.path], data.bloggers[url.nonQueryPath] || null];
- },
-
- getBloggers: function(aURL) {
- let [url, data] = this._setupData(aURL);
- if (!(url && data))
- return;
-
- return data.bloggers[url.nonQueryPath] || null;
- },
-
- setBloggers: function(aURL, aData) {
- let [url, data] = this._setupData(aURL);
- if (!(url && data))
- return;
-
- if (!data.bloggers[url.nonQueryPath]) {
- data.bloggers[url.nonQueryPath] = {
- url: url.prePath + url.nonQueryPath,
- windowState: this.BLOGGERS_STATE_UNKNOWN,
- buttonState: this.BLOGGERS_STATE_UNKNOWN,
- content: null,
- value: 0,
- manual: false
- }
- }
-
- let bloggersData = data.bloggers[url.nonQueryPath];
- if (aData) {
- for (var [propName, propValue] in Iterator(aData)) {
- bloggersData[propName] = propValue;
- }
- }
-
- return bloggersData;
- },
-
- getCY: function(aURL) {
- let [url, data] = this._setupData(aURL);
- if (!(url && data))
- return;
-
- return data.cy[url.path];
- },
-
- setCY: function(aURL, aData) {
- let [url, data] = this._setupData(aURL);
- if (!(url && data))
- return;
-
- if (!data.cy[url.path]) {
- data.cy[url.path] = {
- state: this.CY_STATE_UNKNOWN,
- theme: "",
- domain: "",
- region: "",
- rang: 0,
- value: 0,
- spam: null,
- post: false,
- original: null,
- referrer: null
- }
- }
-
- let cyData = data.cy[url.path];
- if (aData) {
- for (var [propName, propValue] in Iterator(aData)) {
- cyData[propName] = propValue;
- }
- }
-
- return cyData;
- },
-
- _dnsCache: {
- MAX_CACHED_COUNT: 100,
-
- _cached: [],
-
- clear: function() {
- this._cached = [];
- },
-
- put: function(aHost, aData) {
- let cached = {
- host: aHost,
- data: aData
- };
-
- if (this._cached.unshift(cached) > this.MAX_CACHED_COUNT)
- this._cached.splice(-this.MAX_CACHED_COUNT/2);
- },
-
- get: function(aHost) {
- let cached;
-
- this._cached.some(function(aRecord) {
- return (aHost === aRecord.host) && (cached = aRecord.data);
- });
-
- return cached;
- }
- },
-
- asyncGetIPsForURL: function(aURL, aCallback) {
- let cachedData;
-
- let uri = gYaSearchService.makeURI(aURL);
- if (uri && /^https?$/.test(uri.scheme) && uri.host.length > 3) {
-
- cachedData = this._dnsCache.get(uri.host);
-
- if (!cachedData) {
- try {
- const dnsService = Cc["@mozilla.org/network/dns-service;1"].getService(Ci.nsIDNSService);
-
- let dnsListener = new this.DNSListener(uri.host, aCallback);
- dnsService.asyncResolve(uri.host, 0, dnsListener, this._currentThread);
- return;
-
- } catch (e) {}
- }
- }
-
- if (aCallback)
- aCallback(cachedData);
- },
-
- get _currentThread() {
- delete this._currentThread;
-
- const threadManager = Cc["@mozilla.org/thread-manager;1"].getService();
- this.__defineGetter__("_currentThread", function() { return threadManager.currentThread; });
-
- return this._currentThread;
- },
-
- get DNSListener() {
- function DNSListener(aHost, aCallback) {
- this.host = aHost;
- this.callback = aCallback;
- }
-
- DNSListener.prototype = {
- host: null,
- callback: null,
-
- onLookupComplete: function(aRequest, aRecord, aStatus) {
- let ip = [];
-
- if (aStatus == 0 && aRecord) {
- while (aRecord.hasMore())
- ip.push(aRecord.getNextAddrAsString());
- }
-
- if (ip.length)
- gYaURLInfo._dnsCache.put(this.host, ip);
-
- if (this.callback)
- this.callback(ip);
- },
-
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIDNSListener, Ci.nsISupports])
- }
-
- delete this.DNSListener;
- return (this.DNSListener = DNSListener);
- }
- };