зеркало из https://github.com/mozilla/pjs.git
Bug 263683 - Findbar's Highlight feature should not manipulate the DOM. Patch by Graeme McCutcheon <graememcc_firefox@graeme-online.co.uk>, r=me,roc. sr=roc.
This commit is contained in:
Родитель
d02799882f
Коммит
15f0330e65
|
@ -51,7 +51,7 @@ interface nsIDOMNode;
|
|||
interface nsISelection;
|
||||
interface nsISelectionDisplay;
|
||||
|
||||
[scriptable, uuid(5f8f41cb-f182-4010-9e38-7c873e8e8a9f)]
|
||||
[scriptable, uuid(29a6d846-e100-4933-ad7a-2e19d91eb692)]
|
||||
interface nsISelectionController : nsISelectionDisplay
|
||||
{
|
||||
const short SELECTION_NONE=0;
|
||||
|
@ -62,7 +62,8 @@ interface nsISelectionController : nsISelectionDisplay
|
|||
const short SELECTION_IME_CONVERTEDTEXT=16;
|
||||
const short SELECTION_IME_SELECTEDCONVERTEDTEXT=32;
|
||||
const short SELECTION_ACCESSIBILITY=64; // For accessibility API usage
|
||||
const short NUM_SELECTIONTYPES=8;
|
||||
const short SELECTION_FIND=128;
|
||||
const short NUM_SELECTIONTYPES=9;
|
||||
|
||||
const short SELECTION_ANCHOR_REGION = 0;
|
||||
const short SELECTION_FOCUS_REGION = 1;
|
||||
|
|
|
@ -610,7 +610,9 @@ GetIndexFromSelectionType(SelectionType aType)
|
|||
case nsISelectionController::SELECTION_IME_CONVERTEDTEXT: return 4; break;
|
||||
case nsISelectionController::SELECTION_IME_SELECTEDCONVERTEDTEXT: return 5; break;
|
||||
case nsISelectionController::SELECTION_ACCESSIBILITY: return 6; break;
|
||||
default:return -1;break;
|
||||
case nsISelectionController::SELECTION_FIND: return 7; break;
|
||||
default:
|
||||
return -1; break;
|
||||
}
|
||||
/* NOTREACHED */
|
||||
return 0;
|
||||
|
@ -621,15 +623,16 @@ GetSelectionTypeFromIndex(PRInt8 aIndex)
|
|||
{
|
||||
switch (aIndex)
|
||||
{
|
||||
case 0: return nsISelectionController::SELECTION_NORMAL;break;
|
||||
case 1: return nsISelectionController::SELECTION_SPELLCHECK;break;
|
||||
case 2: return nsISelectionController::SELECTION_IME_RAWINPUT;break;
|
||||
case 3: return nsISelectionController::SELECTION_IME_SELECTEDRAWTEXT;break;
|
||||
case 4: return nsISelectionController::SELECTION_IME_CONVERTEDTEXT;break;
|
||||
case 5: return nsISelectionController::SELECTION_IME_SELECTEDCONVERTEDTEXT;break;
|
||||
case 6: return nsISelectionController::SELECTION_ACCESSIBILITY;break;
|
||||
case 0: return nsISelectionController::SELECTION_NORMAL; break;
|
||||
case 1: return nsISelectionController::SELECTION_SPELLCHECK; break;
|
||||
case 2: return nsISelectionController::SELECTION_IME_RAWINPUT; break;
|
||||
case 3: return nsISelectionController::SELECTION_IME_SELECTEDRAWTEXT; break;
|
||||
case 4: return nsISelectionController::SELECTION_IME_CONVERTEDTEXT; break;
|
||||
case 5: return nsISelectionController::SELECTION_IME_SELECTEDCONVERTEDTEXT; break;
|
||||
case 6: return nsISelectionController::SELECTION_ACCESSIBILITY; break;
|
||||
case 7: return nsISelectionController::SELECTION_FIND; break;
|
||||
default:
|
||||
return nsISelectionController::SELECTION_NORMAL;break;
|
||||
return nsISelectionController::SELECTION_NORMAL; break;
|
||||
}
|
||||
/* NOTREACHED */
|
||||
return 0;
|
||||
|
|
|
@ -237,6 +237,8 @@ public:
|
|||
*/
|
||||
PRBool GetSelectionColors(nscolor* aForeColor,
|
||||
nscolor* aBackColor);
|
||||
void GetHighlightColors(nscolor* aForeColor,
|
||||
nscolor* aBackColor);
|
||||
void GetIMESelectionColors(PRInt32 aIndex,
|
||||
nscolor* aForeColor,
|
||||
nscolor* aBackColor);
|
||||
|
@ -2835,6 +2837,24 @@ nsTextPaintStyle::GetSelectionColors(nscolor* aForeColor,
|
|||
return PR_TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
nsTextPaintStyle::GetHighlightColors(nscolor* aForeColor,
|
||||
nscolor* aBackColor)
|
||||
{
|
||||
NS_ASSERTION(aForeColor, "aForeColor is null");
|
||||
NS_ASSERTION(aBackColor, "aBackColor is null");
|
||||
|
||||
nsILookAndFeel* look = mPresContext->LookAndFeel();
|
||||
nscolor foreColor, backColor;
|
||||
look->GetColor(nsILookAndFeel::eColor_TextHighlightBackground,
|
||||
backColor);
|
||||
look->GetColor(nsILookAndFeel::eColor_TextSelectForeground,
|
||||
foreColor);
|
||||
EnsureSufficientContrast(&foreColor, &backColor);
|
||||
*aForeColor = foreColor;
|
||||
*aBackColor = backColor;
|
||||
}
|
||||
|
||||
void
|
||||
nsTextPaintStyle::GetIMESelectionColors(PRInt32 aIndex,
|
||||
nscolor* aForeColor,
|
||||
|
@ -3877,7 +3897,9 @@ static PRBool GetSelectionTextColors(SelectionType aType, nsTextPaintStyle& aTex
|
|||
switch (aType) {
|
||||
case nsISelectionController::SELECTION_NORMAL:
|
||||
return aTextPaintStyle.GetSelectionColors(aForeground, aBackground);
|
||||
|
||||
case nsISelectionController::SELECTION_FIND:
|
||||
aTextPaintStyle.GetHighlightColors(aForeground, aBackground);
|
||||
return PR_TRUE;
|
||||
case nsISelectionController::SELECTION_IME_RAWINPUT:
|
||||
aTextPaintStyle.GetIMESelectionColors(nsTextPaintStyle::eIndexRawInput,
|
||||
aForeground, aBackground);
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Bug 263683 Layout Reftest</title>
|
||||
</head>
|
||||
<body style="color: #000000; background-color: #ffffff" onload="onLoad();">
|
||||
<p>
|
||||
The last word in this text should be <span style="background-color: #f0e020">selected</span>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,72 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<head>
|
||||
<title>Bug 263683 Layout Reftest</title>
|
||||
<script type="text/javascript">
|
||||
|
||||
var userSet = false;
|
||||
var userValue = null;
|
||||
var prefName = "ui.textHighlightBackground";
|
||||
|
||||
function onLoad() {
|
||||
// Request security privileges
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
|
||||
// Get pref branch.
|
||||
var prefs = Components.classes["@mozilla.org/preferences-service;1"]
|
||||
.getService(Components.interfaces.nsIPrefBranch);
|
||||
|
||||
// Check to see if this pref has a user-set value. If so, store it
|
||||
userSet = prefs.prefHasUserValue(prefName);
|
||||
|
||||
if (userSet)
|
||||
userValue = prefs.getCharPref(prefName);
|
||||
|
||||
// Set pref to test colour used in reference file
|
||||
prefs.setCharPref(prefName, "#f0e020");
|
||||
|
||||
var textToSelect = document.getElementById("selecttext");
|
||||
|
||||
// Get docshell
|
||||
var docShell = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
|
||||
.getInterface(Components.interfaces.nsIWebNavigation)
|
||||
.QueryInterface(Components.interfaces.nsIDocShell);
|
||||
// Get selection controller from docshell
|
||||
var controller = docShell.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
|
||||
.getInterface(Components.interfaces.nsISelectionDisplay)
|
||||
.QueryInterface(Components.interfaces.nsISelectionController);
|
||||
// Get selection
|
||||
var findSelection = controller.getSelection(controller.SELECTION_FIND);
|
||||
|
||||
// Lastly add range
|
||||
var range = document.createRange();
|
||||
range.selectNodeContents(textToSelect);
|
||||
findSelection.addRange(range);
|
||||
|
||||
document.documentElement.removeAttribute("class");
|
||||
}
|
||||
|
||||
function onUnload() {
|
||||
// Request security privileges
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
|
||||
// Get the pref branch
|
||||
var prefs = Components.classes["@mozilla.org/preferences-service;1"]
|
||||
.getService(Components.interfaces.nsIPrefBranch);
|
||||
|
||||
prefs.clearUserPref(prefName);
|
||||
|
||||
if (!userSet)
|
||||
return;
|
||||
|
||||
prefs.setCharPref(prefName, userValue);
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body style="color: #000000; background-color: #ffffff" onload="onLoad();" onunload="onUnload();">
|
||||
<p>
|
||||
The last word in this text should be <span id="selecttext">selected</span>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
|
@ -169,6 +169,7 @@ fails == 25888-3r.html 25888-3r-ref.html # bug 25888
|
|||
== 253701-1.html 253701-1-ref.html
|
||||
== 255820-1.html 255820-1-ref.html
|
||||
== 262151-1.html 262151-1-ref.html
|
||||
== 263683-1.html 263683-1-ref.html
|
||||
== 267353-1.html 267353-1-ref.html
|
||||
== 273681-1.html 273681-1-ref.html
|
||||
fails-if(MOZ_WIDGET_TOOLKIT!="cocoa") HTTP == 289480.html#top 289480-ref.html # basically-verbatim acid2 test, HTTP for a 404 page -- bug 409329 for the non-Mac failures
|
||||
|
|
|
@ -55,6 +55,8 @@ _TEST_FILES = findbar_window.xul \
|
|||
test_bug366992.xul \
|
||||
bug331215_window.xul \
|
||||
test_bug331215.xul \
|
||||
bug263683_window.xul \
|
||||
test_bug263683.xul \
|
||||
test_popup_preventdefault_chrome.xul \
|
||||
window_popup_preventdefault_chrome.xul \
|
||||
test_largemenu.xul \
|
||||
|
|
|
@ -0,0 +1,123 @@
|
|||
<?xml version="1.0"?>
|
||||
|
||||
<!-- ***** 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 Findbar Test code
|
||||
-
|
||||
- The Initial Developer of the Original Code is
|
||||
- Mozilla Corporation.
|
||||
- Portions created by the Initial Developer are Copyright (C) 2008
|
||||
- the Initial Developer. All Rights Reserved.
|
||||
-
|
||||
- Contributor(s):
|
||||
- Graeme McCutcheon <graememcc_firefox@graeme-online.co.uk>
|
||||
-
|
||||
- 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 ***** -->
|
||||
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
|
||||
<window id="263683test"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
width="600"
|
||||
height="600"
|
||||
onload="onLoad();"
|
||||
title="263683 test">
|
||||
|
||||
<script type="application/javascript"><![CDATA[
|
||||
const Ci = Components.interfaces;
|
||||
const Cc = Components.classes;
|
||||
const Cr = Components.results;
|
||||
|
||||
var gFindBar = null;
|
||||
var gBrowser;
|
||||
|
||||
function ok(condition, message) {
|
||||
window.opener.wrappedJSObject.SimpleTest.ok(condition, message);
|
||||
}
|
||||
|
||||
function finish() {
|
||||
window.close();
|
||||
window.opener.wrappedJSObject.SimpleTest.finish();
|
||||
}
|
||||
|
||||
function onLoad() {
|
||||
var _delayedOnLoad = function() {
|
||||
gFindBar = document.getElementById("FindToolbar");
|
||||
gBrowser = document.getElementById("content");
|
||||
gBrowser.addEventListener("pageshow", onPageShow, false);
|
||||
gBrowser.loadURI('data:text/html,<h2>Text mozilla</h2><input id="inp" type="text" />');
|
||||
}
|
||||
let tm = Cc["@mozilla.org/thread-manager;1"].
|
||||
getService(Ci.nsIThreadManager);
|
||||
tm.mainThread.dispatch({
|
||||
run: function() _delayedOnLoad()
|
||||
}, Ci.nsIThread.DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
function onPageShow() {
|
||||
gBrowser.removeEventListener("load", onPageShow, true);
|
||||
gFindBar.open();
|
||||
var search = "mozilla";
|
||||
gFindBar._findField.value = search;
|
||||
var matchCase = gFindBar.getElement("find-case-sensitive");
|
||||
if (matchCase.checked)
|
||||
matchCase.doCommand();
|
||||
|
||||
gFindBar._find();
|
||||
var highlightButton = gFindBar.getElement("highlight");
|
||||
if (!highlightButton.checked)
|
||||
highlightButton.click();
|
||||
|
||||
var controller = gFindBar.browser.docShell.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsISelectionDisplay)
|
||||
.QueryInterface(Ci.nsISelectionController);
|
||||
ok('SELECTION_FIND' in controller, "Correctly detects new selection type");
|
||||
var selection = controller.getSelection(controller.SELECTION_FIND);
|
||||
|
||||
ok(selection.rangeCount == 1, "Correctly added a match to the selection type");
|
||||
ok(selection.getRangeAt(0).toString().toLowerCase() == search, "Added the correct match");
|
||||
highlightButton.click();
|
||||
ok(selection.rangeCount == 0, "Correctly removed the range");
|
||||
|
||||
var input = gBrowser.contentDocument.getElementById("inp");
|
||||
input.value = search;
|
||||
|
||||
highlightButton.click();
|
||||
|
||||
var inputController = input.editor.selectionController;
|
||||
var inputSelection = inputController.getSelection(inputController.SELECTION_FIND);
|
||||
|
||||
ok(inputSelection.rangeCount == 1, "Correctly added a match from input to the selection type");
|
||||
ok(inputSelection.getRangeAt(0).toString().toLowerCase() == search, "Added the correct match");
|
||||
highlightButton.click();
|
||||
ok(inputSelection.rangeCount == 0, "Correctly removed the range");
|
||||
finish();
|
||||
}
|
||||
]]></script>
|
||||
|
||||
<browser type="content-primary" flex="1" id="content" src="about:blank"/>
|
||||
<findbar id="FindToolbar" browserid="content"/>
|
||||
</window>
|
|
@ -0,0 +1,43 @@
|
|||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet
|
||||
href="chrome://mochikit/content/tests/SimpleTest/test.css"
|
||||
type="text/css"?>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=263683
|
||||
-->
|
||||
<window title="Mozilla Bug 263683"
|
||||
xmlns:html="http://www.w3.org/1999/xhtml"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
|
||||
<title>Test for Bug 263683</title>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=263683">
|
||||
Mozilla Bug 263683
|
||||
</a>
|
||||
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
|
||||
<script class="testbody" type="application/javascript">
|
||||
<![CDATA[
|
||||
|
||||
/** Test for Bug 263683 **/
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
window.open("bug263683_window.xul", "263683test",
|
||||
"chrome,width=600,height=600");
|
||||
|
||||
]]>
|
||||
</script>
|
||||
|
||||
</window>
|
|
@ -27,6 +27,7 @@
|
|||
- Jason Barnabe <jason_barnabe@fastmail.fm>
|
||||
- Asaf Romano <mano@mozilla.com>
|
||||
- Ehsan Akhgari <ehsan.akhgari@gmail.com>
|
||||
- Graeme McCutcheon <graememcc_firefox@graeme-online.co.uk>
|
||||
-
|
||||
- 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
|
||||
|
@ -430,10 +431,38 @@
|
|||
]]></body>
|
||||
</method>
|
||||
|
||||
<!--
|
||||
- Gets the selection controller for the current browser
|
||||
-->
|
||||
<method name="_getSelectionController">
|
||||
<body><![CDATA[
|
||||
// Yuck. See bug 138068.
|
||||
var Ci = Components.interfaces;
|
||||
var controller = this.browser.docShell
|
||||
.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsISelectionDisplay)
|
||||
.QueryInterface(Ci.nsISelectionController);
|
||||
return controller;
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
<method name="_getEditableNode">
|
||||
<parameter name="aNode"/>
|
||||
<body><![CDATA[
|
||||
while (aNode) {
|
||||
if (aNode instanceof Components.interfaces.nsIDOMNSEditableElement) {
|
||||
return aNode.editor ? aNode : null;
|
||||
}
|
||||
aNode = aNode.parentNode;
|
||||
}
|
||||
return null;
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
<!--
|
||||
- Turns highlight on or off.
|
||||
- @param aHighlight (boolean)
|
||||
- Whether to turn on highlight
|
||||
- Whether to turn the highlight on or off
|
||||
-->
|
||||
<method name="toggleHighlight">
|
||||
<parameter name="aHighlight"/>
|
||||
|
@ -442,14 +471,13 @@
|
|||
if (aHighlight) {
|
||||
// We have to update the status because we might still have the status
|
||||
// of another tab
|
||||
if (this._highlightDoc("yellow", "black", word))
|
||||
if (this._highlightDoc(aHighlight, word))
|
||||
this._updateStatusUI(this.nsITypeAheadFind.FIND_FOUND);
|
||||
else
|
||||
this._updateStatusUI(this.nsITypeAheadFind.FIND_NOTFOUND);
|
||||
}
|
||||
else {
|
||||
this._highlightDoc(null, null, null);
|
||||
this._lastHighlightString = null;
|
||||
this._highlightDoc(aHighlight, this._lastHighlightString, null);
|
||||
}
|
||||
]]></body>
|
||||
</method>
|
||||
|
@ -457,11 +485,8 @@
|
|||
<!--
|
||||
- (Un)highlights each instance of the searched word in the passed
|
||||
- window's content.
|
||||
- @param aHighBackColor
|
||||
- the background color for the highlight
|
||||
- @param aHighTextColor
|
||||
- the text color for the highlight, or null to make it
|
||||
- unhighlight
|
||||
- @param aHighlight (boolean)
|
||||
- Whether to turn on highlight
|
||||
- @param aWord
|
||||
- the word to search for
|
||||
- @param aWindow
|
||||
|
@ -470,16 +495,19 @@
|
|||
- @returns true if aWord was found
|
||||
-->
|
||||
<method name="_highlightDoc">
|
||||
<parameter name="aHighBackColor"/>
|
||||
<parameter name="aHighTextColor"/>
|
||||
<parameter name="aHighlight"/>
|
||||
<parameter name="aWord"/>
|
||||
<parameter name="aWindow"/>
|
||||
<body><![CDATA[
|
||||
var win = aWindow || this.browser.contentWindow;
|
||||
|
||||
if (!aWord)
|
||||
return false;
|
||||
|
||||
var textFound = false;
|
||||
|
||||
for (var i = 0; win.frames && i < win.frames.length; i++) {
|
||||
if (this._highlightDoc(aHighBackColor, aHighTextColor, aWord, win.frames[i]))
|
||||
if (this._highlightDoc(aHighlight, aWord, win.frames[i]))
|
||||
textFound = true;
|
||||
}
|
||||
|
||||
|
@ -502,85 +530,22 @@
|
|||
this._endPt.setStart(body, count);
|
||||
this._endPt.setEnd(body, count);
|
||||
|
||||
if (!aHighBackColor) {
|
||||
// Remove highlighting. We use the find API again rather than
|
||||
// searching for our span elements so that we gain access to the
|
||||
// anonymous content that nsIFind searches.
|
||||
|
||||
if (!this._lastHighlightString)
|
||||
return textFound;
|
||||
|
||||
var retRange = null;
|
||||
var finder = Components.classes["@mozilla.org/embedcomp/rangefind;1"]
|
||||
.createInstance(Components.interfaces.nsIFind);
|
||||
|
||||
while ((retRange = finder.Find(this._lastHighlightString,
|
||||
this._searchRange, this._startPt,
|
||||
this._endPt))) {
|
||||
var startContainer = retRange.startContainer;
|
||||
var elem = null;
|
||||
try {
|
||||
elem = startContainer.parentNode;
|
||||
}
|
||||
catch (ex) { }
|
||||
|
||||
if (elem && elem.className == "__mozilla-findbar-search") {
|
||||
var child = null;
|
||||
var docfrag = doc.createDocumentFragment();
|
||||
var next = elem.nextSibling;
|
||||
var parent = elem.parentNode;
|
||||
|
||||
while ((child = elem.firstChild)) {
|
||||
docfrag.appendChild(child);
|
||||
}
|
||||
|
||||
this._startPt = doc.createRange();
|
||||
this._startPt.setStartAfter(elem);
|
||||
|
||||
parent.removeChild(elem);
|
||||
parent.insertBefore(docfrag, next);
|
||||
parent.normalize();
|
||||
}
|
||||
else {
|
||||
// Somehow we didn't highlight this instance; just skip it.
|
||||
this._startPt = doc.createRange();
|
||||
this._startPt.setStart(retRange.endContainer,
|
||||
retRange.endOffset);
|
||||
}
|
||||
|
||||
this._startPt.collapse(true);
|
||||
|
||||
textFound = true;
|
||||
}
|
||||
return textFound;
|
||||
var controller = this._getSelectionController();
|
||||
if (!controller) {
|
||||
// Without the selection controller,
|
||||
// we are unable to (un)highlight any matches
|
||||
return false;
|
||||
}
|
||||
|
||||
var baseNode = doc.createElementNS("http://www.w3.org/1999/xhtml", "span");
|
||||
baseNode.style.backgroundColor = aHighBackColor;
|
||||
baseNode.style.color = aHighTextColor;
|
||||
baseNode.style.display = "inline";
|
||||
baseNode.style.fontSize = "inherit";
|
||||
baseNode.style.padding = "0";
|
||||
baseNode.className = "__mozilla-findbar-search";
|
||||
// This code should look for individual matches and highlight them
|
||||
// However, as there's no way to access editable elements individual
|
||||
// selection controllers from the top level doc, we also have to use
|
||||
// this to find all the editable matches when clearing the highlight,
|
||||
// which is horribly inefficient, but still faster than the DOM
|
||||
// manipulation of old.
|
||||
// Fixing bug 339400 would make this go away, and allow the removal case
|
||||
// to be reduced to something like findSelection.removeAllRanges()
|
||||
|
||||
return this._highlightText(aWord, baseNode) || textFound;
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
<!--
|
||||
- Highlights each instance of the searched word in the current range.
|
||||
-
|
||||
- @param aWord
|
||||
- the word to search for.
|
||||
- @param aBaseNode
|
||||
- a node to use as a template for what will replace the searched
|
||||
- word.
|
||||
- @returns true if aWord was found
|
||||
-->
|
||||
<method name="_highlightText">
|
||||
<parameter name="aWord"/>
|
||||
<parameter name="aBaseNode"/>
|
||||
<body><![CDATA[
|
||||
var retRange = null;
|
||||
var finder = Components.classes["@mozilla.org/embedcomp/rangefind;1"]
|
||||
.createInstance()
|
||||
|
@ -588,20 +553,26 @@
|
|||
|
||||
finder.caseSensitive = this._shouldBeCaseSensitive(aWord);
|
||||
|
||||
var textFound = false;
|
||||
while((retRange = finder.Find(aWord, this._searchRange,
|
||||
this._startPt, this._endPt))) {
|
||||
// Highlight
|
||||
var nodeSurround = aBaseNode.cloneNode(true);
|
||||
var node = this._highlight(retRange, nodeSurround);
|
||||
this._startPt = node.ownerDocument.createRange();
|
||||
this._startPt.setStart(node, node.childNodes.length);
|
||||
this._startPt.setEnd(node, node.childNodes.length);
|
||||
this._highlight(aHighlight, retRange, controller);
|
||||
this._startPt = retRange.endContainer.ownerDocument.createRange();
|
||||
this._startPt.setStart(retRange.endContainer, retRange.endOffset);
|
||||
this._startPt.setEnd(retRange.endContainer, retRange.endOffset);
|
||||
|
||||
textFound = true;
|
||||
}
|
||||
|
||||
this._lastHighlightString = aWord;
|
||||
if (textFound) {
|
||||
if (aHighlight)
|
||||
this._lastHighlightString = aWord;
|
||||
else {
|
||||
var sel = controller.getSelection(this.nsISelectionController.SELECTION_FIND);
|
||||
sel.removeAllRanges();
|
||||
}
|
||||
controller.setDisplaySelection(this.nsISelectionController.SELECTION_ON);
|
||||
controller.repaintSelection(this.nsISelectionController.SELECTION_FIND);
|
||||
}
|
||||
|
||||
return textFound;
|
||||
]]></body>
|
||||
|
@ -610,25 +581,31 @@
|
|||
<!--
|
||||
- Highlights the word in the passed range.
|
||||
-
|
||||
- @param aHighlight
|
||||
- whether the highlight should be on or off
|
||||
- @param aRange
|
||||
- the range that contains the word to highlight
|
||||
- @param aNode
|
||||
- the node replace the searched word with
|
||||
- @returns the node that replaced the searched word
|
||||
- @param aController
|
||||
- the current document's selection controller
|
||||
-->
|
||||
<method name="_highlight">
|
||||
<parameter name="aHighlight"/>
|
||||
<parameter name="aRange"/>
|
||||
<parameter name="aNode"/>
|
||||
<parameter name="aController"/>
|
||||
<body><![CDATA[
|
||||
var startContainer = aRange.startContainer;
|
||||
var startOffset = aRange.startOffset;
|
||||
var endOffset = aRange.endOffset;
|
||||
var docfrag = aRange.extractContents();
|
||||
var before = startContainer.splitText(startOffset);
|
||||
var parent = before.parentNode;
|
||||
aNode.appendChild(docfrag);
|
||||
parent.insertBefore(aNode, before);
|
||||
return aNode;
|
||||
var node = aRange.startContainer;
|
||||
var controller = aController;
|
||||
var isEditable = this._getEditableNode(node);
|
||||
if (isEditable)
|
||||
controller = isEditable.editor.selectionController;
|
||||
var findSelection = controller.getSelection(this.nsISelectionController.SELECTION_FIND);
|
||||
if (aHighlight)
|
||||
findSelection.addRange(aRange);
|
||||
if (isEditable) {
|
||||
if (!aHighlight)
|
||||
findSelection.removeAllRanges();
|
||||
controller.repaintSelection(this.nsISelectionController.SELECTION_FIND);
|
||||
}
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
|
|
|
@ -75,6 +75,7 @@ public:
|
|||
eColor_TextSelectForeground,
|
||||
eColor_TextSelectBackgroundDisabled,
|
||||
eColor_TextSelectBackgroundAttention,
|
||||
eColor_TextHighlightBackground,
|
||||
|
||||
eColor_IMERawInputBackground,
|
||||
eColor_IMERawInputForeground,
|
||||
|
|
|
@ -170,6 +170,7 @@ const char nsXPLookAndFeel::sColorPrefs[][38] =
|
|||
"ui.textSelectForeground",
|
||||
"ui.textSelectBackgroundDisabled",
|
||||
"ui.textSelectBackgroundAttention",
|
||||
"ui.textHighlightBackground",
|
||||
"ui.IMERawInputBackground",
|
||||
"ui.IMERawInputForeground",
|
||||
"ui.IMERawInputUnderline",
|
||||
|
@ -585,6 +586,13 @@ nsXPLookAndFeel::GetColor(const nsColorID aID, nscolor &aColor)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
if (aID == eColor_TextHighlightBackground) {
|
||||
// This makes the matched text stand out when findbar highlighting is on
|
||||
// Used with nsISelectionController::SELECTION_FIND
|
||||
aColor = NS_RGB(0xf0, 0xe0, 0x20);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(NativeGetColor(aID, aColor))) {
|
||||
if (gfxPlatform::IsCMSEnabled() && !IsSpecialColor(aID, aColor)) {
|
||||
cmsHTRANSFORM transform = gfxPlatform::GetCMSInverseRGBTransform();
|
||||
|
|
Загрузка…
Ссылка в новой задаче