зеркало из https://github.com/mozilla/pjs.git
Merge Places and mozilla-central
This commit is contained in:
Коммит
59c1bb6c46
|
@ -1043,6 +1043,22 @@ nsXULTreeItemAccessibleBase::IsExpandable()
|
|||
return PR_FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
nsXULTreeItemAccessibleBase::GetCellName(nsITreeColumn* aColumn,
|
||||
nsAString& aName)
|
||||
{
|
||||
mTreeView->GetCellText(mRow, aColumn, aName);
|
||||
|
||||
// If there is still no name try the cell value:
|
||||
// This is for graphical cells. We need tree/table view implementors to
|
||||
// implement FooView::GetCellValue to return a meaningful string for cases
|
||||
// where there is something shown in the cell (non-text) such as a star icon;
|
||||
// in which case GetCellValue for that cell would return "starred" or
|
||||
// "flagged" for example.
|
||||
if (aName.IsEmpty())
|
||||
mTreeView->GetCellValue(mRow, aColumn, aName);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsXULTreeItemAccessible
|
||||
|
@ -1068,16 +1084,7 @@ nsXULTreeItemAccessible::GetName(nsAString& aName)
|
|||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
mTreeView->GetCellText(mRow, mColumn, aName);
|
||||
|
||||
// If there is still no name try the cell value:
|
||||
// This is for graphical cells. We need tree/table view implementors to implement
|
||||
// FooView::GetCellValue to return a meaningful string for cases where there is
|
||||
// something shown in the cell (non-text) such as a star icon; in which case
|
||||
// GetCellValue for that cell would return "starred" or "flagged" for example.
|
||||
if (aName.IsEmpty())
|
||||
mTreeView->GetCellValue(mRow, mColumn, aName);
|
||||
|
||||
GetCellName(mColumn, aName);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -244,6 +244,11 @@ protected:
|
|||
*/
|
||||
PRBool IsExpandable();
|
||||
|
||||
/**
|
||||
* Return name for cell at the given column.
|
||||
*/
|
||||
void GetCellName(nsITreeColumn* aColumn, nsAString& aName);
|
||||
|
||||
nsCOMPtr<nsITreeBoxObject> mTree;
|
||||
nsCOMPtr<nsITreeView> mTreeView;
|
||||
PRInt32 mRow;
|
||||
|
|
|
@ -665,6 +665,25 @@ nsXULTreeGridRowAccessible::NativeRole()
|
|||
return nsIAccessibleRole::ROLE_ROW;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULTreeGridRowAccessible::GetName(nsAString& aName)
|
||||
{
|
||||
aName.Truncate();
|
||||
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsITreeColumns> columns;
|
||||
mTree->GetColumns(getter_AddRefs(columns));
|
||||
if (columns) {
|
||||
nsCOMPtr<nsITreeColumn> primaryColumn;
|
||||
columns->GetPrimaryColumn(getter_AddRefs(primaryColumn));
|
||||
if (primaryColumn)
|
||||
GetCellName(primaryColumn, aName);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsAccessible*
|
||||
nsXULTreeGridRowAccessible::GetChildAtPoint(PRInt32 aX, PRInt32 aY,
|
||||
EWhichChildAtPoint aWhichChild)
|
||||
|
|
|
@ -93,6 +93,7 @@ public:
|
|||
|
||||
// nsAccessible
|
||||
virtual PRUint32 NativeRole();
|
||||
NS_IMETHOD GetName(nsAString& aName);
|
||||
virtual nsAccessible* GetChildAtPoint(PRInt32 aX, PRInt32 aY,
|
||||
EWhichChildAtPoint aWhichChild);
|
||||
|
||||
|
|
|
@ -57,6 +57,7 @@ _TEST_FILES =\
|
|||
test_list.html \
|
||||
test_markup.html \
|
||||
test_nsRootAcc.xul \
|
||||
test_tree.xul \
|
||||
markuprules.xml \
|
||||
$(NULL)
|
||||
|
||||
|
|
|
@ -0,0 +1,200 @@
|
|||
<?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"?>
|
||||
<?xml-stylesheet href="general.css"
|
||||
type="text/css"?>
|
||||
|
||||
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
title="Accessibility Name Calculating Test.">
|
||||
|
||||
<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 type="application/javascript"
|
||||
src="../treeview.js" />
|
||||
|
||||
<script type="application/javascript"
|
||||
src="../common.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../role.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../name.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../events.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
function treeTester(aID)
|
||||
{
|
||||
this.DOMNode = getNode(aID);
|
||||
|
||||
this.invoke = function treeTester_invoke()
|
||||
{
|
||||
this.DOMNode.treeBoxObject.view = new nsTreeTreeView();
|
||||
}
|
||||
|
||||
this.check = function treeTester_check(aEvent)
|
||||
{
|
||||
var tree = {
|
||||
role: ROLE_OUTLINE,
|
||||
children: [
|
||||
{
|
||||
role: ROLE_LIST
|
||||
},
|
||||
{
|
||||
role: ROLE_OUTLINEITEM,
|
||||
children: [],
|
||||
name: "row1col"
|
||||
},
|
||||
{
|
||||
role: ROLE_OUTLINEITEM,
|
||||
children: [],
|
||||
name: "row2_col"
|
||||
},
|
||||
{
|
||||
role: ROLE_OUTLINEITEM,
|
||||
children: [],
|
||||
name: "row2.1_col"
|
||||
},
|
||||
{
|
||||
role: ROLE_OUTLINEITEM,
|
||||
children: [],
|
||||
name: "row2.2_col"
|
||||
},
|
||||
{
|
||||
role: ROLE_OUTLINEITEM,
|
||||
children: [],
|
||||
name: "row3_col"
|
||||
},
|
||||
{
|
||||
role: ROLE_OUTLINEITEM,
|
||||
children: [],
|
||||
name: "row4col"
|
||||
}
|
||||
]
|
||||
};
|
||||
testAccessibleTree(this.DOMNode, tree);
|
||||
}
|
||||
|
||||
this.getID = function treeTester_getID()
|
||||
{
|
||||
return "Tree name testing for " + aID;
|
||||
}
|
||||
}
|
||||
|
||||
function tableTester(aID)
|
||||
{
|
||||
this.DOMNode = getNode(aID);
|
||||
|
||||
this.invoke = function tableTester_invoke()
|
||||
{
|
||||
this.DOMNode.treeBoxObject.view = new nsTableTreeView(2);
|
||||
}
|
||||
|
||||
this.check = function tableTester_check(aEvent)
|
||||
{
|
||||
var tree = {
|
||||
role: ROLE_TREE_TABLE,
|
||||
children: [
|
||||
{
|
||||
role: ROLE_LIST
|
||||
},
|
||||
{
|
||||
role: ROLE_ROW,
|
||||
children: [
|
||||
{
|
||||
role: ROLE_GRID_CELL,
|
||||
children: [],
|
||||
name: "row0_col1"
|
||||
},
|
||||
{
|
||||
role: ROLE_GRID_CELL,
|
||||
children: [],
|
||||
name: "row0_col2"
|
||||
}
|
||||
],
|
||||
name: "row0_col1"
|
||||
},
|
||||
{
|
||||
role: ROLE_ROW,
|
||||
children: [
|
||||
{
|
||||
role: ROLE_GRID_CELL,
|
||||
children: [],
|
||||
name: "row1_col1"
|
||||
},
|
||||
{
|
||||
role: ROLE_GRID_CELL,
|
||||
children: [],
|
||||
name: "row1_col2"
|
||||
}
|
||||
],
|
||||
name: "row1_col1"
|
||||
}
|
||||
]
|
||||
};
|
||||
testAccessibleTree(this.DOMNode, tree);
|
||||
}
|
||||
|
||||
this.getID = function tableTester_getID()
|
||||
{
|
||||
return "Tree name testing for " + aID;
|
||||
}
|
||||
}
|
||||
|
||||
var gQueue = null;
|
||||
function doTest()
|
||||
{
|
||||
var gQueue = new eventQueue(EVENT_REORDER);
|
||||
|
||||
gQueue.push(new treeTester("tree"));
|
||||
gQueue.push(new tableTester("table"));
|
||||
|
||||
gQueue.invoke(); // Will call SimpleTest.finish()
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTest);
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<hbox flex="1" style="overflow: auto;">
|
||||
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=546812"
|
||||
title="Treegrid row accessible shouldn't inherit name from tree accessible">
|
||||
Mozilla Bug 546812
|
||||
</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
|
||||
<vbox flex="1">
|
||||
|
||||
<tree id="tree" flex="1">
|
||||
<treecols>
|
||||
<treecol id="col" flex="1" primary="true" label="column"/>
|
||||
</treecols>
|
||||
<treechildren/>
|
||||
</tree>
|
||||
|
||||
<tree id="table" flex="1">
|
||||
<treecols>
|
||||
<treecol id="col1" flex="1" label="column" primary="true"/>
|
||||
<treecol id="col2" flex="1" label="column 2"/>
|
||||
</treecols>
|
||||
<treechildren/>
|
||||
</tree>
|
||||
|
||||
</vbox> <!-- close tests area -->
|
||||
</hbox> <!-- close main area -->
|
||||
</window>
|
||||
|
|
@ -864,6 +864,9 @@ pref("breakpad.reportURL", "http://crash-stats.mozilla.com/report/index/");
|
|||
// base URL for web-based support pages
|
||||
pref("app.support.baseURL", "http://support.mozilla.com/1/firefox/%VERSION%/%OS%/%LOCALE%/");
|
||||
|
||||
// URL for web-based support page on how to upgrade a graphics driver
|
||||
pref("app.support.updateGraphicsDriverURL", "http://support.mozilla.com/%LOCALE%/kb/how-do-i-upgrade-my-graphics-drivers");
|
||||
|
||||
// Name of alternate about: page for certificate errors (when undefined, defaults to about:neterror)
|
||||
pref("security.alternate_certificate_error_page", "certerror");
|
||||
|
||||
|
|
|
@ -4366,6 +4366,10 @@ var XULBrowserWindow = {
|
|||
}
|
||||
},
|
||||
|
||||
onLocationChange2: function (aWebProgress, aRequest, aLocationURI, aFlags) {
|
||||
onLocationChange(aWebProgress, aRequest, aLocationURI);
|
||||
},
|
||||
|
||||
onLocationChange: function (aWebProgress, aRequest, aLocationURI) {
|
||||
var location = aLocationURI ? aLocationURI.spec : "";
|
||||
this._hostChanged = true;
|
||||
|
|
|
@ -425,6 +425,7 @@ let AboutPermissions = {
|
|||
|
||||
gSitesStmt.finalize();
|
||||
gVisitStmt.finalize();
|
||||
gPlacesDatabase.asyncClose(null);
|
||||
},
|
||||
|
||||
observe: function (aSubject, aTopic, aData) {
|
||||
|
|
|
@ -559,6 +559,51 @@ static const PRUnichar kEqualsCh = PRUnichar('=');
|
|||
static const PRUnichar kLessThanCh = PRUnichar('<');
|
||||
static const PRUnichar kGreaterThanCh = PRUnichar('>');
|
||||
|
||||
|
||||
// check whether the Link header field applies to the context resource
|
||||
// see <http://tools.ietf.org/html/rfc5988#section-5.2>
|
||||
|
||||
PRBool
|
||||
nsContentSink::LinkContextIsOurDocument(const nsSubstring& aAnchor)
|
||||
{
|
||||
if (aAnchor.IsEmpty()) {
|
||||
// anchor parameter not present or empty -> same document reference
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
nsIURI* docUri = mDocument->GetDocumentURI();
|
||||
|
||||
// the document URI might contain a fragment identifier ("#...')
|
||||
// we want to ignore that because it's invisible to the server
|
||||
// and just affects the local interpretation in the recipient
|
||||
nsCOMPtr<nsIURI> contextUri;
|
||||
nsresult rv = docUri->CloneIgnoringRef(getter_AddRefs(contextUri));
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
// copying failed
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// resolve anchor against context
|
||||
nsCOMPtr<nsIURI> resolvedUri;
|
||||
rv = NS_NewURI(getter_AddRefs(resolvedUri), aAnchor,
|
||||
nsnull, contextUri);
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
// resolving failed
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
PRBool same;
|
||||
rv = contextUri->Equals(resolvedUri, &same);
|
||||
if (NS_FAILED(rv)) {
|
||||
// comparison failed
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
return same;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsContentSink::ProcessLinkHeader(nsIContent* aElement,
|
||||
const nsAString& aLinkData)
|
||||
|
@ -571,6 +616,7 @@ nsContentSink::ProcessLinkHeader(nsIContent* aElement,
|
|||
nsAutoString title;
|
||||
nsAutoString type;
|
||||
nsAutoString media;
|
||||
nsAutoString anchor;
|
||||
|
||||
// copy to work buffer
|
||||
nsAutoString stringList(aLinkData);
|
||||
|
@ -699,6 +745,11 @@ nsContentSink::ProcessLinkHeader(nsIContent* aElement,
|
|||
// HTML4.0 spec is inconsistent, make it case INSENSITIVE
|
||||
ToLowerCase(media);
|
||||
}
|
||||
} else if (attr.LowerCaseEqualsLiteral("anchor")) {
|
||||
if (anchor.IsEmpty()) {
|
||||
anchor = value;
|
||||
anchor.StripWhitespace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -709,7 +760,7 @@ nsContentSink::ProcessLinkHeader(nsIContent* aElement,
|
|||
|
||||
href.Trim(" \t\n\r\f"); // trim HTML5 whitespace
|
||||
if (!href.IsEmpty() && !rel.IsEmpty()) {
|
||||
rv = ProcessLink(aElement, href, rel, title, type, media);
|
||||
rv = ProcessLink(aElement, anchor, href, rel, title, type, media);
|
||||
}
|
||||
|
||||
href.Truncate();
|
||||
|
@ -717,14 +768,15 @@ nsContentSink::ProcessLinkHeader(nsIContent* aElement,
|
|||
title.Truncate();
|
||||
type.Truncate();
|
||||
media.Truncate();
|
||||
anchor.Truncate();
|
||||
}
|
||||
|
||||
start = ++end;
|
||||
}
|
||||
|
||||
|
||||
href.Trim(" \t\n\r\f"); // trim HTML5 whitespace
|
||||
if (!href.IsEmpty() && !rel.IsEmpty()) {
|
||||
rv = ProcessLink(aElement, href, rel, title, type, media);
|
||||
rv = ProcessLink(aElement, anchor, href, rel, title, type, media);
|
||||
}
|
||||
|
||||
return rv;
|
||||
|
@ -733,14 +785,22 @@ nsContentSink::ProcessLinkHeader(nsIContent* aElement,
|
|||
|
||||
nsresult
|
||||
nsContentSink::ProcessLink(nsIContent* aElement,
|
||||
const nsSubstring& aHref, const nsSubstring& aRel,
|
||||
const nsSubstring& aTitle, const nsSubstring& aType,
|
||||
const nsSubstring& aMedia)
|
||||
const nsSubstring& aAnchor, const nsSubstring& aHref,
|
||||
const nsSubstring& aRel, const nsSubstring& aTitle,
|
||||
const nsSubstring& aType, const nsSubstring& aMedia)
|
||||
{
|
||||
// XXX seems overkill to generate this string array
|
||||
nsTArray<nsString> linkTypes;
|
||||
nsStyleLinkElement::ParseLinkTypes(aRel, linkTypes);
|
||||
|
||||
// The link relation may apply to a different resource, specified
|
||||
// in the anchor parameter. For the link relations supported so far,
|
||||
// we simply abort if the link applies to a resource different to the
|
||||
// one we've loaded
|
||||
if (!LinkContextIsOurDocument(aAnchor)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRBool hasPrefetch = linkTypes.Contains(NS_LITERAL_STRING("prefetch"));
|
||||
// prefetch href if relation is "next" or "prefetch"
|
||||
if (hasPrefetch || linkTypes.Contains(NS_LITERAL_STRING("next"))) {
|
||||
|
|
|
@ -151,6 +151,7 @@ class nsContentSink : public nsICSSLoaderObserver,
|
|||
virtual void UpdateChildCounts() = 0;
|
||||
|
||||
PRBool IsTimeToNotify();
|
||||
PRBool LinkContextIsOurDocument(const nsSubstring& aAnchor);
|
||||
|
||||
static void InitializeStatics();
|
||||
|
||||
|
@ -188,9 +189,10 @@ protected:
|
|||
nsIContent* aContent = nsnull);
|
||||
nsresult ProcessLinkHeader(nsIContent* aElement,
|
||||
const nsAString& aLinkData);
|
||||
nsresult ProcessLink(nsIContent* aElement, const nsSubstring& aHref,
|
||||
const nsSubstring& aRel, const nsSubstring& aTitle,
|
||||
const nsSubstring& aType, const nsSubstring& aMedia);
|
||||
nsresult ProcessLink(nsIContent* aElement, const nsSubstring& aAnchor,
|
||||
const nsSubstring& aHref, const nsSubstring& aRel,
|
||||
const nsSubstring& aTitle, const nsSubstring& aType,
|
||||
const nsSubstring& aMedia);
|
||||
|
||||
virtual nsresult ProcessStyleLink(nsIContent* aElement,
|
||||
const nsSubstring& aHref,
|
||||
|
|
|
@ -1722,7 +1722,6 @@ GK_ATOM(columnSetFrame, "ColumnSetFrame")
|
|||
GK_ATOM(comboboxControlFrame, "ComboboxControlFrame")
|
||||
GK_ATOM(comboboxDisplayFrame, "ComboboxDisplayFrame")
|
||||
GK_ATOM(deckFrame, "DeckFrame")
|
||||
GK_ATOM(directionalFrame, "DirectionalFrame")
|
||||
GK_ATOM(fieldSetFrame, "FieldSetFrame")
|
||||
GK_ATOM(frameSetFrame, "FrameSetFrame")
|
||||
GK_ATOM(gfxButtonControlFrame, "gfxButtonControlFrame")
|
||||
|
|
|
@ -314,6 +314,7 @@ nsWebSocketEstablishedConnection::PrintErrorOnConsole(const char *aBundleURI,
|
|||
PRUint32 aFormatStringsLen)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
|
||||
NS_ABORT_IF_FALSE(mOwner, "No owner");
|
||||
|
||||
nsresult rv;
|
||||
|
||||
|
@ -365,6 +366,8 @@ nsresult
|
|||
nsWebSocketEstablishedConnection::Close()
|
||||
{
|
||||
NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
|
||||
if (!mOwner)
|
||||
return NS_OK;
|
||||
|
||||
// Disconnect() can release this object, so we keep a
|
||||
// reference until the end of the method
|
||||
|
@ -458,6 +461,8 @@ nsresult
|
|||
nsWebSocketEstablishedConnection::UpdateMustKeepAlive()
|
||||
{
|
||||
NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
|
||||
NS_ABORT_IF_FALSE(mOwner, "No owner");
|
||||
|
||||
mOwner->UpdateMustKeepAlive();
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -572,6 +577,9 @@ nsWebSocketEstablishedConnection::GetInterface(const nsIID &aIID,
|
|||
{
|
||||
NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
|
||||
|
||||
if (!mOwner)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if (aIID.Equals(NS_GET_IID(nsIAuthPrompt)) ||
|
||||
aIID.Equals(NS_GET_IID(nsIAuthPrompt2))) {
|
||||
nsresult rv;
|
||||
|
|
|
@ -60,7 +60,6 @@ EXPORTS = \
|
|||
nsIRadioGroupContainer.h \
|
||||
nsITextControlElement.h \
|
||||
nsFormSubmission.h \
|
||||
nsIFrameSetElement.h \
|
||||
nsHTMLAudioElement.h \
|
||||
nsHTMLCanvasElement.h \
|
||||
nsHTMLMediaElement.h \
|
||||
|
|
|
@ -177,8 +177,7 @@ protected:
|
|||
nsresult UpdateContext(nsIPropertyBag *aNewContextOptions = nsnull);
|
||||
nsresult ExtractData(const nsAString& aType,
|
||||
const nsAString& aOptions,
|
||||
char*& aData,
|
||||
PRUint32& aSize,
|
||||
nsIInputStream** aStream,
|
||||
bool& aFellBackToPNG);
|
||||
nsresult ToDataURLImpl(const nsAString& aMimeType,
|
||||
nsIVariant* aEncoderOptions,
|
||||
|
|
|
@ -1,106 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** 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 code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Boris Zbarsky <bzbarsky@mit.edu> (Original author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of 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 ***** */
|
||||
|
||||
#ifndef nsIFramesetElement_h___
|
||||
#define nsIFramesetElement_h___
|
||||
|
||||
#include "nsISupports.h"
|
||||
|
||||
// IID for the nsIFramesetElement interface
|
||||
#define NS_IFRAMESETELEMENT_IID \
|
||||
{ 0xeefe0fe5, 0x44ac, 0x4d7f, \
|
||||
{ 0xa7, 0x51, 0xf4, 0xaa, 0x5f, 0x22, 0xb0, 0xbf } }
|
||||
|
||||
/**
|
||||
* The nsFramesetUnit enum is used to denote the type of each entry
|
||||
* in the row or column spec.
|
||||
*/
|
||||
enum nsFramesetUnit {
|
||||
eFramesetUnit_Fixed = 0,
|
||||
eFramesetUnit_Percent,
|
||||
eFramesetUnit_Relative
|
||||
};
|
||||
|
||||
/**
|
||||
* The nsFramesetSpec struct is used to hold a single entry in the
|
||||
* row or column spec.
|
||||
*/
|
||||
struct nsFramesetSpec {
|
||||
nsFramesetUnit mUnit;
|
||||
nscoord mValue;
|
||||
};
|
||||
|
||||
/**
|
||||
* The maximum number of entries allowed in the frame set element row
|
||||
* or column spec.
|
||||
*/
|
||||
#define NS_MAX_FRAMESET_SPEC_COUNT 16000
|
||||
|
||||
/**
|
||||
* This interface is used by the nsFramesetFrame to access the parsed
|
||||
* values of the "rows" and "cols" attributes
|
||||
*/
|
||||
class nsIFrameSetElement : public nsISupports {
|
||||
public:
|
||||
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_IFRAMESETELEMENT_IID)
|
||||
|
||||
/**
|
||||
* GetRowSpec is used to get the "rows" spec.
|
||||
* @param out PRInt32 aNumValues The number of row sizes specified.
|
||||
* @param out nsFramesetSpec* aSpecs The array of size specifications.
|
||||
This is _not_ owned by the caller, but by the nsIFrameSetElement
|
||||
implementation. DO NOT DELETE IT.
|
||||
* @exceptions NS_ERROR_OUT_OF_MEMORY
|
||||
*/
|
||||
NS_IMETHOD GetRowSpec(PRInt32 *aNumValues, const nsFramesetSpec** aSpecs) = 0;
|
||||
|
||||
/**
|
||||
* GetColSpec is used to get the "cols" spec
|
||||
* @param out PRInt32 aNumValues The number of row sizes specified.
|
||||
* @param out nsFramesetSpec* aSpecs The array of size specifications.
|
||||
This is _not_ owned by the caller, but by the nsIFrameSetElement
|
||||
implementation. DO NOT DELETE IT.
|
||||
* @exceptions NS_ERROR_OUT_OF_MEMORY
|
||||
*/
|
||||
NS_IMETHOD GetColSpec(PRInt32 *aNumValues, const nsFramesetSpec** aSpecs) = 0;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsIFrameSetElement, NS_IFRAMESETELEMENT_IID)
|
||||
|
||||
#endif // nsIFramesetElement_h___
|
|
@ -37,7 +37,7 @@
|
|||
|
||||
#include "nsHTMLCanvasElement.h"
|
||||
|
||||
#include "plbase64.h"
|
||||
#include "mozilla/Base64.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "prmem.h"
|
||||
#include "nsDOMFile.h"
|
||||
|
@ -211,8 +211,7 @@ nsHTMLCanvasElement::ToDataURL(const nsAString& aType, nsIVariant* aParams,
|
|||
nsresult
|
||||
nsHTMLCanvasElement::ExtractData(const nsAString& aType,
|
||||
const nsAString& aOptions,
|
||||
char*& aResult,
|
||||
PRUint32& aSize,
|
||||
nsIInputStream** aStream,
|
||||
bool& aFellBackToPNG)
|
||||
{
|
||||
// note that if we don't have a current context, the spec says we're
|
||||
|
@ -265,45 +264,9 @@ nsHTMLCanvasElement::ExtractData(const nsAString& aType,
|
|||
goto try_again;
|
||||
}
|
||||
|
||||
// at this point, we either need to succeed or bail.
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Generally, there will be only one chunk of data, and it will be available
|
||||
// for us to read right away, so optimize this case.
|
||||
PRUint32 bufSize;
|
||||
rv = imgStream->Available(&bufSize);
|
||||
CheckedUint32 safeBufSize(bufSize);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// ...leave a little extra room so we can call read again and make sure we
|
||||
// got everything. 16 bytes for better padding (maybe)
|
||||
safeBufSize += 16;
|
||||
NS_ENSURE_TRUE(safeBufSize.valid(), NS_ERROR_FAILURE);
|
||||
aSize = 0;
|
||||
aResult = (char*)PR_Malloc(safeBufSize.value());
|
||||
if (!aResult)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
PRUint32 numReadThisTime = 0;
|
||||
while ((rv = imgStream->Read(&aResult[aSize], safeBufSize.value() - aSize,
|
||||
&numReadThisTime)) == NS_OK &&
|
||||
numReadThisTime > 0) {
|
||||
aSize += numReadThisTime;
|
||||
if (aSize == safeBufSize.value()) {
|
||||
// need a bigger buffer, just double
|
||||
safeBufSize *= 2;
|
||||
if (!safeBufSize.valid()) {
|
||||
PR_Free(aResult);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
char* newImgData = (char*)PR_Realloc(aResult, safeBufSize.value());
|
||||
if (! newImgData) {
|
||||
PR_Free(aResult);
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
aResult = newImgData;
|
||||
}
|
||||
}
|
||||
|
||||
return CallQueryInterface(imgStream, aStream);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -343,29 +306,23 @@ nsHTMLCanvasElement::ToDataURLImpl(const nsAString& aMimeType,
|
|||
}
|
||||
}
|
||||
|
||||
PRUint32 imgSize = 0;
|
||||
char* imgData;
|
||||
|
||||
nsresult rv = ExtractData(type, params, imgData, imgSize, fallbackToPNG);
|
||||
nsCOMPtr<nsIInputStream> stream;
|
||||
nsresult rv = ExtractData(type, params, getter_AddRefs(stream),
|
||||
fallbackToPNG);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// base 64, result will be NULL terminated
|
||||
char* encodedImg = PL_Base64Encode(imgData, imgSize, nsnull);
|
||||
PR_Free(imgData);
|
||||
if (!encodedImg) // not sure why this would fail
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
// build data URL string
|
||||
if (fallbackToPNG)
|
||||
aDataURL = NS_LITERAL_STRING("data:image/png;base64,") +
|
||||
NS_ConvertUTF8toUTF16(encodedImg);
|
||||
aDataURL = NS_LITERAL_STRING("data:image/png;base64,");
|
||||
else
|
||||
aDataURL = NS_LITERAL_STRING("data:") + type +
|
||||
NS_LITERAL_STRING(";base64,") + NS_ConvertUTF8toUTF16(encodedImg);
|
||||
NS_LITERAL_STRING(";base64,");
|
||||
|
||||
PR_Free(encodedImg);
|
||||
PRUint32 count;
|
||||
rv = stream->Available(&count);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
return Base64EncodeInputStream(stream, aDataURL, count, aDataURL.Length());
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -389,11 +346,10 @@ nsHTMLCanvasElement::MozGetAsFileImpl(const nsAString& aName,
|
|||
nsIDOMFile** aResult)
|
||||
{
|
||||
bool fallbackToPNG = false;
|
||||
PRUint32 imgSize = 0;
|
||||
char* imgData;
|
||||
|
||||
nsresult rv = ExtractData(aType, EmptyString(), imgData,
|
||||
imgSize, fallbackToPNG);
|
||||
nsCOMPtr<nsIInputStream> stream;
|
||||
nsresult rv = ExtractData(aType, EmptyString(), getter_AddRefs(stream),
|
||||
fallbackToPNG);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsAutoString type(aType);
|
||||
|
@ -401,9 +357,17 @@ nsHTMLCanvasElement::MozGetAsFileImpl(const nsAString& aName,
|
|||
type.AssignLiteral("image/png");
|
||||
}
|
||||
|
||||
PRUint32 imgSize;
|
||||
rv = stream->Available(&imgSize);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
void* imgData = nsnull;
|
||||
rv = NS_ReadInputStreamToBuffer(stream, &imgData, imgSize);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// The DOMFile takes ownership of the buffer
|
||||
nsRefPtr<nsDOMMemoryFile> file =
|
||||
new nsDOMMemoryFile((void*)imgData, imgSize, aName, type);
|
||||
new nsDOMMemoryFile(imgData, imgSize, aName, type);
|
||||
|
||||
return CallQueryInterface(file, aResult);
|
||||
}
|
||||
|
|
|
@ -34,89 +34,8 @@
|
|||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
#include "nsIDOMHTMLFrameSetElement.h"
|
||||
#include "nsIDOMEventTarget.h"
|
||||
#include "nsGenericHTMLElement.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsStyleConsts.h"
|
||||
#include "nsIFrameSetElement.h"
|
||||
#include "nsIHTMLDocument.h"
|
||||
#include "nsIDocument.h"
|
||||
|
||||
class nsHTMLFrameSetElement : public nsGenericHTMLElement,
|
||||
public nsIDOMHTMLFrameSetElement,
|
||||
public nsIFrameSetElement
|
||||
{
|
||||
public:
|
||||
nsHTMLFrameSetElement(already_AddRefed<nsINodeInfo> aNodeInfo);
|
||||
virtual ~nsHTMLFrameSetElement();
|
||||
|
||||
// nsISupports
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
// nsIDOMNode
|
||||
NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::)
|
||||
|
||||
// nsIDOMElement
|
||||
NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
|
||||
|
||||
// nsIDOMHTMLElement
|
||||
NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::)
|
||||
|
||||
// nsIDOMHTMLFrameSetElement
|
||||
NS_DECL_NSIDOMHTMLFRAMESETELEMENT
|
||||
|
||||
// These override the SetAttr methods in nsGenericHTMLElement (need
|
||||
// both here to silence compiler warnings).
|
||||
nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
const nsAString& aValue, PRBool aNotify)
|
||||
{
|
||||
return SetAttr(aNameSpaceID, aName, nsnull, aValue, aNotify);
|
||||
}
|
||||
virtual nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
nsIAtom* aPrefix, const nsAString& aValue,
|
||||
PRBool aNotify);
|
||||
|
||||
// nsIFramesetElement
|
||||
NS_IMETHOD GetRowSpec(PRInt32 *aNumValues, const nsFramesetSpec** aSpecs);
|
||||
NS_IMETHOD GetColSpec(PRInt32 *aNumValues, const nsFramesetSpec** aSpecs);
|
||||
|
||||
virtual PRBool ParseAttribute(PRInt32 aNamespaceID,
|
||||
nsIAtom* aAttribute,
|
||||
const nsAString& aValue,
|
||||
nsAttrValue& aResult);
|
||||
virtual nsChangeHint GetAttributeChangeHint(const nsIAtom* aAttribute,
|
||||
PRInt32 aModType) const;
|
||||
|
||||
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
|
||||
virtual nsXPCClassInfo* GetClassInfo();
|
||||
private:
|
||||
nsresult ParseRowCol(const nsAString& aValue,
|
||||
PRInt32& aNumSpecs,
|
||||
nsFramesetSpec** aSpecs);
|
||||
|
||||
/**
|
||||
* The number of size specs in our "rows" attr
|
||||
*/
|
||||
PRInt32 mNumRows;
|
||||
/**
|
||||
* The number of size specs in our "cols" attr
|
||||
*/
|
||||
PRInt32 mNumCols;
|
||||
/**
|
||||
* The style hint to return for the rows/cols attrs in
|
||||
* GetAttributeChangeHint
|
||||
*/
|
||||
nsChangeHint mCurrentRowColHint;
|
||||
/**
|
||||
* The parsed representation of the "rows" attribute
|
||||
*/
|
||||
nsAutoArrayPtr<nsFramesetSpec> mRowSpecs; // parsed, non-computed dimensions
|
||||
/**
|
||||
* The parsed representation of the "cols" attribute
|
||||
*/
|
||||
nsAutoArrayPtr<nsFramesetSpec> mColSpecs; // parsed, non-computed dimensions
|
||||
};
|
||||
#include "nsHTMLFrameSetElement.h"
|
||||
|
||||
NS_IMPL_NS_NEW_HTML_ELEMENT(FrameSet)
|
||||
|
||||
|
@ -140,9 +59,8 @@ DOMCI_NODE_DATA(HTMLFrameSetElement, nsHTMLFrameSetElement)
|
|||
|
||||
// QueryInterface implementation for nsHTMLFrameSetElement
|
||||
NS_INTERFACE_TABLE_HEAD(nsHTMLFrameSetElement)
|
||||
NS_HTML_CONTENT_INTERFACE_TABLE2(nsHTMLFrameSetElement,
|
||||
nsIDOMHTMLFrameSetElement,
|
||||
nsIFrameSetElement)
|
||||
NS_HTML_CONTENT_INTERFACE_TABLE1(nsHTMLFrameSetElement,
|
||||
nsIDOMHTMLFrameSetElement)
|
||||
NS_HTML_CONTENT_INTERFACE_TABLE_TO_MAP_SEGUE(nsHTMLFrameSetElement,
|
||||
nsGenericHTMLElement)
|
||||
NS_HTML_CONTENT_INTERFACE_TABLE_TAIL_CLASSINFO(HTMLFrameSetElement)
|
||||
|
@ -194,7 +112,7 @@ nsHTMLFrameSetElement::SetAttr(PRInt32 aNameSpaceID,
|
|||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsresult
|
||||
nsHTMLFrameSetElement::GetRowSpec(PRInt32 *aNumValues,
|
||||
const nsFramesetSpec** aSpecs)
|
||||
{
|
||||
|
@ -228,7 +146,7 @@ nsHTMLFrameSetElement::GetRowSpec(PRInt32 *aNumValues,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsresult
|
||||
nsHTMLFrameSetElement::GetColSpec(PRInt32 *aNumValues,
|
||||
const nsFramesetSpec** aSpecs)
|
||||
{
|
||||
|
@ -429,4 +347,3 @@ nsHTMLFrameSetElement::ParseRowCol(const nsAString & aValue,
|
|||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,172 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** 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 Communicator client code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Boris Zbarsky <bzbarsky@mit.edu> (Original author)
|
||||
* Sebastian Kromp <46b@gulli.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of 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 ***** */
|
||||
|
||||
#ifndef nsHTMLFrameSetElement_h
|
||||
#define nsHTMLFrameSetElement_h
|
||||
|
||||
#include "nsISupports.h"
|
||||
#include "nsIDOMHTMLFrameSetElement.h"
|
||||
#include "nsIDOMEventTarget.h"
|
||||
#include "nsGenericHTMLElement.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsStyleConsts.h"
|
||||
#include "nsIHTMLDocument.h"
|
||||
#include "nsIDocument.h"
|
||||
|
||||
/**
|
||||
* The nsFramesetUnit enum is used to denote the type of each entry
|
||||
* in the row or column spec.
|
||||
*/
|
||||
enum nsFramesetUnit {
|
||||
eFramesetUnit_Fixed = 0,
|
||||
eFramesetUnit_Percent,
|
||||
eFramesetUnit_Relative
|
||||
};
|
||||
|
||||
/**
|
||||
* The nsFramesetSpec struct is used to hold a single entry in the
|
||||
* row or column spec.
|
||||
*/
|
||||
struct nsFramesetSpec {
|
||||
nsFramesetUnit mUnit;
|
||||
nscoord mValue;
|
||||
};
|
||||
|
||||
/**
|
||||
* The maximum number of entries allowed in the frame set element row
|
||||
* or column spec.
|
||||
*/
|
||||
#define NS_MAX_FRAMESET_SPEC_COUNT 16000
|
||||
|
||||
class nsHTMLFrameSetElement : public nsGenericHTMLElement,
|
||||
public nsIDOMHTMLFrameSetElement
|
||||
{
|
||||
public:
|
||||
nsHTMLFrameSetElement(already_AddRefed<nsINodeInfo> aNodeInfo);
|
||||
virtual ~nsHTMLFrameSetElement();
|
||||
|
||||
// nsISupports
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
// nsIDOMNode
|
||||
NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::)
|
||||
|
||||
// nsIDOMElement
|
||||
NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
|
||||
|
||||
// nsIDOMHTMLElement
|
||||
NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::)
|
||||
|
||||
// nsIDOMHTMLFrameSetElement
|
||||
NS_DECL_NSIDOMHTMLFRAMESETELEMENT
|
||||
|
||||
// These override the SetAttr methods in nsGenericHTMLElement (need
|
||||
// both here to silence compiler warnings).
|
||||
nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
const nsAString& aValue, PRBool aNotify)
|
||||
{
|
||||
return SetAttr(aNameSpaceID, aName, nsnull, aValue, aNotify);
|
||||
}
|
||||
virtual nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
nsIAtom* aPrefix, const nsAString& aValue,
|
||||
PRBool aNotify);
|
||||
|
||||
/**
|
||||
* GetRowSpec is used to get the "rows" spec.
|
||||
* @param out PRInt32 aNumValues The number of row sizes specified.
|
||||
* @param out nsFramesetSpec* aSpecs The array of size specifications.
|
||||
This is _not_ owned by the caller, but by the nsFrameSetElement
|
||||
implementation. DO NOT DELETE IT.
|
||||
*/
|
||||
nsresult GetRowSpec(PRInt32 *aNumValues, const nsFramesetSpec** aSpecs);
|
||||
/**
|
||||
* GetColSpec is used to get the "cols" spec
|
||||
* @param out PRInt32 aNumValues The number of row sizes specified.
|
||||
* @param out nsFramesetSpec* aSpecs The array of size specifications.
|
||||
This is _not_ owned by the caller, but by the nsFrameSetElement
|
||||
implementation. DO NOT DELETE IT.
|
||||
*/
|
||||
nsresult GetColSpec(PRInt32 *aNumValues, const nsFramesetSpec** aSpecs);
|
||||
|
||||
|
||||
virtual PRBool ParseAttribute(PRInt32 aNamespaceID,
|
||||
nsIAtom* aAttribute,
|
||||
const nsAString& aValue,
|
||||
nsAttrValue& aResult);
|
||||
virtual nsChangeHint GetAttributeChangeHint(const nsIAtom* aAttribute,
|
||||
PRInt32 aModType) const;
|
||||
|
||||
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
|
||||
virtual nsXPCClassInfo* GetClassInfo();
|
||||
static nsHTMLFrameSetElement* FromContent(nsIContent *aContent)
|
||||
{
|
||||
if (aContent->IsHTML(nsGkAtoms::frameset))
|
||||
return static_cast<nsHTMLFrameSetElement*>(aContent);
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
private:
|
||||
nsresult ParseRowCol(const nsAString& aValue,
|
||||
PRInt32& aNumSpecs,
|
||||
nsFramesetSpec** aSpecs);
|
||||
|
||||
/**
|
||||
* The number of size specs in our "rows" attr
|
||||
*/
|
||||
PRInt32 mNumRows;
|
||||
/**
|
||||
* The number of size specs in our "cols" attr
|
||||
*/
|
||||
PRInt32 mNumCols;
|
||||
/**
|
||||
* The style hint to return for the rows/cols attrs in
|
||||
* GetAttributeChangeHint
|
||||
*/
|
||||
nsChangeHint mCurrentRowColHint;
|
||||
/**
|
||||
* The parsed representation of the "rows" attribute
|
||||
*/
|
||||
nsAutoArrayPtr<nsFramesetSpec> mRowSpecs; // parsed, non-computed dimensions
|
||||
/**
|
||||
* The parsed representation of the "cols" attribute
|
||||
*/
|
||||
nsAutoArrayPtr<nsFramesetSpec> mColSpecs; // parsed, non-computed dimensions
|
||||
};
|
||||
|
||||
#endif nsHTMLFrameSetElement_h
|
|
@ -427,7 +427,7 @@ PRBool nsOggReader::DecodeAudioData()
|
|||
return PR_TRUE;
|
||||
}
|
||||
|
||||
nsresult nsOggReader::DecodeTheora(ogg_packet* aPacket)
|
||||
nsresult nsOggReader::DecodeTheora(ogg_packet* aPacket, PRInt64 aTimeThreshold)
|
||||
{
|
||||
NS_ASSERTION(aPacket->granulepos >= TheoraVersion(&mTheoraState->mInfo,3,2,1),
|
||||
"Packets must have valid granulepos and packetno");
|
||||
|
@ -447,6 +447,12 @@ nsresult nsOggReader::DecodeTheora(ogg_packet* aPacket)
|
|||
}
|
||||
|
||||
PRInt64 endTime = mTheoraState->Time(aPacket->granulepos);
|
||||
if (endTime < aTimeThreshold) {
|
||||
// The end time of this frame is already before the current playback
|
||||
// position. It will never be displayed, don't bother enqueing it.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (ret == TH_DUPFRAME) {
|
||||
VideoData* v = VideoData::CreateDuplicate(mPageOffset,
|
||||
time,
|
||||
|
@ -523,7 +529,7 @@ PRBool nsOggReader::DecodeVideoFrame(PRBool &aKeyframeSkip,
|
|||
(th_packet_iskeyframe(packet) && frameEndTime >= aTimeThreshold))
|
||||
{
|
||||
aKeyframeSkip = PR_FALSE;
|
||||
nsresult res = DecodeTheora(packet);
|
||||
nsresult res = DecodeTheora(packet, aTimeThreshold);
|
||||
decoded++;
|
||||
if (NS_FAILED(res)) {
|
||||
return PR_FALSE;
|
||||
|
|
|
@ -231,8 +231,10 @@ private:
|
|||
|
||||
// Decodes a packet of Theora data, and inserts its frame into the
|
||||
// video queue. May return NS_ERROR_OUT_OF_MEMORY. Caller must have obtained
|
||||
// the reader's monitor.
|
||||
nsresult DecodeTheora(ogg_packet* aPacket);
|
||||
// the reader's monitor. aTimeThreshold is the current playback position
|
||||
// in media time in microseconds. Frames with an end time before this will
|
||||
// not be enqueued.
|
||||
nsresult DecodeTheora(ogg_packet* aPacket, PRInt64 aTimeThreshold);
|
||||
|
||||
// Read a page of data from the Ogg file. Returns the offset of the start
|
||||
// of the page, or -1 if the page read failed.
|
||||
|
|
|
@ -1726,17 +1726,20 @@ nsDocShell::GetChromeEventHandler(nsIDOMEventTarget** aChromeEventHandler)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
/* [noscript] void setCurrentURI (in nsIURI uri); */
|
||||
/* void setCurrentURI (in nsIURI uri); */
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::SetCurrentURI(nsIURI *aURI)
|
||||
{
|
||||
SetCurrentURI(aURI, nsnull, PR_TRUE);
|
||||
// Note that securityUI will set STATE_IS_INSECURE, even if
|
||||
// the scheme of |aURI| is "https".
|
||||
SetCurrentURI(aURI, nsnull, PR_TRUE,
|
||||
nsIWebProgressListener2::LOCATION_CHANGE_NORMAL);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsDocShell::SetCurrentURI(nsIURI *aURI, nsIRequest *aRequest,
|
||||
PRBool aFireOnLocationChange)
|
||||
PRBool aFireOnLocationChange, PRUint32 aLocationFlags)
|
||||
{
|
||||
#ifdef PR_LOGGING
|
||||
if (gDocShellLeakLog && PR_LOG_TEST(gDocShellLeakLog, PR_LOG_DEBUG)) {
|
||||
|
@ -1780,7 +1783,7 @@ nsDocShell::SetCurrentURI(nsIURI *aURI, nsIRequest *aRequest,
|
|||
}
|
||||
|
||||
if (aFireOnLocationChange) {
|
||||
FireOnLocationChange(this, aRequest, aURI);
|
||||
FireOnLocationChange(this, aRequest, aURI, aLocationFlags);
|
||||
}
|
||||
return !aFireOnLocationChange;
|
||||
}
|
||||
|
@ -5874,7 +5877,8 @@ nsDocShell::OnStateChange(nsIWebProgress * aProgress, nsIRequest * aRequest,
|
|||
// a new DOM here.
|
||||
rv = AddToSessionHistory(uri, wcwgChannel, nsnull, PR_FALSE,
|
||||
getter_AddRefs(mLSHE));
|
||||
SetCurrentURI(uri, aRequest, PR_TRUE);
|
||||
SetCurrentURI(uri, aRequest, PR_TRUE,
|
||||
nsIWebProgressListener2::LOCATION_CHANGE_NORMAL);
|
||||
// Save history state of the previous page
|
||||
rv = PersistLayoutHistoryState();
|
||||
// We'll never get an Embed() for this load, so just go ahead
|
||||
|
@ -6528,7 +6532,8 @@ nsDocShell::CreateAboutBlankContentViewer(nsIPrincipal* aPrincipal,
|
|||
viewer->SetContainer(static_cast<nsIContentViewerContainer *>(this));
|
||||
Embed(viewer, "", 0);
|
||||
|
||||
SetCurrentURI(blankDoc->GetDocumentURI(), nsnull, PR_TRUE);
|
||||
SetCurrentURI(blankDoc->GetDocumentURI(), nsnull, PR_TRUE,
|
||||
nsIWebProgressListener2::LOCATION_CHANGE_NORMAL);
|
||||
rv = mIsBeingDestroyed ? NS_ERROR_NOT_AVAILABLE : NS_OK;
|
||||
}
|
||||
}
|
||||
|
@ -7179,7 +7184,8 @@ nsDocShell::RestoreFromHistory()
|
|||
// is still mLSHE or whether it's now mOSHE.
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
origLSHE->GetURI(getter_AddRefs(uri));
|
||||
SetCurrentURI(uri, document->GetChannel(), PR_TRUE);
|
||||
SetCurrentURI(uri, document->GetChannel(), PR_TRUE,
|
||||
nsIWebProgressListener2::LOCATION_CHANGE_NORMAL);
|
||||
}
|
||||
|
||||
// This is the end of our CreateContentViewer() replacement.
|
||||
|
@ -7518,7 +7524,8 @@ nsDocShell::CreateContentViewer(const char *aContentType,
|
|||
}
|
||||
|
||||
if (onLocationChangeNeeded) {
|
||||
FireOnLocationChange(this, request, mCurrentURI);
|
||||
FireOnLocationChange(this, request, mCurrentURI,
|
||||
nsIWebProgressListener2::LOCATION_CHANGE_NORMAL);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -8360,11 +8367,7 @@ nsDocShell::InternalLoad(nsIURI * aURI,
|
|||
// sometimes we might scroll even if we don't fire a hashchange
|
||||
// event! See bug 653741.
|
||||
if (!aSHEntry) {
|
||||
// Take the '#' off the hashes before passing them to
|
||||
// ScrollToAnchor.
|
||||
nsDependentCSubstring curHashName(curHash, 1);
|
||||
nsDependentCSubstring newHashName(newHash, 1);
|
||||
rv = ScrollToAnchor(curHashName, newHashName, aLoadType);
|
||||
rv = ScrollToAnchor(curHash, newHash, aLoadType);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
|
@ -8389,6 +8392,11 @@ nsDocShell::InternalLoad(nsIURI * aURI,
|
|||
// Pass true for aCloneSHChildren, since we're not
|
||||
// changing documents here, so all of our subframes are
|
||||
// still relevant to the new session history entry.
|
||||
//
|
||||
// It also makes OnNewURI(...) set LOCATION_CHANGE_SAME_DOCUMENT
|
||||
// flag on firing onLocationChange(...).
|
||||
// Anyway, aCloneSHChildren param is simply reflecting
|
||||
// doShortCircuitedLoad in this scope.
|
||||
OnNewURI(aURI, nsnull, owner, mLoadType, PR_TRUE, PR_TRUE, PR_TRUE);
|
||||
|
||||
nsCOMPtr<nsIInputStream> postData;
|
||||
|
@ -9159,16 +9167,20 @@ nsDocShell::ScrollToAnchor(nsACString & aCurHash, nsACString & aNewHash,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// Take the '#' off aNewHash to get the ref name. (aNewHash might be empty,
|
||||
// but that's fine.)
|
||||
nsDependentCSubstring newHashName(aNewHash, 1);
|
||||
|
||||
// Both the new and current URIs refer to the same page. We can now
|
||||
// browse to the hash stored in the new URI.
|
||||
|
||||
if (!aNewHash.IsEmpty()) {
|
||||
if (!newHashName.IsEmpty()) {
|
||||
// anchor is there, but if it's a load from history,
|
||||
// we don't have any anchor jumping to do
|
||||
PRBool scroll = aLoadType != LOAD_HISTORY &&
|
||||
aLoadType != LOAD_RELOAD_NORMAL;
|
||||
|
||||
char *str = ToNewCString(aNewHash);
|
||||
char *str = ToNewCString(newHashName);
|
||||
if (!str) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
@ -9210,7 +9222,7 @@ nsDocShell::ScrollToAnchor(nsACString & aCurHash, nsACString & aNewHash,
|
|||
nsXPIDLString uStr;
|
||||
|
||||
rv = textToSubURI->UnEscapeAndConvert(PromiseFlatCString(aCharset).get(),
|
||||
PromiseFlatCString(aNewHash).get(),
|
||||
PromiseFlatCString(newHashName).get(),
|
||||
getter_Copies(uStr));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
|
@ -9450,9 +9462,9 @@ nsDocShell::OnNewURI(nsIURI * aURI, nsIChannel * aChannel, nsISupports* aOwner,
|
|||
}
|
||||
}
|
||||
|
||||
// If this was a history load, update the index in
|
||||
// SH.
|
||||
if (rootSH && (mLoadType & LOAD_CMD_HISTORY)) {
|
||||
// If this was a history load or a refresh,
|
||||
// update the index in SH.
|
||||
if (rootSH && (mLoadType & (LOAD_CMD_HISTORY | LOAD_CMD_RELOAD))) {
|
||||
nsCOMPtr<nsISHistoryInternal> shInternal(do_QueryInterface(rootSH));
|
||||
if (shInternal) {
|
||||
rootSH->GetIndex(&mPreviousTransIndex);
|
||||
|
@ -9464,8 +9476,14 @@ nsDocShell::OnNewURI(nsIURI * aURI, nsIChannel * aChannel, nsISupports* aOwner,
|
|||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// aCloneSHChildren exactly means "we are not loading a new document".
|
||||
PRUint32 locationFlags = aCloneSHChildren?
|
||||
PRUint32(nsIWebProgressListener2::LOCATION_CHANGE_SAME_DOCUMENT) :
|
||||
PRUint32(nsIWebProgressListener2::LOCATION_CHANGE_NORMAL);
|
||||
PRBool onLocationChangeNeeded = SetCurrentURI(aURI, aChannel,
|
||||
aFireOnLocationChange);
|
||||
aFireOnLocationChange,
|
||||
locationFlags);
|
||||
// Make sure to store the referrer from the channel, if any
|
||||
SetupReferrerFromChannel(aChannel);
|
||||
return onLocationChangeNeeded;
|
||||
|
@ -9769,8 +9787,15 @@ nsDocShell::AddState(nsIVariant *aData, const nsAString& aTitle,
|
|||
// gets updated and the back button is enabled, but we only need to
|
||||
// explicitly call FireOnLocationChange if we're not calling SetCurrentURI,
|
||||
// since SetCurrentURI will call FireOnLocationChange for us.
|
||||
//
|
||||
// Both SetCurrentURI(...) and FireDummyOnLocationChange() pass
|
||||
// nsnull for aRequest param to FireOnLocationChange(...). Such an update
|
||||
// notification is allowed only when we know docshell is not loading a new
|
||||
// document and it requires LOCATION_CHANGE_SAME_DOCUMENT flag. Otherwise,
|
||||
// FireOnLocationChange(...) breaks security UI.
|
||||
if (!equalURIs) {
|
||||
SetCurrentURI(newURI, nsnull, PR_TRUE);
|
||||
SetCurrentURI(newURI, nsnull, PR_TRUE,
|
||||
nsIWebProgressListener2::LOCATION_CHANGE_SAME_DOCUMENT);
|
||||
document->SetDocumentURI(newURI);
|
||||
|
||||
AddURIVisit(newURI, oldURI, oldURI, 0);
|
||||
|
|
|
@ -94,7 +94,7 @@
|
|||
#include "nsISupportsArray.h"
|
||||
#include "nsIWebNavigation.h"
|
||||
#include "nsIWebPageDescriptor.h"
|
||||
#include "nsIWebProgressListener.h"
|
||||
#include "nsIWebProgressListener2.h"
|
||||
#include "nsISHContainer.h"
|
||||
#include "nsIDocShellLoadInfo.h"
|
||||
#include "nsIDocShellHistory.h"
|
||||
|
@ -268,10 +268,13 @@ public:
|
|||
|
||||
friend class OnLinkClickEvent;
|
||||
|
||||
// We need dummy OnLocationChange in some cases to update the UI.
|
||||
// We need dummy OnLocationChange in some cases to update the UI without
|
||||
// updating security info.
|
||||
void FireDummyOnLocationChange()
|
||||
{
|
||||
FireOnLocationChange(this, nsnull, mCurrentURI);
|
||||
FireOnLocationChange
|
||||
(this, nsnull, mCurrentURI,
|
||||
nsIWebProgressListener2::LOCATION_CHANGE_SAME_DOCUMENT);
|
||||
}
|
||||
|
||||
nsresult HistoryTransactionRemoved(PRInt32 aIndex);
|
||||
|
@ -592,7 +595,8 @@ protected:
|
|||
// FireOnLocationChange is called.
|
||||
// In all other cases PR_FALSE is returned.
|
||||
PRBool SetCurrentURI(nsIURI *aURI, nsIRequest *aRequest,
|
||||
PRBool aFireOnLocationChange);
|
||||
PRBool aFireOnLocationChange,
|
||||
PRUint32 aLocationFlags);
|
||||
|
||||
// The following methods deal with saving and restoring content viewers
|
||||
// in session history.
|
||||
|
|
|
@ -716,7 +716,13 @@ nsSHistory::GetCanGoBack(PRBool * aCanGoBack)
|
|||
NS_ENSURE_ARG_POINTER(aCanGoBack);
|
||||
*aCanGoBack = PR_FALSE;
|
||||
|
||||
// If there is already a pending navigation, we cannot go back.
|
||||
PRInt32 index = -1;
|
||||
NS_ENSURE_SUCCESS(GetRequestedIndex(&index), NS_ERROR_FAILURE);
|
||||
|
||||
if(index != -1)
|
||||
return NS_OK;
|
||||
|
||||
NS_ENSURE_SUCCESS(GetIndex(&index), NS_ERROR_FAILURE);
|
||||
if(index > 0)
|
||||
*aCanGoBack = PR_TRUE;
|
||||
|
@ -730,9 +736,15 @@ nsSHistory::GetCanGoForward(PRBool * aCanGoForward)
|
|||
NS_ENSURE_ARG_POINTER(aCanGoForward);
|
||||
*aCanGoForward = PR_FALSE;
|
||||
|
||||
// If there is already a pending navigation, we cannot go forward.
|
||||
PRInt32 index = -1;
|
||||
PRInt32 count = -1;
|
||||
|
||||
NS_ENSURE_SUCCESS(GetRequestedIndex(&index), NS_ERROR_FAILURE);
|
||||
|
||||
if(index != -1)
|
||||
return NS_OK;
|
||||
|
||||
NS_ENSURE_SUCCESS(GetIndex(&index), NS_ERROR_FAILURE);
|
||||
NS_ENSURE_SUCCESS(GetCount(&count), NS_ERROR_FAILURE);
|
||||
|
||||
|
|
|
@ -109,6 +109,8 @@ _TEST_FILES = \
|
|||
test_bug660404.html \
|
||||
file_bug660404 \
|
||||
file_bug660404^headers^ \
|
||||
test_bug662170.html \
|
||||
file_bug662170.html \
|
||||
$(NULL)
|
||||
|
||||
ifeq ($(MOZ_WIDGET_TOOLKIT),cocoa)
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>A</title>
|
||||
</head>
|
||||
<body>
|
||||
<a id="link" href="662200b.html">Next</a>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,8 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>B</title>
|
||||
</head>
|
||||
<body>
|
||||
<a id="link" href="662200c.html">Next</a>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,7 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>C</title>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
|
@ -109,6 +109,11 @@ _TEST_FILES = \
|
|||
test_bug454235.xul \
|
||||
bug454235-subframe.xul \
|
||||
test_bug456980.xul \
|
||||
test_bug662200.xul \
|
||||
bug662200_window.xul \
|
||||
662200a.html \
|
||||
662200b.html \
|
||||
662200c.html \
|
||||
$(NULL)
|
||||
|
||||
_DOCSHELL_SUBHARNESS = \
|
||||
|
|
|
@ -0,0 +1,129 @@
|
|||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
|
||||
<window id="303267Test"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
width="600"
|
||||
height="600"
|
||||
onload="setTimeout(nextTest,0);"
|
||||
title="bug 662200 test">
|
||||
|
||||
<script type="application/javascript"
|
||||
src="docshell_helpers.js">
|
||||
</script>
|
||||
<script type="application/javascript" src= "chrome://mochikit/content/chrome-harness.js" />
|
||||
<script type="application/javascript"><![CDATA[
|
||||
|
||||
// Define the generator-iterator for the tests.
|
||||
var tests = testIterator();
|
||||
|
||||
////
|
||||
// Execute the next test in the generator function.
|
||||
//
|
||||
function nextTest() {
|
||||
tests.next();
|
||||
}
|
||||
|
||||
////
|
||||
// Generator function for test steps for bug 662200:
|
||||
// Description goes here.
|
||||
//
|
||||
function testIterator()
|
||||
{
|
||||
// Load the first test page
|
||||
var navData = {
|
||||
uri: getHttpUrl("662200a.html"),
|
||||
eventsToListenFor: ["pageshow"],
|
||||
expectedEvents: [ {type: "pageshow", title: "A"} ],
|
||||
onNavComplete: nextTest
|
||||
};
|
||||
doPageNavigation(navData);
|
||||
yield;
|
||||
|
||||
// Load the second test page.
|
||||
navData = {
|
||||
eventsToListenFor: ["pageshow", "pagehide"],
|
||||
expectedEvents: [ {type: "pagehide",
|
||||
title: "A"},
|
||||
{type: "pageshow",
|
||||
title: "B"} ],
|
||||
onNavComplete: nextTest
|
||||
}
|
||||
waitForPageEvents(navData);
|
||||
var link = TestWindow.getDocument().getElementById("link");
|
||||
var event = TestWindow.getDocument().createEvent("MouseEvents");
|
||||
event.initMouseEvent("click", true, true, TestWindow.getWindow(),
|
||||
0, 0, 0, 0, 0, false, false, false, false, 0, null);
|
||||
link.dispatchEvent(event);
|
||||
yield;
|
||||
|
||||
// Load the third test page.
|
||||
navData = {
|
||||
eventsToListenFor: ["pageshow", "pagehide"],
|
||||
expectedEvents: [ {type: "pagehide",
|
||||
title: "B"},
|
||||
{type: "pageshow",
|
||||
title: "C"} ],
|
||||
onNavComplete: nextTest
|
||||
};
|
||||
waitForPageEvents(navData);
|
||||
var link = TestWindow.getDocument().getElementById("link");
|
||||
var event = TestWindow.getDocument().createEvent("MouseEvents");
|
||||
event.initMouseEvent("click", true, true, TestWindow.getWindow(),
|
||||
0, 0, 0, 0, 0, false, false, false, false, 0, null);
|
||||
link.dispatchEvent(event);
|
||||
yield;
|
||||
|
||||
// Go back.
|
||||
navData = {
|
||||
back: true,
|
||||
eventsToListenFor: ["pageshow", "pagehide"],
|
||||
expectedEvents: [ {type: "pagehide",
|
||||
title: "C"},
|
||||
{type: "pageshow",
|
||||
title: "B"} ],
|
||||
onNavComplete: nextTest
|
||||
};
|
||||
doPageNavigation(navData);
|
||||
yield;
|
||||
|
||||
var Ci = Components.interfaces;
|
||||
var docshell = TestWindow.getWindow()
|
||||
.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebNavigation)
|
||||
.QueryInterface(Ci.nsIDocShell);
|
||||
var shistory = docshell.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsISHistory)
|
||||
.QueryInterface(Ci.nsIWebNavigation);
|
||||
|
||||
// Reload.
|
||||
navData = {
|
||||
eventsToListenFor: ["pageshow", "pagehide"],
|
||||
expectedEvents: [ {type: "pagehide",
|
||||
title: "B"},
|
||||
{type: "pageshow",
|
||||
title: "B"} ],
|
||||
onNavComplete: nextTest
|
||||
};
|
||||
// Asking the docshell harness to reload for us will call reload on
|
||||
// nsDocShell which has different behavior than the reload on nsSHistory
|
||||
// so we call reload explicitly here
|
||||
waitForPageEvents(navData);
|
||||
shistory.reload(0);
|
||||
yield;
|
||||
|
||||
// After this sequence of events, we should be able to go back and forward
|
||||
is(TestWindow.getBrowser().canGoBack, true, "Should be able to go back!");
|
||||
is(TestWindow.getBrowser().canGoForward, true, "Should be able to go forward!");
|
||||
is(shistory.requestedIndex, -1, "Requested index should be cleared!");
|
||||
|
||||
// Tell the framework the test is finished. Include the final 'yield'
|
||||
// statement to prevent a StopIteration exception from being thrown.
|
||||
finish();
|
||||
yield;
|
||||
}
|
||||
|
||||
]]></script>
|
||||
|
||||
<browser type="content-primary" flex="1" id="content" src="about:blank"/>
|
||||
</window>
|
|
@ -41,6 +41,8 @@ var gExtractedPath = null; //used to cache file path for extracting files fro
|
|||
*
|
||||
* forward: if true, the browser will execute goForward()
|
||||
*
|
||||
* reload: if true, the browser will execute reload()
|
||||
*
|
||||
* eventsToListenFor: an array containing one or more of the following event
|
||||
* types to listen for: "pageshow", "pagehide", "onload",
|
||||
* "onunload". If this property is undefined, only a
|
||||
|
|
|
@ -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=662200.xul
|
||||
-->
|
||||
<window title="Mozilla Bug 662200"
|
||||
xmlns:html="http://www.w3.org/1999/xhtml"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
|
||||
<title>Test for Bug 662200</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=662200">
|
||||
Mozilla Bug 662200</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 662200 **/
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
window.open("bug662200_window.xul", "bug662200",
|
||||
"chrome,width=600,height=600");
|
||||
|
||||
]]>
|
||||
</script>
|
||||
|
||||
</window>
|
|
@ -0,0 +1,13 @@
|
|||
<html>
|
||||
<body onload='(parent || opener).childLoad()'>
|
||||
|
||||
<div style='height:500px; background:yellow'>
|
||||
<a id='#top'>Top of the page</a>
|
||||
</div>
|
||||
|
||||
<div id='bottom'>
|
||||
<a id='#bottom'>Bottom of the page</a>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,52 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=662170
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 662170</title>
|
||||
<script type="application/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/WindowSnapshot.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=662170">Mozilla Bug 662170</a>
|
||||
|
||||
<script type="application/javascript;version=1.7">
|
||||
|
||||
/** Test for Bug 662170 **/
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
function childLoad() {
|
||||
// Spin the event loop so we leave the onload handler.
|
||||
SimpleTest.executeSoon(childLoad2);
|
||||
}
|
||||
|
||||
function childLoad2() {
|
||||
let cw = $('iframe').contentWindow;
|
||||
|
||||
// When we initially load the page, we should be at the top.
|
||||
is(cw.pageYOffset, 0, 'Initial Y offset should be 0.');
|
||||
|
||||
// Scroll the iframe to the bottom.
|
||||
cw.scrollTo(0, 300);
|
||||
|
||||
// Did we actually scroll somewhere?
|
||||
isnot(cw.pageYOffset, 0, 'Y offset should be non-zero after scrolling.');
|
||||
|
||||
// Now load file_bug662170.html#, which should take us to the top of the
|
||||
// page.
|
||||
cw.location = cw.location + '#';
|
||||
|
||||
is(cw.pageYOffset, 0, 'Correct Y offset after loading #.');
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<!-- When the iframe loads, it calls childLoad(). -->
|
||||
<iframe height='100px' id='iframe' src='file_bug662170.html'></iframe>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -103,7 +103,7 @@ ConvertCloneBuffersToArrayInternal(
|
|||
JSAutoStructuredCloneBuffer& buffer = aBuffers[index];
|
||||
|
||||
jsval val;
|
||||
if (!buffer.read(&val, aCx)) {
|
||||
if (!IDBObjectStore::DeserializeValue(aCx, buffer, &val)) {
|
||||
NS_WARNING("Failed to decode!");
|
||||
return NS_ERROR_DOM_DATA_CLONE_ERR;
|
||||
}
|
||||
|
@ -491,35 +491,6 @@ AsyncConnectionHelper::WrapNative(JSContext* aCx,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult
|
||||
AsyncConnectionHelper::ConvertCloneBufferToJSVal(
|
||||
JSContext* aCx,
|
||||
JSAutoStructuredCloneBuffer& aBuffer,
|
||||
jsval* aResult)
|
||||
{
|
||||
NS_ASSERTION(aCx, "Null context!");
|
||||
NS_ASSERTION(aResult, "Null pointer!");
|
||||
|
||||
JSAutoRequest ar(aCx);
|
||||
|
||||
if (aBuffer.data()) {
|
||||
JSBool ok = aBuffer.read(aResult, aCx);
|
||||
|
||||
aBuffer.clear(aCx);
|
||||
|
||||
if (!ok) {
|
||||
NS_ERROR("Failed to decode!");
|
||||
return NS_ERROR_DOM_DATA_CLONE_ERR;
|
||||
}
|
||||
}
|
||||
else {
|
||||
*aResult = JSVAL_VOID;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult
|
||||
AsyncConnectionHelper::ConvertCloneBuffersToArray(
|
||||
|
|
|
@ -165,14 +165,6 @@ protected:
|
|||
nsISupports* aNative,
|
||||
jsval* aResult);
|
||||
|
||||
/**
|
||||
* Helper to decode a clone buffer to a jsval.
|
||||
*/
|
||||
static nsresult ConvertCloneBufferToJSVal(
|
||||
JSContext* aCx,
|
||||
JSAutoStructuredCloneBuffer& aBuffer,
|
||||
jsval* aResult);
|
||||
|
||||
/**
|
||||
* Helper to make a JS array object out of an array of clone buffers.
|
||||
*/
|
||||
|
|
|
@ -470,9 +470,7 @@ IDBCursor::GetValue(JSContext* aCx,
|
|||
mRooted = true;
|
||||
}
|
||||
|
||||
JSAutoRequest ar(aCx);
|
||||
|
||||
if (!mCloneBuffer.read(&mCachedValue, aCx)) {
|
||||
if (!IDBObjectStore::DeserializeValue(aCx, mCloneBuffer, &mCachedValue)) {
|
||||
mCachedValue = JSVAL_VOID;
|
||||
return NS_ERROR_DOM_DATA_CLONE_ERR;
|
||||
}
|
||||
|
|
|
@ -780,11 +780,11 @@ nsresult
|
|||
GetHelper::GetSuccessResult(JSContext* aCx,
|
||||
jsval* aVal)
|
||||
{
|
||||
nsresult rv = ConvertCloneBufferToJSVal(aCx, mCloneBuffer, aVal);
|
||||
bool result = IDBObjectStore::DeserializeValue(aCx, mCloneBuffer, aVal);
|
||||
|
||||
mCloneBuffer.clear(aCx);
|
||||
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ENSURE_TRUE(result, NS_ERROR_FAILURE);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -834,6 +834,43 @@ IDBObjectStore::ClearStructuredCloneBuffer(JSAutoStructuredCloneBuffer& aBuffer)
|
|||
}
|
||||
}
|
||||
|
||||
// static
|
||||
bool
|
||||
IDBObjectStore::DeserializeValue(JSContext* aCx,
|
||||
JSAutoStructuredCloneBuffer& aBuffer,
|
||||
jsval* aValue)
|
||||
{
|
||||
/*
|
||||
* This function can be called on multiple threads! Be careful!
|
||||
*/
|
||||
NS_ASSERTION(aCx, "A JSContext is required!");
|
||||
|
||||
if (!aBuffer.data()) {
|
||||
*aValue = JSVAL_VOID;
|
||||
return true;
|
||||
}
|
||||
|
||||
JSAutoRequest ar(aCx);
|
||||
|
||||
return aBuffer.read(aValue, aCx, nsnull);
|
||||
}
|
||||
|
||||
// static
|
||||
bool
|
||||
IDBObjectStore::SerializeValue(JSContext* aCx,
|
||||
JSAutoStructuredCloneBuffer& aBuffer,
|
||||
jsval aValue)
|
||||
{
|
||||
/*
|
||||
* This function can be called on multiple threads! Be careful!
|
||||
*/
|
||||
NS_ASSERTION(aCx, "A JSContext is required!");
|
||||
|
||||
JSAutoRequest ar(aCx);
|
||||
|
||||
return aBuffer.write(aCx, aValue, nsnull);
|
||||
}
|
||||
|
||||
IDBObjectStore::IDBObjectStore()
|
||||
: mId(LL_MININT),
|
||||
mAutoIncrement(PR_FALSE)
|
||||
|
@ -895,7 +932,7 @@ IDBObjectStore::GetAddInfo(JSContext* aCx,
|
|||
rv = GetIndexUpdateInfo(info, aCx, aValue, aUpdateInfoArray);
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
if (!aCloneBuffer.write(aCx, aValue)) {
|
||||
if (!IDBObjectStore::SerializeValue(aCx, aCloneBuffer, aValue)) {
|
||||
return NS_ERROR_DOM_DATA_CLONE_ERR;
|
||||
}
|
||||
|
||||
|
@ -1750,14 +1787,14 @@ AddHelper::ModifyValueForNewKey()
|
|||
|
||||
const nsString& keyPath = mObjectStore->KeyPath();
|
||||
|
||||
JSContext* cx;
|
||||
JSContext* cx = nsnull;
|
||||
nsresult rv = nsContentUtils::ThreadJSContextStack()->GetSafeJSContext(&cx);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
JSAutoRequest ar(cx);
|
||||
|
||||
jsval clone;
|
||||
if (!mCloneBuffer.read(&clone, cx)) {
|
||||
if (!IDBObjectStore::DeserializeValue(cx, mCloneBuffer, &clone)) {
|
||||
return NS_ERROR_DOM_DATA_CLONE_ERR;
|
||||
}
|
||||
|
||||
|
@ -1785,7 +1822,7 @@ AddHelper::ModifyValueForNewKey()
|
|||
nsnull, JSPROP_ENUMERATE);
|
||||
NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE);
|
||||
|
||||
if (!mCloneBuffer.write(cx, OBJECT_TO_JSVAL(obj))) {
|
||||
if (!IDBObjectStore::SerializeValue(cx, mCloneBuffer, OBJECT_TO_JSVAL(obj))) {
|
||||
return NS_ERROR_DOM_DATA_CLONE_ERR;
|
||||
}
|
||||
|
||||
|
@ -1840,11 +1877,11 @@ nsresult
|
|||
GetHelper::GetSuccessResult(JSContext* aCx,
|
||||
jsval* aVal)
|
||||
{
|
||||
nsresult rv = ConvertCloneBufferToJSVal(aCx, mCloneBuffer, aVal);
|
||||
bool result = IDBObjectStore::DeserializeValue(aCx, mCloneBuffer, aVal);
|
||||
|
||||
mCloneBuffer.clear(aCx);
|
||||
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ENSURE_TRUE(result, NS_ERROR_FAILURE);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -116,6 +116,16 @@ public:
|
|||
static void
|
||||
ClearStructuredCloneBuffer(JSAutoStructuredCloneBuffer& aBuffer);
|
||||
|
||||
static bool
|
||||
DeserializeValue(JSContext* aCx,
|
||||
JSAutoStructuredCloneBuffer& aBuffer,
|
||||
jsval* aValue);
|
||||
|
||||
static bool
|
||||
SerializeValue(JSContext* aCx,
|
||||
JSAutoStructuredCloneBuffer& aBuffer,
|
||||
jsval aValue);
|
||||
|
||||
const nsString& Name() const
|
||||
{
|
||||
return mName;
|
||||
|
|
|
@ -13,13 +13,35 @@
|
|||
const done = window.opener.wrappedJSObject.done;
|
||||
const SimpleTest = window.opener.wrappedJSObject.SimpleTest;
|
||||
|
||||
function getMinidumpDirectory() {
|
||||
var dir = Services.dirsvc.get('ProfD', Components.interfaces.nsIFile);
|
||||
dir.append("minidumps");
|
||||
return dir;
|
||||
}
|
||||
|
||||
function removeFile(directory, filename) {
|
||||
var file = directory.clone();
|
||||
file.append(filename);
|
||||
if (file.exists()) {
|
||||
file.remove(false);
|
||||
}
|
||||
}
|
||||
|
||||
function crashObserver(subject, topic, data) {
|
||||
is(topic, 'ipc:content-shutdown', 'Received correct observer topic.');
|
||||
ok(subject instanceof Components.interfaces.nsIPropertyBag2,
|
||||
'Subject implements nsIPropertyBag2.');
|
||||
|
||||
|
||||
var dumpID;
|
||||
if ('nsICrashReporter' in Components.interfaces) {
|
||||
ok(subject.getPropertyAsAString('dumpID'), "dumpID is present and not an empty string");
|
||||
dumpID = subject.getPropertyAsAString('dumpID');
|
||||
ok(dumpID, "dumpID is present and not an empty string");
|
||||
}
|
||||
|
||||
if (dumpID) {
|
||||
var minidumpDirectory = getMinidumpDirectory();
|
||||
removeFile(minidumpDirectory, dumpID + '.dmp');
|
||||
removeFile(minidumpDirectory, dumpID + '.extra');
|
||||
}
|
||||
|
||||
Services.obs.removeObserver(crashObserver, 'ipc:content-shutdown');
|
||||
|
|
|
@ -2304,11 +2304,6 @@ _setvalue(NPP npp, NPPVariable variable, void *result)
|
|||
return inst->SetCached(bCached);
|
||||
}
|
||||
|
||||
case NPPVpluginWantsAllNetworkStreams: {
|
||||
PRBool bWantsAllNetworkStreams = (result != nsnull);
|
||||
return inst->SetWantsAllNetworkStreams(bWantsAllNetworkStreams);
|
||||
}
|
||||
|
||||
case NPPVpluginUsesDOMForCursorBool: {
|
||||
PRBool useDOMForCursor = (result != nsnull);
|
||||
return inst->SetUsesDOMForCursor(useDOMForCursor);
|
||||
|
|
|
@ -82,7 +82,6 @@ nsNPAPIPluginInstance::nsNPAPIPluginInstance(nsNPAPIPlugin* plugin)
|
|||
mWindowlessLocal(PR_FALSE),
|
||||
mTransparent(PR_FALSE),
|
||||
mCached(PR_FALSE),
|
||||
mWantsAllNetworkStreams(PR_FALSE),
|
||||
mUsesDOMForCursor(PR_FALSE),
|
||||
mInPluginInitCall(PR_FALSE),
|
||||
mPlugin(plugin),
|
||||
|
@ -680,12 +679,6 @@ NPError nsNPAPIPluginInstance::SetTransparent(PRBool aTransparent)
|
|||
return NPERR_NO_ERROR;
|
||||
}
|
||||
|
||||
NPError nsNPAPIPluginInstance::SetWantsAllNetworkStreams(PRBool aWantsAllNetworkStreams)
|
||||
{
|
||||
mWantsAllNetworkStreams = aWantsAllNetworkStreams;
|
||||
return NPERR_NO_ERROR;
|
||||
}
|
||||
|
||||
NPError nsNPAPIPluginInstance::SetUsesDOMForCursor(PRBool aUsesDOMForCursor)
|
||||
{
|
||||
mUsesDOMForCursor = aUsesDOMForCursor;
|
||||
|
|
|
@ -224,7 +224,6 @@ protected:
|
|||
PRPackedBool mWindowlessLocal;
|
||||
PRPackedBool mTransparent;
|
||||
PRPackedBool mCached;
|
||||
PRPackedBool mWantsAllNetworkStreams;
|
||||
PRPackedBool mUsesDOMForCursor;
|
||||
|
||||
public:
|
||||
|
|
|
@ -102,9 +102,13 @@ child:
|
|||
|
||||
rpc NPP_SetWindow(NPRemoteWindow window);
|
||||
|
||||
rpc NPP_GetValue_NPPVpluginWantsAllNetworkStreams()
|
||||
returns (bool value, NPError result);
|
||||
|
||||
// this message is not used on non-X platforms
|
||||
rpc NPP_GetValue_NPPVpluginNeedsXEmbed()
|
||||
returns (bool value, NPError result);
|
||||
|
||||
rpc NPP_GetValue_NPPVpluginScriptableNPObject()
|
||||
returns (nullable PPluginScriptableObject value, NPError result);
|
||||
|
||||
|
|
|
@ -513,6 +513,24 @@ PluginInstanceChild::NPN_SetValue(NPPVariable aVar, void* aValue)
|
|||
}
|
||||
}
|
||||
|
||||
bool
|
||||
PluginInstanceChild::AnswerNPP_GetValue_NPPVpluginWantsAllNetworkStreams(
|
||||
bool* wantsAllStreams, NPError* rv)
|
||||
{
|
||||
AssertPluginThread();
|
||||
|
||||
PRBool value = 0;
|
||||
if (!mPluginIface->getvalue) {
|
||||
*rv = NPERR_GENERIC_ERROR;
|
||||
}
|
||||
else {
|
||||
*rv = mPluginIface->getvalue(GetNPP(), NPPVpluginWantsAllNetworkStreams,
|
||||
&value);
|
||||
}
|
||||
*wantsAllStreams = value;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
PluginInstanceChild::AnswerNPP_GetValue_NPPVpluginNeedsXEmbed(
|
||||
bool* needs, NPError* rv)
|
||||
|
|
|
@ -87,6 +87,8 @@ class PluginInstanceChild : public PPluginInstanceChild
|
|||
protected:
|
||||
virtual bool AnswerNPP_SetWindow(const NPRemoteWindow& window);
|
||||
|
||||
virtual bool
|
||||
AnswerNPP_GetValue_NPPVpluginWantsAllNetworkStreams(bool* wantsAllStreams, NPError* rv);
|
||||
virtual bool
|
||||
AnswerNPP_GetValue_NPPVpluginNeedsXEmbed(bool* needs, NPError* rv);
|
||||
virtual bool
|
||||
|
|
|
@ -920,6 +920,22 @@ PluginInstanceParent::NPP_GetValue(NPPVariable aVariable,
|
|||
{
|
||||
switch (aVariable) {
|
||||
|
||||
case NPPVpluginWantsAllNetworkStreams: {
|
||||
bool wantsAllStreams;
|
||||
NPError rv;
|
||||
|
||||
if (!CallNPP_GetValue_NPPVpluginWantsAllNetworkStreams(&wantsAllStreams, &rv)) {
|
||||
return NPERR_GENERIC_ERROR;
|
||||
}
|
||||
|
||||
if (NPERR_NO_ERROR != rv) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
(*(NPBool*)_retval) = wantsAllStreams;
|
||||
return NPERR_NO_ERROR;
|
||||
}
|
||||
|
||||
#ifdef MOZ_X11
|
||||
case NPPVpluginNeedsXEmbed: {
|
||||
bool needsXEmbed;
|
||||
|
|
|
@ -100,6 +100,7 @@ _MOCHITEST_FILES = \
|
|||
test_redirect_handling.html \
|
||||
test_clear_site_data.html \
|
||||
test_zero_opacity.html \
|
||||
test_NPPVpluginWantsAllNetworkStreams.html \
|
||||
$(NULL)
|
||||
|
||||
# test_plugin_scroll_painting.html \ bug 596491
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Test NPPVpluginWantsAllNetworkStreams</title>
|
||||
<script type="application/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
</head>
|
||||
<body onload="runNextTest()">
|
||||
<embed id="plugin1" type="application/x-test" width="200" height="200"></embed>
|
||||
|
||||
<script class="testbody" type="application/javascript">
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var p = document.getElementById("plugin1");
|
||||
|
||||
var missingDoc = "not-found.html";
|
||||
|
||||
var expectedWriteURL = "";
|
||||
var expectedNotifyStatus = -1;
|
||||
|
||||
var writeHappened = false;
|
||||
var expectedWrite = false;
|
||||
|
||||
function writeCallback(url) {
|
||||
writeHappened = true;
|
||||
}
|
||||
|
||||
function notifyCallback(status, data) {
|
||||
is(writeHappened, expectedWrite, "Test for expected write.");
|
||||
is(status, expectedNotifyStatus, "Test for expected stream notification status.");
|
||||
runNextTest();
|
||||
}
|
||||
|
||||
function test1() {
|
||||
// In this test we do not expect a stream for the missing document.
|
||||
p.setPluginWantsAllStreams(false);
|
||||
|
||||
expectedWriteURL = missingDoc;
|
||||
expectedNotifyStatus = 1;
|
||||
|
||||
writeHappened = false;
|
||||
expectedWrite = false;
|
||||
|
||||
p.streamTest(missingDoc, false, null, writeCallback, notifyCallback, null, false);
|
||||
}
|
||||
|
||||
function test2() {
|
||||
// In this test we expect a stream for the missing document.
|
||||
p.setPluginWantsAllStreams(true);
|
||||
|
||||
expectedWriteURL = missingDoc;
|
||||
expectedNotifyStatus = 0;
|
||||
|
||||
writeHappened = false;
|
||||
expectedWrite = true;
|
||||
|
||||
p.streamTest(missingDoc, false, null, writeCallback, notifyCallback, null, false);
|
||||
}
|
||||
|
||||
var tests = [test1, test2];
|
||||
var currentTest = -1;
|
||||
function runNextTest() {
|
||||
currentTest++;
|
||||
if (currentTest < tests.length) {
|
||||
tests[currentTest]();
|
||||
} else {
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -354,8 +354,8 @@ If the plugin is instantiated as a full-page plugin, the following defaults
|
|||
are used:
|
||||
streammode="seek" frame="testframe" range="100,100"
|
||||
|
||||
The streamTest(url, doPost, postData, writeCallback, notifyCallback, redirectCallback, allowRedirects)
|
||||
function will test how NPN_GetURLNotify and NPN_PostURLNotify behave when they are
|
||||
* streamTest(url, doPost, postData, writeCallback, notifyCallback, redirectCallback, allowRedirects)
|
||||
This will test how NPN_GetURLNotify and NPN_PostURLNotify behave when they are
|
||||
called with arbitrary (malformed) URLs. The function will return `true` if
|
||||
NPN_[Get/Post]URLNotify succeeds, and `false` if it fails.
|
||||
@url url to request
|
||||
|
@ -366,6 +366,9 @@ NPN_[Get/Post]URLNotify succeeds, and `false` if it fails.
|
|||
@redirectCallback will be called from urlredirectnotify if a redirect is attempted
|
||||
@allowRedirects boolean value indicating whether or not to allow redirects
|
||||
|
||||
* setPluginWantsAllStreams(wantsAllStreams)
|
||||
Set the value returned by the plugin for NPPVpluginWantsAllNetworkStreams.
|
||||
|
||||
== Internal consistency ==
|
||||
|
||||
* doInternalConsistencyCheck()
|
||||
|
|
|
@ -137,6 +137,7 @@ static bool throwExceptionNextInvoke(NPObject* npobj, const NPVariant* args, uin
|
|||
static bool convertPointX(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
|
||||
static bool convertPointY(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
|
||||
static bool streamTest(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
|
||||
static bool setPluginWantsAllStreams(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
|
||||
static bool crashPlugin(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
|
||||
static bool crashOnDestroy(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
|
||||
static bool getObjectValue(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
|
||||
|
@ -195,6 +196,7 @@ static const NPUTF8* sPluginMethodIdentifierNames[] = {
|
|||
"convertPointX",
|
||||
"convertPointY",
|
||||
"streamTest",
|
||||
"setPluginWantsAllStreams",
|
||||
"crash",
|
||||
"crashOnDestroy",
|
||||
"getObjectValue",
|
||||
|
@ -254,6 +256,7 @@ static const ScriptableFunction sPluginMethodFunctions[] = {
|
|||
convertPointX,
|
||||
convertPointY,
|
||||
streamTest,
|
||||
setPluginWantsAllStreams,
|
||||
crashPlugin,
|
||||
crashOnDestroy,
|
||||
getObjectValue,
|
||||
|
@ -743,6 +746,7 @@ NPP_New(NPMIMEType pluginType, NPP instance, uint16_t mode, int16_t argc, char*
|
|||
instanceData->focusEventCount = 0;
|
||||
instanceData->eventModel = 0;
|
||||
instanceData->closeStream = false;
|
||||
instanceData->wantsAllStreams = false;
|
||||
instance->pdata = instanceData;
|
||||
|
||||
TestNPObject* scriptableObject = (TestNPObject*)NPN_CreateObject(instance, &sNPClass);
|
||||
|
@ -1172,7 +1176,7 @@ NPP_Write(NPP instance, NPStream* stream, int32_t offset, int32_t len, void* buf
|
|||
if (instanceData->closeStream) {
|
||||
instanceData->closeStream = false;
|
||||
if (instanceData->testrange != NULL) {
|
||||
NPError err = NPN_RequestRead(stream, instanceData->testrange);
|
||||
NPN_RequestRead(stream, instanceData->testrange);
|
||||
}
|
||||
NPN_DestroyStream(instance, stream, NPRES_USER_BREAK);
|
||||
}
|
||||
|
@ -1345,6 +1349,10 @@ NPP_GetValue(NPP instance, NPPVariable variable, void* value)
|
|||
*(NPBool*)value = instanceData->hasWidget;
|
||||
return NPERR_NO_ERROR;
|
||||
}
|
||||
if (variable == NPPVpluginWantsAllNetworkStreams) {
|
||||
*(NPBool*)value = instanceData->wantsAllStreams;
|
||||
return NPERR_NO_ERROR;
|
||||
}
|
||||
|
||||
return NPERR_GENERIC_ERROR;
|
||||
}
|
||||
|
@ -2553,6 +2561,24 @@ streamTest(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant*
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
setPluginWantsAllStreams(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
|
||||
{
|
||||
if (1 != argCount)
|
||||
return false;
|
||||
|
||||
if (!NPVARIANT_IS_BOOLEAN(args[0]))
|
||||
return false;
|
||||
bool wantsAllStreams = NPVARIANT_TO_BOOLEAN(args[0]);
|
||||
|
||||
NPP npp = static_cast<TestNPObject*>(npobj)->npp;
|
||||
InstanceData* id = static_cast<InstanceData*>(npp->pdata);
|
||||
|
||||
id->wantsAllStreams = wantsAllStreams;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
crashPlugin(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
|
||||
{
|
||||
|
|
|
@ -139,6 +139,7 @@ typedef struct InstanceData {
|
|||
int32_t eventModel;
|
||||
bool closeStream;
|
||||
std::string lastKeyText;
|
||||
bool wantsAllStreams;
|
||||
} InstanceData;
|
||||
|
||||
void notifyDidPaint(InstanceData* instanceData);
|
||||
|
|
|
@ -42,14 +42,6 @@ VPATH = @srcdir@
|
|||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = spellchecker
|
||||
DIRS = idl locales
|
||||
|
||||
ifeq (camino,$(MOZ_BUILD_APP))
|
||||
DIRS += osxspell
|
||||
else
|
||||
DIRS += hunspell
|
||||
endif
|
||||
|
||||
DIRS += src
|
||||
DIRS = idl locales hunspell src
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
|
|
@ -1,47 +0,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 Mozilla Spellchecker Component.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Mike Pinkerton.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2006
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s): Mike Pinkerton <mikepinkerton@mac.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 *****
|
||||
|
||||
DEPTH = ../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = hunspell
|
||||
DIRS = src
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
|
@ -1,53 +0,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 Mozilla Spellchecker Component.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Mike Pinkerton.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2006
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s): Mike Pinkerton <mikepinkerton@mac.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 *****
|
||||
|
||||
DEPTH = ../../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = hunspell
|
||||
LIBRARY_NAME = osxspell_s
|
||||
FORCE_STATIC_LIB = 1
|
||||
LIBXUL_LIBRARY = 1
|
||||
|
||||
|
||||
CMMSRCS = \
|
||||
mozOSXSpell.mm \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
|
@ -1,338 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** 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 Spellchecker Component.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mike Pinkerton.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2006
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s): Mike Pinkerton <mikepinkerton@mac.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.
|
||||
*
|
||||
* This spellchecker is based on the built-in spellchecker on Mac OS X. It
|
||||
* does not use any Hunspell technology or rely on their dictionaries. It's just
|
||||
* a thin wrapper around the Cocoa NSSpellChecker API.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "mozOSXSpell.h"
|
||||
#include "nsReadableUtils.h"
|
||||
#include "nsCRT.h"
|
||||
#include "nsObjCExceptions.h"
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
// utility category we need for PRUnichar<->NSString conversion (taken from Camino)
|
||||
@interface NSString(PRUnicharUtils)
|
||||
+ (id)stringWithPRUnichars:(const PRUnichar*)inString;
|
||||
- (PRUnichar*)createNewUnicodeBuffer;
|
||||
@end
|
||||
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(mozOSXSpell)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(mozOSXSpell)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(mozOSXSpell)
|
||||
NS_INTERFACE_MAP_ENTRY(mozISpellCheckingEngine)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, mozISpellCheckingEngine)
|
||||
NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(mozOSXSpell)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_1(mozOSXSpell, mPersonalDictionary);
|
||||
|
||||
mozOSXSpell::mozOSXSpell()
|
||||
{
|
||||
}
|
||||
|
||||
mozOSXSpell::~mozOSXSpell()
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// GetDictionary
|
||||
//
|
||||
// Nothing to do here, we don't have a dictionary on disk, so this is really
|
||||
// just a no-op. The caller is responsible for disposing of |aDictionary|.
|
||||
//
|
||||
NS_IMETHODIMP mozOSXSpell::GetDictionary(PRUnichar **aDictionary)
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
|
||||
|
||||
NS_ENSURE_ARG_POINTER(aDictionary);
|
||||
|
||||
*aDictionary = [@"" createNewUnicodeBuffer];
|
||||
return NS_OK;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
|
||||
}
|
||||
|
||||
//
|
||||
// SetDictionary
|
||||
//
|
||||
// Another no-op as there's nothing to load or initialize.
|
||||
//
|
||||
NS_IMETHODIMP mozOSXSpell::SetDictionary(const PRUnichar *aDictionary)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//
|
||||
// GetLanguage
|
||||
//
|
||||
// Returns the language of the current dictionary, which should be the l10n
|
||||
// the user is running. The caller is responsible for disposing of |aLanguage|.
|
||||
//
|
||||
NS_IMETHODIMP mozOSXSpell::GetLanguage(PRUnichar **aLanguage)
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
|
||||
|
||||
NS_ENSURE_ARG_POINTER(aLanguage);
|
||||
|
||||
if (!mLanguage.Length()) {
|
||||
@try {
|
||||
NSString* lang = [[NSSpellChecker sharedSpellChecker] language];
|
||||
*aLanguage = [lang createNewUnicodeBuffer];
|
||||
}
|
||||
@catch (id exception) {
|
||||
// If we get here, the spelling system on the user's machine is almost
|
||||
// certainly damaged; do what the rest of the OS does, and silently
|
||||
// ignore it.
|
||||
*aLanguage = NULL;
|
||||
}
|
||||
mLanguage.Assign(*aLanguage);
|
||||
}
|
||||
else {
|
||||
*aLanguage = ToNewUnicode(mLanguage);
|
||||
}
|
||||
|
||||
return *aLanguage ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
|
||||
}
|
||||
|
||||
//
|
||||
// GetProvidesPersonalDictionary
|
||||
//
|
||||
// We let Gecko handle the personal dictionary, even though NSSpellChecker can
|
||||
// handle ignoring words itself.
|
||||
//
|
||||
NS_IMETHODIMP mozOSXSpell::GetProvidesPersonalDictionary(PRBool *aProvidesPersonalDictionary)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aProvidesPersonalDictionary);
|
||||
|
||||
*aProvidesPersonalDictionary = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//
|
||||
// GetProvidesWordUtils
|
||||
//
|
||||
// I have no idea what this is, so we don't provide it.
|
||||
//
|
||||
NS_IMETHODIMP mozOSXSpell::GetProvidesWordUtils(PRBool *aProvidesWordUtils)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aProvidesWordUtils);
|
||||
|
||||
*aProvidesWordUtils = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//
|
||||
// GetName
|
||||
//
|
||||
// Name not supported (nor is it in Hunspell impl)
|
||||
//
|
||||
NS_IMETHODIMP mozOSXSpell::GetName(PRUnichar * *aName)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
//
|
||||
// GetCopyright
|
||||
//
|
||||
// Copyright not supported (nor is it in Hunspell impl)
|
||||
//
|
||||
NS_IMETHODIMP mozOSXSpell::GetCopyright(PRUnichar * *aCopyright)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
//
|
||||
// GetPersonalDictionary
|
||||
//
|
||||
// Return the personal dictionary we've been given with Set.
|
||||
//
|
||||
NS_IMETHODIMP mozOSXSpell::GetPersonalDictionary(mozIPersonalDictionary** aPersonalDictionary)
|
||||
{
|
||||
*aPersonalDictionary = mPersonalDictionary;
|
||||
NS_IF_ADDREF(*aPersonalDictionary);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//
|
||||
// SetPersonalDictionary
|
||||
//
|
||||
// Hold onto the personal dictionary we're given.
|
||||
//
|
||||
NS_IMETHODIMP mozOSXSpell::SetPersonalDictionary(mozIPersonalDictionary* aPersonalDictionary)
|
||||
{
|
||||
mPersonalDictionary = aPersonalDictionary;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//
|
||||
// GetDictionaryList
|
||||
//
|
||||
// We only support the OS dictionary from NSSpellChecker so there will only ever
|
||||
// be one. The caller is responsible for disposing of |aDictionaries|.
|
||||
//
|
||||
NS_IMETHODIMP mozOSXSpell::GetDictionaryList(PRUnichar ***aDictionaries, PRUint32 *aCount)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aDictionaries);
|
||||
NS_ENSURE_ARG_POINTER(aCount);
|
||||
|
||||
*aCount = 1;
|
||||
*aDictionaries = (PRUnichar **)nsMemory::Alloc(sizeof(PRUnichar *)); // only one entry
|
||||
GetLanguage(*aDictionaries);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//
|
||||
// Check
|
||||
//
|
||||
// Check if the given word is spelled correctly. If the main dictionary says
|
||||
// it's not, check again against the peronal dictionary we were given.
|
||||
//
|
||||
NS_IMETHODIMP mozOSXSpell::Check(const PRUnichar *aWord, PRBool *aResult)
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
|
||||
|
||||
NS_ENSURE_ARG_POINTER(aWord);
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
*aResult = PR_FALSE;
|
||||
|
||||
NSString* wordStr = [NSString stringWithPRUnichars:aWord];
|
||||
NSRange misspelledRange;
|
||||
@try {
|
||||
misspelledRange = [[NSSpellChecker sharedSpellChecker] checkSpellingOfString:wordStr startingAt:0];
|
||||
}
|
||||
@catch (id exception) {
|
||||
// Silently return true; if something is seriously wrong with the
|
||||
// spelling system on a user's machine, the best thing to do is
|
||||
// to just treat everything as correct.
|
||||
*aResult = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
if (misspelledRange.location != NSNotFound && mPersonalDictionary)
|
||||
mPersonalDictionary->Check(aWord, mLanguage.get(), aResult);
|
||||
else
|
||||
*aResult = PR_TRUE;
|
||||
|
||||
return NS_OK;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
|
||||
}
|
||||
|
||||
//
|
||||
// Suggest
|
||||
//
|
||||
// Provide a list of suggestions for the incrorectly spelled word |aWord| by
|
||||
// converting the list we get back from NSSpellChecker into an array of PRUnichar
|
||||
// strings. If |aWord| is spelled correctly, |aSuggestions| will be NULL. The caller
|
||||
// is responsible for disposing of |aSuggestions|.
|
||||
//
|
||||
NS_IMETHODIMP mozOSXSpell::Suggest(const PRUnichar *aWord, PRUnichar ***aSuggestions, PRUint32 *aSuggestionCount)
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
|
||||
|
||||
NS_ENSURE_ARG_POINTER(aSuggestions);
|
||||
NS_ENSURE_ARG_POINTER(aSuggestionCount);
|
||||
*aSuggestions = NULL;
|
||||
|
||||
// check the word against the NSSpellChecker
|
||||
NSString* wordStr = [NSString stringWithPRUnichars:aWord];
|
||||
NSArray* guesses = [[NSSpellChecker sharedSpellChecker] guessesForWord:wordStr];
|
||||
*aSuggestionCount = [guesses count];
|
||||
|
||||
// convert results from NSArray to array of PRUnichar's
|
||||
if (*aSuggestionCount) {
|
||||
*aSuggestions = (PRUnichar **)nsMemory::Alloc(*aSuggestionCount * sizeof(PRUnichar *));
|
||||
PRUint32 i = 0;
|
||||
NSEnumerator* e = [guesses objectEnumerator];
|
||||
NSString* guess = nil;
|
||||
while ((guess = [e nextObject])) {
|
||||
(*aSuggestions)[i] = [guess createNewUnicodeBuffer];
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP mozOSXSpell::LoadDictionariesFromDir(nsIFile* aFile)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
//
|
||||
// String utilities taken from Camino
|
||||
//
|
||||
|
||||
@implementation NSString(PRUnicharUtils)
|
||||
|
||||
- (PRUnichar*)createNewUnicodeBuffer
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSNULL;
|
||||
|
||||
PRUint32 length = [self length];
|
||||
PRUnichar* retStr = (PRUnichar*)nsMemory::Alloc((length + 1) * sizeof(PRUnichar));
|
||||
if (!retStr)
|
||||
return NULL;
|
||||
[self getCharacters:retStr];
|
||||
retStr[length] = PRUnichar(0);
|
||||
return retStr;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NSNULL;
|
||||
}
|
||||
|
||||
+ (id)stringWithPRUnichars:(const PRUnichar*)inString
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
if (inString)
|
||||
return [self stringWithCharacters:inString length:nsCRT::strlen(inString)];
|
||||
else
|
||||
return [self string];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
@end
|
|
@ -62,13 +62,8 @@ CPPSRCS = \
|
|||
mozInlineSpellWordUtil.cpp \
|
||||
$(NULL)
|
||||
|
||||
ifeq (camino,$(MOZ_BUILD_APP))
|
||||
SHARED_LIBRARY_LIBS += ../osxspell/src/$(LIB_PREFIX)osxspell_s.$(LIB_SUFFIX)
|
||||
LOCAL_INCLUDES += -I$(srcdir)/../osxspell/src
|
||||
else
|
||||
SHARED_LIBRARY_LIBS += ../hunspell/src/$(LIB_PREFIX)hunspell_s.$(LIB_SUFFIX)
|
||||
LOCAL_INCLUDES += -I$(srcdir)/../hunspell/src
|
||||
endif
|
||||
|
||||
EXTRA_DSO_LDOPTS = \
|
||||
$(LIBS_DIR) \
|
||||
|
|
|
@ -36,14 +36,8 @@
|
|||
|
||||
|
||||
#include "mozilla/ModuleUtils.h"
|
||||
|
||||
#ifdef MOZ_MACBROWSER
|
||||
#include "mozOSXSpell.h"
|
||||
#else
|
||||
#include "mozHunspell.h"
|
||||
#include "mozHunspellDirProvider.h"
|
||||
#endif
|
||||
|
||||
#include "mozSpellChecker.h"
|
||||
#include "mozInlineSpellChecker.h"
|
||||
#include "nsTextServicesCID.h"
|
||||
|
@ -60,13 +54,8 @@
|
|||
0x9fe5d975, 0x9bd, 0x44aa, \
|
||||
{ 0xa0, 0x1a, 0x66, 0x40, 0x2e, 0xa2, 0x86, 0x57} }
|
||||
|
||||
#ifdef MOZ_MACBROWSER
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(mozOSXSpell)
|
||||
#else
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(mozHunspell, Init)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(mozHunspellDirProvider)
|
||||
#endif
|
||||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(mozSpellChecker, Init)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(mozPersonalDictionary, Init)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(mozSpellI18NManager)
|
||||
|
@ -104,24 +93,16 @@ mozInlineSpellCheckerConstructor(nsISupports *aOuter, REFNSIID aIID,
|
|||
return rv;
|
||||
}
|
||||
|
||||
#ifdef MOZ_MACBROWSER
|
||||
NS_DEFINE_NAMED_CID(MOZ_OSXSPELL_CID);
|
||||
#else
|
||||
NS_DEFINE_NAMED_CID(MOZ_HUNSPELL_CID);
|
||||
NS_DEFINE_NAMED_CID(HUNSPELLDIRPROVIDER_CID);
|
||||
#endif // MOZ_MACBROWSER
|
||||
NS_DEFINE_NAMED_CID(NS_SPELLCHECKER_CID);
|
||||
NS_DEFINE_NAMED_CID(MOZ_PERSONALDICTIONARY_CID);
|
||||
NS_DEFINE_NAMED_CID(MOZ_SPELLI18NMANAGER_CID);
|
||||
NS_DEFINE_NAMED_CID(MOZ_INLINESPELLCHECKER_CID);
|
||||
|
||||
static const mozilla::Module::CIDEntry kSpellcheckCIDs[] = {
|
||||
#ifdef MOZ_MACBROWSER
|
||||
{ &kMOZ_OSXSPELL_CID, false, NULL, mozOSXSpellConstructor },
|
||||
#else
|
||||
{ &kMOZ_HUNSPELL_CID, false, NULL, mozHunspellConstructor },
|
||||
{ &kHUNSPELLDIRPROVIDER_CID, false, NULL, mozHunspellDirProviderConstructor },
|
||||
#endif // MOZ_MACBROWSER
|
||||
{ &kNS_SPELLCHECKER_CID, false, NULL, mozSpellCheckerConstructor },
|
||||
{ &kMOZ_PERSONALDICTIONARY_CID, false, NULL, mozPersonalDictionaryConstructor },
|
||||
{ &kMOZ_SPELLI18NMANAGER_CID, false, NULL, mozSpellI18NManagerConstructor },
|
||||
|
@ -130,12 +111,8 @@ static const mozilla::Module::CIDEntry kSpellcheckCIDs[] = {
|
|||
};
|
||||
|
||||
static const mozilla::Module::ContractIDEntry kSpellcheckContracts[] = {
|
||||
#ifdef MOZ_MACBROWSER
|
||||
{ MOZ_OSXSPELL_CONTRACTID, &kMOZ_OSXSPELL_CID },
|
||||
#else
|
||||
{ MOZ_HUNSPELL_CONTRACTID, &kMOZ_HUNSPELL_CID },
|
||||
{ mozHunspellDirProvider::kContractID, &kHUNSPELLDIRPROVIDER_CID },
|
||||
#endif // MOZ_MACBROWSER
|
||||
{ NS_SPELLCHECKER_CONTRACTID, &kNS_SPELLCHECKER_CID },
|
||||
{ MOZ_PERSONALDICTIONARY_CONTRACTID, &kMOZ_PERSONALDICTIONARY_CID },
|
||||
{ MOZ_SPELLI18NMANAGER_CONTRACTID, &kMOZ_SPELLI18NMANAGER_CID },
|
||||
|
@ -144,9 +121,7 @@ static const mozilla::Module::ContractIDEntry kSpellcheckContracts[] = {
|
|||
};
|
||||
|
||||
static const mozilla::Module::CategoryEntry kSpellcheckCategories[] = {
|
||||
#ifndef MOZ_MACBROWSER
|
||||
{ XPCOM_DIRECTORY_PROVIDER_CATEGORY, "spellcheck-directory-provider", mozHunspellDirProvider::kContractID },
|
||||
#endif
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
|
|
|
@ -130,6 +130,7 @@ struct _cairo_d2d_surface {
|
|||
/** Indicates if text rendering is initialized */
|
||||
enum TextRenderingState {
|
||||
TEXT_RENDERING_UNINITIALIZED,
|
||||
TEXT_RENDERING_NO_CLEARTYPE,
|
||||
TEXT_RENDERING_NORMAL,
|
||||
TEXT_RENDERING_GDI_CLASSIC
|
||||
};
|
||||
|
|
|
@ -4105,26 +4105,23 @@ _cairo_d2d_show_glyphs (void *surface,
|
|||
cairo_clip_t *clip,
|
||||
int *remaining_glyphs)
|
||||
{
|
||||
if (((cairo_surface_t*)surface)->type != CAIRO_SURFACE_TYPE_D2D) {
|
||||
if (((cairo_surface_t*)surface)->type != CAIRO_SURFACE_TYPE_D2D ||
|
||||
scaled_font->backend->type != CAIRO_FONT_TYPE_DWRITE)
|
||||
{
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
}
|
||||
|
||||
cairo_d2d_surface_t *d2dsurf = static_cast<cairo_d2d_surface_t*>(surface);
|
||||
cairo_bool_t forceGDIClassic =
|
||||
scaled_font->backend->type == CAIRO_FONT_TYPE_DWRITE &&
|
||||
reinterpret_cast<cairo_dwrite_scaled_font_t*>(scaled_font)->force_GDI_classic;
|
||||
cairo_d2d_surface_t::TextRenderingState textRenderingState =
|
||||
(forceGDIClassic ? cairo_d2d_surface_t::TEXT_RENDERING_GDI_CLASSIC : cairo_d2d_surface_t::TEXT_RENDERING_NORMAL);
|
||||
reinterpret_cast<cairo_dwrite_scaled_font_t*>(scaled_font)->rendering_mode;
|
||||
if (d2dsurf->textRenderingState != textRenderingState) {
|
||||
RefPtr<IDWriteRenderingParams> params =
|
||||
DWriteFactory::RenderingParams(forceGDIClassic);
|
||||
DWriteFactory::RenderingParams(textRenderingState);
|
||||
d2dsurf->rt->SetTextRenderingParams(params);
|
||||
d2dsurf->textRenderingState = textRenderingState;
|
||||
}
|
||||
cairo_int_status_t status = CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
if (scaled_font->backend->type == CAIRO_FONT_TYPE_DWRITE) {
|
||||
status = (cairo_int_status_t)
|
||||
_cairo_dwrite_show_glyphs_on_d2d_surface(surface, op, source, glyphs, num_glyphs, scaled_font, clip);
|
||||
}
|
||||
cairo_int_status_t status = (cairo_int_status_t)
|
||||
_cairo_dwrite_show_glyphs_on_d2d_surface(surface, op, source, glyphs, num_glyphs, scaled_font, clip);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
|
|
@ -119,7 +119,8 @@ private:
|
|||
|
||||
IDWriteFactory *DWriteFactory::mFactoryInstance = NULL;
|
||||
IDWriteFontCollection *DWriteFactory::mSystemCollection = NULL;
|
||||
IDWriteRenderingParams *DWriteFactory::mRenderingParams = NULL;
|
||||
IDWriteRenderingParams *DWriteFactory::mDefaultRenderingParams = NULL;
|
||||
IDWriteRenderingParams *DWriteFactory::mCustomClearTypeRenderingParams = NULL;
|
||||
IDWriteRenderingParams *DWriteFactory::mForceGDIClassicRenderingParams = NULL;
|
||||
FLOAT DWriteFactory::mGamma = -1.0;
|
||||
FLOAT DWriteFactory::mEnhancedContrast = -1.0;
|
||||
|
@ -468,7 +469,7 @@ _cairo_dwrite_font_face_scaled_font_create (void *abstract_face,
|
|||
// this means that if cleartype settings are changed but the scaled_fonts
|
||||
// are re-used, they might not adhere to the new system setting until re-
|
||||
// creation.
|
||||
switch (_cairo_win32_get_system_text_quality()) {
|
||||
switch (cairo_win32_get_system_text_quality()) {
|
||||
case CLEARTYPE_QUALITY:
|
||||
default_quality = CAIRO_ANTIALIAS_SUBPIXEL;
|
||||
break;
|
||||
|
@ -496,7 +497,9 @@ _cairo_dwrite_font_face_scaled_font_create (void *abstract_face,
|
|||
}
|
||||
|
||||
dwriteFont->manual_show_glyphs_allowed = TRUE;
|
||||
dwriteFont->force_GDI_classic = FALSE;
|
||||
dwriteFont->rendering_mode =
|
||||
default_quality == CAIRO_ANTIALIAS_SUBPIXEL ?
|
||||
cairo_d2d_surface_t::TEXT_RENDERING_NORMAL : cairo_d2d_surface_t::TEXT_RENDERING_NO_CLEARTYPE;
|
||||
|
||||
return _cairo_scaled_font_set_metrics (*font, &extents);
|
||||
}
|
||||
|
@ -1083,14 +1086,18 @@ void
|
|||
cairo_dwrite_scaled_font_set_force_GDI_classic(cairo_scaled_font_t *dwrite_scaled_font, cairo_bool_t force)
|
||||
{
|
||||
cairo_dwrite_scaled_font_t *font = reinterpret_cast<cairo_dwrite_scaled_font_t*>(dwrite_scaled_font);
|
||||
font->force_GDI_classic = force;
|
||||
if (force && font->rendering_mode == cairo_d2d_surface_t::TEXT_RENDERING_NORMAL) {
|
||||
font->rendering_mode = cairo_d2d_surface_t::TEXT_RENDERING_GDI_CLASSIC;
|
||||
} else if (!force && font->rendering_mode == cairo_d2d_surface_t::TEXT_RENDERING_GDI_CLASSIC) {
|
||||
font->rendering_mode = cairo_d2d_surface_t::TEXT_RENDERING_NORMAL;
|
||||
}
|
||||
}
|
||||
|
||||
cairo_bool_t
|
||||
cairo_dwrite_scaled_font_get_force_GDI_classic(cairo_scaled_font_t *dwrite_scaled_font)
|
||||
{
|
||||
cairo_dwrite_scaled_font_t *font = reinterpret_cast<cairo_dwrite_scaled_font_t*>(dwrite_scaled_font);
|
||||
return font->force_GDI_classic;
|
||||
return font->rendering_mode == cairo_d2d_surface_t::TEXT_RENDERING_GDI_CLASSIC;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1100,6 +1107,12 @@ cairo_dwrite_set_cleartype_params(FLOAT gamma, FLOAT contrast, FLOAT level,
|
|||
DWriteFactory::SetRenderingParams(gamma, contrast, level, geometry, mode);
|
||||
}
|
||||
|
||||
int
|
||||
cairo_dwrite_get_cleartype_rendering_mode()
|
||||
{
|
||||
return DWriteFactory::GetClearTypeRenderingMode();
|
||||
}
|
||||
|
||||
cairo_int_status_t
|
||||
_dwrite_draw_glyphs_to_gdi_surface_gdi(cairo_win32_surface_t *surface,
|
||||
DWRITE_MATRIX *transform,
|
||||
|
@ -1113,7 +1126,7 @@ _dwrite_draw_glyphs_to_gdi_surface_gdi(cairo_win32_surface_t *surface,
|
|||
IDWriteBitmapRenderTarget *rt;
|
||||
|
||||
IDWriteRenderingParams *params =
|
||||
DWriteFactory::RenderingParams(scaled_font->force_GDI_classic);
|
||||
DWriteFactory::RenderingParams(scaled_font->rendering_mode);
|
||||
|
||||
gdiInterop->CreateBitmapRenderTarget(surface->dc,
|
||||
area.right - area.left,
|
||||
|
@ -1414,8 +1427,7 @@ DWriteFactory::CreateRenderingParams()
|
|||
return;
|
||||
}
|
||||
|
||||
RefPtr<IDWriteRenderingParams> defaultParams;
|
||||
Instance()->CreateRenderingParams(&defaultParams);
|
||||
Instance()->CreateRenderingParams(&mDefaultRenderingParams);
|
||||
|
||||
// For EnhancedContrast, we override the default if the user has not set it
|
||||
// in the registry (by using the ClearType Tuner).
|
||||
|
@ -1427,7 +1439,7 @@ DWriteFactory::CreateRenderingParams()
|
|||
if (RegOpenKeyExA(ENHANCED_CONTRAST_REGISTRY_KEY,
|
||||
0, KEY_READ, &hKey) == ERROR_SUCCESS)
|
||||
{
|
||||
contrast = defaultParams->GetEnhancedContrast();
|
||||
contrast = mDefaultRenderingParams->GetEnhancedContrast();
|
||||
RegCloseKey(hKey);
|
||||
} else {
|
||||
contrast = 1.0;
|
||||
|
@ -1437,18 +1449,20 @@ DWriteFactory::CreateRenderingParams()
|
|||
// For parameters that have not been explicitly set via the SetRenderingParams API,
|
||||
// we copy values from default params (or our overridden value for contrast)
|
||||
FLOAT gamma =
|
||||
mGamma >= 1.0 && mGamma <= 2.2 ? mGamma : defaultParams->GetGamma();
|
||||
mGamma >= 1.0 && mGamma <= 2.2 ?
|
||||
mGamma : mDefaultRenderingParams->GetGamma();
|
||||
FLOAT clearTypeLevel =
|
||||
mClearTypeLevel >= 0.0 && mClearTypeLevel <= 1.0 ? mClearTypeLevel : defaultParams->GetClearTypeLevel();
|
||||
mClearTypeLevel >= 0.0 && mClearTypeLevel <= 1.0 ?
|
||||
mClearTypeLevel : mDefaultRenderingParams->GetClearTypeLevel();
|
||||
DWRITE_PIXEL_GEOMETRY pixelGeometry =
|
||||
mPixelGeometry >= DWRITE_PIXEL_GEOMETRY_FLAT && mPixelGeometry <= DWRITE_PIXEL_GEOMETRY_BGR ?
|
||||
(DWRITE_PIXEL_GEOMETRY)mPixelGeometry : defaultParams->GetPixelGeometry();
|
||||
(DWRITE_PIXEL_GEOMETRY)mPixelGeometry : mDefaultRenderingParams->GetPixelGeometry();
|
||||
DWRITE_RENDERING_MODE renderingMode =
|
||||
mRenderingMode >= DWRITE_RENDERING_MODE_DEFAULT && mRenderingMode <= DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC ?
|
||||
(DWRITE_RENDERING_MODE)mRenderingMode : defaultParams->GetRenderingMode();
|
||||
(DWRITE_RENDERING_MODE)mRenderingMode : mDefaultRenderingParams->GetRenderingMode();
|
||||
Instance()->CreateCustomRenderingParams(gamma, contrast, clearTypeLevel,
|
||||
pixelGeometry, renderingMode,
|
||||
&mRenderingParams);
|
||||
&mCustomClearTypeRenderingParams);
|
||||
Instance()->CreateCustomRenderingParams(gamma, contrast, clearTypeLevel,
|
||||
pixelGeometry, DWRITE_RENDERING_MODE_CLEARTYPE_GDI_CLASSIC,
|
||||
&mForceGDIClassicRenderingParams);
|
||||
|
|
|
@ -36,7 +36,6 @@
|
|||
#include <dwrite.h>
|
||||
#include <D2d1.h>
|
||||
|
||||
|
||||
// DirectWrite is not available on all platforms.
|
||||
typedef HRESULT (WINAPI*DWriteCreateFactoryFunc)(
|
||||
__in DWRITE_FACTORY_TYPE factoryType,
|
||||
|
@ -52,7 +51,7 @@ struct _cairo_dwrite_scaled_font {
|
|||
cairo_antialias_t antialias_mode;
|
||||
DWRITE_MEASURING_MODE measuring_mode;
|
||||
cairo_bool_t manual_show_glyphs_allowed;
|
||||
cairo_bool_t force_GDI_classic;
|
||||
cairo_d2d_surface_t::TextRenderingState rendering_mode;
|
||||
};
|
||||
typedef struct _cairo_dwrite_scaled_font cairo_dwrite_scaled_font_t;
|
||||
|
||||
|
@ -103,13 +102,22 @@ public:
|
|||
return family;
|
||||
}
|
||||
|
||||
static IDWriteRenderingParams *RenderingParams(cairo_bool_t forceGDIClassic)
|
||||
static IDWriteRenderingParams *RenderingParams(cairo_d2d_surface_t::TextRenderingState mode)
|
||||
{
|
||||
if (!mRenderingParams || !mForceGDIClassicRenderingParams) {
|
||||
if (!mDefaultRenderingParams ||
|
||||
!mForceGDIClassicRenderingParams ||
|
||||
!mCustomClearTypeRenderingParams)
|
||||
{
|
||||
CreateRenderingParams();
|
||||
}
|
||||
IDWriteRenderingParams *params =
|
||||
forceGDIClassic ? mForceGDIClassicRenderingParams : mRenderingParams;
|
||||
IDWriteRenderingParams *params;
|
||||
if (mode == cairo_d2d_surface_t::TEXT_RENDERING_NO_CLEARTYPE) {
|
||||
params = mDefaultRenderingParams;
|
||||
} else if (mode == cairo_d2d_surface_t::TEXT_RENDERING_GDI_CLASSIC && mRenderingMode < 0) {
|
||||
params = mForceGDIClassicRenderingParams;
|
||||
} else {
|
||||
params = mCustomClearTypeRenderingParams;
|
||||
}
|
||||
if (params) {
|
||||
params->AddRef();
|
||||
}
|
||||
|
@ -127,15 +135,23 @@ public:
|
|||
mClearTypeLevel = aClearTypeLevel;
|
||||
mPixelGeometry = aPixelGeometry;
|
||||
mRenderingMode = aRenderingMode;
|
||||
// discard any current RenderingParams object
|
||||
if (mRenderingParams) {
|
||||
mRenderingParams->Release();
|
||||
mRenderingParams = NULL;
|
||||
// discard any current RenderingParams objects
|
||||
if (mCustomClearTypeRenderingParams) {
|
||||
mCustomClearTypeRenderingParams->Release();
|
||||
mCustomClearTypeRenderingParams = NULL;
|
||||
}
|
||||
if (mForceGDIClassicRenderingParams) {
|
||||
mForceGDIClassicRenderingParams->Release();
|
||||
mForceGDIClassicRenderingParams = NULL;
|
||||
}
|
||||
if (mDefaultRenderingParams) {
|
||||
mDefaultRenderingParams->Release();
|
||||
mDefaultRenderingParams = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int GetClearTypeRenderingMode() {
|
||||
return mRenderingMode;
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -143,7 +159,8 @@ private:
|
|||
|
||||
static IDWriteFactory *mFactoryInstance;
|
||||
static IDWriteFontCollection *mSystemCollection;
|
||||
static IDWriteRenderingParams *mRenderingParams;
|
||||
static IDWriteRenderingParams *mDefaultRenderingParams;
|
||||
static IDWriteRenderingParams *mCustomClearTypeRenderingParams;
|
||||
static IDWriteRenderingParams *mForceGDIClassicRenderingParams;
|
||||
static FLOAT mGamma;
|
||||
static FLOAT mEnhancedContrast;
|
||||
|
|
|
@ -258,7 +258,7 @@ _have_cleartype_quality (void)
|
|||
}
|
||||
|
||||
BYTE
|
||||
_cairo_win32_get_system_text_quality (void)
|
||||
cairo_win32_get_system_text_quality (void)
|
||||
{
|
||||
BOOL font_smoothing;
|
||||
UINT smoothing_type;
|
||||
|
@ -325,7 +325,7 @@ _win32_scaled_font_create (LOGFONTW *logfont,
|
|||
* here is the hint_metrics options.
|
||||
*/
|
||||
if (options->antialias == CAIRO_ANTIALIAS_DEFAULT)
|
||||
f->quality = _cairo_win32_get_system_text_quality ();
|
||||
f->quality = cairo_win32_get_system_text_quality ();
|
||||
else {
|
||||
switch (options->antialias) {
|
||||
case CAIRO_ANTIALIAS_NONE:
|
||||
|
|
|
@ -216,9 +216,6 @@ _cairo_win32_scaled_font_is_type1 (cairo_scaled_font_t *scaled_font);
|
|||
cairo_bool_t
|
||||
_cairo_win32_scaled_font_is_bitmap (cairo_scaled_font_t *scaled_font);
|
||||
|
||||
BYTE
|
||||
_cairo_win32_get_system_text_quality (void);
|
||||
|
||||
#ifdef WINCE
|
||||
|
||||
// These are the required stubs for windows mobile
|
||||
|
|
|
@ -80,6 +80,8 @@ cairo_win32_surface_set_can_convert_to_dib (cairo_surface_t *surface, cairo_bool
|
|||
cairo_public cairo_status_t
|
||||
cairo_win32_surface_get_can_convert_to_dib (cairo_surface_t *surface, cairo_bool_t *can_convert);
|
||||
|
||||
BYTE cairo_win32_get_system_text_quality (void);
|
||||
|
||||
#if CAIRO_HAS_WIN32_FONT
|
||||
|
||||
/*
|
||||
|
@ -135,6 +137,9 @@ cairo_dwrite_scaled_font_get_force_GDI_classic(cairo_scaled_font_t *dwrite_scale
|
|||
void
|
||||
cairo_dwrite_set_cleartype_params(FLOAT gamma, FLOAT contrast, FLOAT level, int geometry, int mode);
|
||||
|
||||
int
|
||||
cairo_dwrite_get_cleartype_rendering_mode();
|
||||
|
||||
#endif /* CAIRO_HAS_DWRITE_FONT */
|
||||
|
||||
#if CAIRO_HAS_D2D_SURFACE
|
||||
|
|
|
@ -694,7 +694,8 @@ bool
|
|||
gfxDWriteFont::GetForceGDIClassic()
|
||||
{
|
||||
return static_cast<gfxDWriteFontEntry*>(mFontEntry.get())->GetForceGDIClassic() &&
|
||||
GetAdjustedSize() <=
|
||||
cairo_dwrite_get_cleartype_rendering_mode() < 0 &&
|
||||
GetAdjustedSize() <=
|
||||
gfxDWriteFontList::PlatformFontList()->GetForceGDIClassicMaxFontSize();
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
|
||||
<title>CSS Writing Modes Module Level 3</title>
|
||||
<script type="text/javascript">
|
||||
function boom() {
|
||||
document.getElementById("example").style.fontSize = "larger";
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body onload=boom()>
|
||||
<div id="example">
|
||||
<p>א</p>
|
||||
<pre><code>
|
||||
<HEBREW>
|
||||
<PAR>HEBREW1 HEBREW2 english3 HEBREW4 HEBREW5</PAR>
|
||||
<PAR>HEBREW6 <EMPH>HEBREW7</EMPH> HEBREW8</PAR>
|
||||
</HEBREW>
|
||||
<ENGLISH>
|
||||
<PAR>english9 english10 english11 HEBREW12 HEBREW13</PAR>
|
||||
<PAR>english14 english15 english16</PAR>
|
||||
<PAR>english17 <HE-QUO>HEBREW18 english19 HEBREW20</HE-QUO></PAR>
|
||||
</ENGLISH>
|
||||
</code></pre>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,15 @@
|
|||
<!DOCTYPE html>
|
||||
<html style="direction: rtl; -moz-column-width: 1px;"><head><script>
|
||||
|
||||
function boom()
|
||||
{
|
||||
document.documentElement.offsetHeight;
|
||||
document.body.style.unicodeBidi = "bidi-override";
|
||||
document.documentElement.offsetHeight;
|
||||
}
|
||||
|
||||
</script></head><body style="white-space: pre;" onload="boom();">
|
||||
H
|
||||
|
||||
|
||||
</body></html>
|
|
@ -0,0 +1,14 @@
|
|||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<script>
|
||||
|
||||
function boom()
|
||||
{
|
||||
document.body.offsetHeight;
|
||||
document.body.appendChild(document.createTextNode('Y'));
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body style="white-space: pre;" onload="boom();">
ٌ</body>
|
||||
</html>
|
|
@ -0,0 +1,3 @@
|
|||
<html xmlns="http://www.w3.org/1999/xhtml" style="direction: rtl;"><body style="-moz-column-width: 1px; word-wrap: break-word; white-space: pre-wrap;" onload="document.documentElement.offsetHeight; document.body.style.wordWrap='';">
|
||||
|
||||
xy</body></html>
|
|
@ -35,6 +35,7 @@ load 243159-2.xhtml
|
|||
asserts(1) load 243519-1.html # bug 536692
|
||||
load 244490-1.html
|
||||
load 254367-1.html
|
||||
load 263359-1.html
|
||||
load 265027-1.html
|
||||
load 265736-1.html
|
||||
load 265736-2.html
|
||||
|
@ -327,4 +328,7 @@ load 629035-1.html
|
|||
load 629908-1.html
|
||||
load 635329.html
|
||||
== 640272.html 640272-ref.html
|
||||
load 645193.html
|
||||
load 650475.xhtml
|
||||
load 650489.xhtml
|
||||
load 653133-1.html
|
||||
|
|
|
@ -47,7 +47,6 @@
|
|||
#include "nsRenderingContext.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsFrameManager.h"
|
||||
#include "nsBidiFrames.h"
|
||||
#include "nsBidiUtils.h"
|
||||
#include "nsCSSFrameConstructor.h"
|
||||
#include "nsHTMLContainerFrame.h"
|
||||
|
@ -56,6 +55,7 @@
|
|||
#include "nsContainerFrame.h"
|
||||
#include "nsFirstLetterFrame.h"
|
||||
#include "gfxUnicodeProperties.h"
|
||||
#include "nsTextFrame.h"
|
||||
|
||||
#undef NOISY_BIDI
|
||||
#undef REALLY_NOISY_BIDI
|
||||
|
@ -75,8 +75,7 @@ static const PRUnichar ALEF = 0x05D0;
|
|||
#define CHAR_IS_HEBREW(c) ((0x0590 <= (c)) && ((c)<= 0x05FF))
|
||||
// Note: The above code are moved from gfx/src/windows/nsRenderingContextWin.cpp
|
||||
|
||||
nsIFrame*
|
||||
NS_NewDirectionalFrame(nsIPresShell* aPresShell, nsStyleContext* aContext, PRUnichar aChar);
|
||||
#define NS_BIDI_CONTROL_FRAME ((nsIFrame*)0xfffb1d1)
|
||||
|
||||
nsBidiPresUtils::nsBidiPresUtils() : mArraySize(8),
|
||||
mIndexMap(nsnull),
|
||||
|
@ -166,22 +165,31 @@ SplitInlineAncestors(nsIFrame* aFrame)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// Convert bidi continuations to fluid continuations for a frame and all of its
|
||||
// inline ancestors.
|
||||
static void
|
||||
MakeContinuationFluid(nsIFrame* aFrame, nsIFrame* aNext)
|
||||
{
|
||||
NS_ASSERTION (!aFrame->GetNextInFlow() || aFrame->GetNextInFlow() == aNext,
|
||||
"next-in-flow is not next continuation!");
|
||||
aFrame->SetNextInFlow(aNext);
|
||||
|
||||
NS_ASSERTION (!aNext->GetPrevInFlow() || aNext->GetPrevInFlow() == aFrame,
|
||||
"prev-in-flow is not prev continuation!");
|
||||
aNext->SetPrevInFlow(aFrame);
|
||||
}
|
||||
|
||||
// If aFrame is the last child of its parent, convert bidi continuations to
|
||||
// fluid continuations for all of its inline ancestors.
|
||||
static void
|
||||
JoinInlineAncestors(nsIFrame* aFrame)
|
||||
{
|
||||
nsIFrame* frame = aFrame;
|
||||
if (aFrame->GetNextSibling()) {
|
||||
return;
|
||||
}
|
||||
nsIFrame* frame = aFrame->GetParent();
|
||||
while (frame && IsBidiSplittable(frame)) {
|
||||
nsIFrame* next = frame->GetNextContinuation();
|
||||
if (next) {
|
||||
NS_ASSERTION (!frame->GetNextInFlow() || frame->GetNextInFlow() == next,
|
||||
"next-in-flow is not next continuation!");
|
||||
frame->SetNextInFlow(next);
|
||||
|
||||
NS_ASSERTION (!next->GetPrevInFlow() || next->GetPrevInFlow() == frame,
|
||||
"prev-in-flow is not prev continuation!");
|
||||
next->SetPrevInFlow(frame);
|
||||
MakeContinuationFluid(frame, next);
|
||||
}
|
||||
// Join the parent only as long as we're its last child.
|
||||
if (frame->GetNextSibling())
|
||||
|
@ -191,8 +199,9 @@ JoinInlineAncestors(nsIFrame* aFrame)
|
|||
}
|
||||
|
||||
static nsresult
|
||||
CreateBidiContinuation(nsIFrame* aFrame,
|
||||
nsIFrame** aNewFrame)
|
||||
CreateContinuation(nsIFrame* aFrame,
|
||||
nsIFrame** aNewFrame,
|
||||
PRBool aIsFluid)
|
||||
{
|
||||
NS_PRECONDITION(aNewFrame, "null OUT ptr");
|
||||
NS_PRECONDITION(aFrame, "null ptr");
|
||||
|
@ -201,10 +210,10 @@ CreateBidiContinuation(nsIFrame* aFrame,
|
|||
|
||||
nsPresContext *presContext = aFrame->PresContext();
|
||||
nsIPresShell *presShell = presContext->PresShell();
|
||||
NS_ASSERTION(presShell, "PresShell must be set on PresContext before calling nsBidiPresUtils::CreateBidiContinuation");
|
||||
NS_ASSERTION(presShell, "PresShell must be set on PresContext before calling nsBidiPresUtils::CreateContinuation");
|
||||
|
||||
nsIFrame* parent = aFrame->GetParent();
|
||||
NS_ASSERTION(parent, "Couldn't get frame parent in nsBidiPresUtils::CreateBidiContinuation");
|
||||
NS_ASSERTION(parent, "Couldn't get frame parent in nsBidiPresUtils::CreateContinuation");
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
|
@ -215,12 +224,12 @@ CreateBidiContinuation(nsIFrame* aFrame,
|
|||
parent->GetStyleDisplay()->IsFloating()) {
|
||||
nsFirstLetterFrame* letterFrame = do_QueryFrame(parent);
|
||||
rv = letterFrame->CreateContinuationForFloatingParent(presContext, aFrame,
|
||||
aNewFrame, PR_FALSE);
|
||||
aNewFrame, aIsFluid);
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = presShell->FrameConstructor()->
|
||||
CreateContinuingFrame(presContext, aFrame, parent, aNewFrame, PR_FALSE);
|
||||
CreateContinuingFrame(presContext, aFrame, parent, aNewFrame, aIsFluid);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
@ -232,11 +241,13 @@ CreateBidiContinuation(nsIFrame* aFrame,
|
|||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Split inline ancestor frames
|
||||
rv = SplitInlineAncestors(aFrame);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
|
||||
if (!aIsFluid) {
|
||||
// Split inline ancestor frames
|
||||
rv = SplitInlineAncestors(aFrame);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -287,7 +298,7 @@ AdvanceLineIteratorToFrame(nsIFrame* aFrame,
|
|||
*
|
||||
* Walk through the descendants of aBlockFrame and build:
|
||||
* * mLogicalFrames: an nsTArray of nsIFrame* pointers in logical order
|
||||
* * mBuffer: an nsAutoString containing a representation of
|
||||
* * mBuffer: an nsString containing a representation of
|
||||
* the content of the frames.
|
||||
* In the case of text frames, this is the actual text context of the
|
||||
* frames, but some other elements are represented in a symbolic form which
|
||||
|
@ -317,93 +328,19 @@ nsBidiPresUtils::Resolve(nsBlockFrame* aBlockFrame)
|
|||
{
|
||||
mLogicalFrames.Clear();
|
||||
mContentToFrameIndex.Clear();
|
||||
mLinePerFrame.Clear();
|
||||
mBuffer.SetLength(0);
|
||||
mEmbeddingStack.Clear();
|
||||
|
||||
nsPresContext *presContext = aBlockFrame->PresContext();
|
||||
nsIPresShell* shell = presContext->PresShell();
|
||||
nsStyleContext* styleContext = aBlockFrame->GetStyleContext();
|
||||
|
||||
// handle bidi-override being set on the block itself before calling
|
||||
// InitLogicalArray.
|
||||
const nsStyleVisibility* vis = aBlockFrame->GetStyleVisibility();
|
||||
const nsStyleTextReset* text = aBlockFrame->GetStyleTextReset();
|
||||
|
||||
if (text->mUnicodeBidi == NS_STYLE_UNICODE_BIDI_OVERRIDE) {
|
||||
nsIFrame *directionalFrame = nsnull;
|
||||
mParaLevel = (NS_STYLE_DIRECTION_RTL == vis->mDirection) ?
|
||||
NSBIDI_RTL : NSBIDI_LTR;
|
||||
|
||||
if (NS_STYLE_DIRECTION_RTL == vis->mDirection) {
|
||||
directionalFrame = NS_NewDirectionalFrame(shell, styleContext, kRLO);
|
||||
}
|
||||
else if (NS_STYLE_DIRECTION_LTR == vis->mDirection) {
|
||||
directionalFrame = NS_NewDirectionalFrame(shell, styleContext, kLRO);
|
||||
}
|
||||
|
||||
if (directionalFrame) {
|
||||
mLogicalFrames.AppendElement(directionalFrame);
|
||||
}
|
||||
}
|
||||
for (nsBlockFrame* block = aBlockFrame; block;
|
||||
block = static_cast<nsBlockFrame*>(block->GetNextContinuation())) {
|
||||
block->RemoveStateBits(NS_BLOCK_NEEDS_BIDI_RESOLUTION);
|
||||
InitLogicalArray(block->GetFirstChild(nsnull));
|
||||
}
|
||||
|
||||
if (text->mUnicodeBidi == NS_STYLE_UNICODE_BIDI_OVERRIDE) {
|
||||
nsIFrame* directionalFrame = NS_NewDirectionalFrame(shell, styleContext, kPDF);
|
||||
if (directionalFrame) {
|
||||
mLogicalFrames.AppendElement(directionalFrame);
|
||||
}
|
||||
}
|
||||
|
||||
CreateBlockBuffer();
|
||||
|
||||
PRInt32 bufferLength = mBuffer.Length();
|
||||
|
||||
if (bufferLength < 1) {
|
||||
mSuccess = NS_OK;
|
||||
return mSuccess;
|
||||
}
|
||||
PRInt32 runCount;
|
||||
PRUint8 embeddingLevel;
|
||||
|
||||
nsBidiLevel paraLevel = embeddingLevel =
|
||||
(NS_STYLE_DIRECTION_RTL == vis->mDirection)
|
||||
? NSBIDI_RTL : NSBIDI_LTR;
|
||||
|
||||
mSuccess = mBidiEngine->SetPara(mBuffer.get(), bufferLength, paraLevel, nsnull);
|
||||
if (NS_FAILED(mSuccess) ) {
|
||||
return mSuccess;
|
||||
}
|
||||
|
||||
mSuccess = mBidiEngine->CountRuns(&runCount);
|
||||
if (NS_FAILED(mSuccess) ) {
|
||||
return mSuccess;
|
||||
}
|
||||
PRInt32 runLength = 0; // the length of the current run of text
|
||||
PRInt32 lineOffset = 0; // the start of the current run
|
||||
PRInt32 logicalLimit = 0; // the end of the current run + 1
|
||||
PRInt32 numRun = -1;
|
||||
PRInt32 fragmentLength = 0; // the length of the current text frame
|
||||
PRInt32 frameIndex = -1; // index to the frames in mLogicalFrames
|
||||
PRInt32 frameCount = mLogicalFrames.Length();
|
||||
PRInt32 contentOffset = 0; // offset of current frame in its content node
|
||||
PRBool isTextFrame = PR_FALSE;
|
||||
nsIFrame* frame = nsnull;
|
||||
nsIContent* content = nsnull;
|
||||
PRInt32 contentTextLength;
|
||||
nsIAtom* frameType = nsnull;
|
||||
|
||||
FramePropertyTable *propTable = presContext->PropertyTable();
|
||||
|
||||
nsBlockInFlowLineIterator lineIter(aBlockFrame, aBlockFrame->begin_lines(), PR_FALSE);
|
||||
if (lineIter.GetLine() == aBlockFrame->end_lines()) {
|
||||
// Advance to first valid line (might be in a next-continuation)
|
||||
lineIter.Next();
|
||||
}
|
||||
nsIFrame* prevFrame = nsnull;
|
||||
PRBool lineNeedsUpdate = PR_FALSE;
|
||||
|
||||
PRBool isVisual = presContext->IsVisualMode();
|
||||
if (isVisual) {
|
||||
mIsVisual = presContext->IsVisualMode();
|
||||
if (mIsVisual) {
|
||||
/**
|
||||
* Drill up in content to detect whether this is an element that needs to be
|
||||
* rendered with logical order even on visual pages.
|
||||
|
@ -418,13 +355,94 @@ nsBidiPresUtils::Resolve(nsBlockFrame* aBlockFrame)
|
|||
* element appears in a visual page, it will be generated by an XBL binding
|
||||
* and contain localized text which will be in logical order.
|
||||
*/
|
||||
for (content = aBlockFrame->GetContent() ; content; content = content->GetParent()) {
|
||||
if (content->IsNodeOfType(nsINode::eHTML_FORM_CONTROL) || content->IsXUL()) {
|
||||
isVisual = PR_FALSE;
|
||||
for (nsIContent* content = aBlockFrame->GetContent() ; content;
|
||||
content = content->GetParent()) {
|
||||
if (content->IsNodeOfType(nsINode::eHTML_FORM_CONTROL) ||
|
||||
content->IsXUL()) {
|
||||
mIsVisual = PR_FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// handle bidi-override being set on the block itself before calling
|
||||
// TraverseFrames.
|
||||
const nsStyleTextReset* text = aBlockFrame->GetStyleTextReset();
|
||||
PRUnichar ch = 0;
|
||||
if (text->mUnicodeBidi == NS_STYLE_UNICODE_BIDI_OVERRIDE) {
|
||||
if (NS_STYLE_DIRECTION_RTL == vis->mDirection) {
|
||||
ch = kRLO;
|
||||
}
|
||||
else if (NS_STYLE_DIRECTION_LTR == vis->mDirection) {
|
||||
ch = kLRO;
|
||||
}
|
||||
if (ch != 0) {
|
||||
mLogicalFrames.AppendElement(NS_BIDI_CONTROL_FRAME);
|
||||
mLinePerFrame.AppendElement((nsLineBox*)nsnull);
|
||||
mBuffer.Append(ch);
|
||||
mEmbeddingStack.AppendElement(ch);
|
||||
}
|
||||
}
|
||||
mPrevContent = nsnull;
|
||||
for (nsBlockFrame* block = aBlockFrame; block;
|
||||
block = static_cast<nsBlockFrame*>(block->GetNextContinuation())) {
|
||||
block->RemoveStateBits(NS_BLOCK_NEEDS_BIDI_RESOLUTION);
|
||||
nsBlockInFlowLineIterator lineIter(block, block->begin_lines(), PR_FALSE);
|
||||
mPrevFrame = nsnull;
|
||||
TraverseFrames(aBlockFrame, &lineIter, block->GetFirstChild(nsnull));
|
||||
}
|
||||
|
||||
if (ch != 0) {
|
||||
mLogicalFrames.AppendElement(NS_BIDI_CONTROL_FRAME);
|
||||
mLinePerFrame.AppendElement((nsLineBox*)nsnull);
|
||||
mBuffer.Append(kPDF);
|
||||
NS_ASSERTION(mEmbeddingStack.Length(), "embedding/override underflow");
|
||||
mEmbeddingStack.TruncateLength(mEmbeddingStack.Length() - 1);
|
||||
}
|
||||
|
||||
ResolveParagraph(aBlockFrame);
|
||||
return mSuccess;
|
||||
}
|
||||
|
||||
void
|
||||
nsBidiPresUtils::ResolveParagraph(nsBlockFrame* aBlockFrame)
|
||||
{
|
||||
nsPresContext *presContext = aBlockFrame->PresContext();
|
||||
PRInt32 bufferLength = mBuffer.Length();
|
||||
|
||||
if (bufferLength < 1) {
|
||||
mSuccess = NS_OK;
|
||||
return;
|
||||
}
|
||||
mBuffer.ReplaceChar("\t\r\n", kSpace);
|
||||
|
||||
PRInt32 runCount;
|
||||
PRUint8 embeddingLevel = mParaLevel;
|
||||
|
||||
mSuccess = mBidiEngine->SetPara(mBuffer.get(), bufferLength, mParaLevel, nsnull);
|
||||
if (NS_FAILED(mSuccess) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
mSuccess = mBidiEngine->CountRuns(&runCount);
|
||||
if (NS_FAILED(mSuccess) ) {
|
||||
return;
|
||||
}
|
||||
PRInt32 runLength = 0; // the length of the current run of text
|
||||
PRInt32 lineOffset = 0; // the start of the current run
|
||||
PRInt32 logicalLimit = 0; // the end of the current run + 1
|
||||
PRInt32 numRun = -1;
|
||||
PRInt32 fragmentLength = 0; // the length of the current text frame
|
||||
PRInt32 frameIndex = -1; // index to the frames in mLogicalFrames
|
||||
PRInt32 frameCount = mLogicalFrames.Length();
|
||||
PRInt32 contentOffset = 0; // offset of current frame in its content node
|
||||
PRBool isTextFrame = PR_FALSE;
|
||||
nsIFrame* frame = nsnull;
|
||||
nsIContent* content = nsnull;
|
||||
PRInt32 contentTextLength;
|
||||
|
||||
FramePropertyTable *propTable = presContext->PropertyTable();
|
||||
nsLineBox* currentLine = nsnull;
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifdef NOISY_BIDI
|
||||
|
@ -444,9 +462,17 @@ nsBidiPresUtils::Resolve(nsBlockFrame* aBlockFrame)
|
|||
break;
|
||||
}
|
||||
frame = mLogicalFrames[frameIndex];
|
||||
frameType = frame->GetType();
|
||||
lineNeedsUpdate = PR_TRUE;
|
||||
if (nsGkAtoms::textFrame == frameType) {
|
||||
if (frame == NS_BIDI_CONTROL_FRAME ||
|
||||
nsGkAtoms::textFrame != frame->GetType()) {
|
||||
/*
|
||||
* Any non-text frame corresponds to a single character in the text buffer
|
||||
* (a bidi control character, LINE SEPARATOR, or OBJECT SUBSTITUTE)
|
||||
*/
|
||||
isTextFrame = PR_FALSE;
|
||||
fragmentLength = 1;
|
||||
}
|
||||
else {
|
||||
currentLine = mLinePerFrame[frameIndex];
|
||||
content = frame->GetContent();
|
||||
if (!content) {
|
||||
mSuccess = NS_OK;
|
||||
|
@ -460,7 +486,7 @@ nsBidiPresUtils::Resolve(nsBlockFrame* aBlockFrame)
|
|||
propTable->Set(frame, nsIFrame::EmbeddingLevelProperty(),
|
||||
NS_INT32_TO_PTR(embeddingLevel));
|
||||
propTable->Set(frame, nsIFrame::BaseLevelProperty(),
|
||||
NS_INT32_TO_PTR(paraLevel));
|
||||
NS_INT32_TO_PTR(mParaLevel));
|
||||
continue;
|
||||
}
|
||||
PRInt32 start, end;
|
||||
|
@ -471,14 +497,6 @@ nsBidiPresUtils::Resolve(nsBlockFrame* aBlockFrame)
|
|||
contentOffset = start;
|
||||
isTextFrame = PR_TRUE;
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* Any non-text frame corresponds to a single character in the text buffer
|
||||
* (a bidi control character, LINE SEPARATOR, or OBJECT SUBSTITUTE)
|
||||
*/
|
||||
isTextFrame = PR_FALSE;
|
||||
fragmentLength = 1;
|
||||
}
|
||||
} // if (fragmentLength <= 0)
|
||||
|
||||
if (runLength <= 0) {
|
||||
|
@ -492,13 +510,12 @@ nsBidiPresUtils::Resolve(nsBlockFrame* aBlockFrame)
|
|||
break;
|
||||
}
|
||||
runLength = logicalLimit - lineOffset;
|
||||
if (isVisual) {
|
||||
embeddingLevel = paraLevel;
|
||||
if (mIsVisual) {
|
||||
embeddingLevel = mParaLevel;
|
||||
}
|
||||
} // if (runLength <= 0)
|
||||
|
||||
if (nsGkAtoms::directionalFrame == frameType) {
|
||||
frame->Destroy();
|
||||
if (frame == NS_BIDI_CONTROL_FRAME) {
|
||||
frame = nsnull;
|
||||
++lineOffset;
|
||||
}
|
||||
|
@ -506,18 +523,14 @@ nsBidiPresUtils::Resolve(nsBlockFrame* aBlockFrame)
|
|||
propTable->Set(frame, nsIFrame::EmbeddingLevelProperty(),
|
||||
NS_INT32_TO_PTR(embeddingLevel));
|
||||
propTable->Set(frame, nsIFrame::BaseLevelProperty(),
|
||||
NS_INT32_TO_PTR(paraLevel));
|
||||
NS_INT32_TO_PTR(mParaLevel));
|
||||
if (isTextFrame) {
|
||||
if ( (runLength > 0) && (runLength < fragmentLength) ) {
|
||||
/*
|
||||
* The text in this frame continues beyond the end of this directional run.
|
||||
* Create a non-fluid continuation frame for the next directional run.
|
||||
*/
|
||||
if (lineNeedsUpdate) {
|
||||
AdvanceLineIteratorToFrame(frame, &lineIter, prevFrame);
|
||||
lineNeedsUpdate = PR_FALSE;
|
||||
}
|
||||
lineIter.GetLine()->MarkDirty();
|
||||
currentLine->MarkDirty();
|
||||
nsIFrame* nextBidi;
|
||||
PRInt32 runEnd = contentOffset + runLength;
|
||||
EnsureBidiContinuation(frame, &nextBidi, frameIndex,
|
||||
|
@ -553,12 +566,17 @@ nsBidiPresUtils::Resolve(nsBlockFrame* aBlockFrame)
|
|||
*/
|
||||
PRInt32 newIndex = frameIndex;
|
||||
do {
|
||||
} while (mLogicalFrames[++newIndex]->GetType() == nsGkAtoms::directionalFrame);
|
||||
RemoveBidiContinuation(frame, frameIndex, newIndex, lineOffset);
|
||||
} else if (runLength == fragmentLength) {
|
||||
} while (++newIndex < frameCount &&
|
||||
mLogicalFrames[newIndex] == NS_BIDI_CONTROL_FRAME);
|
||||
if (newIndex < frameCount) {
|
||||
RemoveBidiContinuation(frame, frameIndex, newIndex, lineOffset);
|
||||
}
|
||||
} else if (runLength == fragmentLength &&
|
||||
numRun + 1 < runCount) {
|
||||
/*
|
||||
* The directional run ends at the end of the frame. Make sure that
|
||||
* the next frame is a non-fluid continuation
|
||||
* If the directional run ends at the end of the frame, and this is
|
||||
* not the end of our paragraph, make sure that the next frame is a
|
||||
* non-fluid continuation
|
||||
*/
|
||||
nsIFrame* next = frame->GetNextInFlow();
|
||||
if (next) {
|
||||
|
@ -567,29 +585,25 @@ nsBidiPresUtils::Resolve(nsBlockFrame* aBlockFrame)
|
|||
}
|
||||
}
|
||||
frame->AdjustOffsetsForBidi(contentOffset, contentOffset + fragmentLength);
|
||||
if (lineNeedsUpdate) {
|
||||
AdvanceLineIteratorToFrame(frame, &lineIter, prevFrame);
|
||||
lineNeedsUpdate = PR_FALSE;
|
||||
}
|
||||
lineIter.GetLine()->MarkDirty();
|
||||
currentLine->MarkDirty();
|
||||
}
|
||||
} // isTextFrame
|
||||
else {
|
||||
++lineOffset;
|
||||
}
|
||||
} // not directionalFrame
|
||||
} // not bidi control frame
|
||||
PRInt32 temp = runLength;
|
||||
runLength -= fragmentLength;
|
||||
fragmentLength -= temp;
|
||||
|
||||
if (frame && fragmentLength <= 0) {
|
||||
// If the frame is at the end of a run, split all ancestor inlines that
|
||||
// need splitting.
|
||||
// If the frame is at the end of a run, and this is not the end of our
|
||||
// paragrah, split all ancestor inlines that need splitting.
|
||||
// To determine whether we're at the end of the run, we check that we've
|
||||
// finished processing the current run, and that the current frame
|
||||
// doesn't have a fluid continuation (it could have a fluid continuation
|
||||
// of zero length, so testing runLength alone is not sufficient).
|
||||
if (runLength <= 0 && !frame->GetNextInFlow()) {
|
||||
if (numRun + 1 < runCount && runLength <= 0 && !frame->GetNextInFlow()) {
|
||||
nsIFrame* child = frame;
|
||||
nsIFrame* parent = frame->GetParent();
|
||||
// As long as we're on the last sibling, the parent doesn't have to be split.
|
||||
|
@ -611,12 +625,11 @@ nsBidiPresUtils::Resolve(nsBlockFrame* aBlockFrame)
|
|||
if (parent && IsBidiSplittable(parent))
|
||||
SplitInlineAncestors(child);
|
||||
}
|
||||
else if (!frame->GetNextSibling()) {
|
||||
// We're not at an end of a run, and |frame| is the last child of its parent.
|
||||
// If its ancestors happen to have bidi continuations, convert them into
|
||||
// fluid continuations.
|
||||
nsIFrame* parent = frame->GetParent();
|
||||
JoinInlineAncestors(parent);
|
||||
else {
|
||||
// We're not at an end of a run. If |frame| is the last child of its
|
||||
// parent, and its ancestors happen to have bidi continuations, convert
|
||||
// them into fluid continuations.
|
||||
JoinInlineAncestors(frame);
|
||||
}
|
||||
}
|
||||
} // for
|
||||
|
@ -628,8 +641,6 @@ nsBidiPresUtils::Resolve(nsBlockFrame* aBlockFrame)
|
|||
printf("===\n");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return mSuccess;
|
||||
}
|
||||
|
||||
// Should this frame be treated as a leaf (e.g. when building mLogicalFrames)?
|
||||
|
@ -640,16 +651,25 @@ PRBool IsBidiLeaf(nsIFrame* aFrame) {
|
|||
}
|
||||
|
||||
void
|
||||
nsBidiPresUtils::InitLogicalArray(nsIFrame* aCurrentFrame)
|
||||
nsBidiPresUtils::TraverseFrames(nsBlockFrame* aBlockFrame,
|
||||
nsBlockInFlowLineIterator* aLineIter,
|
||||
nsIFrame* aCurrentFrame)
|
||||
{
|
||||
if (!aCurrentFrame)
|
||||
return;
|
||||
|
||||
nsIPresShell* shell = aCurrentFrame->PresContext()->PresShell();
|
||||
nsStyleContext* styleContext;
|
||||
|
||||
for (nsIFrame* childFrame = aCurrentFrame; childFrame;
|
||||
childFrame = childFrame->GetNextSibling()) {
|
||||
nsIFrame* childFrame = aCurrentFrame;
|
||||
do {
|
||||
/*
|
||||
* It's important to get the next sibling and next continuation *before*
|
||||
* handling the frame: If we encounter a forced paragraph break and call
|
||||
* ResolveParagraph within this loop, doing GetNextSibling and
|
||||
* GetNextContinuation after that could return a bidi continuation that had
|
||||
* just been split from the original childFrame and we would process it
|
||||
* twice.
|
||||
*/
|
||||
nsIFrame* nextSibling = childFrame->GetNextSibling();
|
||||
PRBool isLastFrame = !childFrame->GetNextContinuation();
|
||||
|
||||
// If the real frame for a placeholder is a first letter frame, we need to
|
||||
// drill down into it and include its contents in Bidi resolution.
|
||||
|
@ -671,8 +691,6 @@ nsBidiPresUtils::InitLogicalArray(nsIFrame* aCurrentFrame)
|
|||
case NS_STYLE_UNICODE_BIDI_NORMAL:
|
||||
break;
|
||||
case NS_STYLE_UNICODE_BIDI_EMBED:
|
||||
styleContext = frame->GetStyleContext();
|
||||
|
||||
if (NS_STYLE_DIRECTION_RTL == vis->mDirection) {
|
||||
ch = kRLE;
|
||||
}
|
||||
|
@ -681,8 +699,6 @@ nsBidiPresUtils::InitLogicalArray(nsIFrame* aCurrentFrame)
|
|||
}
|
||||
break;
|
||||
case NS_STYLE_UNICODE_BIDI_OVERRIDE:
|
||||
styleContext = frame->GetStyleContext();
|
||||
|
||||
if (NS_STYLE_DIRECTION_RTL == vis->mDirection) {
|
||||
ch = kRLO;
|
||||
}
|
||||
|
@ -692,13 +708,13 @@ nsBidiPresUtils::InitLogicalArray(nsIFrame* aCurrentFrame)
|
|||
break;
|
||||
}
|
||||
|
||||
// Create a directional frame before the first frame of an
|
||||
// element specifying embedding or override
|
||||
// Add a dummy frame pointer representing a bidi control code before the
|
||||
// first frame of an element specifying embedding or override
|
||||
if (ch != 0 && !frame->GetPrevContinuation()) {
|
||||
nsIFrame* dirFrame = NS_NewDirectionalFrame(shell, styleContext, ch);
|
||||
if (dirFrame) {
|
||||
mLogicalFrames.AppendElement(dirFrame);
|
||||
}
|
||||
mLogicalFrames.AppendElement(NS_BIDI_CONTROL_FRAME);
|
||||
mLinePerFrame.AppendElement((nsLineBox*)nsnull);
|
||||
mBuffer.Append(ch);
|
||||
mEmbeddingStack.AppendElement(ch);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -713,66 +729,196 @@ nsBidiPresUtils::InitLogicalArray(nsIFrame* aCurrentFrame)
|
|||
mContentToFrameIndex.Put(content, mLogicalFrames.Length());
|
||||
}
|
||||
mLogicalFrames.AppendElement(frame);
|
||||
|
||||
AdvanceLineIteratorToFrame(frame, aLineIter, mPrevFrame);
|
||||
mLinePerFrame.AppendElement(aLineIter->GetLine().get());
|
||||
|
||||
// Append the content of the frame to the paragraph buffer
|
||||
nsIAtom* frameType = frame->GetType();
|
||||
if (nsGkAtoms::textFrame == frameType) {
|
||||
if (content != mPrevContent) {
|
||||
mPrevContent = content;
|
||||
if (!frame->GetStyleContext()->GetStyleText()->NewlineIsSignificant()) {
|
||||
content->AppendTextTo(mBuffer);
|
||||
} else {
|
||||
/*
|
||||
* For preformatted text we have to do bidi resolution on each line
|
||||
* separately.
|
||||
*/
|
||||
nsAutoString text;
|
||||
content->AppendTextTo(text);
|
||||
nsIFrame* next;
|
||||
do {
|
||||
next = nsnull;
|
||||
|
||||
PRInt32 start, end;
|
||||
frame->GetOffsets(start, end);
|
||||
PRInt32 endLine = text.FindCharInSet(NS_LITERAL_STRING("\n\r"),
|
||||
start);
|
||||
if (endLine == -1) {
|
||||
/*
|
||||
* If there is no newline in the frame, just save the text and
|
||||
* do bidi resolution later
|
||||
*/
|
||||
mBuffer.Append(Substring(text, start));
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* If there is a newline in the frame, break the frame after the
|
||||
* newline, do bidi resolution and repeat until the end of the
|
||||
* element.
|
||||
*/
|
||||
++endLine;
|
||||
|
||||
/*
|
||||
* If the frame ends before the new line, save the text and move
|
||||
* into the next continuation
|
||||
*/
|
||||
while (end < endLine) {
|
||||
mBuffer.Append(Substring(text, start, end - start));
|
||||
frame = frame->GetNextContinuation();
|
||||
NS_ASSERTION(frame, "Premature end of continuation chain");
|
||||
frame->GetOffsets(start, end);
|
||||
mLogicalFrames.AppendElement(frame);
|
||||
AdvanceLineIteratorToFrame(frame, aLineIter, mPrevFrame);
|
||||
mLinePerFrame.AppendElement(aLineIter->GetLine().get());
|
||||
|
||||
/*
|
||||
* If we have already overshot the saved next-sibling while
|
||||
* scanning the frame's continuations, advance it.
|
||||
*/
|
||||
if (frame == nextSibling) {
|
||||
nextSibling = frame->GetNextSibling();
|
||||
}
|
||||
}
|
||||
|
||||
mBuffer.Append(Substring(text, start, endLine - start));
|
||||
|
||||
PRBool createdContinuation = PR_FALSE;
|
||||
if (PRUint32(endLine) < text.Length()) {
|
||||
/*
|
||||
* Timing is everything here: if the frame already has a bidi
|
||||
* continuation, we need to make the continuation fluid *before*
|
||||
* resetting the length of the current frame. Otherwise
|
||||
* nsTextFrame::SetLength won't set the continuation frame's
|
||||
* text offsets correctly.
|
||||
*
|
||||
* On the other hand, if the frame doesn't have a continuation,
|
||||
* we need to create one *after* resetting the length, or
|
||||
* CreateContinuingFrame will complain that there is no more
|
||||
* content for the continuation.
|
||||
*/
|
||||
next = frame->GetNextInFlow();
|
||||
if (!next) {
|
||||
// If the frame already has a bidi continuation, make it fluid
|
||||
next = frame->GetNextContinuation();
|
||||
if (next) {
|
||||
MakeContinuationFluid(frame, next);
|
||||
JoinInlineAncestors(frame);
|
||||
}
|
||||
}
|
||||
|
||||
nsTextFrame* textFrame = static_cast<nsTextFrame*>(frame);
|
||||
textFrame->SetLength(endLine - start, nsnull);
|
||||
|
||||
if (!next) {
|
||||
// If the frame has no next in flow, create one.
|
||||
CreateContinuation(frame, &next, PR_TRUE);
|
||||
createdContinuation = PR_TRUE;
|
||||
}
|
||||
}
|
||||
ResolveParagraphWithinBlock(aBlockFrame);
|
||||
|
||||
if (!nextSibling && !createdContinuation) {
|
||||
break;
|
||||
} else if (next) {
|
||||
frame = next;
|
||||
mLogicalFrames.AppendElement(frame);
|
||||
AdvanceLineIteratorToFrame(frame, aLineIter, mPrevFrame);
|
||||
mLinePerFrame.AppendElement(aLineIter->GetLine().get());
|
||||
}
|
||||
|
||||
/*
|
||||
* If we have already overshot the saved next-sibling while
|
||||
* scanning the frame's continuations, advance it.
|
||||
*/
|
||||
if (frame && frame == nextSibling) {
|
||||
nextSibling = frame->GetNextSibling();
|
||||
}
|
||||
|
||||
} while (next);
|
||||
}
|
||||
}
|
||||
} else if (nsGkAtoms::brFrame == frameType) {
|
||||
// break frame -- append line separator
|
||||
mBuffer.Append(kLineSeparator);
|
||||
ResolveParagraphWithinBlock(aBlockFrame);
|
||||
} else {
|
||||
// other frame type -- see the Unicode Bidi Algorithm:
|
||||
// "...inline objects (such as graphics) are treated as if they are ...
|
||||
// U+FFFC"
|
||||
mBuffer.Append(kObjectSubstitute);
|
||||
if (!frame->GetStyleContext()->GetStyleDisplay()->IsInlineOutside()) {
|
||||
// if it is not inline, end the paragraph
|
||||
ResolveParagraphWithinBlock(aBlockFrame);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// For a non-leaf frame, recurse into TraverseFrames
|
||||
nsIFrame* kid = frame->GetFirstChild(nsnull);
|
||||
InitLogicalArray(kid);
|
||||
TraverseFrames(aBlockFrame, aLineIter, kid);
|
||||
}
|
||||
|
||||
// If the element is attributed by dir, indicate direction pop (add PDF frame)
|
||||
if (ch != 0 && !frame->GetNextContinuation()) {
|
||||
// Create a directional frame after the last frame of an
|
||||
// element specifying embedding or override
|
||||
nsIFrame* dirFrame = NS_NewDirectionalFrame(shell, styleContext, kPDF);
|
||||
if (dirFrame) {
|
||||
mLogicalFrames.AppendElement(dirFrame);
|
||||
}
|
||||
if (ch != 0 && isLastFrame) {
|
||||
// Add a dummy frame pointer representing a bidi control code after the
|
||||
// last frame of an element specifying embedding or override
|
||||
mLogicalFrames.AppendElement(NS_BIDI_CONTROL_FRAME);
|
||||
mLinePerFrame.AppendElement((nsLineBox*)nsnull);
|
||||
mBuffer.Append(kPDF);
|
||||
NS_ASSERTION(mEmbeddingStack.Length(), "embedding/override underflow");
|
||||
mEmbeddingStack.TruncateLength(mEmbeddingStack.Length() - 1);
|
||||
}
|
||||
} // for
|
||||
childFrame = nextSibling;
|
||||
} while (childFrame);
|
||||
}
|
||||
|
||||
void
|
||||
nsBidiPresUtils::CreateBlockBuffer()
|
||||
nsBidiPresUtils::ResolveParagraphWithinBlock(nsBlockFrame* aBlockFrame)
|
||||
{
|
||||
mBuffer.SetLength(0);
|
||||
nsIPresShell* shell;
|
||||
nsStyleContext* styleContext;
|
||||
|
||||
nsIFrame* frame;
|
||||
nsIContent* prevContent = nsnull;
|
||||
PRUint32 i;
|
||||
PRUint32 count = mLogicalFrames.Length();
|
||||
if (mEmbeddingStack.Length() > 0) {
|
||||
shell = aBlockFrame->PresContext()->PresShell();
|
||||
styleContext = aBlockFrame->GetStyleContext();
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
frame = mLogicalFrames[i];
|
||||
nsIAtom* frameType = frame->GetType();
|
||||
|
||||
if (nsGkAtoms::textFrame == frameType) {
|
||||
nsIContent* content = frame->GetContent();
|
||||
if (!content) {
|
||||
mSuccess = NS_OK;
|
||||
break;
|
||||
}
|
||||
if (content == prevContent) {
|
||||
continue;
|
||||
}
|
||||
prevContent = content;
|
||||
content->AppendTextTo(mBuffer);
|
||||
}
|
||||
else if (nsGkAtoms::brFrame == frameType) { // break frame
|
||||
// Append line separator
|
||||
mBuffer.Append(kLineSeparator);
|
||||
}
|
||||
else if (nsGkAtoms::directionalFrame == frameType) {
|
||||
nsDirectionalFrame* dirFrame = static_cast<nsDirectionalFrame*>(frame);
|
||||
mBuffer.Append(dirFrame->GetChar());
|
||||
}
|
||||
else { // not text frame
|
||||
// See the Unicode Bidi Algorithm:
|
||||
// "...inline objects (such as graphics) are treated as if they are ... U+FFFC"
|
||||
mBuffer.Append(kObjectSubstitute);
|
||||
// pop all embeddings and overrides
|
||||
for (PRUint32 i = 0; i < mEmbeddingStack.Length(); ++i) {
|
||||
mBuffer.Append(kPDF);
|
||||
mLogicalFrames.AppendElement(NS_BIDI_CONTROL_FRAME);
|
||||
mLinePerFrame.AppendElement((nsLineBox*)nsnull);
|
||||
}
|
||||
}
|
||||
// XXX: TODO: Handle preformatted text ('\n')
|
||||
mBuffer.ReplaceChar("\t\r\n", kSpace);
|
||||
|
||||
ResolveParagraph(aBlockFrame);
|
||||
|
||||
// Clear the frame array and paragraph buffer, and restore the stored
|
||||
// embeddings and overrides
|
||||
mLogicalFrames.Clear();
|
||||
mContentToFrameIndex.Clear();
|
||||
mLinePerFrame.Clear();
|
||||
mBuffer.SetLength(0);
|
||||
mPrevContent = nsnull;
|
||||
if (mEmbeddingStack.Length() > 0) {
|
||||
for (PRUint32 i = 0; i < mEmbeddingStack.Length(); ++i) {
|
||||
mBuffer.Append(mEmbeddingStack[i]);
|
||||
mLogicalFrames.AppendElement(NS_BIDI_CONTROL_FRAME);
|
||||
mLinePerFrame.AppendElement((nsLineBox*)nsnull);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1219,7 +1365,7 @@ nsBidiPresUtils::EnsureBidiContinuation(nsIFrame* aFrame,
|
|||
NS_PRECONDITION(aFrame, "aFrame is null");
|
||||
|
||||
aFrame->AdjustOffsetsForBidi(aStart, aEnd);
|
||||
mSuccess = CreateBidiContinuation(aFrame, aNewFrame);
|
||||
mSuccess = CreateContinuation(aFrame, aNewFrame, PR_FALSE);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1236,8 +1382,7 @@ nsBidiPresUtils::RemoveBidiContinuation(nsIFrame* aFrame,
|
|||
|
||||
for (PRInt32 index = aFirstIndex + 1; index <= aLastIndex; index++) {
|
||||
nsIFrame* frame = mLogicalFrames[index];
|
||||
if (nsGkAtoms::directionalFrame == frame->GetType()) {
|
||||
frame->Destroy();
|
||||
if (frame == NS_BIDI_CONTROL_FRAME) {
|
||||
++aOffset;
|
||||
}
|
||||
else {
|
||||
|
@ -1252,14 +1397,7 @@ nsBidiPresUtils::RemoveBidiContinuation(nsIFrame* aFrame,
|
|||
while (frame) {
|
||||
nsIFrame* prev = frame->GetPrevContinuation();
|
||||
if (prev) {
|
||||
NS_ASSERTION (!frame->GetPrevInFlow() || frame->GetPrevInFlow() == prev,
|
||||
"prev-in-flow is not prev continuation!");
|
||||
frame->SetPrevInFlow(prev);
|
||||
|
||||
NS_ASSERTION (!prev->GetNextInFlow() || prev->GetNextInFlow() == frame,
|
||||
"next-in-flow is not next continuation!");
|
||||
prev->SetNextInFlow(frame);
|
||||
|
||||
MakeContinuationFluid(prev, frame);
|
||||
frame = frame->GetParent();
|
||||
} else {
|
||||
break;
|
||||
|
|
|
@ -175,6 +175,8 @@ public:
|
|||
* @lina 06/18/2000
|
||||
*/
|
||||
nsresult Resolve(nsBlockFrame* aBlockFrame);
|
||||
void ResolveParagraph(nsBlockFrame* aBlockFrame);
|
||||
void ResolveParagraphWithinBlock(nsBlockFrame* aBlockFrame);
|
||||
|
||||
/**
|
||||
* Reorder this line using Bidi engine.
|
||||
|
@ -362,18 +364,16 @@ private:
|
|||
nscoord* aWidth /* may be null */);
|
||||
|
||||
/**
|
||||
* Create a string containing entire text content of this block.
|
||||
*
|
||||
* @lina 05/02/2000
|
||||
* Traverse the child frames of the block element and:
|
||||
* Set up an array of the frames in logical order
|
||||
* Create a string containing the text content of all the frames
|
||||
* If we encounter content that requires us to split the element into more
|
||||
* than one paragraph for bidi resolution, resolve the paragraph up to that
|
||||
* point.
|
||||
*/
|
||||
void CreateBlockBuffer();
|
||||
|
||||
/**
|
||||
* Set up an array of the frames after splitting frames so that each frame has
|
||||
* consistent directionality. At this point the frames are still in logical
|
||||
* order
|
||||
*/
|
||||
void InitLogicalArray(nsIFrame* aCurrentFrame);
|
||||
void TraverseFrames(nsBlockFrame* aBlockFrame,
|
||||
nsBlockInFlowLineIterator* aLineIter,
|
||||
nsIFrame* aCurrentFrame);
|
||||
|
||||
/**
|
||||
* Initialize the logically-ordered array of frames
|
||||
|
@ -513,14 +513,20 @@ private:
|
|||
PRUint32 aSrcLength,
|
||||
PRUnichar* aDest);
|
||||
|
||||
nsAutoString mBuffer;
|
||||
nsString mBuffer;
|
||||
nsTArray<PRUnichar> mEmbeddingStack;
|
||||
nsTArray<nsIFrame*> mLogicalFrames;
|
||||
nsTArray<nsLineBox*> mLinePerFrame;
|
||||
nsTArray<nsIFrame*> mVisualFrames;
|
||||
nsDataHashtable<nsISupportsHashKey, PRInt32> mContentToFrameIndex;
|
||||
PRInt32 mArraySize;
|
||||
PRInt32* mIndexMap;
|
||||
PRUint8* mLevels;
|
||||
nsresult mSuccess;
|
||||
PRPackedBool mIsVisual;
|
||||
nsBidiLevel mParaLevel;
|
||||
nsIFrame* mPrevFrame;
|
||||
nsIContent* mPrevContent;
|
||||
|
||||
nsBidi* mBidiEngine;
|
||||
};
|
||||
|
|
|
@ -772,8 +772,10 @@ nsPresContext::GetUserPreferences()
|
|||
}
|
||||
|
||||
void
|
||||
nsPresContext::AppUnitsPerDevPixelChanged()
|
||||
nsPresContext::InvalidateThebesLayers()
|
||||
{
|
||||
if (!mShell)
|
||||
return;
|
||||
nsIFrame* rootFrame = mShell->FrameManager()->GetRootFrame();
|
||||
if (rootFrame) {
|
||||
// FrameLayerBuilder caches invalidation-related values that depend on the
|
||||
|
@ -781,6 +783,12 @@ nsPresContext::AppUnitsPerDevPixelChanged()
|
|||
// is completely flushed.
|
||||
FrameLayerBuilder::InvalidateThebesLayersInSubtree(rootFrame);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsPresContext::AppUnitsPerDevPixelChanged()
|
||||
{
|
||||
InvalidateThebesLayers();
|
||||
|
||||
mDeviceContext->FlushFontCache();
|
||||
|
||||
|
@ -868,6 +876,7 @@ nsPresContext::UpdateAfterPreferencesChanged()
|
|||
mShell->SetPreferenceStyleRules(PR_TRUE);
|
||||
}
|
||||
|
||||
InvalidateThebesLayers();
|
||||
mDeviceContext->FlushFontCache();
|
||||
|
||||
nsChangeHint hint = nsChangeHint(0);
|
||||
|
|
|
@ -1049,6 +1049,7 @@ protected:
|
|||
|
||||
NS_HIDDEN_(void) UpdateCharSet(const nsAFlatCString& aCharSet);
|
||||
|
||||
void InvalidateThebesLayers();
|
||||
void AppUnitsPerDevPixelChanged();
|
||||
|
||||
PRBool MayHavePaintEventListener();
|
||||
|
|
|
@ -332,6 +332,7 @@ _TEST_FILES += \
|
|||
test_bug588174.html \
|
||||
test_bug607529.html \
|
||||
file_bug607529.html \
|
||||
test_bug644768.html \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=644768
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 644768</title>
|
||||
<script type="text/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/WindowSnapshot.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body onload="test()">
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=644768">Mozilla Bug 644768</a>
|
||||
<p id="display"></p>
|
||||
<div id="content">
|
||||
<!-- test text is
|
||||
== زادروزها ==
|
||||
* [[۱۳۰۷]]
|
||||
-->
|
||||
<textarea id="testInput" dir="rtl" cols="80" rows="25">
|
||||
|
||||
== زادروزها ==
|
||||
* [[۱۳۰۷]]</textarea>
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
/** Test for Bug 644768 **/
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
function test() {
|
||||
var textInput = $("testInput");
|
||||
var s1, s2, equal, str1, str2;
|
||||
|
||||
textInput.focus();
|
||||
s1 = snapshotWindow(window);
|
||||
|
||||
synthesizeKey("VK_UP", { });
|
||||
synthesizeKey("VK_UP", { });
|
||||
synthesizeKey("VK_UP", { });
|
||||
synthesizeKey("VK_DELETE", { });
|
||||
synthesizeKey("VK_ENTER", { });
|
||||
s2 = snapshotWindow(window);
|
||||
|
||||
[equal, str1, str2] = compareSnapshots(s1, s2, true);
|
||||
ok(equal, "newline before bidi text shouldn't change direction: expected " +
|
||||
str1 + " but got " + str2);
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -71,13 +71,6 @@ EXPORTS = \
|
|||
nsObjectFrame.h \
|
||||
$(NULL)
|
||||
|
||||
ifdef IBMBIDI
|
||||
EXPORTS += \
|
||||
nsBidiFrames.h \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
|
||||
CPPSRCS = \
|
||||
nsAbsoluteContainingBlock.cpp \
|
||||
nsBRFrame.cpp \
|
||||
|
@ -126,12 +119,6 @@ CPPSRCS += \
|
|||
$(NULL)
|
||||
endif
|
||||
|
||||
ifdef IBMBIDI
|
||||
CPPSRCS += \
|
||||
nsBidiFrames.cpp \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
|
||||
CMMSRCS += \
|
||||
nsPluginUtilsOSX.mm \
|
||||
|
|
|
@ -73,6 +73,7 @@
|
|||
#include "nsNodeUtils.h"
|
||||
#include "mozAutoDocUpdate.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "nsHTMLFrameSetElement.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
|
@ -310,7 +311,7 @@ nsHTMLFramesetFrame::Init(nsIContent* aContent,
|
|||
nscolor borderColor = GetBorderColor();
|
||||
|
||||
// Get the rows= cols= data
|
||||
nsCOMPtr<nsIFrameSetElement> ourContent(do_QueryInterface(mContent));
|
||||
nsHTMLFrameSetElement* ourContent = nsHTMLFrameSetElement::FromContent(mContent);
|
||||
NS_ASSERTION(ourContent, "Someone gave us a broken frameset element!");
|
||||
const nsFramesetSpec* rowSpecs = nsnull;
|
||||
const nsFramesetSpec* colSpecs = nsnull;
|
||||
|
@ -989,7 +990,7 @@ nsHTMLFramesetFrame::Reflow(nsPresContext* aPresContext,
|
|||
height -= (mNumRows - 1) * borderWidth;
|
||||
if (height < 0) height = 0;
|
||||
|
||||
nsCOMPtr<nsIFrameSetElement> ourContent(do_QueryInterface(mContent));
|
||||
nsHTMLFrameSetElement* ourContent = nsHTMLFrameSetElement::FromContent(mContent);
|
||||
NS_ASSERTION(ourContent, "Someone gave us a broken frameset element!");
|
||||
const nsFramesetSpec* rowSpecs = nsnull;
|
||||
const nsFramesetSpec* colSpecs = nsnull;
|
||||
|
@ -1500,7 +1501,7 @@ nsHTMLFramesetFrame::MouseDrag(nsPresContext* aPresContext,
|
|||
if (change != 0) {
|
||||
// Recompute the specs from the new sizes.
|
||||
nscoord width = mRect.width - (mNumCols - 1) * GetBorderWidth(aPresContext, PR_TRUE);
|
||||
nsCOMPtr<nsIFrameSetElement> ourContent(do_QueryInterface(mContent));
|
||||
nsHTMLFrameSetElement* ourContent = nsHTMLFrameSetElement::FromContent(mContent);
|
||||
NS_ASSERTION(ourContent, "Someone gave us a broken frameset element!");
|
||||
const nsFramesetSpec* colSpecs = nsnull;
|
||||
ourContent->GetColSpec(&mNumCols, &colSpecs);
|
||||
|
@ -1523,7 +1524,7 @@ nsHTMLFramesetFrame::MouseDrag(nsPresContext* aPresContext,
|
|||
if (change != 0) {
|
||||
// Recompute the specs from the new sizes.
|
||||
nscoord height = mRect.height - (mNumRows - 1) * GetBorderWidth(aPresContext, PR_TRUE);
|
||||
nsCOMPtr<nsIFrameSetElement> ourContent(do_QueryInterface(mContent));
|
||||
nsHTMLFrameSetElement* ourContent = nsHTMLFrameSetElement::FromContent(mContent);
|
||||
NS_ASSERTION(ourContent, "Someone gave us a broken frameset element!");
|
||||
const nsFramesetSpec* rowSpecs = nsnull;
|
||||
ourContent->GetRowSpec(&mNumRows, &rowSpecs);
|
||||
|
|
|
@ -45,7 +45,6 @@
|
|||
#include "nsColor.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "nsWeakPtr.h"
|
||||
#include "nsIFrameSetElement.h"
|
||||
|
||||
class nsIContent;
|
||||
class nsIFrame;
|
||||
|
@ -61,6 +60,9 @@ class nsHTMLFramesetFrame;
|
|||
|
||||
#define NO_COLOR 0xFFFFFFFA
|
||||
|
||||
// defined at nsHTMLFrameSetElement.h
|
||||
struct nsFramesetSpec;
|
||||
|
||||
struct nsBorderColor
|
||||
{
|
||||
nscolor mLeft;
|
||||
|
|
|
@ -88,7 +88,6 @@ public:
|
|||
nsContainerFrame_id,
|
||||
nsContinuingTextFrame_id,
|
||||
nsDeckFrame_id,
|
||||
nsDirectionalFrame_id,
|
||||
nsDocElementBoxFrame_id,
|
||||
nsFieldSetFrame_id,
|
||||
nsFileControlFrame_id,
|
||||
|
|
|
@ -718,6 +718,11 @@ nsSubDocumentFrame::AttributeChanged(PRInt32 aNameSpaceID,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
if (mFrameLoader->GetRemoteBrowser()) {
|
||||
// TODO: Implement ContentShellAdded for remote browsers (bug 658304)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Note: This logic duplicates a lot of logic in
|
||||
// nsFrameLoader::EnsureDocShell. We should fix that.
|
||||
|
||||
|
|
|
@ -106,7 +106,6 @@
|
|||
#endif
|
||||
#include "nsAutoPtr.h"
|
||||
|
||||
#include "nsBidiFrames.h"
|
||||
#include "nsBidiPresUtils.h"
|
||||
#include "nsBidiUtils.h"
|
||||
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>br-as-bidi-paragraph-break</title>
|
||||
<meta charset="UTF-8">
|
||||
</head>
|
||||
<body>
|
||||
<p>א -->‎<br>--> ב</p>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,10 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>br-as-bidi-paragraph-break</title>
|
||||
<meta charset="UTF-8">
|
||||
</head>
|
||||
<body>
|
||||
<p>א --><br>--> ב</p>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,43 @@
|
|||
<DOCTYPE html>
|
||||
<html DIR=RTL>
|
||||
<head>
|
||||
<meta charset=UTF-8>
|
||||
<title>BIDI Layout Testing</title>
|
||||
</head>
|
||||
<body>
|
||||
<h2>This is a testing for BiDi layout issues.</h2>
|
||||
<br>
|
||||
|
||||
1 - No tag<br>
|
||||
2 - SPAN<br>
|
||||
3 - P<br>
|
||||
4 - DIV<br>
|
||||
|
||||
<br>
|
||||
<b>Test1: No space</b><br>
|
||||
This is a testing for BiDi layout issues.‏<br>
|
||||
<span>This is a testing for BiDi layout issues.‏<br></span>
|
||||
<p>This is a testing for BiDi layout issues.‏<br></p>
|
||||
<div>This is a testing for BiDi layout issues.‏<br></div>
|
||||
<br><br>
|
||||
<b>Test2: 3 spaces at the end</b><br>
|
||||
This is a testing for BiDi layout issues.‏ <br>
|
||||
<span>This is a testing for BiDi layout issues.‏ <br></span>
|
||||
|
||||
<p>This is a testing for BiDi layout issues.‏ <br></p>
|
||||
<div>This is a testing for BiDi layout issues.‏ <br></div>
|
||||
<br><br>
|
||||
<b>Test3: 3 spaces at the beginning</b><br>
|
||||
This is a testing for BiDi layout issues.‏<br>
|
||||
<span> This is a testing for BiDi layout issues.‏<br></span>
|
||||
<p> This is a testing for BiDi layout issues.‏<br></p>
|
||||
<div> This is a testing for BiDi layout issues.‏<br></div>
|
||||
<br><br>
|
||||
|
||||
<b>Test4: 3 spaces at the end and the beginning</b><br>
|
||||
This is a testing for BiDi layout issues.‏ <br>
|
||||
<span> This is a testing for BiDi layout issues.‏ <br></span>
|
||||
<p> This is a testing for BiDi layout issues.‏ <br></p>
|
||||
<div> This is a testing for BiDi layout issues.‏ <br></div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,43 @@
|
|||
<DOCTYPE html>
|
||||
<html DIR=RTL>
|
||||
<head>
|
||||
<meta charset=UTF-8>
|
||||
<title>BIDI Layout Testing</title>
|
||||
</head>
|
||||
<body>
|
||||
<h2>This is a testing for BiDi layout issues.</h2>
|
||||
<br>
|
||||
|
||||
1 - No tag<br>
|
||||
2 - SPAN<br>
|
||||
3 - P<br>
|
||||
4 - DIV<br>
|
||||
|
||||
<br>
|
||||
<b>Test1: No space</b><br>
|
||||
This is a testing for BiDi layout issues.<br>
|
||||
<span>This is a testing for BiDi layout issues.<br></span>
|
||||
<p>This is a testing for BiDi layout issues.<br></p>
|
||||
<div>This is a testing for BiDi layout issues.<br></div>
|
||||
<br><br>
|
||||
<b>Test2: 3 spaces at the end</b><br>
|
||||
This is a testing for BiDi layout issues. <br>
|
||||
<span>This is a testing for BiDi layout issues. <br></span>
|
||||
|
||||
<p>This is a testing for BiDi layout issues. <br></p>
|
||||
<div>This is a testing for BiDi layout issues. <br></div>
|
||||
<br><br>
|
||||
<b>Test3: 3 spaces at the beginning</b><br>
|
||||
This is a testing for BiDi layout issues.<br>
|
||||
<span> This is a testing for BiDi layout issues.<br></span>
|
||||
<p> This is a testing for BiDi layout issues.<br></p>
|
||||
<div> This is a testing for BiDi layout issues.<br></div>
|
||||
<br><br>
|
||||
|
||||
<b>Test4: 3 spaces at the end and the beginning</b><br>
|
||||
This is a testing for BiDi layout issues. <br>
|
||||
<span> This is a testing for BiDi layout issues. <br></span>
|
||||
<p> This is a testing for BiDi layout issues. <br></p>
|
||||
<div> This is a testing for BiDi layout issues. <br></div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,35 @@
|
|||
<DOCTYPE html>
|
||||
<!-- This tests that embeddings and overrides are preserved after <br> -->
|
||||
<html>
|
||||
<head>
|
||||
<meta charset=UTF-8>
|
||||
<title>Bug 229367</title>
|
||||
<style type="text/css">
|
||||
p { margin: 0; text-align: left; }
|
||||
p.er { unicode-bidi: embed; direction: rtl; }
|
||||
p.ol { unicode-bidi: bidi-override; direction: ltr; }
|
||||
p.or { unicode-bidi: bidi-override; direction: rtl; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<p>במה מדליקין,</p>
|
||||
<p>ובמה אין מדליקין?</p>
|
||||
<p class="er">אין מדליקין לא בלכש, </p>
|
||||
<p class="er">ולא בחוסן, </p>
|
||||
<p class="er">ולא בכלך, </p>
|
||||
<p class="er">ולא בפתילת האידן, </p>
|
||||
<p class="ol">ולא בפתילת המדבר, </p>
|
||||
<p class="ol">ולא בירוקה שעל פני המים. </p>
|
||||
<p class="ol">לא בזפת, </p>
|
||||
<p class="or">ולא בשעווה, </p>
|
||||
<p class="or">ולא בשמן קיק, </p>
|
||||
<p class="or">ולא בשמן שריפה, </p>
|
||||
<p class="or">ולא באליה, </p>
|
||||
<p class="ol">ולא בחלב. </p>
|
||||
<p class="ol">נחום המדי אומר, </p>
|
||||
<p class="er">מדליקין בחלב מבושל;</p>
|
||||
<p class="er">וחכמים אומרים, </p>
|
||||
<p>אחד מבושל ואחד שאינו מבושל,</p>
|
||||
<p>אין מדליקין בו.</p>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,30 @@
|
|||
<DOCTYPE html>
|
||||
<!-- This tests that embeddings and overrides are preserved after <br> -->
|
||||
<html>
|
||||
<head>
|
||||
<meta charset=UTF-8>
|
||||
<title>Bug 229367</title>
|
||||
</head>
|
||||
<body>
|
||||
<div>במה מדליקין,<br>
|
||||
ובמה אין מדליקין?<br>
|
||||
<span style="unicode-bidi: embed; direction: rtl">אין מדליקין לא בלכש, <br>
|
||||
ולא בחוסן, <br>
|
||||
ולא בכלך, <br>
|
||||
ולא בפתילת האידן, <br>
|
||||
<span style="unicode-bidi: bidi-override; direction: ltr">ולא בפתילת המדבר, <br>
|
||||
ולא בירוקה שעל פני המים. <br>
|
||||
לא בזפת, <br>
|
||||
<span style="unicode-bidi: bidi-override; direction: rtl">ולא בשעווה, <br>
|
||||
ולא בשמן קיק, <br>
|
||||
ולא בשמן שריפה, <br>
|
||||
ולא באליה, <br></span>
|
||||
ולא בחלב. <br>
|
||||
נחום המדי אומר, <br></span>
|
||||
מדליקין בחלב מבושל; <br>
|
||||
וחכמים אומרים, <br></span>
|
||||
אחד מבושל ואחד שאינו מבושל,<br>
|
||||
אין מדליקין בו.
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,11 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>preformatted-paragraph-break-as-bidi-paragraph-break</title>
|
||||
<meta charset="UTF-8">
|
||||
</head>
|
||||
<body>
|
||||
<pre>א -->‎
|
||||
--> ב</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,12 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>preformatted-paragraph-break-as-bidi-paragraph-break</title>
|
||||
<meta charset="UTF-8">
|
||||
</head>
|
||||
<body>
|
||||
<pre>א -->
|
||||
--> ב</pre>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>preformatted-paragraph-break-as-bidi-paragraph-break</title>
|
||||
<meta charset="UTF-8">
|
||||
<script type="text/javascript">
|
||||
|
||||
function boom()
|
||||
{
|
||||
document.getElementById("w").style.whiteSpace="pre";
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body onload="boom();">
|
||||
<pre id="w" style="white-space: normal">א -->
|
||||
--> ב</pre>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>preformatted-paragraph-break-as-bidi-paragraph-break</title>
|
||||
<meta charset="UTF-8">
|
||||
<script type="text/javascript">
|
||||
|
||||
function boom()
|
||||
{
|
||||
document.getElementById("w").style.whiteSpace="normal";
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body onload="boom();">
|
||||
<pre id="w">א -->
|
||||
--> ב</pre>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
<DOCTYPE html>
|
||||
<html DIR=RTL>
|
||||
<head>
|
||||
<meta charset=UTF-8>
|
||||
<title>BIDI Layout Testing</title>
|
||||
</head>
|
||||
<body>
|
||||
<div style="white-space: pre">
|
||||
<b>Test1: No space</b>
|
||||
This is a testing for BiDi layout issues. ‏
|
||||
<span>This is a testing for BiDi layout issues.‏
|
||||
</span>
|
||||
<p>This is a testing for BiDi layout issues.‏
|
||||
</p>
|
||||
<div>This is a testing for BiDi layout issues.‏
|
||||
</div>
|
||||
|
||||
<b>Test2: 3 spaces at the end</b>
|
||||
This is a testing for BiDi layout issues.‏
|
||||
<span>This is a testing for BiDi layout issues.‏
|
||||
</span>
|
||||
|
||||
<p>This is a testing for BiDi layout issues.‏
|
||||
</p>
|
||||
<div>This is a testing for BiDi layout issues.‏
|
||||
</div>
|
||||
|
||||
<b>Test3: 3 spaces at the beginning</b>
|
||||
This is a testing for BiDi layout issues.‏
|
||||
<span> This is a testing for BiDi layout issues.‏
|
||||
</span>
|
||||
<p> This is a testing for BiDi layout issues.‏
|
||||
</p>
|
||||
<div> This is a testing for BiDi layout issues.‏
|
||||
</div>
|
||||
|
||||
<b>Test4: 3 spaces at the end and the beginning</b>
|
||||
This is a testing for BiDi layout issues.‏
|
||||
<span> This is a testing for BiDi layout issues.‏
|
||||
</span>
|
||||
<p> This is a testing for BiDi layout issues.‏
|
||||
</p>
|
||||
<div> This is a testing for BiDi layout issues.‏
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,46 @@
|
|||
<DOCTYPE html>
|
||||
<html DIR=RTL>
|
||||
<head>
|
||||
<meta charset=UTF-8>
|
||||
<title>BIDI Layout Testing</title>
|
||||
</head>
|
||||
<body>
|
||||
<div style="white-space: pre">
|
||||
<b>Test1: No space</b>
|
||||
This is a testing for BiDi layout issues.
|
||||
<span>This is a testing for BiDi layout issues.
|
||||
</span>
|
||||
<p>This is a testing for BiDi layout issues.
|
||||
</p>
|
||||
<div>This is a testing for BiDi layout issues.</div>
|
||||
|
||||
<b>Test2: 3 spaces at the end</b>
|
||||
This is a testing for BiDi layout issues.
|
||||
<span>This is a testing for BiDi layout issues.
|
||||
</span>
|
||||
|
||||
<p>This is a testing for BiDi layout issues.
|
||||
</p>
|
||||
<div>This is a testing for BiDi layout issues.
|
||||
</div>
|
||||
|
||||
<b>Test3: 3 spaces at the beginning</b>
|
||||
This is a testing for BiDi layout issues.
|
||||
<span> This is a testing for BiDi layout issues.
|
||||
</span>
|
||||
<p> This is a testing for BiDi layout issues.
|
||||
</p>
|
||||
<div> This is a testing for BiDi layout issues.
|
||||
</div>
|
||||
|
||||
<b>Test4: 3 spaces at the end and the beginning</b>
|
||||
This is a testing for BiDi layout issues.
|
||||
<span> This is a testing for BiDi layout issues.
|
||||
</span>
|
||||
<p> This is a testing for BiDi layout issues.
|
||||
</p>
|
||||
<div> This is a testing for BiDi layout issues.
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,35 @@
|
|||
<DOCTYPE html>
|
||||
<!-- This tests that embeddings and overrides are preserved after <br> -->
|
||||
<html>
|
||||
<head>
|
||||
<meta charset=UTF-8>
|
||||
<title>Bug 263359</title>
|
||||
<style type="text/css">
|
||||
p { margin: 0; text-align: left; white-space: pre }
|
||||
p.er { direction: rtl; }
|
||||
p.ol { unicode-bidi: bidi-override; direction: ltr; }
|
||||
p.or { unicode-bidi: bidi-override; direction: rtl; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<p>במה מדליקין,</p>
|
||||
<p>ובמה אין מדליקין?</p>
|
||||
<p class="er">אין מדליקין לא בלכש,</p>
|
||||
<p class="er">ולא בחוסן,</p>
|
||||
<p class="er">ולא בכלך,</p>
|
||||
<p class="er">ולא בפתילת האידן,</p>
|
||||
<p class="ol">ולא בפתילת המדבר,</p>
|
||||
<p class="ol">ולא בירוקה שעל פני המים.</p>
|
||||
<p class="ol">לא בזפת,</p>
|
||||
<p class="or">ולא בשעווה,</p>
|
||||
<p class="or">ולא בשמן קיק,</p>
|
||||
<p class="or">ולא בשמן שריפה,</p>
|
||||
<p class="or">ולא באליה,</p>
|
||||
<p class="ol">ולא בחלב.</p>
|
||||
<p class="ol">נחום המדי אומר,</p>
|
||||
<p class="er">מדליקין בחלב מבושל;</p>
|
||||
<p class="er">וחכמים אומרים,</p>
|
||||
<p>אחד מבושל ואחד שאינו מבושל,</p>
|
||||
<p>אין מדליקין בו.</p>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,36 @@
|
|||
<DOCTYPE html>
|
||||
<!-- This tests that embeddings and overrides are preserved in <pre> -->
|
||||
<html>
|
||||
<head>
|
||||
<meta charset=UTF-8>
|
||||
<title>Bug 263359</title>
|
||||
<style type="text/css">
|
||||
p {
|
||||
white-space: pre;
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<p style="">במה מדליקין,
|
||||
ובמה אין מדליקין?
|
||||
<span dir="rtl">אין מדליקין לא בלכש,
|
||||
ולא בחוסן,
|
||||
ולא בכלך,
|
||||
ולא בפתילת האידן,
|
||||
<span style="unicode-bidi: bidi-override; direction: ltr">ולא בפתילת המדבר,
|
||||
ולא בירוקה שעל פני המים.
|
||||
לא בזפת,
|
||||
<span style="unicode-bidi: bidi-override; direction: rtl">ולא בשעווה,
|
||||
ולא בשמן קיק,
|
||||
ולא בשמן שריפה,
|
||||
ולא באליה, </span>
|
||||
ולא בחלב.
|
||||
נחום המדי אומר, </span>
|
||||
מדליקין בחלב מבושל;
|
||||
וחכמים אומרים, </span>
|
||||
אחד מבושל ואחד שאינו מבושל,
|
||||
אין מדליקין בו.
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,16 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>change direction of pre with bidi text</title>
|
||||
<meta charset="UTF-8">
|
||||
</head>
|
||||
<body>
|
||||
<pre dir="rtl"> can_be_executable=TRUE
|
||||
[he]description=סוג לא ידוע
|
||||
description=Unknown type
|
||||
[ar]description=نوع غير معروف
|
||||
[az]description=Namə'lum növ
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>change direction of pre with bidi text</title>
|
||||
<meta charset="UTF-8">
|
||||
<script type="text/javascript">
|
||||
|
||||
function boom()
|
||||
{
|
||||
document.getElementById("w").style.direction="rtl";
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body onload="boom();">
|
||||
<pre id="w"> can_be_executable=TRUE
|
||||
[he]description=סוג לא ידוע
|
||||
description=Unknown type
|
||||
[ar]description=نوع غير معروف
|
||||
[az]description=Namə'lum növ
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче