Add 'View Selection/MathML Source' to the context menu & the support for that to work, namely: enlist MathML entity names, break viewSource.xul into a sharable XUL overlay, and implement the necessary logic to automatically re-select a selection into the inflated view-source display. b=49721,1222524, r=bzbarsky, sr=alecf

This commit is contained in:
rbs%maths.uq.edu.au 2002-05-10 22:05:59 +00:00
Родитель 944c721427
Коммит eae1de0251
16 изменённых файлов: 2072 добавлений и 185 удалений

Просмотреть файл

@ -275,11 +275,7 @@ res:loading-image.gif
res:broken-image.gif
res:builtin:htmlBindings.xml
res:builtin:platformHTMLBindings.xml
res:entityTables:html40Latin1.properties
res:entityTables:html40Special.properties
res:entityTables:html40Symbols.properties
res:entityTables:htmlEntityVersions.properties
res:entityTables:transliterate.properties
res:entityTables:*
res:fonts:*
;

Просмотреть файл

@ -275,11 +275,7 @@ res:loading-image.gif
res:broken-image.gif
res:builtin:htmlBindings.xml
res:builtin:platformHTMLBindings.xml
res:entityTables:html40Latin1.properties
res:entityTables:html40Special.properties
res:entityTables:html40Symbols.properties
res:entityTables:htmlEntityVersions.properties
res:entityTables:transliterate.properties
res:entityTables:*
res:fonts:*
;

Просмотреть файл

@ -296,11 +296,7 @@ res\loading-image.gif
res\broken-image.gif
res\builtin\htmlBindings.xml
res\builtin\platformHTMLBindings.xml
res\entityTables\html40Latin1.properties
res\entityTables\html40Special.properties
res\entityTables\html40Symbols.properties
res\entityTables\htmlEntityVersions.properties
res\entityTables\transliterate.properties
res\entityTables\*
res\fonts\*
;

Просмотреть файл

@ -52,10 +52,11 @@ interface nsIEntityConverter : nsISupports
const unsigned long html40Symbols = 2;
const unsigned long html40Special = 4; // excludes &quot, &amp, &lt, &gt
const unsigned long transliterate = 8;
const unsigned long mathml20 = 16;
const unsigned long html32 = html40Latin1;
const unsigned long html40 = html40Latin1+html40Symbols+html40Special;
string ConvertToEntity(in wchar character, in unsigned long entityVersion);
string ConvertToEntity(in wchar character, in unsigned long entityVersion);
wstring ConvertToEntities(in wstring inString, in unsigned long entityVersion);
};

Просмотреть файл

@ -36,6 +36,10 @@ _PROP_TABLES = \
transliterate.properties \
$(NULL)
ifdef MOZ_MATHML
_PROP_TABLES += mathml20.properties
endif
libs:: $(_PROP_TABLES)
$(INSTALL) $^ $(DIST)/bin/res/entityTables

Просмотреть файл

@ -25,8 +25,9 @@
# list supported versions number/name pair
# length should not be greater than 32
length=4
length=5
1=html40Latin1
2=html40Symbols
3=html40Special
4=transliterate
5=mathml20

Просмотреть файл

@ -1,41 +0,0 @@
#!gmake
#
# The contents of this file are subject to the Netscape 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/NPL/
#
# 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 mozilla.org code.
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
MODULE=unicharutil
DEPTH=..\..\..
include <$(DEPTH)/config/rules.mak>
libs::
$(MAKE_INSTALL) .\htmlEntityVersions.properties $(DIST)\bin\res\entityTables
$(MAKE_INSTALL) .\html40Latin1.properties $(DIST)\bin\res\entityTables
$(MAKE_INSTALL) .\html40Symbols.properties $(DIST)\bin\res\entityTables
$(MAKE_INSTALL) .\html40Special.properties $(DIST)\bin\res\entityTables
$(MAKE_INSTALL) .\transliterate.properties $(DIST)\bin\res\entityTables
clobber::
rm -fr $(DIST)\res
rm -fr $(DIST)\bin\res\entityTables

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -25,6 +25,9 @@ comm.jar:
content/navigator/turboDialog.xul (resources/content/turboDialog.xul)
content/navigator/viewsource.js (resources/content/viewsource.js)
content/navigator/viewSource.xul (resources/content/viewSource.xul)
content/navigator/viewSourceOverlay.xul (resources/content/viewSourceOverlay.xul)
content/navigator/viewPartialSource.js (resources/content/viewPartialSource.js)
content/navigator/viewPartialSource.xul (resources/content/viewPartialSource.xul)
en-US.jar:
locale/en-US/navigator/contents.rdf (resources/locale/en-US/contents.rdf)
locale/en-US/navigator/viewSource.dtd (resources/locale/en-US/viewSource.dtd)

Просмотреть файл

