[Pkg-mozext-commits] [itsalltext] 249/459: Restructuring to try to minimize memory leaks.
David Prévot
taffit at moszumanska.debian.org
Tue Feb 24 23:26:26 UTC 2015
This is an automated email from the git hooks/post-receive script.
taffit pushed a commit to branch master
in repository itsalltext.
commit fbb2f2fa6d75c9a536942a1a65085a6a7c7b04fc
Author: docwhat at gerf.org <docwhat at gerf.org>
Date: Wed Jun 20 11:27:55 2007 -0400
Restructuring to try to minimize memory leaks.
---
Makefile | 8 +-
src/chrome/content/Color.js | 2 +-
src/chrome/content/cacheobj.js | 45 +++++++-
src/chrome/content/itsalltext.js | 228 ++++++++++++++++++++++-----------------
4 files changed, 175 insertions(+), 108 deletions(-)
diff --git a/Makefile b/Makefile
index 95d8b73..0aad221 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
#
# It's All Text - Easy external editing of web forms.
-# Copyright (C) 2006 Christian Höltje
+# Copyright (C) 2006-2007 Christian Höltje
#
# 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
@@ -105,13 +105,15 @@ lint: $(SOURCES_JS_LINT)
$(SOURCES_JS_LINT): lint/%.js.lint: %.js
$(Q)mkdir -p $(dir $@)
- $(Q)$(JSLINT) -p $< > $@
+ $(Q)perl -p -e 's/^(\s*)const(\s+)/$$1var$$2/' $< > $@.pre
+ $(Q)$(JSLINT) -p $@.pre > $@
$(Q)if [ `wc -l $@|cut -d' ' -f1` -ne 1 ]; then\
touch --date='1972-01-01' "$@"; echo "lint: $@"; false; fi
.PHONY: showlint
showlint:
- $(Q)$(QMAKE) lint || find ./lint -type f -print0 | xargs -0 cat | egrep -v '^jslint: No problems found in' || :
+ $(Q)$(QMAKE) -k lint || :
+ $(Q)find ./lint -type f -name '*.lint' -print0 | xargs -0 cat | egrep -v '^jslint: No problems found in'
##
## Narf is a magick keyword that should stop builds from working
diff --git a/src/chrome/content/Color.js b/src/chrome/content/Color.js
index 1426f1d..33023c6 100644
--- a/src/chrome/content/Color.js
+++ b/src/chrome/content/Color.js
@@ -221,7 +221,7 @@ var Color = function() {
this.green = clamp(Math.round(parseInt(components[2],base) * m), 0, 255);
this.blue = clamp(Math.round(parseInt(components[3],base) * m), 0, 255);
- if (isNaN(components[4])) {
+ if (typeof(components[4]) === 'undefined' || isNaN(components[4])) {
this.alpha = 1;
} else {
this.alpha = clamp(parseFloat("0" + components[4]), 0.0, 1.0);
diff --git a/src/chrome/content/cacheobj.js b/src/chrome/content/cacheobj.js
index 1f5a1ce..3671a7e 100644
--- a/src/chrome/content/cacheobj.js
+++ b/src/chrome/content/cacheobj.js
@@ -1,3 +1,24 @@
+/*
+ * It's All Text - Easy external editing of web forms.
+ * Copyright (C) 2006-2007 Christian Höltje
+ *
+ * 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 2 of the License or
+ * 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, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+/*jslint nomen: true, evil: false, browser: true */
+
/**
* A Cache object is used to manage the node and the file behind it.
* @constructor
@@ -18,7 +39,7 @@ function CacheObj(node) {
that.node = node;
that.button = null;
that.initial_background = '';
- that._is_watching = false;
+ that.private_is_watching = false;
that.node_id = that.getNodeIdentifier(node);
var doc = node.ownerDocument;
@@ -91,6 +112,22 @@ function CacheObj(node) {
}
/**
+ * Destroys the object, unallocating as much as possible to prevent leaks.
+ */
+CacheObj.prototype.destroy = function() {
+ ItsAllText.debug('destroying %o',this);
+ var node = this.node;
+ var doc = this.node.ownerDocument;
+ var html = doc.getElementsByTagName('html')[0];
+
+ node.removeAttribute(ItsAllText.MYSTRING+'_UID');
+ html.removeAttribute(ItsAllText.MYSTRING+'_id_serial');
+
+ delete this.node;
+ delete this.button;
+};
+
+/**
* Set the extension for the file to ext.
* @param {String} ext The extension. Must include the dot. Example: .txt
*/
@@ -137,7 +174,7 @@ CacheObj.prototype.initFromExistingFile = function() {
}
if (ext !== null) {
this.setExtension(ext);
- this._is_watching = true;
+ this.private_is_watching = true;
}
};
@@ -264,7 +301,7 @@ CacheObj.prototype.edit = function(extension) {
args = [filename];
result = {};
ec = process.run(false, args, args.length, result);
- this._is_watching = true;
+ this.private_is_watching = true;
} catch(e) {
params = {out:null,
exists: program ? program.exists() : false,
@@ -340,7 +377,7 @@ CacheObj.prototype.read = function() {
*/
CacheObj.prototype.hasChanged = function() {
/* Check exists. Check ts and size. */
- if(!this._is_watching ||
+ if(!this.private_is_watching ||
!this.file.exists() ||
!this.file.isReadable() ||
(this.file.lastModifiedTime == this.timestamp &&
diff --git a/src/chrome/content/itsalltext.js b/src/chrome/content/itsalltext.js
index 9eaa422..523ebeb 100644
--- a/src/chrome/content/itsalltext.js
+++ b/src/chrome/content/itsalltext.js
@@ -1,6 +1,6 @@
/*
* It's All Text - Easy external editing of web forms.
- * Copyright 2006 Christian Höltje
+ * Copyright (C) 2006-2007 Christian Höltje
*
* 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
@@ -17,6 +17,8 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
+/*jslint nomen: true, evil: false, browser: true */
+
// @todo [9] IDEA: dropdown list for charsets (utf-8, western-iso, default)?
// @todo [3] Have a menu/context menu item for turning on monitoring/watch.
// @todo [9] Menu item to pick the file to load into a textarea.
@@ -66,14 +68,6 @@ var ItsAllText = function() {
/* The XUL Namespace */
that.XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
-
- var string_bundle = Components.classes["@mozilla.org/intl/stringbundle;1"].
- getService(Components.interfaces.nsIStringBundleService);
- /**
- * A localization bundle. Use it like so:
- * ItsAllText.locale.getStringFromName('blah');
- */
- that.locale = string_bundle.createBundle("chrome://itsalltext/locale/itsalltext.properties");
/**
* Formats a locale string, replacing $N with the arguments in arr.
* @param {String} name Locale property name
@@ -81,7 +75,7 @@ var ItsAllText = function() {
* @returns String
*/
that.localeFormat = function(name, arr) {
- return this.locale.formatStringFromName(name, arr, arr.length);
+ return this.getLocale().formatStringFromName(name, arr, arr.length);
};
/**
* Returns the locale string matching name.
@@ -89,7 +83,7 @@ var ItsAllText = function() {
* @returns String
*/
that.localeString = function(name) {
- return this.locale.GetStringFromName(name);
+ return this.getLocale().GetStringFromName(name);
};
/**
@@ -117,12 +111,12 @@ var ItsAllText = function() {
*/
that.log = function() {
var message = that.logString.apply(that, arguments);
- var consoleService, e;
+ var e;
+ const consoleService = Components.
+ classes["@mozilla.org/consoleservice;1"].
+ getService(Components.interfaces.nsIConsoleService);
try {
// idiom: Convert arguments to an array for easy handling.
- consoleService = Components.
- classes["@mozilla.org/consoleservice;1"].
- getService(Components.interfaces.nsIConsoleService);
consoleService.logStringMessage(message);
} catch(e) {
Components.utils.reportError(message);
@@ -160,7 +154,7 @@ var ItsAllText = function() {
* @returns {nsILocalFile}
*/
that.factoryFile = function(path) {
- var file = Components.
+ const file = Components.
classes["@mozilla.org/file/local;1"].
createInstance(Components.interfaces.nsILocalFile);
if (typeof(path) == 'string' && path !== '') {
@@ -175,7 +169,7 @@ var ItsAllText = function() {
*/
that.getEditDir = function() {
/* Where is the directory that we use. */
- var fobj = Components.classes["@mozilla.org/file/directory_service;1"].
+ const fobj = Components.classes["@mozilla.org/file/directory_service;1"].
getService(Components.interfaces.nsIProperties).
get("ProfD", Components.interfaces.nsIFile);
fobj.append(that.MYSTRING);
@@ -189,35 +183,16 @@ var ItsAllText = function() {
return fobj;
};
- /**
- * Cleans out the edit directory, deleting all old files.
- */
- that.cleanEditDir = function(force) {
- force = (force && typeof(force) != 'undefined');
- var last_week = Date.now() - (1000*60*60*24*7);
- var fobj = that.getEditDir();
- var entries = fobj.directoryEntries;
- var entry;
- while (entries.hasMoreElements()) {
- entry = entries.getNext();
- entry.QueryInterface(Components.interfaces.nsIFile);
- if(force || !entry.exists() || entry.lastModifiedTime < last_week){
- try{
- entry.remove(false);
- } catch(e) {
- that.debug('unable to remove',entry,'because:',e);
- }
- }
- }
- };
-
/* Clean the edit directory whenever we create a new window. */
that.cleanEditDir();
- /* Load the various bits needed to make this work. */
- var loader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"].getService(Components.interfaces.mozIJSSubScriptLoader);
- loader.loadSubScript('chrome://itsalltext/content/Color.js', that);
- loader.loadSubScript('chrome://itsalltext/content/cacheobj.js', that);
+ var loadthings = function() {
+ /* Load the various bits needed to make this work. */
+ const loader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"].getService(Components.interfaces.mozIJSSubScriptLoader);
+ loader.loadSubScript('chrome://itsalltext/content/Color.js', that);
+ loader.loadSubScript('chrome://itsalltext/content/cacheobj.js', that);
+ };
+ loadthings();
/**
* Dictionary for storing the preferences in.
@@ -232,9 +207,9 @@ var ItsAllText = function() {
* @param {String} aData The name of the pref to fetch.
* @returns {Object} The value of the preference.
*/
- _get: function(aData) {
+ private_get: function(aData) {
var po = that.preference_observer;
- return po._branch['get'+(po.types[aData])+'Pref'](aData);
+ return po.private_branch['get'+(po.types[aData])+'Pref'](aData);
},
/**
@@ -242,9 +217,9 @@ var ItsAllText = function() {
* @param {String} aData The name of the pref to change.
* @param {Object} value The value to set.
*/
- _set: function(aData, value) {
+ private_set: function(aData, value) {
var po = that.preference_observer;
- return po._branch['set'+(po.types[aData])+'Pref'](aData, value);
+ return po.private_branch['set'+(po.types[aData])+'Pref'](aData, value);
}
};
@@ -270,15 +245,15 @@ var ItsAllText = function() {
* Register the observer.
*/
register: function() {
- var prefService = Components.
+ const prefService = Components.
classes["@mozilla.org/preferences-service;1"].
getService(Components.interfaces.nsIPrefService);
- this._branch = prefService.getBranch("extensions."+that.MYSTRING+".");
- this._branch.QueryInterface(Components.interfaces.nsIPrefBranch2);
- this._branch.addObserver("", this, false);
+ this.private_branch = prefService.getBranch("extensions."+that.MYSTRING+".");
+ this.private_branch.QueryInterface(Components.interfaces.nsIPrefBranch2);
+ this.private_branch.addObserver("", this, false);
/* setup the preferences */
for(var type in this.types) {
- that.preferences[type] = that.preferences._get(type);
+ that.preferences[type] = that.preferences.private_get(type);
}
},
@@ -287,8 +262,8 @@ var ItsAllText = function() {
* useful in the future.
*/
unregister: function() {
- if (!this._branch) {return;}
- this._branch.removeObserver("", this);
+ if (!this.private_branch) {return;}
+ this.private_branch.removeObserver("", this);
},
/**
@@ -300,7 +275,7 @@ var ItsAllText = function() {
observe: function(aSubject, aTopic, aData) {
if (aTopic != "nsPref:changed") {return;}
if (that.preferences) {
- that.preferences[aData] = that.preferences._get(aData);
+ that.preferences[aData] = that.preferences.private_get(aData);
if (aData == 'refresh') {
that.monitor.restart();
}
@@ -340,10 +315,10 @@ var ItsAllText = function() {
http://developer.mozilla.org/en/docs/Code_snippets:Miscellaneous#Operating_system_detection
*/
- var is_darwin = that._is_darwin;
+ var is_darwin = that.private_is_darwin;
if (typeof(is_darwin) == 'undefined') {
is_darwin = /^Darwin/i.test(Components.classes["@mozilla.org/xre/app-info;1"].getService(Components.interfaces.nsIXULRuntime).OS);
- that._is_darwin = is_darwin;
+ that.private_is_darwin = is_darwin;
}
return is_darwin;
};
@@ -364,7 +339,7 @@ var ItsAllText = function() {
if (editor === '' && that.isDarwin()) {
editor = '/usr/bin/open';
- that.preferences._set('editor', editor);
+ that.preferences.private_set('editor', editor);
}
if (editor !== '') {
@@ -416,7 +391,7 @@ var ItsAllText = function() {
var instantApply = getBoolPref("browser.preferences.instantApply", false) && !wait;
var features = "chrome,titlebar,toolbar,centerscreen" + (instantApply ? ",dialog=no" : ",modal");
- var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"].getService(Components.interfaces.nsIWindowMediator);
+ const wm = Components.classes["@mozilla.org/appshell/window-mediator;1"].getService(Components.interfaces.nsIWindowMediator);
var win = wm.getMostRecentWindow("Browser:Preferences");
var pane;
if (win) {
@@ -450,7 +425,7 @@ var ItsAllText = function() {
} else {
value = [value,',',ext].join('');
}
- that.preferences._set('extensions', value);
+ that.preferences.private_set('extensions', value);
};
// @todo [3] Profiling and optimization.
@@ -481,14 +456,16 @@ var ItsAllText = function() {
* Cleans out all old cache objects.
*/
that.cleanCacheObjs = function() {
+ doc = typeof(doc) === 'undefined'?null:doc;
var count = 0;
- var cobj, id;
+ var cobj, id, cdoc;
for(id in that.tracker) {
cobj = that.tracker[id];
- if (cobj.node.ownerDocument.location === null) {
- that.debug('cleaning %s', id);
- delete cobj.node;
- delete cobj.button;
+ cdoc = cobj.node.ownerDocument;
+ if (!cdoc.defaultView || !cdoc.location) {
+ cobj.destroy();
+ cdoc = null;
+ delete cobj;
delete that.tracker[id];
} else {
count += 1;
@@ -617,13 +594,13 @@ var ItsAllText = function() {
/* Walk the documents looking for changes */
var documents = monitor.documents;
- that.debuglog('monitor.watcher(',offset,'): ', documents.length);
+ //that.debuglog('monitor.watcher(',offset,'): ', documents.length);
var i, doc;
var did_delete = false;
for(i in documents) {
doc = documents[i];
if (doc.location) {
- that.debuglog('refreshing', doc.location);
+ //that.debuglog('refreshing', doc.location);
that.refreshDocument(doc);
}
}
@@ -712,49 +689,44 @@ var ItsAllText = function() {
browser.selectedTab = browser.addTab(that.README, null);
};
- /**
- * Initialize the module. Should be called once, when a window is loaded.
- * @private
- */
- var windowload = function(event) {
- that.debug("startup(): It's All Text! is watching this window...");
-
- // Start watching the preferences.
- that.preference_observer.register();
-
- // Start the monitor
- that.monitor.restart();
-
- var appcontent = document.getElementById("appcontent"); // The Browser
- if (appcontent) {
- // Normal web-page.
- appcontent.addEventListener("DOMContentLoaded", that.onDOMContentLoad,
- true);
- } else {
- that.onDOMContentLoad(event);
- }
- // Attach the context menu, if we can.
- var contentAreaContextMenu = document.getElementById("contentAreaContextMenu");
- if (contentAreaContextMenu) {
- contentAreaContextMenu.addEventListener("popupshowing",
- that.onContextMenu, false);
- }
- };
// Do the startup when things are loaded.
- window.addEventListener("load", windowload, true);
+ window.addEventListener("load", function(event){that.pageload(event);}, true);
// Do the startup when things are unloaded.
- window.addEventListener("unload", function(event){that.monitor.unwatch(event.originalTarget||document); that.preference_observer.unregister();}, true);
+ window.addEventListener("unload", function(event){that.pageunload(event);}, true);
+
+};
+/**
+ * Cleans out the edit directory, deleting all old files.
+ */
+ItsAllText.prototype.cleanEditDir = function(force) {
+ force = typeof(force) === 'boolean'?force:false;
+ var last_week = Date.now() - (1000*60*60*24*7);
+ var fobj = this.getEditDir();
+ var entries = fobj.directoryEntries;
+ var entry;
+ while (entries.hasMoreElements()) {
+ entry = entries.getNext();
+ entry.QueryInterface(Components.interfaces.nsIFile);
+ if(force || !entry.exists() || entry.lastModifiedTime < last_week){
+ try{
+ entry.remove(false);
+ } catch(e) {
+ this.debug('unable to remove',entry,'because:',e);
+ }
+ }
+ }
};
+
/**
* The command that is called when picking a new extension.
* @param {Event} event
*/
ItsAllText.prototype.menuNewExtEdit = function(event) {
var that = this;
- var uid = this._current_uid;
+ var uid = this.private_current_uid;
var cobj = that.getCacheObj(uid);
var params = {out:null};
@@ -776,7 +748,7 @@ ItsAllText.prototype.menuNewExtEdit = function(event) {
*/
ItsAllText.prototype.menuExtEdit = function(event) {
var that = this;
- var uid = that._current_uid;
+ var uid = that.private_current_uid;
var ext = event.target.getAttribute('label');
var cobj = that.getCacheObj(uid);
cobj.edit(ext);
@@ -797,7 +769,7 @@ ItsAllText.prototype.rebuildMenu = function(uid, menu_id, is_disabled) {
var items = menu.childNodes;
var items_length = items.length - 1; /* We ignore the preferences item */
var node;
- that._current_uid = uid;
+ that.private_current_uid = uid;
var magic_stop_node = null;
var magic_start = null;
var magic_stop = null;
@@ -834,5 +806,61 @@ ItsAllText.prototype.rebuildMenu = function(uid, menu_id, is_disabled) {
return menu;
};
+/**
+ * Returns the locale object for translation.
+ */
+ItsAllText.prototype.getLocale = function() {
+ const string_bundle = Components.classes["@mozilla.org/intl/stringbundle;1"].
+ getService(Components.interfaces.nsIStringBundleService);
+ /**
+ * A localization bundle. Use it like so:
+ * ItsAllText.locale.getStringFromName('blah');
+ */
+ return string_bundle.createBundle("chrome://itsalltext/locale/itsalltext.properties");
+};
+
+/**
+ * Initialize the module. Should be called once, when a window is loaded.
+ * @private
+ */
+ItsAllText.prototype.pageload = function(event) {
+ var doc = event.originalTarget || document;
+ this.debug("pageload(): A page has been loaded");
+
+ // Start watching the preferences.
+ this.preference_observer.register();
+
+ // Start the monitor
+ this.monitor.restart();
+
+ var appcontent = document.getElementById("appcontent"); // The Browser
+ if (appcontent) {
+ // Normal web-page.
+ appcontent.addEventListener("DOMContentLoaded", this.onDOMContentLoad,
+ true);
+ } else {
+ this.onDOMContentLoad(event);
+ }
+ // Attach the context menu, if we can.
+ var contentAreaContextMenu = doc.getElementById("contentAreaContextMenu");
+ if (contentAreaContextMenu) {
+ contentAreaContextMenu.addEventListener("popupshowing",
+ this.onContextMenu, false);
+ }
+};
+
+/**
+ * Uninitialize the module. Should be called once, when a window is unloaded.
+ * @private
+ */
+ItsAllText.prototype.pageunload = function(event) {
+ var doc = event.originalTarget||document;
+ this.debug("pageunload(): A page has been unloaded");
+ this.monitor.unwatch(doc);
+ this.preference_observer.unregister();
+ this.cleanCacheObjs();
+};
+
+
ItsAllText = new ItsAllText();
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-mozext/itsalltext.git
More information about the Pkg-mozext-commits
mailing list