зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1067325 - MathML source in tab. r=mconley
This commit is contained in:
Родитель
23ee447382
Коммит
a9e07e1d86
|
@ -1012,8 +1012,14 @@ nsContextMenu.prototype = {
|
||||||
inBackground: false
|
inBackground: false
|
||||||
});
|
});
|
||||||
let viewSourceBrowser = gBrowser.getBrowserForTab(tab);
|
let viewSourceBrowser = gBrowser.getBrowserForTab(tab);
|
||||||
top.gViewSourceUtils.viewSourceFromSelectionInBrowser(reference,
|
if (aContext == "selection") {
|
||||||
viewSourceBrowser);
|
top.gViewSourceUtils
|
||||||
|
.viewSourceFromSelectionInBrowser(reference, viewSourceBrowser);
|
||||||
|
} else {
|
||||||
|
top.gViewSourceUtils
|
||||||
|
.viewSourceFromFragmentInBrowser(reference, aContext,
|
||||||
|
viewSourceBrowser);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// unused (and play nice for fragments generated via XSLT too)
|
// unused (and play nice for fragments generated via XSLT too)
|
||||||
var docUrl = null;
|
var docUrl = null;
|
||||||
|
|
|
@ -13,15 +13,17 @@ XPCOMUtils.defineLazyModuleGetter(this, "Services",
|
||||||
XPCOMUtils.defineLazyModuleGetter(this, "Deprecated",
|
XPCOMUtils.defineLazyModuleGetter(this, "Deprecated",
|
||||||
"resource://gre/modules/Deprecated.jsm");
|
"resource://gre/modules/Deprecated.jsm");
|
||||||
|
|
||||||
const NS_XHTML = 'http://www.w3.org/1999/xhtml';
|
const NS_XHTML = "http://www.w3.org/1999/xhtml";
|
||||||
|
const VIEW_SOURCE_CSS = "resource://gre-resources/viewsource.css";
|
||||||
|
const BUNDLE_URL = "chrome://global/locale/viewSource.properties";
|
||||||
|
|
||||||
// These are markers used to delimit the selection during processing. They
|
// These are markers used to delimit the selection during processing. They
|
||||||
// are removed from the final rendering.
|
// are removed from the final rendering.
|
||||||
// We use noncharacter Unicode codepoints to minimize the risk of clashing
|
// We use noncharacter Unicode codepoints to minimize the risk of clashing
|
||||||
// with anything that might legitimately be present in the document.
|
// with anything that might legitimately be present in the document.
|
||||||
// U+FDD0..FDEF <noncharacters>
|
// U+FDD0..FDEF <noncharacters>
|
||||||
const MARK_SELECTION_START = '\uFDD0';
|
const MARK_SELECTION_START = "\uFDD0";
|
||||||
const MARK_SELECTION_END = '\uFDEF';
|
const MARK_SELECTION_END = "\uFDEF";
|
||||||
|
|
||||||
this.EXPORTED_SYMBOLS = ["ViewSourceBrowser"];
|
this.EXPORTED_SYMBOLS = ["ViewSourceBrowser"];
|
||||||
|
|
||||||
|
@ -115,6 +117,23 @@ ViewSourceBrowser.prototype = {
|
||||||
return this.browser.webNavigation;
|
return this.browser.webNavigation;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Getter for whether long lines should be wrapped.
|
||||||
|
*/
|
||||||
|
get wrapLongLines() {
|
||||||
|
return Services.prefs.getBoolPref("view_source.wrap_long_lines");
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A getter for the view source string bundle.
|
||||||
|
*/
|
||||||
|
get bundle() {
|
||||||
|
if (this._bundle) {
|
||||||
|
return this._bundle;
|
||||||
|
}
|
||||||
|
return this._bundle = Services.strings.createBundle(BUNDLE_URL);
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads the source for a URL while applying some optional features if
|
* Loads the source for a URL while applying some optional features if
|
||||||
* enabled.
|
* enabled.
|
||||||
|
@ -339,4 +358,185 @@ ViewSourceBrowser.prototype = {
|
||||||
} while (n != ancestor && p);
|
} while (n != ancestor && p);
|
||||||
return path;
|
return path;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load the view source browser from a fragment of some document, as in
|
||||||
|
* markups such as MathML where reformatting the output is helpful.
|
||||||
|
*
|
||||||
|
* @param aNode
|
||||||
|
* Some element within the fragment of interest.
|
||||||
|
* @param aContext
|
||||||
|
* A string denoting the type of fragment. Currently, "mathml" is the
|
||||||
|
* only accepted value.
|
||||||
|
*/
|
||||||
|
loadViewSourceFromFragment(node, context) {
|
||||||
|
var Node = node.ownerDocument.defaultView.Node;
|
||||||
|
this._lineCount = 0;
|
||||||
|
this._startTargetLine = 0;
|
||||||
|
this._endTargetLine = 0;
|
||||||
|
this._targetNode = node;
|
||||||
|
if (this._targetNode && this._targetNode.nodeType == Node.TEXT_NODE)
|
||||||
|
this._targetNode = this._targetNode.parentNode;
|
||||||
|
|
||||||
|
// walk up the tree to the top-level element (e.g., <math>, <svg>)
|
||||||
|
var topTag;
|
||||||
|
if (context == "mathml")
|
||||||
|
topTag = "math";
|
||||||
|
else
|
||||||
|
throw "not reached";
|
||||||
|
var topNode = this._targetNode;
|
||||||
|
while (topNode && topNode.localName != topTag)
|
||||||
|
topNode = topNode.parentNode;
|
||||||
|
if (!topNode)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// serialize
|
||||||
|
var title = this.bundle.GetStringFromName("viewMathMLSourceTitle");
|
||||||
|
var wrapClass = this.wrapLongLines ? ' class="wrap"' : '';
|
||||||
|
var source =
|
||||||
|
'<!DOCTYPE html>'
|
||||||
|
+ '<html>'
|
||||||
|
+ '<head><title>' + title + '</title>'
|
||||||
|
+ '<link rel="stylesheet" type="text/css" href="' + VIEW_SOURCE_CSS + '">'
|
||||||
|
+ '<style type="text/css">'
|
||||||
|
+ '#target { border: dashed 1px; background-color: lightyellow; }'
|
||||||
|
+ '</style>'
|
||||||
|
+ '</head>'
|
||||||
|
+ '<body id="viewsource"' + wrapClass
|
||||||
|
+ ' onload="document.title=\''+title+'\'; document.getElementById(\'target\').scrollIntoView(true)">'
|
||||||
|
+ '<pre>'
|
||||||
|
+ this._getOuterMarkup(topNode, 0)
|
||||||
|
+ '</pre></body></html>'
|
||||||
|
; // end
|
||||||
|
|
||||||
|
// display
|
||||||
|
this.browser.loadURI("data:text/html;charset=utf-8," +
|
||||||
|
encodeURIComponent(source));
|
||||||
|
},
|
||||||
|
|
||||||
|
_getInnerMarkup(node, indent) {
|
||||||
|
var str = '';
|
||||||
|
for (var i = 0; i < node.childNodes.length; i++) {
|
||||||
|
str += this._getOuterMarkup(node.childNodes.item(i), indent);
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
},
|
||||||
|
|
||||||
|
_getOuterMarkup(node, indent) {
|
||||||
|
var Node = node.ownerDocument.defaultView.Node;
|
||||||
|
var newline = "";
|
||||||
|
var padding = "";
|
||||||
|
var str = "";
|
||||||
|
if (node == this._targetNode) {
|
||||||
|
this._startTargetLine = this._lineCount;
|
||||||
|
str += '</pre><pre id="target">';
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (node.nodeType) {
|
||||||
|
case Node.ELEMENT_NODE: // Element
|
||||||
|
// to avoid the wide gap problem, '\n' is not emitted on the first
|
||||||
|
// line and the lines before & after the <pre id="target">...</pre>
|
||||||
|
if (this._lineCount > 0 &&
|
||||||
|
this._lineCount != this._startTargetLine &&
|
||||||
|
this._lineCount != this._endTargetLine) {
|
||||||
|
newline = "\n";
|
||||||
|
}
|
||||||
|
this._lineCount++;
|
||||||
|
for (var k = 0; k < indent; k++) {
|
||||||
|
padding += " ";
|
||||||
|
}
|
||||||
|
str += newline + padding
|
||||||
|
+ '<<span class="start-tag">' + node.nodeName + '</span>';
|
||||||
|
for (var i = 0; i < node.attributes.length; i++) {
|
||||||
|
var attr = node.attributes.item(i);
|
||||||
|
if (attr.nodeName.match(/^[-_]moz/)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
str += ' <span class="attribute-name">'
|
||||||
|
+ attr.nodeName
|
||||||
|
+ '</span>=<span class="attribute-value">"'
|
||||||
|
+ this._unicodeToEntity(attr.nodeValue)
|
||||||
|
+ '"</span>';
|
||||||
|
}
|
||||||
|
if (!node.hasChildNodes()) {
|
||||||
|
str += "/>";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
str += ">";
|
||||||
|
var oldLine = this._lineCount;
|
||||||
|
str += this._getInnerMarkup(node, indent + 2);
|
||||||
|
if (oldLine == this._lineCount) {
|
||||||
|
newline = "";
|
||||||
|
padding = "";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
newline = (this._lineCount == this._endTargetLine) ? "" : "\n";
|
||||||
|
this._lineCount++;
|
||||||
|
}
|
||||||
|
str += newline + padding
|
||||||
|
+ '</<span class="end-tag">' + node.nodeName + '</span>>';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Node.TEXT_NODE: // Text
|
||||||
|
var tmp = node.nodeValue;
|
||||||
|
tmp = tmp.replace(/(\n|\r|\t)+/g, " ");
|
||||||
|
tmp = tmp.replace(/^ +/, "");
|
||||||
|
tmp = tmp.replace(/ +$/, "");
|
||||||
|
if (tmp.length != 0) {
|
||||||
|
str += '<span class="text">' + this._unicodeToEntity(tmp) + '</span>';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node == this._targetNode) {
|
||||||
|
this._endTargetLine = this._lineCount;
|
||||||
|
str += '</pre><pre>';
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
},
|
||||||
|
|
||||||
|
_unicodeToEntity(text) {
|
||||||
|
const charTable = {
|
||||||
|
'&': '&<span class="entity">amp;</span>',
|
||||||
|
'<': '&<span class="entity">lt;</span>',
|
||||||
|
'>': '&<span class="entity">gt;</span>',
|
||||||
|
'"': '&<span class="entity">quot;</span>'
|
||||||
|
};
|
||||||
|
|
||||||
|
function charTableLookup(letter) {
|
||||||
|
return charTable[letter];
|
||||||
|
}
|
||||||
|
|
||||||
|
function convertEntity(letter) {
|
||||||
|
try {
|
||||||
|
var unichar = this._entityConverter
|
||||||
|
.ConvertToEntity(letter, entityVersion);
|
||||||
|
var entity = unichar.substring(1); // extract '&'
|
||||||
|
return '&<span class="entity">' + entity + '</span>';
|
||||||
|
} catch (ex) {
|
||||||
|
return letter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this._entityConverter) {
|
||||||
|
try {
|
||||||
|
this._entityConverter = Cc["@mozilla.org/intl/entityconverter;1"]
|
||||||
|
.createInstance(Ci.nsIEntityConverter);
|
||||||
|
} catch(e) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
const entityVersion = Ci.nsIEntityConverter.entityW3C;
|
||||||
|
|
||||||
|
var str = text;
|
||||||
|
|
||||||
|
// replace chars in our charTable
|
||||||
|
str = str.replace(/[<>&"]/g, charTableLookup);
|
||||||
|
|
||||||
|
// replace chars > 0x7f via nsIEntityConverter
|
||||||
|
str = str.replace(/[^\0-\u007f]/g, convertEntity);
|
||||||
|
|
||||||
|
return str;
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -6,22 +6,12 @@
|
||||||
|
|
||||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||||
|
|
||||||
var gDebug = 0;
|
function onLoadViewPartialSource() {
|
||||||
var gLineCount = 0;
|
|
||||||
var gStartTargetLine = 0;
|
|
||||||
var gEndTargetLine = 0;
|
|
||||||
var gTargetNode = null;
|
|
||||||
|
|
||||||
var gEntityConverter = null;
|
|
||||||
var gWrapLongLines = false;
|
|
||||||
const gViewSourceCSS = 'resource://gre-resources/viewsource.css';
|
|
||||||
|
|
||||||
function onLoadViewPartialSource()
|
|
||||||
{
|
|
||||||
// check the view_source.wrap_long_lines pref
|
// check the view_source.wrap_long_lines pref
|
||||||
// and set the menuitem's checked attribute accordingly
|
// and set the menuitem's checked attribute accordingly
|
||||||
gWrapLongLines = Services.prefs.getBoolPref("view_source.wrap_long_lines");
|
let wrapLongLines = Services.prefs.getBoolPref("view_source.wrap_long_lines");
|
||||||
document.getElementById("menu_wrapLongLines").setAttribute("checked", gWrapLongLines);
|
document.getElementById("menu_wrapLongLines")
|
||||||
|
.setAttribute("checked", wrapLongLines);
|
||||||
document.getElementById("menu_highlightSyntax")
|
document.getElementById("menu_highlightSyntax")
|
||||||
.setAttribute("checked",
|
.setAttribute("checked",
|
||||||
Services.prefs.getBoolPref("view_source.syntax_highlight"));
|
Services.prefs.getBoolPref("view_source.syntax_highlight"));
|
||||||
|
@ -29,186 +19,7 @@ function onLoadViewPartialSource()
|
||||||
if (window.arguments[3] == 'selection')
|
if (window.arguments[3] == 'selection')
|
||||||
viewSourceChrome.loadViewSourceFromSelection(window.arguments[2]);
|
viewSourceChrome.loadViewSourceFromSelection(window.arguments[2]);
|
||||||
else
|
else
|
||||||
viewPartialSourceForFragment(window.arguments[2], window.arguments[3]);
|
viewSourceChrome.loadViewSourceFromFragment(window.arguments[2], window.arguments[3]);
|
||||||
|
|
||||||
window.content.focus();
|
window.content.focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// special handler for markups such as MathML where reformatting the output is
|
|
||||||
// helpful
|
|
||||||
function viewPartialSourceForFragment(node, context)
|
|
||||||
{
|
|
||||||
gTargetNode = node;
|
|
||||||
if (gTargetNode && gTargetNode.nodeType == Node.TEXT_NODE)
|
|
||||||
gTargetNode = gTargetNode.parentNode;
|
|
||||||
|
|
||||||
// walk up the tree to the top-level element (e.g., <math>, <svg>)
|
|
||||||
var topTag;
|
|
||||||
if (context == 'mathml')
|
|
||||||
topTag = 'math';
|
|
||||||
else
|
|
||||||
throw 'not reached';
|
|
||||||
var topNode = gTargetNode;
|
|
||||||
while (topNode && topNode.localName != topTag)
|
|
||||||
topNode = topNode.parentNode;
|
|
||||||
if (!topNode)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// serialize
|
|
||||||
var title = gViewSourceBundle.getString("viewMathMLSourceTitle");
|
|
||||||
var wrapClass = gWrapLongLines ? ' class="wrap"' : '';
|
|
||||||
var source =
|
|
||||||
'<!DOCTYPE html>'
|
|
||||||
+ '<html>'
|
|
||||||
+ '<head><title>' + title + '</title>'
|
|
||||||
+ '<link rel="stylesheet" type="text/css" href="' + gViewSourceCSS + '">'
|
|
||||||
+ '<style type="text/css">'
|
|
||||||
+ '#target { border: dashed 1px; background-color: lightyellow; }'
|
|
||||||
+ '</style>'
|
|
||||||
+ '</head>'
|
|
||||||
+ '<body id="viewsource"' + wrapClass
|
|
||||||
+ ' onload="document.title=\''+title+'\';document.getElementById(\'target\').scrollIntoView(true)">'
|
|
||||||
+ '<pre>'
|
|
||||||
+ getOuterMarkup(topNode, 0)
|
|
||||||
+ '</pre></body></html>'
|
|
||||||
; // end
|
|
||||||
|
|
||||||
// display
|
|
||||||
gBrowser.loadURI("data:text/html;charset=utf-8," + encodeURIComponent(source));
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
function getInnerMarkup(node, indent) {
|
|
||||||
var str = '';
|
|
||||||
for (var i = 0; i < node.childNodes.length; i++) {
|
|
||||||
str += getOuterMarkup(node.childNodes.item(i), indent);
|
|
||||||
}
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
function getOuterMarkup(node, indent) {
|
|
||||||
var newline = '';
|
|
||||||
var padding = '';
|
|
||||||
var str = '';
|
|
||||||
if (node == gTargetNode) {
|
|
||||||
gStartTargetLine = gLineCount;
|
|
||||||
str += '</pre><pre id="target">';
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (node.nodeType) {
|
|
||||||
case Node.ELEMENT_NODE: // Element
|
|
||||||
// to avoid the wide gap problem, '\n' is not emitted on the first
|
|
||||||
// line and the lines before & after the <pre id="target">...</pre>
|
|
||||||
if (gLineCount > 0 &&
|
|
||||||
gLineCount != gStartTargetLine &&
|
|
||||||
gLineCount != gEndTargetLine) {
|
|
||||||
newline = '\n';
|
|
||||||
}
|
|
||||||
gLineCount++;
|
|
||||||
if (gDebug) {
|
|
||||||
newline += gLineCount;
|
|
||||||
}
|
|
||||||
for (var k = 0; k < indent; k++) {
|
|
||||||
padding += ' ';
|
|
||||||
}
|
|
||||||
str += newline + padding
|
|
||||||
+ '<<span class="start-tag">' + node.nodeName + '</span>';
|
|
||||||
for (var i = 0; i < node.attributes.length; i++) {
|
|
||||||
var attr = node.attributes.item(i);
|
|
||||||
if (!gDebug && attr.nodeName.match(/^[-_]moz/)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
str += ' <span class="attribute-name">'
|
|
||||||
+ attr.nodeName
|
|
||||||
+ '</span>=<span class="attribute-value">"'
|
|
||||||
+ unicodeTOentity(attr.nodeValue)
|
|
||||||
+ '"</span>';
|
|
||||||
}
|
|
||||||
if (!node.hasChildNodes()) {
|
|
||||||
str += '/>';
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
str += '>';
|
|
||||||
var oldLine = gLineCount;
|
|
||||||
str += getInnerMarkup(node, indent + 2);
|
|
||||||
if (oldLine == gLineCount) {
|
|
||||||
newline = '';
|
|
||||||
padding = '';
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
newline = (gLineCount == gEndTargetLine) ? '' : '\n';
|
|
||||||
gLineCount++;
|
|
||||||
if (gDebug) {
|
|
||||||
newline += gLineCount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
str += newline + padding
|
|
||||||
+ '</<span class="end-tag">' + node.nodeName + '</span>>';
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case Node.TEXT_NODE: // Text
|
|
||||||
var tmp = node.nodeValue;
|
|
||||||
tmp = tmp.replace(/(\n|\r|\t)+/g, " ");
|
|
||||||
tmp = tmp.replace(/^ +/, "");
|
|
||||||
tmp = tmp.replace(/ +$/, "");
|
|
||||||
if (tmp.length != 0) {
|
|
||||||
str += '<span class="text">' + unicodeTOentity(tmp) + '</span>';
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (node == gTargetNode) {
|
|
||||||
gEndTargetLine = gLineCount;
|
|
||||||
str += '</pre><pre>';
|
|
||||||
}
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
function unicodeTOentity(text)
|
|
||||||
{
|
|
||||||
const charTable = {
|
|
||||||
'&': '&<span class="entity">amp;</span>',
|
|
||||||
'<': '&<span class="entity">lt;</span>',
|
|
||||||
'>': '&<span class="entity">gt;</span>',
|
|
||||||
'"': '&<span class="entity">quot;</span>'
|
|
||||||
};
|
|
||||||
|
|
||||||
function charTableLookup(letter) {
|
|
||||||
return charTable[letter];
|
|
||||||
}
|
|
||||||
|
|
||||||
function convertEntity(letter) {
|
|
||||||
try {
|
|
||||||
var unichar = gEntityConverter.ConvertToEntity(letter, entityVersion);
|
|
||||||
var entity = unichar.substring(1); // extract '&'
|
|
||||||
return '&<span class="entity">' + entity + '</span>';
|
|
||||||
} catch (ex) {
|
|
||||||
return letter;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!gEntityConverter) {
|
|
||||||
try {
|
|
||||||
gEntityConverter =
|
|
||||||
Components.classes["@mozilla.org/intl/entityconverter;1"]
|
|
||||||
.createInstance(Components.interfaces.nsIEntityConverter);
|
|
||||||
} catch(e) { }
|
|
||||||
}
|
|
||||||
|
|
||||||
const entityVersion = Components.interfaces.nsIEntityConverter.entityW3C;
|
|
||||||
|
|
||||||
var str = text;
|
|
||||||
|
|
||||||
// replace chars in our charTable
|
|
||||||
str = str.replace(/[<>&"]/g, charTableLookup);
|
|
||||||
|
|
||||||
// replace chars > 0x7f via nsIEntityConverter
|
|
||||||
str = str.replace(/[^\0-\u007f]/g, convertEntity);
|
|
||||||
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
|
@ -19,8 +19,8 @@ const BUNDLE_URL = "chrome://global/locale/viewSource.properties";
|
||||||
// We use noncharacter Unicode codepoints to minimize the risk of clashing
|
// We use noncharacter Unicode codepoints to minimize the risk of clashing
|
||||||
// with anything that might legitimately be present in the document.
|
// with anything that might legitimately be present in the document.
|
||||||
// U+FDD0..FDEF <noncharacters>
|
// U+FDD0..FDEF <noncharacters>
|
||||||
const MARK_SELECTION_START = '\uFDD0';
|
const MARK_SELECTION_START = "\uFDD0";
|
||||||
const MARK_SELECTION_END = '\uFDEF';
|
const MARK_SELECTION_END = "\uFDEF";
|
||||||
|
|
||||||
let global = this;
|
let global = this;
|
||||||
|
|
||||||
|
@ -69,7 +69,8 @@ let ViewSourceContent = {
|
||||||
|
|
||||||
get isViewSource() {
|
get isViewSource() {
|
||||||
let uri = content.document.documentURI;
|
let uri = content.document.documentURI;
|
||||||
return uri.startsWith("view-source:");
|
return uri.startsWith("view-source:") ||
|
||||||
|
(uri.startsWith("data:") && uri.includes("MathML"));
|
||||||
},
|
},
|
||||||
|
|
||||||
get isAboutBlank() {
|
get isAboutBlank() {
|
||||||
|
|
|
@ -109,6 +109,27 @@ var gViewSourceUtils = {
|
||||||
viewSourceBrowser.loadViewSourceFromSelection(aSelection);
|
viewSourceBrowser.loadViewSourceFromSelection(aSelection);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays view source for a MathML fragment from some document in the
|
||||||
|
* provided <browser>. This allows for non-window display methods, such as a
|
||||||
|
* tab from Firefox. The caller that manages the <browser> is responsible for
|
||||||
|
* ensuring the companion frame script, viewSource-content.js, has been loaded
|
||||||
|
* for the <browser>.
|
||||||
|
*
|
||||||
|
* @param aNode
|
||||||
|
* Some element within the fragment of interest.
|
||||||
|
* @param aContext
|
||||||
|
* A string denoting the type of fragment. Currently, "mathml" is the
|
||||||
|
* only accepted value.
|
||||||
|
* @param aViewSourceInBrowser
|
||||||
|
* The browser to display the view source in.
|
||||||
|
*/
|
||||||
|
viewSourceFromFragmentInBrowser: function(aNode, aContext,
|
||||||
|
aViewSourceInBrowser) {
|
||||||
|
let viewSourceBrowser = new ViewSourceBrowser(aViewSourceInBrowser);
|
||||||
|
viewSourceBrowser.loadViewSourceFromFragment(aNode, aContext);
|
||||||
|
},
|
||||||
|
|
||||||
// Opens the interval view source viewer
|
// Opens the interval view source viewer
|
||||||
_openInInternalViewer: function(aArgsOrURL, aPageDescriptor, aDocument, aLineNumber)
|
_openInInternalViewer: function(aArgsOrURL, aPageDescriptor, aDocument, aLineNumber)
|
||||||
{
|
{
|
||||||
|
|
Загрузка…
Ссылка в новой задаче