@ -0,0 +1,478 @@
/* ***** 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 mozilla.org view-source front-end.
*
* The Initial Developer of the Original Code is mozilla.org.
* Portions created by the Initial Developer are Copyright (C) 2002
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Roger B. Sidje <rbs@maths.uq.edu.au> (Original Author)
* Steve Swanson <steve.swanson@mackichan.com>
* Doron Rosenberg <doronr@naboonline.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 ***** */
var gDebug = 0;
var gLineCount = 0;
var gStartTargetLine = 0;
var gEndTargetLine = 0;
var gTargetNode = null;
var gEntityConverter = null;
var gWrapLongLines = false;
const gViewSourceCSS = 'resource:///res/viewsource.css';
const NS_XHTML = 'http://www.w3.org/1999/xhtml';
// These are markers used to delimit the selection during processing. They
// are removed from the final rendering, but we pick space-like characters for
// safety (and futhermore, these are known to be mapped to a 0-length string
// in transliterate.properties). It is okay to set start=end, we use findNext()
// U+200B ZERO WIDTH SPACE
const MARK_SELECTION_START = '\u200B\u200B\u200B\u200B\u200B';
const MARK_SELECTION_END = '\u200B\u200B\u200B\u200B\u200B';
function onLoadViewPartialSource()
{
// check the view_source.wrap_long_lines pref and set the menuitem's checked attribute accordingly
if (gPrefs) {
try {
var wraplonglinesPrefValue = gPrefs.getBoolPref('view_source.wrap_long_lines');
if (wraplonglinesPrefValue) {
document.getElementById('menu_wrapLongLines').setAttribute('checked', 'true');
gWrapLongLines = true;
}
} catch (e) { }
}
// disable menu items that don't work since the selection is munged and
// the editor doesn't work for MathML
document.getElementById('cmd_savePage').setAttribute('disabled', 'true');
document.getElementById('cmd_editPage').setAttribute('disabled', 'true');
if (window.arguments[3] == 'selection')
viewPartialSourceForSelection(window.arguments[2]);
else
viewPartialSourceForFragment(window.arguments[2], window.arguments[3]);
window._content.focus();
}
////////////////////////////////////////////////////////////////////////////////
// view-source of a selection with the special effect of remapping the selection
// to the underlying view-source output
function viewPartialSourceForSelection(selection)
{
var range = selection.getRangeAt(0);
var ancestorContainer = range.commonAncestorContainer;
var doc = ancestorContainer.ownerDocument;
var startContainer = range.startContainer;
var endContainer = range.endContainer;
var startOffset = range.startOffset;
var endOffset = range.endOffset;
// let the ancestor be an element
if (ancestorContainer.nodeType == Node.TEXT_NODE ||
ancestorContainer.nodeType == Node.CDATA_SECTION_NODE)
ancestorContainer = ancestorContainer.parentNode;
// each path is a "child sequence" (a.k.a. "tumbler") that
// descends from the ancestor down to the boundary point
var startPath = getPath(ancestorContainer, startContainer);
var endPath = getPath(ancestorContainer, endContainer);
// clone the fragment of interest and reset everything to be relative to it
ancestorContainer = ancestorContainer.cloneNode(true);
startContainer = ancestorContainer;
endContainer = ancestorContainer;
var i;
for (i = startPath ? startPath.length-1 : -1; i >= 0; i--) {
startContainer = startContainer.childNodes.item(startPath[i]);
}
for (i = endPath ? endPath.length-1 : -1; i >= 0; i--) {
endContainer = endContainer.childNodes.item(endPath[i]);
}
// add special markers to record the extent of the selection
// note: |startOffset| and |endOffset| are interpreted either as
// offsets in the text data or as child indices (see the Range spec)
// (here, munging the end point first to keep the start point safe...)
var tmpNode;
if (endContainer.nodeType == Node.TEXT_NODE ||
endContainer.nodeType == Node.CDATA_SECTION_NODE) {
// do some extra tweaks to try to avoid the view-source output to look like
// ...<tag>]... or ...]</tag>... (where ']' marks the end of the selection).
// To get a neat output, the idea here is to remap the end point from:
// 1. ...<tag>]... to ...]<tag>...
// 2. ...]</tag>... to ...</tag>]...
if ((endOffset > 0 && endOffset < endContainer.data.length-1) ||
!endContainer.parentNode || !endContainer.parentNode.parentNode)
endContainer.insertData(endOffset, MARK_SELECTION_END);
else {
tmpNode = doc.createTextNode(MARK_SELECTION_END);
endContainer = endContainer.parentNode;
if (endOffset == 0)
endContainer.parentNode.insertBefore(tmpNode, endContainer);
else
endContainer.parentNode.insertBefore(tmpNode, endContainer.nextSibling);
}
}
else {
tmpNode = doc.createTextNode(MARK_SELECTION_END);
endContainer.insertBefore(tmpNode, endContainer.childNodes.item(endOffset));
}
if (startContainer.nodeType == Node.TEXT_NODE ||
startContainer.nodeType == Node.CDATA_SECTION_NODE) {
// do some extra tweaks to try to avoid the view-source output to look like
// ...<tag>[... or ...[</tag>... (where '[' marks the start of the selection).
// To get a neat output, the idea here is to remap the start point from:
// 1. ...<tag>[... to ...[<tag>...
// 2. ...[</tag>... to ...</tag>[...
if ((startOffset > 0 && startOffset < startContainer.data.length-1) ||
!startContainer.parentNode || !startContainer.parentNode.parentNode)
startContainer.insertData(startOffset, MARK_SELECTION_START);
else {
tmpNode = doc.createTextNode(MARK_SELECTION_START);
startContainer = startContainer.parentNode;
if (startOffset == 0)
startContainer.parentNode.insertBefore(tmpNode, startContainer);
else
startContainer.parentNode.insertBefore(tmpNode, startContainer.nextSibling);
}
}
else {
tmpNode = doc.createTextNode(MARK_SELECTION_START);
startContainer.insertBefore(tmpNode, startContainer.childNodes.item(startOffset));
}
// now extract and display the syntax highlighted source
tmpNode = doc.createElementNS(NS_XHTML, 'div');
tmpNode.appendChild(ancestorContainer);
// the load is aynchronous and so we will wait until the view-source DOM is done
// before drawing the selection.
window.document.getElementById("appcontent").addEventListener("load", drawSelection, true);
// all our content is held by the data:URI and URIs are internally stored as utf-8 (see nsIURI.idl)
var loadFlags = Components.interfaces.nsIWebNavigation.LOAD_FLAGS_BYPASS_CACHE;
getBrowser().webNavigation
.loadURI("view-source:data:text/html;charset=utf-8," + escape(tmpNode.innerHTML),
loadFlags, null, null, null);
}
////////////////////////////////////////////////////////////////////////////////
// helper to get a path like FIXptr, but with an array instead of the "tumbler" notation
// see FIXptr: http://lists.w3.org/Archives/Public/www-xml-linking-comments/2001AprJun/att-0074/01-NOTE-FIXptr-20010425.htm
function getPath(ancestor, node)
{
var n = node;
var p = n.parentNode;
if (n == ancestor || !p)
return null;
var path = new Array();
if (!path)
return null;
do {
for (var i = 0; i < p.childNodes.length; i++) {
if (p.childNodes.item(i) == n) {
path.push(i);
break;
}
}
n = p;
p = n.parentNode;
} while (n != ancestor && p);
return path;
}
////////////////////////////////////////////////////////////////////////////////
// using special markers left in the serialized source, this helper makes the
// underlying markup of the selected fragement to automatically appear as selected
// on the inflated view-source DOM
function drawSelection()
{
// find the special selection markers that we added earlier, and
// draw the selection between the two...
var findService = null;
try {
// get the find service which stores the global find state
findService = Components.classes["@mozilla.org/find/find_service;1"]
.getService(Components.interfaces.nsIFindService);
} catch(e) { }
if (!findService)
return;
// cache the current global find state
var matchCase = findService.matchCase;
var entireWord = findService.entireWord;
var wrapFind = findService.wrapFind;
var findBackwards = findService.findBackwards;
var searchString = findService.searchString;
var replaceString = findService.replaceString;
// setup our find instance
var findInst = getBrowser().webBrowserFind;
findInst.matchCase = true;
findInst.entireWord = false;
findInst.wrapFind = false;
findInst.findBackwards = false;
// ...lookup the start mark
findInst.searchString = MARK_SELECTION_START;
var startLength = MARK_SELECTION_START.length;
findInst.findNext();
var contentWindow = getBrowser().contentDocument.defaultView;
var selection = contentWindow.getSelection();
var range = selection.getRangeAt(0);
var startContainer = range.startContainer;
var startOffset = range.startOffset;
// ...lookup the end mark
findInst.searchString = MARK_SELECTION_END;
var endLength = MARK_SELECTION_END.length;
findInst.findNext();
var endContainer = selection.anchorNode;
var endOffset = selection.anchorOffset;
// reset the selection that find has left
selection.removeAllRanges();
// delete the special markers now...
endContainer.deleteData(endOffset, endLength);
startContainer.deleteData(startOffset, startLength);
if (startContainer == endContainer)
endOffset -= startLength; // has shrunk if on same text node...
range.setEnd(endContainer, endOffset);
// show the selection and scroll it into view
selection.addRange(range);
// the default behavior of the selection is to scroll at the end of
// the selection, whereas in this situation, it is more user-friendly
// to scroll at the beginning. So we override the default behavior here
try {
getBrowser().docShell
.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsISelectionDisplay)
.QueryInterface(Components.interfaces.nsISelectionController)
.scrollSelectionIntoView(Components.interfaces.nsISelectionController.SELECTION_NORMAL,
Components.interfaces.nsISelectionController.SELECTION_ANCHOR_REGION);
}
catch(e) { }
// restore the current find state
findService.matchCase = matchCase;
findService.entireWord = entireWord;
findService.wrapFind = wrapFind;
findService.findBackwards = findBackwards;
findService.searchString = searchString;
findService.replaceString = replaceString;
findInst.matchCase = matchCase;
findInst.entireWord = entireWord;
findInst.wrapFind = wrapFind;
findInst.findBackwards = findBackwards;
findInst.searchString = searchString;
}
////////////////////////////////////////////////////////////////////////////////
// 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 (note: the main window overrides the title set here)
var wrapClass = gWrapLongLines ? ' class="wrap"' : '';
var source =
'<html>'
+ '<head><title>Mozilla</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.getElementById(\'target\').scrollIntoView(true)">'
+ '<pre>'
+ getOuterMarkup(topNode, 0)
+ '</pre></body></html>'
; // end
// display
var doc = getBrowser().contentDocument;
doc.open("text/html", "replace");
doc.write(source);
doc.close();
}
////////////////////////////////////////////////////////////////////////////////
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
+ '&lt;<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 += '/&gt;';
}
else {
str += '&gt;';
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
+ '&lt;/<span class="end-tag">' + node.nodeName + '</span>&gt;';
}
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)
{
if (!gEntityConverter) {
try {
gEntityConverter = Components.classes["@mozilla.org/intl/entityconverter;1"]
.createInstance(Components.interfaces.nsIEntityConverter);
} catch(e) { }
}
var entityVersion = Components.interfaces.nsIEntityConverter.html40
+ Components.interfaces.nsIEntityConverter.mathml20;
var str = '';
for (var i = 0; i < text.length; i++) {
var c = text.charCodeAt(i);
if ((c <= 0x7F) || !gEntityConverter) {
if (text[i] == '<')
str += '&amp;<span class="entity">lt;</span>';
else if (text[i] == '>')
str += '&amp;<span class="entity">gt;</span>';
else if (text[i] == '&')
str += '&amp;<span class="entity">amp;</span>';
else
str += text[i];
}
else {
try {
var unichar = gEntityConverter.ConvertToEntity(text[i], entityVersion);
str += '&amp;<span class="entity">'
+ unichar.substring(1, unichar.length) // extract '&'
+ '</span>';
}
catch(e) {
str += text[i];
}
}
}
return str;
}

