mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-01-28 00:07:28 +00:00
Moved Ben's JavaScript ASSERT function to be NS_ASSERT in
toolkit/content/debug.js debug.js is now included by globalOverlay.js, but if that's not in your scope you can just #include debug.js directly. NS_ASSERT() shows a dialog box containing a stack trace when it's called with a condition that isn't true. The dialog box will be suppressed in final builds, but in nightlies and alphas, it's useful for encouraging bug submissions. To disable the dialogs, set XUL_ASSERT_PROMPT=0 in your environment. bug=327349 r=darin@meer.net, gavin.sharp@gmail.com
This commit is contained in:
parent
269cc93d64
commit
bd7b62fd23
@ -6283,14 +6283,14 @@ var BrowserController = {
|
||||
|
||||
isCommandEnabled: function BC_isCommandEnabled(command) {
|
||||
//LOG("BrowserController.isCommandEnabled: " + command);
|
||||
ASSERT(this.supportsCommand(command),
|
||||
NS_ASSERT(this.supportsCommand(command),
|
||||
"Controller does not support: " + command);
|
||||
return this.commands[command].enabled;
|
||||
},
|
||||
|
||||
doCommand: function BC_doCommand(command) {
|
||||
//LOG("BrowserController.doCommand: " + command);
|
||||
ASSERT(this.supportsCommand(command),
|
||||
NS_ASSERT(this.supportsCommand(command),
|
||||
"Controller does not support: " + command);
|
||||
this.commands[command].execute();
|
||||
},
|
||||
|
@ -46,4 +46,3 @@ include $(DEPTH)/config/autoconf.mk
|
||||
DIRS = public src
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
|
@ -36,6 +36,7 @@
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include controller.js
|
||||
#include ../../../../toolkit/content/debug.js
|
||||
|
||||
var BookmarkPropertiesPanel = {
|
||||
|
||||
@ -195,7 +196,7 @@ var BookmarkPropertiesPanel = {
|
||||
* receive a string instead of an nsIURI object.
|
||||
*/
|
||||
_assertURINotString: function BPP__assertURINotString(value) {
|
||||
ASSERT((typeof(value) == "object") && !(value instanceof String),
|
||||
NS_ASSERT((typeof(value) == "object") && !(value instanceof String),
|
||||
"This method should be passed a URI as a nsIURI object, not as a string.");
|
||||
},
|
||||
|
||||
@ -369,7 +370,7 @@ var BookmarkPropertiesPanel = {
|
||||
*/
|
||||
_populateTags:
|
||||
function BPP__populateTags (container, depth, parentElement, elementDict) {
|
||||
ASSERT(container.containerOpen, "The containerOpen property of the container parameter should be set to true before calling populateTags(), and then set to false again afterwards.");
|
||||
NS_ASSERT(container.containerOpen, "The containerOpen property of the container parameter should be set to true before calling populateTags(), and then set to false again afterwards.");
|
||||
|
||||
var row = null;
|
||||
for (var i = 0; i < container.childCount; i++) {
|
||||
|
@ -39,39 +39,6 @@ function LOG(str) {
|
||||
dump("*** " + str + "\n");
|
||||
}
|
||||
|
||||
var gTraceOnAssert = true;
|
||||
|
||||
// XXXben - develop this further into a multi-purpose assertion system.
|
||||
function ASSERT(condition, message) {
|
||||
if (!condition) {
|
||||
var caller = arguments.callee.caller;
|
||||
var str = "ASSERT: ";
|
||||
str += message;
|
||||
LOG(str);
|
||||
var assertionText = str + "\n";
|
||||
|
||||
var stackText = "Stack Trace: \n";
|
||||
if (gTraceOnAssert) {
|
||||
var count = 0;
|
||||
while (caller) {
|
||||
stackText += count++ + ":" + caller.name + "(";
|
||||
for (var i = 0; i < caller.arguments.length; ++i) {
|
||||
var arg = caller.arguments[i];
|
||||
stackText += arg;
|
||||
if (i < caller.arguments.length - 1)
|
||||
stackText += ",";
|
||||
}
|
||||
stackText += ")\n";
|
||||
caller = caller.arguments.callee.caller;
|
||||
}
|
||||
}
|
||||
var ps =
|
||||
Cc["@mozilla.org/embedcomp/prompt-service;1"].
|
||||
getService(Ci.nsIPromptService);
|
||||
ps.alert(window, "Assertion Failed", assertionText + stackText);
|
||||
}
|
||||
}
|
||||
|
||||
const Ci = Components.interfaces;
|
||||
const Cc = Components.classes;
|
||||
const Cr = Components.results;
|
||||
@ -247,7 +214,7 @@ function QI_node(node, iid) {
|
||||
}
|
||||
catch (e) {
|
||||
}
|
||||
ASSERT(result, "Node QI Failed");
|
||||
NS_ASSERT(result, "Node QI Failed");
|
||||
return result;
|
||||
}
|
||||
function asFolder(node) { return QI_node(node, Ci.nsINavHistoryFolderResultNode); }
|
||||
@ -473,7 +440,7 @@ var PlacesController = {
|
||||
* false otherwise.
|
||||
*/
|
||||
_hasRemovableSelection: function PC__hasRemovableSelection() {
|
||||
ASSERT(this._activeView, "No active view - cannot paste!");
|
||||
NS_ASSERT(this._activeView, "No active view - cannot paste!");
|
||||
if (!this._activeView)
|
||||
return false;
|
||||
var nodes = this._activeView.getSelectionNodes();
|
||||
@ -514,7 +481,7 @@ var PlacesController = {
|
||||
* Determines whether or not nodes can be inserted relative to the selection.
|
||||
*/
|
||||
_canInsert: function PC__canInsert() {
|
||||
ASSERT(this._activeView, "No active view - cannot insert!");
|
||||
NS_ASSERT(this._activeView, "No active view - cannot insert!");
|
||||
if (!this._activeView)
|
||||
return false;
|
||||
var nodes = this._activeView.getSelectionNodes();
|
||||
@ -543,7 +510,7 @@ var PlacesController = {
|
||||
* @returns true if the node is a Bookmark folder, false otherwise
|
||||
*/
|
||||
nodeIsFolder: function PC_nodeIsFolder(node) {
|
||||
ASSERT(node, "null node");
|
||||
NS_ASSERT(node, "null node");
|
||||
return (node.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_FOLDER);
|
||||
},
|
||||
|
||||
@ -554,7 +521,7 @@ var PlacesController = {
|
||||
* @returns true if the node is a Bookmark separator, false otherwise
|
||||
*/
|
||||
nodeIsSeparator: function PC_nodeIsSeparator(node) {
|
||||
ASSERT(node, "null node");
|
||||
NS_ASSERT(node, "null node");
|
||||
return (node.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_SEPARATOR);
|
||||
},
|
||||
|
||||
@ -565,7 +532,7 @@ var PlacesController = {
|
||||
* @returns true if the node is a URL item, false otherwise
|
||||
*/
|
||||
nodeIsURI: function PC_nodeIsURI(node) {
|
||||
ASSERT(node, "null node");
|
||||
NS_ASSERT(node, "null node");
|
||||
const NHRN = Ci.nsINavHistoryResultNode;
|
||||
return node.type == NHRN.RESULT_TYPE_URI ||
|
||||
node.type == NHRN.RESULT_TYPE_VISIT ||
|
||||
@ -579,7 +546,7 @@ var PlacesController = {
|
||||
* @returns true if the node is a Query item, false otherwise
|
||||
*/
|
||||
nodeIsQuery: function PC_nodeIsQuery(node) {
|
||||
ASSERT(node, "null node");
|
||||
NS_ASSERT(node, "null node");
|
||||
return node.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_QUERY;
|
||||
},
|
||||
|
||||
@ -591,7 +558,7 @@ var PlacesController = {
|
||||
* @returns true if the node is readonly, false otherwise
|
||||
*/
|
||||
nodeIsReadOnly: function PC_nodeIsReadOnly(node) {
|
||||
ASSERT(node, "null node");
|
||||
NS_ASSERT(node, "null node");
|
||||
if (this.nodeIsFolder(node))
|
||||
return this.bookmarks.getFolderReadonly(asFolder(node).folderId);
|
||||
else if (this.nodeIsQuery(node))
|
||||
@ -827,7 +794,7 @@ var PlacesController = {
|
||||
* receive a string instead of an nsIURI object.
|
||||
*/
|
||||
_assertURINotString: function PC__assertURINotString(value) {
|
||||
ASSERT((typeof(value) == "object") && !(value instanceof String),
|
||||
NS_ASSERT((typeof(value) == "object") && !(value instanceof String),
|
||||
"This method should be passed a URI as a nsIURI object, not as a string.");
|
||||
},
|
||||
|
||||
@ -873,7 +840,7 @@ var PlacesController = {
|
||||
changeBookmarkURI: function PC_changeBookmarkProperties(oldURI, newURI) {
|
||||
this._assertURINotString(oldURI);
|
||||
this._assertURINotString(newURI);
|
||||
ASSERT(this.bookmarks.isBookmarked(oldURI));
|
||||
NS_ASSERT(this.bookmarks.isBookmarked(oldURI));
|
||||
|
||||
if (oldURI.spec == newURI.spec)
|
||||
return;
|
||||
@ -972,7 +939,7 @@ var PlacesController = {
|
||||
* The sorting mode to be applied to the displayed contents.
|
||||
*/
|
||||
loadNodeIntoView: function PC_loadQueries(view, node, groupings, sortingMode) {
|
||||
ASSERT(view, "Must have a view to load node contents into!");
|
||||
NS_ASSERT(view, "Must have a view to load node contents into!");
|
||||
asQuery(node);
|
||||
var queries = node.getQueries({ });
|
||||
var newQueries = [];
|
||||
@ -1061,7 +1028,7 @@ var PlacesController = {
|
||||
*/
|
||||
groupByAnnotation:
|
||||
function PC_groupByAnnotation(annotation, groupings, sortingMode) {
|
||||
ASSERT(this._groupableView, "Need a groupable view to load!");
|
||||
NS_ASSERT(this._groupableView, "Need a groupable view to load!");
|
||||
if (!this._groupableView)
|
||||
return;
|
||||
var query = this.history.getNewQuery();
|
||||
@ -1117,7 +1084,7 @@ var PlacesController = {
|
||||
* An array of transactions.
|
||||
*/
|
||||
_removeRange: function PC__removeRange(range, transactions) {
|
||||
ASSERT(transactions instanceof Array, "Must pass a transactions array");
|
||||
NS_ASSERT(transactions instanceof Array, "Must pass a transactions array");
|
||||
var index = this.getIndexOfNode(range[0]);
|
||||
|
||||
// Walk backwards to preserve insertion order on undo
|
||||
@ -1181,7 +1148,7 @@ var PlacesController = {
|
||||
* as part of another operation.
|
||||
*/
|
||||
remove: function PC_remove(txnName) {
|
||||
ASSERT(txnName !== undefined, "Must supply Transaction Name");
|
||||
NS_ASSERT(txnName !== undefined, "Must supply Transaction Name");
|
||||
this._activeView.saveSelection(this._activeView.SAVE_SELECTION_REMOVE);
|
||||
|
||||
// Delete the selected rows. Do this by walking the selection backward, so
|
||||
@ -1738,7 +1705,7 @@ function PlacesAggregateTransaction(name, transactions) {
|
||||
this._name = name;
|
||||
this.redoTransaction = this.doTransaction;
|
||||
this.pageTransaction = PlacesController.activeView.filterTransactions;
|
||||
ASSERT(this.pageTransaction !== undefined, "Don't know if this transaction must be filtered");
|
||||
NS_ASSERT(this.pageTransaction !== undefined, "Don't know if this transaction must be filtered");
|
||||
}
|
||||
PlacesAggregateTransaction.prototype = {
|
||||
__proto__: PlacesBaseTransaction.prototype,
|
||||
@ -1773,7 +1740,7 @@ function PlacesCreateFolderTransaction(name, container, index) {
|
||||
this._id = null;
|
||||
this.redoTransaction = this.doTransaction;
|
||||
this.pageTransaction = PlacesController.activeView.filterTransactions;
|
||||
ASSERT(this.pageTransaction !== undefined, "Don't know if this transaction must be filtered");
|
||||
NS_ASSERT(this.pageTransaction !== undefined, "Don't know if this transaction must be filtered");
|
||||
}
|
||||
PlacesCreateFolderTransaction.prototype = {
|
||||
__proto__: PlacesBaseTransaction.prototype,
|
||||
@ -1798,7 +1765,7 @@ function PlacesCreateItemTransaction(uri, container, index) {
|
||||
this._index = index;
|
||||
this.redoTransaction = this.doTransaction;
|
||||
this.pageTransaction = PlacesController.activeView.filterTransactions;
|
||||
ASSERT(this.pageTransaction !== undefined, "Don't know if this transaction must be filtered");
|
||||
NS_ASSERT(this.pageTransaction !== undefined, "Don't know if this transaction must be filtered");
|
||||
}
|
||||
PlacesCreateItemTransaction.prototype = {
|
||||
__proto__: PlacesBaseTransaction.prototype,
|
||||
@ -1840,7 +1807,7 @@ PlacesInsertSeparatorTransaction.prototype = {
|
||||
* Move a Folder
|
||||
*/
|
||||
function PlacesMoveFolderTransaction(id, oldContainer, oldIndex, newContainer, newIndex) {
|
||||
ASSERT(!isNaN(id + oldContainer + oldIndex + newContainer + newIndex), "Parameter is NaN!");
|
||||
NS_ASSERT(!isNaN(id + oldContainer + oldIndex + newContainer + newIndex), "Parameter is NaN!");
|
||||
this._id = id;
|
||||
this._oldContainer = oldContainer;
|
||||
this._oldIndex = oldIndex;
|
||||
@ -1848,7 +1815,7 @@ function PlacesMoveFolderTransaction(id, oldContainer, oldIndex, newContainer, n
|
||||
this._newIndex = newIndex;
|
||||
this.redoTransaction = this.doTransaction;
|
||||
this.pageTransaction = PlacesController.activeView.filterTransactions;
|
||||
ASSERT(this.pageTransaction !== undefined, "Don't know if this transaction must be filtered");
|
||||
NS_ASSERT(this.pageTransaction !== undefined, "Don't know if this transaction must be filtered");
|
||||
}
|
||||
PlacesMoveFolderTransaction.prototype = {
|
||||
__proto__: PlacesBaseTransaction.prototype,
|
||||
@ -1875,7 +1842,7 @@ function PlacesMoveItemTransaction(uri, oldContainer, oldIndex, newContainer, ne
|
||||
this._newIndex = newIndex;
|
||||
this.redoTransaction = this.doTransaction;
|
||||
this.pageTransaction = PlacesController.activeView.filterTransactions;
|
||||
ASSERT(this.pageTransaction !== undefined, "Don't know if this transaction must be filtered");
|
||||
NS_ASSERT(this.pageTransaction !== undefined, "Don't know if this transaction must be filtered");
|
||||
}
|
||||
PlacesMoveItemTransaction.prototype = {
|
||||
__proto__: PlacesBaseTransaction.prototype,
|
||||
@ -1933,7 +1900,7 @@ function PlacesRemoveFolderTransaction(id, oldContainer, oldIndex) {
|
||||
this._contents = null; // The encoded contents of this folder
|
||||
this.redoTransaction = this.doTransaction;
|
||||
this.pageTransaction = PlacesController.activeView.filterTransactions;
|
||||
ASSERT(this.pageTransaction !== undefined, "Don't know if this transaction must be filtered");
|
||||
NS_ASSERT(this.pageTransaction !== undefined, "Don't know if this transaction must be filtered");
|
||||
}
|
||||
PlacesRemoveFolderTransaction.prototype = {
|
||||
__proto__: PlacesBaseTransaction.prototype,
|
||||
@ -2012,7 +1979,7 @@ function PlacesRemoveItemTransaction(uri, oldContainer, oldIndex) {
|
||||
this._oldIndex = oldIndex;
|
||||
this.redoTransaction = this.doTransaction;
|
||||
this.pageTransaction = PlacesController.activeView.filterTransactions;
|
||||
ASSERT(this.pageTransaction !== undefined, "Don't know if this transaction must be filtered");
|
||||
NS_ASSERT(this.pageTransaction !== undefined, "Don't know if this transaction must be filtered");
|
||||
}
|
||||
PlacesRemoveItemTransaction.prototype = {
|
||||
__proto__: PlacesBaseTransaction.prototype,
|
||||
@ -2060,7 +2027,7 @@ function PlacesEditFolderTransaction(id, oldAttributes, newAttributes) {
|
||||
this._newAttributes = newAttributes;
|
||||
this.redoTransaction = this.doTransaction;
|
||||
this.pageTransaction = PlacesController.activeView.filterTransactions;
|
||||
ASSERT(this.pageTransaction !== undefined, "Don't know if this transaction must be filtered");
|
||||
NS_ASSERT(this.pageTransaction !== undefined, "Don't know if this transaction must be filtered");
|
||||
}
|
||||
PlacesEditFolderTransaction.prototype = {
|
||||
__proto__: PlacesBaseTransaction.prototype,
|
||||
@ -2085,7 +2052,7 @@ function PlacesEditItemTransaction(uri, newAttributes) {
|
||||
this._oldAttributes = { };
|
||||
this.redoTransaction = this.doTransaction;
|
||||
this.pageTransaction = PlacesController.activeView.filterTransactions;
|
||||
ASSERT(this.pageTransaction !== undefined, "Don't know if this transaction must be filtered");
|
||||
NS_ASSERT(this.pageTransaction !== undefined, "Don't know if this transaction must be filtered");
|
||||
}
|
||||
PlacesEditItemTransaction.prototype = {
|
||||
__proto__: PlacesBaseTransaction.prototype,
|
||||
|
@ -35,6 +35,8 @@
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include ../../../../toolkit/content/debug.js
|
||||
|
||||
const PREF_PLACES_GROUPING_GENERIC = "browser.places.grouping.generic";
|
||||
const PREF_PLACES_GROUPING_BOOKMARK = "browser.places.grouping.bookmark";
|
||||
|
||||
@ -1085,4 +1087,4 @@ var Groupers = {
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
@ -1,6 +1,6 @@
|
||||
browser.jar:
|
||||
* content/browser/places/places.xul (content/places.xul)
|
||||
content/browser/places/places.js (content/places.js)
|
||||
* content/browser/places/places.js (content/places.js)
|
||||
content/browser/places/places.xml (content/places.xml)
|
||||
content/browser/places/places.css (content/places.css)
|
||||
content/browser/places/organizer.css (content/organizer.css)
|
||||
|
102
toolkit/content/debug.js
Normal file
102
toolkit/content/debug.js
Normal file
@ -0,0 +1,102 @@
|
||||
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- *//* vim:set ts=2 sw=2 sts=2 ci et: */
|
||||
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Places Bookmark Properties.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Google Inc.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2006
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Joe Hughes <jhughes@google.com>
|
||||
* Ben Goodger <beng@google.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
/**
|
||||
* This file contains functions that are useful for debugging purposes from
|
||||
* within JavaScript code.
|
||||
*/
|
||||
|
||||
const NS_ASSERT_ENVIRONMENT_VARIABLE_NAME = "XUL_ASSERT_PROMPT";
|
||||
var gTraceOnAssert = true;
|
||||
|
||||
/**
|
||||
* This function provides a simple assertion function for JavaScript.
|
||||
* If the condition is true, this function will do nothing. If the
|
||||
* condition is false, then the message will be printed to the console
|
||||
* and an alert will appear showing a stack trace, so that the (alpha
|
||||
* or nightly) user can file a bug containing it. For future enhancements,
|
||||
* see bugs 330077 and 330078.
|
||||
*
|
||||
* To suppress the dialogs, you can run with the environment variable
|
||||
* XUL_ASSERT_PROMPT set to 0 (if unset, this defaults to 1).
|
||||
*
|
||||
* @param condition represents the condition that we're asserting to be
|
||||
* true when we call this function--should be
|
||||
* something that can be evaluated as a boolean.
|
||||
* @param message a string to be displayed upon failure of the assertion
|
||||
*/
|
||||
|
||||
function NS_ASSERT(condition, message) {
|
||||
if (condition)
|
||||
return;
|
||||
|
||||
var caller = arguments.callee.caller;
|
||||
var assertionText = "ASSERT: " + message + "\n";
|
||||
dump(assertionText);
|
||||
|
||||
if (gTraceOnAssert) {
|
||||
var stackText = "Stack Trace: \n";
|
||||
var count = 0;
|
||||
while (caller) {
|
||||
stackText += count++ + ":" + caller.name + "(";
|
||||
for (var i = 0; i < caller.arguments.length; ++i) {
|
||||
var arg = caller.arguments[i];
|
||||
stackText += arg;
|
||||
if (i < caller.arguments.length - 1)
|
||||
stackText += ",";
|
||||
}
|
||||
stackText += ")\n";
|
||||
caller = caller.arguments.callee.caller;
|
||||
}
|
||||
}
|
||||
|
||||
var environment = Components.classes["@mozilla.org/process/environment;1"].
|
||||
getService(Components.interfaces.nsIEnvironment);
|
||||
if (environment.exists(NS_ASSERT_ENVIRONMENT_VARIABLE_NAME) &&
|
||||
!parseInt(environment.get(NS_ASSERT_ENVIRONMENT_VARIABLE_NAME)))
|
||||
return;
|
||||
|
||||
var source = null;
|
||||
if (this.window)
|
||||
source = window;
|
||||
var ps = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].
|
||||
getService(Components.interfaces.nsIPromptService);
|
||||
ps.alert(source, "Assertion Failed", assertionText + stackText);
|
||||
|
||||
}
|
@ -256,3 +256,5 @@ function FillInTooltip ( tipElement )
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
#include debug.js
|
||||
|
@ -6,6 +6,7 @@ toolkit.jar:
|
||||
content/global/XPCNativeWrapper.js (XPCNativeWrapper.js)
|
||||
* content/global/xul.css (xul.css)
|
||||
* content/global/about.xhtml (about.xhtml)
|
||||
* content/global/debug.js (debug.js)
|
||||
+ content/global/buildconfig.html (buildconfig.html)
|
||||
+ content/global/charsetOverlay.js (charsetOverlay.js)
|
||||
+ content/global/charsetOverlay.xul (charsetOverlay.xul)
|
||||
|
Loading…
x
Reference in New Issue
Block a user