зеркало из https://github.com/mozilla/pjs.git
Fix jsconsole to open our view source window.
This commit is contained in:
Родитель
da3e06b2c1
Коммит
6f65425281
|
@ -1,57 +0,0 @@
|
||||||
|
|
||||||
.console-box {
|
|
||||||
-moz-binding: url("chrome://global/content/consoleBindings.xml#console-box");
|
|
||||||
overflow: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.console-rows {
|
|
||||||
-moz-user-focus: normal;
|
|
||||||
}
|
|
||||||
|
|
||||||
.console-row[type="error"],
|
|
||||||
.console-row[type="warning"] {
|
|
||||||
-moz-binding: url("chrome://global/content/consoleBindings.xml#error");
|
|
||||||
}
|
|
||||||
|
|
||||||
.console-row[type="message"] {
|
|
||||||
-moz-binding: url("chrome://global/content/consoleBindings.xml#message");
|
|
||||||
}
|
|
||||||
|
|
||||||
.console-error-msg {
|
|
||||||
white-space: normal;
|
|
||||||
}
|
|
||||||
|
|
||||||
.console-msg-text {
|
|
||||||
white-space: pre;
|
|
||||||
}
|
|
||||||
|
|
||||||
.console-error-source {
|
|
||||||
-moz-binding: url("chrome://global/content/consoleBindings.xml#console-error-source");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* :::::::::: hiding and showing of rows for each mode :::::::::: */
|
|
||||||
|
|
||||||
.console-box[mode="Warnings"] > .console-box-internal > .console-rows
|
|
||||||
> .console-row[type="error"],
|
|
||||||
.console-box[mode="Messages"] > .console-box-internal > .console-rows
|
|
||||||
> .console-row[type="error"]
|
|
||||||
{
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.console-box[mode="Errors"] > .console-box-internal > .console-rows
|
|
||||||
> .console-row[type="warning"],
|
|
||||||
.console-box[mode="Messages"] > .console-box-internal > .console-rows
|
|
||||||
> .console-row[type="warning"]
|
|
||||||
{
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.console-box[mode="Errors"] > .console-box-internal > .console-rows
|
|
||||||
> .console-row[type="message"],
|
|
||||||
.console-box[mode="Warnings"] > .console-box-internal > .console-rows
|
|
||||||
> .console-row[type="message"]
|
|
||||||
{
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ Contributor(s): Joe Hewitt <hewitt@netscape.com>
|
||||||
|
|
||||||
<?xml-stylesheet href="chrome://communicator/skin/" type="text/css"?>
|
<?xml-stylesheet href="chrome://communicator/skin/" type="text/css"?>
|
||||||
<?xml-stylesheet href="chrome://global/skin/console.css" type="text/css"?>
|
<?xml-stylesheet href="chrome://global/skin/console.css" type="text/css"?>
|
||||||
<?xml-stylesheet href="chrome://global/content/console.css" type="text/css"?>
|
<?xml-stylesheet href="chrome://browser/content/console/console.css" type="text/css"?>
|
||||||
|
|
||||||
<?xul-overlay href="chrome://global/content/globalOverlay.xul"?>
|
<?xul-overlay href="chrome://global/content/globalOverlay.xul"?>
|
||||||
<?xul-overlay href="chrome://communicator/content/utilityOverlay.xul"?>
|
<?xul-overlay href="chrome://communicator/content/utilityOverlay.xul"?>
|
||||||
|
|
|
@ -1,419 +0,0 @@
|
||||||
<?xml version="1.0"?>
|
|
||||||
|
|
||||||
<!DOCTYPE window SYSTEM "chrome://global/locale/console.dtd">
|
|
||||||
|
|
||||||
<bindings id="consoleBindings"
|
|
||||||
xmlns="http://www.mozilla.org/xbl"
|
|
||||||
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
|
||||||
xmlns:xbl="http://www.mozilla.org/xbl">
|
|
||||||
|
|
||||||
<binding id="console-box" extends="xul:box">
|
|
||||||
<content>
|
|
||||||
<xul:stringbundle src="chrome://global/locale/console.properties" role="string-bundle"/>
|
|
||||||
<xul:vbox class="console-box-internal">
|
|
||||||
<xul:vbox class="console-rows" role="console-rows" xbl:inherits="dir=sortOrder"/>
|
|
||||||
</xul:vbox>
|
|
||||||
</content>
|
|
||||||
|
|
||||||
<implementation>
|
|
||||||
<field name="limit" readonly="true">
|
|
||||||
250
|
|
||||||
</field>
|
|
||||||
<field name="_showChromeErrors">-1</field>
|
|
||||||
|
|
||||||
<property name="showChromeErrors">
|
|
||||||
<getter><![CDATA[
|
|
||||||
if (this._showChromeErrors != -1)
|
|
||||||
return this._showChromeErrors;
|
|
||||||
var pref = Components.classes['@mozilla.org/preferences-service;1'].getService();
|
|
||||||
pref = pref.QueryInterface(Components.interfaces.nsIPrefBranch);
|
|
||||||
|
|
||||||
try {
|
|
||||||
return this._showChromeErrors = pref.getBoolPref("javascript.options.showInConsole");
|
|
||||||
}
|
|
||||||
catch(ex) {
|
|
||||||
return this._showChromeErrors = false;
|
|
||||||
}
|
|
||||||
]]></getter>
|
|
||||||
</property>
|
|
||||||
|
|
||||||
<property name="count" readonly="true">
|
|
||||||
<getter>return this.mCount</getter>
|
|
||||||
</property>
|
|
||||||
|
|
||||||
<property name="mode">
|
|
||||||
<getter>return this.mMode;</getter>
|
|
||||||
<setter><![CDATA[
|
|
||||||
this.mMode = val || "All";
|
|
||||||
this.setAttribute("mode", this.mMode);
|
|
||||||
return val;
|
|
||||||
]]></setter>
|
|
||||||
</property>
|
|
||||||
|
|
||||||
<property name="sortOrder">
|
|
||||||
<getter>return this.getAttribute("sortOrder");</getter>
|
|
||||||
<setter>this.setAttribute("sortOrder", val); return val;</setter>
|
|
||||||
</property>
|
|
||||||
<field name="mSelectedItem">null</field>
|
|
||||||
<property name="selectedItem">
|
|
||||||
<getter>return this.mSelectedItem</getter>
|
|
||||||
<setter><![CDATA[
|
|
||||||
if (this.mSelectedItem)
|
|
||||||
this.mSelectedItem.removeAttribute("selected");
|
|
||||||
|
|
||||||
this.mSelectedItem = val;
|
|
||||||
val.setAttribute("selected", "true");
|
|
||||||
]]></setter>
|
|
||||||
</property>
|
|
||||||
|
|
||||||
<method name="init">
|
|
||||||
<body><![CDATA[
|
|
||||||
this.mCount = 0;
|
|
||||||
|
|
||||||
this.mConsoleListener = {
|
|
||||||
console: this,
|
|
||||||
observe : function(aObject) { this.console.appendItem(aObject); }
|
|
||||||
};
|
|
||||||
|
|
||||||
this.mConsoleRowBox = this.getAnonElByAttr("role", "console-rows");
|
|
||||||
this.mStrBundle = this.getAnonElByAttr("role", "string-bundle");
|
|
||||||
|
|
||||||
try {
|
|
||||||
var isupports = Components.classes['@mozilla.org/consoleservice;1'].getService();
|
|
||||||
this.mCService = isupports.QueryInterface(Components.interfaces.nsIConsoleService);
|
|
||||||
this.mCService.registerListener(this.mConsoleListener);
|
|
||||||
} catch (ex) {
|
|
||||||
appendItem(
|
|
||||||
"Unable to display errors - couldn't get Console Service component. " +
|
|
||||||
"(Missing @mozilla.org/consoleservice;1)");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.mMode = this.getAttribute("mode") || "All";
|
|
||||||
|
|
||||||
this.appendInitialItems();
|
|
||||||
]]></body>
|
|
||||||
</method>
|
|
||||||
|
|
||||||
<method name="destroy">
|
|
||||||
<body><![CDATA[
|
|
||||||
this.mCService.unregisterListener(this.mConsoleListener);
|
|
||||||
]]></body>
|
|
||||||
</method>
|
|
||||||
|
|
||||||
<method name="appendInitialItems">
|
|
||||||
<body><![CDATA[
|
|
||||||
var out = {}; // Throwaway references to support 'out' parameters.
|
|
||||||
this.mCService.getMessageArray(out, {});
|
|
||||||
var messages = out.value;
|
|
||||||
|
|
||||||
// In case getMessageArray returns 0-length array as null
|
|
||||||
if (!messages)
|
|
||||||
messages = [];
|
|
||||||
|
|
||||||
var limit = messages.length - this.limit;
|
|
||||||
if (limit < 0) limit = 0;
|
|
||||||
|
|
||||||
// Checks if console ever been cleared
|
|
||||||
for (var i = messages.length - 1; i >= limit; --i)
|
|
||||||
if (!messages[i].message)
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Populate with messages after latest "clear"
|
|
||||||
while (++i < messages.length)
|
|
||||||
this.appendItem(messages[i]);
|
|
||||||
]]></body>
|
|
||||||
</method>
|
|
||||||
|
|
||||||
<method name="appendItem">
|
|
||||||
<parameter name="aObject"/>
|
|
||||||
<body><![CDATA[
|
|
||||||
if (!aObject.message) return;
|
|
||||||
|
|
||||||
try {
|
|
||||||
// Try to QI it to a script error to get more info
|
|
||||||
var scriptError = aObject.QueryInterface(Components.interfaces.nsIScriptError);
|
|
||||||
|
|
||||||
// filter chrome urls
|
|
||||||
if (!this.showChromeErrors && scriptError.sourceName.substr(0, 9) == "chrome://")
|
|
||||||
return;
|
|
||||||
|
|
||||||
this.appendError(scriptError);
|
|
||||||
} catch (ex) {
|
|
||||||
try {
|
|
||||||
// Try to QI it to a console message
|
|
||||||
var msg = aObject.QueryInterface(Components.interfaces.nsIConsoleMessage);
|
|
||||||
this.appendMessage(msg.message);
|
|
||||||
} catch (ex2) {
|
|
||||||
// Give up and append the object itself as a string
|
|
||||||
this.appendMessage(aObject);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]]></body>
|
|
||||||
</method>
|
|
||||||
|
|
||||||
<method name="appendError">
|
|
||||||
<parameter name="aObject"/>
|
|
||||||
<body><![CDATA[
|
|
||||||
var row = this.createConsoleRow();
|
|
||||||
var nsIScriptError = Components.interfaces.nsIScriptError;
|
|
||||||
|
|
||||||
// Is this error actually just a non-fatal warning?
|
|
||||||
var warning = aObject.flags & nsIScriptError.warningFlag != 0;
|
|
||||||
|
|
||||||
var typetext = warning ? "typeWarning" : "typeError";
|
|
||||||
row.setAttribute("typetext", this.mStrBundle.getString(typetext));
|
|
||||||
row.setAttribute("type", warning ? "warning" : "error");
|
|
||||||
row.setAttribute("msg", aObject.message);
|
|
||||||
if (aObject.lineNumber || aObject.sourceName) {
|
|
||||||
row.setAttribute("url", aObject.sourceName);
|
|
||||||
row.setAttribute("line", aObject.lineNumber);
|
|
||||||
} else {
|
|
||||||
row.setAttribute("hideSource", "true");
|
|
||||||
}
|
|
||||||
if (aObject.sourceLine) {
|
|
||||||
row.setAttribute("code", aObject.sourceLine.replace("\n", "", "g"));
|
|
||||||
if (aObject.columnNumber) {
|
|
||||||
row.setAttribute("col", aObject.columnNumber);
|
|
||||||
row.setAttribute("errorDots", this.repeatChar(" ", aObject.columnNumber));
|
|
||||||
row.setAttribute("errorCaret", " ");
|
|
||||||
} else {
|
|
||||||
row.setAttribute("hideCaret", "true");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
row.setAttribute("hideCode", "true");
|
|
||||||
}
|
|
||||||
this.appendConsoleRow(row);
|
|
||||||
]]></body>
|
|
||||||
</method>
|
|
||||||
|
|
||||||
<method name="appendMessage">
|
|
||||||
<parameter name="aMessage"/>
|
|
||||||
<parameter name="aType"/>
|
|
||||||
<body><![CDATA[
|
|
||||||
var row = this.createConsoleRow();
|
|
||||||
row.setAttribute("type", aType || "message");
|
|
||||||
row.setAttribute("msg", aMessage);
|
|
||||||
this.appendConsoleRow(row);
|
|
||||||
]]></body>
|
|
||||||
</method>
|
|
||||||
|
|
||||||
<method name="clear">
|
|
||||||
<body><![CDATA[
|
|
||||||
this.mCService.logStringMessage(null);
|
|
||||||
this.mCount = 0;
|
|
||||||
|
|
||||||
var newRows = this.mConsoleRowBox.cloneNode(false);
|
|
||||||
this.mConsoleRowBox.parentNode.replaceChild(newRows, this.mConsoleRowBox);
|
|
||||||
this.mConsoleRowBox = newRows;
|
|
||||||
]]></body>
|
|
||||||
</method>
|
|
||||||
|
|
||||||
<method name="copySelectedItem">
|
|
||||||
<body><![CDATA[
|
|
||||||
if (this.mSelectedItem)
|
|
||||||
this.copyString(this.mSelectedItem.toString());
|
|
||||||
]]></body>
|
|
||||||
</method>
|
|
||||||
|
|
||||||
<method name="createConsoleRow">
|
|
||||||
<body><![CDATA[
|
|
||||||
var row = document.createElement("box");
|
|
||||||
row.setAttribute("class", "console-row");
|
|
||||||
row._IsConsoleRow = true;
|
|
||||||
row._ConsoleBox = this;
|
|
||||||
return row;
|
|
||||||
]]></body>
|
|
||||||
</method>
|
|
||||||
|
|
||||||
<method name="appendConsoleRow">
|
|
||||||
<parameter name="aRow"/>
|
|
||||||
<body><![CDATA[
|
|
||||||
this.mConsoleRowBox.appendChild(aRow);
|
|
||||||
if (++this.mCount > this.limit) this.deleteFirst();
|
|
||||||
]]></body>
|
|
||||||
</method>
|
|
||||||
|
|
||||||
<method name="deleteFirst">
|
|
||||||
<body><![CDATA[
|
|
||||||
var node = this.mConsoleRowBox.firstChild;
|
|
||||||
this.mConsoleRowBox.removeChild(node);
|
|
||||||
--this.mCount;
|
|
||||||
]]></body>
|
|
||||||
</method>
|
|
||||||
|
|
||||||
<!-- UTILITY FUNCTIONS -->
|
|
||||||
|
|
||||||
<!-- We need this method only because document.getAnonymousElementByAttribute
|
|
||||||
is crashing (as of 2/26/2001) -->
|
|
||||||
<method name="getAnonElByAttr">
|
|
||||||
<parameter name="aAttr"/>
|
|
||||||
<parameter name="aVal"/>
|
|
||||||
<body><![CDATA[
|
|
||||||
var kids = document.getAnonymousNodes(this);
|
|
||||||
for (var i = 0; i < kids.length; ++i) {
|
|
||||||
if (kids[i].getAttribute(aAttr) == aVal)
|
|
||||||
return kids[i];
|
|
||||||
var kids2 = kids[i].getElementsByAttribute(aAttr, aVal);
|
|
||||||
if (kids2.length > 0)
|
|
||||||
return kids2[0];
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
]]></body>
|
|
||||||
</method>
|
|
||||||
|
|
||||||
<method name="repeatChar">
|
|
||||||
<parameter name="aChar"/>
|
|
||||||
<parameter name="aCol"/>
|
|
||||||
<body><![CDATA[
|
|
||||||
var str = "";
|
|
||||||
if (aCol)
|
|
||||||
for (var i = 1; i < aCol; ++i)
|
|
||||||
str += aChar;
|
|
||||||
|
|
||||||
return str;
|
|
||||||
]]></body>
|
|
||||||
</method>
|
|
||||||
|
|
||||||
<method name="copyString">
|
|
||||||
<parameter name="aString"/>
|
|
||||||
<body><![CDATA[
|
|
||||||
try {
|
|
||||||
const clipURI = "@mozilla.org/widget/clipboard;1";
|
|
||||||
const clipI = Components.interfaces.nsIClipboard;
|
|
||||||
var clipboard = Components.classes[clipURI].getService(clipI);
|
|
||||||
|
|
||||||
const transURI = "@mozilla.org/widget/transferable;1";
|
|
||||||
var transferable = Components.classes[transURI].createInstance(Components.interfaces.nsITransferable);
|
|
||||||
|
|
||||||
transferable.addDataFlavor("text/unicode");
|
|
||||||
|
|
||||||
const strURI = "@mozilla.org/supports-string;1";
|
|
||||||
var wstring = Components.classes[strURI].createInstance(Components.interfaces.nsISupportsString);
|
|
||||||
|
|
||||||
wstring.data = aString;
|
|
||||||
transferable.setTransferData("text/unicode", wstring, aString.length * 2);
|
|
||||||
clipboard.setData(transferable, null, clipI.kGlobalClipboard);
|
|
||||||
} catch (ex) {
|
|
||||||
// Unable to copy anything, die quietly
|
|
||||||
}
|
|
||||||
]]></body>
|
|
||||||
</method>
|
|
||||||
|
|
||||||
<constructor> this.init(); </constructor>
|
|
||||||
<destructor> this.destroy(); </destructor>
|
|
||||||
</implementation>
|
|
||||||
|
|
||||||
<handlers>
|
|
||||||
<handler event="mousedown"><![CDATA[
|
|
||||||
if (event.button == 0 || event.button == 2) {
|
|
||||||
var target = event.originalTarget;
|
|
||||||
|
|
||||||
while (target && !("_IsConsoleRow" in target))
|
|
||||||
target = target.parentNode;
|
|
||||||
|
|
||||||
if (target)
|
|
||||||
this.selectedItem = target;
|
|
||||||
}
|
|
||||||
]]></handler>
|
|
||||||
</handlers>
|
|
||||||
</binding>
|
|
||||||
|
|
||||||
<binding id="error" extends="xul:box">
|
|
||||||
<content>
|
|
||||||
<xul:box class="console-row-internal-box" flex="1">
|
|
||||||
<xul:box class="console-row-icon" align="center" xbl:inherits="selected">
|
|
||||||
<xul:image class="console-icon" xbl:inherits="src,type"/>
|
|
||||||
</xul:box>
|
|
||||||
<xul:vbox class="console-row-content" xbl:inherits="selected" flex="1">
|
|
||||||
<xul:box class="console-row-msg" align="start">
|
|
||||||
<xul:label class="label" xbl:inherits="value=typetext"/>
|
|
||||||
<xul:description class="console-error-msg" xbl:inherits="value=msg" flex="1"/>
|
|
||||||
</xul:box>
|
|
||||||
<xul:box class="console-row-file" xbl:inherits="hidden=hideSource">
|
|
||||||
<xul:label class="label" value="&errFile.label;"/>
|
|
||||||
<xul:box class="console-error-source" xbl:inherits="url"/>
|
|
||||||
<spacer flex="1"/>
|
|
||||||
<xul:label class="label" value="&errLine.label;"/>
|
|
||||||
<xul:label class="label" xbl:inherits="value=line" flex="1"/>
|
|
||||||
</xul:box>
|
|
||||||
<xul:vbox class="console-row-code" xbl:inherits="selected,hidden=hideCode">
|
|
||||||
<xul:label class="monospace console-code" xbl:inherits="value=code"/>
|
|
||||||
<xul:box xbl:inherits="hidden=hideCaret">
|
|
||||||
<xul:label class="monospace console-dots" xbl:inherits="value=errorDots"/>
|
|
||||||
<xul:label class="monospace console-caret" xbl:inherits="value=errorCaret"/>
|
|
||||||
<xul:spacer flex="1"/>
|
|
||||||
</xul:box>
|
|
||||||
</xul:vbox>
|
|
||||||
</xul:vbox>
|
|
||||||
</xul:box>
|
|
||||||
</content>
|
|
||||||
|
|
||||||
<implementation>
|
|
||||||
|
|
||||||
<method name="toString">
|
|
||||||
<body><![CDATA[
|
|
||||||
var msg = this.getAttribute("typetext") + " " + this.getAttribute("msg");
|
|
||||||
|
|
||||||
var strBundle = this._ConsoleBox.mStrBundle;
|
|
||||||
|
|
||||||
if (this.hasAttribute("line") && this.hasAttribute("url")) {
|
|
||||||
msg += "\n" + strBundle.getFormattedString("errFile",
|
|
||||||
[this.getAttribute("url")]) + "\n";
|
|
||||||
if (this.hasAttribute("col")) {
|
|
||||||
msg += strBundle.getFormattedString("errLineCol",
|
|
||||||
[this.getAttribute("line"), this.getAttribute("col")]);
|
|
||||||
} else
|
|
||||||
msg += strBundle.getFormattedString("errLine", [this.getAttribute("line")]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.hasAttribute("code"))
|
|
||||||
msg += "\n" + strBundle.getString("errCode") + "\n" + this.getAttribute("code");
|
|
||||||
|
|
||||||
return msg;
|
|
||||||
]]></body>
|
|
||||||
</method>
|
|
||||||
|
|
||||||
</implementation>
|
|
||||||
|
|
||||||
</binding>
|
|
||||||
|
|
||||||
<binding id="message" extends="xul:box">
|
|
||||||
<content>
|
|
||||||
<xul:box class="console-internal-box" flex="1">
|
|
||||||
<xul:box class="console-row-icon" align="center">
|
|
||||||
<xul:image class="console-icon" xbl:inherits="src,type"/>
|
|
||||||
</xul:box>
|
|
||||||
<xul:vbox class="console-row-content" xbl:inherits="selected" flex="1">
|
|
||||||
<xul:vbox class="console-row-msg" flex="1">
|
|
||||||
<xul:description class="console-msg-text" xbl:inherits="value=msg" flex="1"/>
|
|
||||||
</xul:vbox>
|
|
||||||
</xul:vbox>
|
|
||||||
</xul:box>
|
|
||||||
</content>
|
|
||||||
|
|
||||||
<implementation>
|
|
||||||
<method name="toString">
|
|
||||||
<body><![CDATA[
|
|
||||||
return this.getAttribute("msg");
|
|
||||||
]]></body>
|
|
||||||
</method>
|
|
||||||
</implementation>
|
|
||||||
</binding>
|
|
||||||
|
|
||||||
<binding id="console-error-source" extends="xul:box">
|
|
||||||
<content>
|
|
||||||
<xul:label class="text-link" xbl:inherits="value=url" crop="right"/>
|
|
||||||
</content>
|
|
||||||
|
|
||||||
<handlers>
|
|
||||||
<handler event="click"><![CDATA[
|
|
||||||
window.openDialog(
|
|
||||||
"chrome://navigator/content/viewSource.xul", "_blank",
|
|
||||||
"scrollbars,resizable,chrome,dialog=no", this.getAttribute("url"));
|
|
||||||
]]></handler>
|
|
||||||
</handlers>
|
|
||||||
</binding>
|
|
||||||
|
|
||||||
</bindings>
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ browser.jar:
|
||||||
content/browser/console/console.js (content/console.js)
|
content/browser/console/console.js (content/console.js)
|
||||||
content/browser/console/console.xul (content/console.xul)
|
content/browser/console/console.xul (content/console.xul)
|
||||||
content/browser/console/console.css (content/console.css)
|
content/browser/console/console.css (content/console.css)
|
||||||
content/browser/console/consoleBindings.xml (content/consoleBindings.xml)
|
content/browser/console/consoleBindings.xml (content/consoleBindings.xml)
|
||||||
|
|
||||||
en-US.jar:
|
en-US.jar:
|
||||||
locale/en-US/browser/console/console.dtd (locale/console.dtd)
|
locale/en-US/browser/console/console.dtd (locale/console.dtd)
|
||||||
|
|
Загрузка…
Ссылка в новой задаче