Просмотреть файл

@ -0,0 +1,82 @@
<?xml version="1.0"?> <!-- -*- Mode: HTML -*- -->
<?xml-stylesheet href="chrome://navigator/skin/" type="text/css"?>
<!--
- 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 mozilla.org view-source front end.
-
- The Initial Developer of the Original Code is mozilla.org.
- Portions created by the Initial Developer are Copyright (C) 2002
- the Initial Developer. All Rights Reserved.
-
- Contributor(s):
- Roger B. Sidje <rbs@maths.uq.edu.au> (Original Author)
- Doron Rosenberg <doronr@naboonline.com>
-
- Alternatively, the contents of this file may be used under the
- terms of the GNU General Public License Version 2 or later (the
- "GPL"), in which case the provisions of the GPL are applicable
- instead of those above. If you wish to allow use of your
- version of this file only under the terms of the GPL and not to
- allow others to use your version of this file under the MPL,
- indicate your decision by deleting the provisions above and
- replace them with the notice and other provisions required by
- the GPL. If you do not delete the provisions above, a recipient
- may use your version of this file under either the MPL or the
- GPL.
-->
<?xul-overlay href="chrome://navigator/content/viewSourceOverlay.xul"?>
<!DOCTYPE window [
<!ENTITY % brandDTD SYSTEM "chrome://global/locale/brand.dtd" >
%brandDTD;
<!ENTITY % sourceDTD SYSTEM "chrome://navigator/locale/viewSource.dtd" >
%sourceDTD;
<!ENTITY % navigatorDTD SYSTEM "chrome://navigator/locale/navigator.dtd" >
%navigatorDTD;
<!ENTITY % contentAreaCommandsDTD SYSTEM "chrome://communicator/locale/contentAreaCommands.dtd" >
%contentAreaCommandsDTD;
]>
<window id="main-window"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
onload="onLoadViewPartialSource();"
contenttitlesetting="false"
title="&mainWindow.title;"
titlemodifier="&mainWindow.titlemodifier;"
titlepreface=""
titlemenuseparator ="&mainWindow.titlemodifierseparator;"
windowtype="navigator:view-source"
width="500" height="300"
screenX="10" screenY="10"
persist="screenX screenY width height sizemode">
<script type="application/x-javascript" src="chrome://navigator/content/viewPartialSource.js"/>
<commandset id="commands"/>
<keyset id="viewSourceKeys"/>
<stringbundleset id="viewSource-stringbundleset"/>
<popupset id="viewSourceContextSet" />
<popup id="contentAreaContextMenu"/>
<toolbox id="viewSource-toolbox"/>
<vbox id="appcontent" flex="1"
ondragdrop="nsDragAndDrop.drop(event, contentAreaDNDObserver);">
<browser id="content" type="content-primary" name="content" src="about:blank" flex="1"
context="viewSourceContextMenu"/>
</vbox>
</window>

Просмотреть файл

@ -1,7 +1,7 @@
<?xml version="1.0"?> <!-- -*- Mode: HTML -*- -->
<?xml-stylesheet href="chrome://navigator/skin/" type="text/css"?>
<!--
<!--
- 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
@ -21,9 +21,22 @@
-
- Contributor(s):
- Doron Rosenberg (doronr@naboonline.com)
- Roger B. Sidje (rbs@maths.uq.edu.au)
-
- Alternatively, the contents of this file may be used under the
- terms of the GNU General Public License Version 2 or later (the
- "GPL"), in which case the provisions of the GPL are applicable
- instead of those above. If you wish to allow use of your
- version of this file only under the terms of the GPL and not to
- allow others to use your version of this file under the MPL,
- indicate your decision by deleting the provisions above and
- replace them with the notice and other provisions required by
- the GPL. If you do not delete the provisions above, a recipient
- may use your version of this file under either the MPL or the
- GPL.
-->
<?xul-overlay href="chrome://navigator/content/navigatorOverlay.xul"?>
<?xul-overlay href="chrome://navigator/content/viewSourceOverlay.xul"?>
<!DOCTYPE window [
<!ENTITY % brandDTD SYSTEM "chrome://global/locale/brand.dtd" >
@ -38,133 +51,24 @@
<window id="main-window"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
onload="onLoadViewSource();"
contenttitlesetting="true"
title="&mainWindow.title;"
titlemodifier="&mainWindow.titlemodifier;"
titlepreface="&mainWindow.preface;"
titlemenuseparator ="&mainWindow.titlemodifierseparator;"
windowtype="navigator:view-source"
width="640" height="480"
screenX="10" screenY="10"
persist="screenX screenY width height sizemode">
<script type="application/x-javascript" src="chrome://global/content/nsJSSupportsUtils.js"/>
<script type="application/x-javascript" src="chrome://global/content/nsJSComponentManager.js"/>
<script type="application/x-javascript" src="chrome://global/content/nsTransferable.js"/>
<script type="application/x-javascript" src="chrome://global/content/nsDragAndDrop.js"/>
<script type="application/x-javascript" src="chrome://communicator/content/contentAreaDD.js"/>
<script type="application/x-javascript" src="chrome://navigator/content/browser.js"/>
<script type="application/x-javascript" src="chrome://navigator/content/viewsource.js"/>
<script type="application/x-javascript" src="chrome://communicator/content/findUtils.js"/>
<script type="application/x-javascript" src="chrome://communicator/content/contentAreaUtils.js"/>
onload="onLoadViewSource();"
contenttitlesetting="true"
title="&mainWindow.title;"
titlemodifier="&mainWindow.titlemodifier;"
titlepreface="&mainWindow.preface;"
titlemenuseparator ="&mainWindow.titlemodifierseparator;"
windowtype="navigator:view-source"
width="640" height="480"
screenX="10" screenY="10"
persist="screenX screenY width height sizemode">
<commandset id="commands">
<commandset id="globalEditMenuItems"/>
<commandset id="selectEditMenuItems"/>
<commandset id="clipboardEditMenuItems"/>
<commandset id="viewSourceMenuItems">
<command id="cmdWrapLongLines" oncommand="wrapLongLines()"/>
<command id="cmd_close" oncommand="ViewSourceClose()"/>
<command id="cmd_savePage" oncommand="ViewSourceSavePage();"/>
</commandset>
</commandset>
<stringbundleset id="stringbundleset">
<stringbundle id="findBundle" src="chrome://global/locale/finddialog.properties"/>
</stringbundleset>
<commandset id="commands"/>
<keyset id="viewSourceKeys"/>
<stringbundleset id="viewSource-stringbundleset"/>
<popupset id="viewSourceContextSet" />
<popup id="contentAreaContextMenu"/>
<!-- keys are appended from the overlay -->
<keyset id="viewSourceKeys">
<!-- File Menu -->
<key id="key_newNavigator"/>
<key id="key_newBlankPage"/>
<key id="key_savePage" key="&savePageCmd.commandkey;" command="cmd_savePage" modifiers="accel"/>
<key id="key_editPage" key="&editPageCmd.commandkey;" command="Browser:EditPage" modifiers="accel"/>
<key id="printKb" key="&printCmd.commandkey;" command="Browser:Print" modifiers="accel"/>
<key id="key_close"/>
<!-- Edit Menu -->
<key id="key_undo"/>
<key id="key_redo"/>
<key id="key_cut"/>
<key id="key_copy"/>
<key id="key_paste"/>
<key id="key_delete"/>
<key id="key_selectAll"/>
<key id="key_find" key="&findOnCmd.commandkey;" command="Browser:Find" modifiers="accel"/>
<key id="key_findAgain" key="&findAgainCmd.commandkey;" command="Browser:FindAgain" modifiers="accel"/>
<keyset id="viewZoomKeys"/>
</keyset>
<!-- context menu -->
<popupset id="viewSourceContextSet">
<popup id="viewSourceContextMenu">
<menuitem label="&findNextCmd.label;" accesskey="&findNextCmd.accesskey;" command="Browser:FindAgain"/>
<menuseparator/>
<menuitem id="menu_copy_cm" label="&copyCmd.label;" accesskey="&copyCmd.accesskey;" command="cmd_copy"/>
<menuseparator/>
<menuitem id="menu_selectAll_cm" label="&selectAllCmd.label;" accesskey="&selectAllCmd.accesskey;" command="cmd_selectAll"/>
</popup>
</popupset>
<!-- Menu -->
<toolbox>
<menubar id="zmain-menubar">
<menu id="menu_File">
<menupopup id="filemenu-popup">
<menu id="menu_New">
<menupopup id="menu_NewPopup">
<menuitem id="menu_newNavigator" command="cmd_newNavigator"/>
<menuitem id="menu_newEditor" command="cmd_newEditor"/>
</menupopup>
</menu>
<menuseparator/>
<menuitem id="menu_close"/>
<menuitem label="&savePageCmd.label;" accesskey="&savePageCmd.accesskey;" key="key_savePage" command="cmd_savePage"/>
<menuitem id="savepage" label="&saveFrameCmd.label;" accesskey="&saveFrameCmd.accesskey;" oncommand="ViewSourceSavePage();" hidden="true"/>
<menuseparator/>
<menuitem label="&editPageCmd.label;" accesskey="&editPageCmd.accesskey;" key="key_editPage" oncommand="ViewSourceEditPage();"/>
<menuseparator/>
<menuitem label="&printCmd.label;" accesskey="&printCmd.accesskey;" key="printKb" command="Browser:Print"/>
<!-- <menuitem accesskey="&printPreviewCmd.accesskey;" observes="Browser:PrintPreview"/> -->
</menupopup>
</menu>
<menu id="menu_Edit">
<menupopup>
<menuitem id="menu_undo"/>
<menuitem id="menu_redo"/>
<menuseparator/>
<menuitem id="menu_cut"/>
<menuitem id="menu_copy"/>
<menuitem id="menu_paste"/>
<menuitem id="menu_delete"/>
<menuseparator/>
<menuitem id="menu_selectAll"/>
<menuseparator />
<menuitem id="menu_find" label="&findOnCmd.label;" accesskey="&findOnCmd.accesskey;" key="key_find" command="Browser:Find"/>
<menuitem id="menu_findAgain" label="&findAgainCmd.label;" accesskey="&findAgainCmd.accesskey;" key="key_findAgain" command="Browser:FindAgain"/>
</menupopup>
</menu>
<menu id="menu_view" accesskey="&viewMenu.accesskey;" label="&viewMenu.label;">
<menupopup>
<menu id="menu_textZoom"/>
<menuseparator/>
<!-- <menuitem accesskey="&pageInfoCmd.accesskey;" label="&pageInfoCmd.label;" key="key_viewInfo" observes="View:PageInfo"/>
<menuseparator id="file_moduleSeparator"/>-->
<menu id = "charsetMenu"/>
<menuitem id="menu_wrapLongLines" label="&menu_wrapLongLines.title;" accesskey="&menu_wrapLongLines.accesskey;" type="checkbox" command="cmdWrapLongLines"/>
</menupopup>
</menu>
<menu id="menu_Help"/>
</menubar>
</toolbox>
<toolbox id="viewSource-toolbox"/>
<vbox id="appcontent" flex="1"
ondragdrop="nsDragAndDrop.drop(event, contentAreaDNDObserver);">

Просмотреть файл

@ -0,0 +1,172 @@
<?xml version="1.0"?> <!-- -*- Mode: HTML -*- -->
<?xml-stylesheet href="chrome://navigator/skin/" type="text/css"?>
<!--
- 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 mozilla.org view-source front-end.
-
- The Initial Developer of the Original Code is mozilla.org.
- Portions created by the Initial Developer are Copyright (C) 2002
- the Initial Developer. All Rights Reserved.
-
- Contributor(s):
- Doron Rosenberg (doronr@naboonline.com)
- Roger B. Sidje (rbs@maths.uq.edu.au)
-
- Alternatively, the contents of this file may be used under the
- terms of the GNU General Public License Version 2 or later (the
- "GPL"), in which case the provisions of the GPL are applicable
- instead of those above. If you wish to allow use of your
- version of this file only under the terms of the GPL and not to
- allow others to use your version of this file under the MPL,
- indicate your decision by deleting the provisions above and
- replace them with the notice and other provisions required by
- the GPL. If you do not delete the provisions above, a recipient
- may use your version of this file under either the MPL or the
- GPL.
-->
<?xul-overlay href="chrome://navigator/content/navigatorOverlay.xul"?>
<!DOCTYPE window [
<!ENTITY % brandDTD SYSTEM "chrome://global/locale/brand.dtd" >
%brandDTD;
<!ENTITY % sourceDTD SYSTEM "chrome://navigator/locale/viewSource.dtd" >
%sourceDTD;
<!ENTITY % navigatorDTD SYSTEM "chrome://navigator/locale/navigator.dtd" >
%navigatorDTD;
<!ENTITY % contentAreaCommandsDTD SYSTEM "chrome://communicator/locale/contentAreaCommands.dtd" >
%contentAreaCommandsDTD;
]>
<overlay id="viewSourceOverlay"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/x-javascript" src="chrome://global/content/nsJSSupportsUtils.js"/>
<script type="application/x-javascript" src="chrome://global/content/nsJSComponentManager.js"/>
<script type="application/x-javascript" src="chrome://global/content/nsTransferable.js"/>
<script type="application/x-javascript" src="chrome://global/content/nsDragAndDrop.js"/>
<script type="application/x-javascript" src="chrome://communicator/content/contentAreaDD.js"/>
<script type="application/x-javascript" src="chrome://navigator/content/browser.js"/>
<script type="application/x-javascript" src="chrome://navigator/content/viewsource.js"/>
<script type="application/x-javascript" src="chrome://communicator/content/findUtils.js"/>
<script type="application/x-javascript" src="chrome://communicator/content/contentAreaUtils.js"/>
<commandset id="commands">
<commandset id="globalEditMenuItems"/>
<commandset id="selectEditMenuItems"/>
<commandset id="clipboardEditMenuItems"/>
<commandset id="viewSourceMenuItems">
<command id="cmd_wrapLongLines" oncommand="wrapLongLines()"/>
<command id="cmd_close" oncommand="ViewSourceClose()"/>
<command id="cmd_savePage" oncommand="ViewSourceSavePage();"/>
<command id="cmd_editPage" oncommand="ViewSourceEditPage();"/>
</commandset>
</commandset>
<stringbundleset id="viewSource-stringbundleset">
<stringbundle id="bundle_viewZoom"/>
<stringbundle id="findBundle" src="chrome://global/locale/finddialog.properties"/>
</stringbundleset>
<!-- keys are appended from the overlay -->
<keyset id="viewSourceKeys">
<!-- File Menu -->
<key id="key_newNavigator"/>
<key id="key_newBlankPage"/>
<key id="key_savePage" key="&savePageCmd.commandkey;" command="cmd_savePage" modifiers="accel"/>
<key id="key_editPage" key="&editPageCmd.commandkey;" command="Browser:EditPage" modifiers="accel"/>
<key id="printKb" key="&printCmd.commandkey;" command="Browser:Print" modifiers="accel"/>
<key id="key_close"/>
<!-- Edit Menu -->
<key id="key_undo"/>
<key id="key_redo"/>
<key id="key_cut"/>
<key id="key_copy"/>
<key id="key_paste"/>
<key id="key_delete"/>
<key id="key_selectAll"/>
<key id="key_find" key="&findOnCmd.commandkey;" command="Browser:Find" modifiers="accel"/>
<key id="key_findAgain" key="&findAgainCmd.commandkey;" command="Browser:FindAgain" modifiers="accel"/>
<keyset id="viewZoomKeys"/>
</keyset>
<!-- context menu -->
<popupset id="viewSourceContextSet">
<popup id="viewSourceContextMenu">
<menuitem label="&findNextCmd.label;" accesskey="&findNextCmd.accesskey;" command="Browser:FindAgain"/>
<menuseparator/>
<menuitem id="menu_copy_cm" label="&copyCmd.label;" accesskey="&copyCmd.accesskey;" command="cmd_copy"/>
<menuseparator/>
<menuitem id="menu_selectAll_cm" label="&selectAllCmd.label;" accesskey="&selectAllCmd.accesskey;" command="cmd_selectAll"/>
</popup>
</popupset>
<!-- Menu -->
<toolbox id="viewSource-toolbox">
<menubar id="viewSource-main-menubar">
<menu id="menu_File">
<menupopup id="filemenu-popup">
<menu id="menu_New">
<menupopup id="menu_NewPopup">
<menuitem id="menu_newNavigator"/>
<menuitem id="menu_newEditor"/>
</menupopup>
</menu>
<menuseparator/>
<menuitem id="menu_close"/>
<menuitem label="&savePageCmd.label;" accesskey="&savePageCmd.accesskey;" key="key_savePage" command="cmd_savePage"/>
<!-- XXX misnomer should have been called "saveframe" -->
<!-- <menuitem id="savepage" label="&saveFrameCmd.label;" accesskey="&saveFrameCmd.accesskey;" oncommand="ViewSourceSavePage();" hidden="true"/> -->
<menuseparator/>
<menuitem label="&editPageCmd.label;" accesskey="&editPageCmd.accesskey;" key="key_editPage" command="cmd_editPage"/>
<menuseparator/>
<menuitem label="&printCmd.label;" accesskey="&printCmd.accesskey;" key="printKb" command="Browser:Print"/>
<!-- <menuitem accesskey="&printPreviewCmd.accesskey;" observes="Browser:PrintPreview"/> -->
</menupopup>
</menu>
<menu id="menu_Edit">
<menupopup>
<menuitem id="menu_undo"/>
<menuitem id="menu_redo"/>
<menuseparator/>
<menuitem id="menu_cut"/>
<menuitem id="menu_copy"/>
<menuitem id="menu_paste"/>
<menuitem id="menu_delete"/>
<menuseparator/>
<menuitem id="menu_selectAll"/>
<menuseparator />
<menuitem id="menu_find" label="&findOnCmd.label;" accesskey="&findOnCmd.accesskey;" key="key_find" command="Browser:Find"/>
<menuitem id="menu_findAgain" label="&findAgainCmd.label;" accesskey="&findAgainCmd.accesskey;" key="key_findAgain" command="Browser:FindAgain"/>
</menupopup>
</menu>
<menu id="menu_View">
<menupopup>
<menu id="menu_textZoom"/>
<menuseparator/>
<!-- <menuitem accesskey="&pageInfoCmd.accesskey;" label="&pageInfoCmd.label;" key="key_viewInfo" observes="View:PageInfo"/>
<menuseparator id="file_moduleSeparator"/>-->
<menu id="charsetMenu"/>
<menuitem id="menu_wrapLongLines" label="&menu_wrapLongLines.title;" accesskey="&menu_wrapLongLines.accesskey;" type="checkbox" command="cmd_wrapLongLines"/>
</menupopup>
</menu>
<menu id="menu_Help"/>
</menubar>
</toolbox>
</overlay>

Просмотреть файл

@ -187,6 +187,14 @@
</menupopup>
</menu>
<menuseparator id="context-sep-properties"/>
<menuitem id="context-viewpartialsource-selection"
label="&viewPartialSourceForSelectionCmd.label;"
accesskey="&viewPartialSourceCmd.accesskey;"
oncommand="gContextMenu.viewPartialSource('selection');"/>
<menuitem id="context-viewpartialsource-mathml"
label="&viewPartialSourceForMathMLCmd.label;"
accesskey="&viewPartialSourceCmd.accesskey;"
oncommand="gContextMenu.viewPartialSource('mathml');"/>
<menuitem id="context-viewsource"
label="&viewPageSourceCmd.label;"
accesskey="&viewPageSourceCmd.accesskey;"

Просмотреть файл

@ -41,6 +41,7 @@ function nsContextMenu( xulMenu ) {
this.onLink = false;
this.onMailtoLink = false;
this.onSaveableLink = false;
this.onMathML = false;
this.link = false;
this.inFrame = false;
this.hasBGImage = false;
@ -116,6 +117,8 @@ nsContextMenu.prototype = {
},
initViewItems : function () {
// View source is always OK, unless in directory listing.
this.showItem( "context-viewpartialsource-selection", this.isTextSelected );
this.showItem( "context-viewpartialsource-mathml", this.onMathML && !this.isTextSelected );
this.showItem( "context-viewsource", !( this.inDirList || this.onImage || this.isTextSelected || this.onLink || this.onTextInput ) );
this.showItem( "context-viewinfo", !( this.inDirList || this.onImage || this.isTextSelected || this.onLink || this.onTextInput ) );
@ -209,12 +212,14 @@ nsContextMenu.prototype = {
this.onTextInput = false;
this.imageURL = "";
this.onLink = false;
this.onMathML = false;
this.inFrame = false;
this.hasBGImage = false;
this.bgImageURL = "";
// Remember the node that was clicked.
this.target = node;
// See if the user clicked on an image.
if ( this.target.nodeType == Node.ELEMENT_NODE ) {
if ( this.target.localName.toUpperCase() == "IMG" ) {
@ -331,6 +336,13 @@ nsContextMenu.prototype = {
// We have meta data on images.
this.onMetaDataItem = this.onImage;
// See if the user clicked on MathML
const NS_MathML = "http://www.w3.org/1998/Math/MathML";
if ((this.target.nodeType == Node.TEXT_NODE &&
this.target.parentNode.namespaceURI == NS_MathML)
|| (this.target.namespaceURI == NS_MathML))
this.onMathML = true;
// See if the user clicked in a frame.
if ( this.target.ownerDocument != window._content.document ) {
this.inFrame = true;
@ -468,6 +480,31 @@ nsContextMenu.prototype = {
showOnlyThisFrame : function () {
window._content.location.href = this.target.ownerDocument.location.href;
},
// View Partial Source
viewPartialSource : function ( context ) {
var focusedWindow = document.commandDispatcher.focusedWindow;
if (focusedWindow == window)
focusedWindow = _content;
var docCharset = null;
if (focusedWindow)
docCharset = "charset=" + focusedWindow.document.characterSet;
// "View Selection Source" and others such as "View MathML Source"
// are mutually exclusive, with the precedence given to the selection
// when there is one
var reference = null;
if (context == "selection")
reference = focusedWindow.getSelection();
else if (context == "mathml")
reference = this.target;
else
throw "not reached";
var docUrl = null; // unused (and play nice for fragments generated via XSLT too)
window.openDialog("chrome://navigator/content/viewPartialSource.xul",
"_blank", "scrollbars,resizable,chrome,dialog=no",
docUrl, docCharset, reference, context);
},
// Open new "view source" window with the frame's URL.
viewFrameSource : function () {
BrowserViewSourceOfDocument(this.target.ownerDocument);

Просмотреть файл

@ -24,6 +24,9 @@
<!ENTITY stopCmd.accesskey "S">
<!ENTITY reloadFrameCmd.label "Reload Frame">
<!ENTITY reloadFrameCmd.accesskey "r">
<!ENTITY viewPartialSourceForSelectionCmd.label "View Selection Source">
<!ENTITY viewPartialSourceForMathMLCmd.label "View MathML Source">
<!ENTITY viewPartialSourceCmd.accesskey "e">
<!ENTITY viewPageSourceCmd.label "View Page Source">
<!ENTITY viewPageSourceCmd.accesskey "v">
<!ENTITY viewFrameSourceCmd.label "View Frame Source">