merge mozilla-inbound to mozilla-central a=merge

This commit is contained in:
Carsten "Tomcat" Book 2015-11-27 11:08:41 +01:00
commit 7ee93cdf5d
180 changed files with 4058 additions and 2501 deletions

View File

@ -2161,7 +2161,7 @@ void
DocAccessible::PutChildrenBack(nsTArray<RefPtr<Accessible> >* aChildren,
uint32_t aStartIdx)
{
nsTArray<Accessible*> containers;
nsTArray<RefPtr<Accessible> > containers;
for (auto idx = aStartIdx; idx < aChildren->Length(); idx++) {
Accessible* child = aChildren->ElementAt(idx);
@ -2198,7 +2198,11 @@ DocAccessible::PutChildrenBack(nsTArray<RefPtr<Accessible> >* aChildren,
// And put it back where it belongs to.
aChildren->RemoveElementsAt(aStartIdx, aChildren->Length() - aStartIdx);
for (uint32_t idx = 0; idx < containers.Length(); idx++) {
UpdateTreeOnInsertion(containers[idx]);
NS_ASSERTION(containers[idx]->IsInDocument(),
"A container has been destroyed.");
if (containers[idx]->IsInDocument()) {
UpdateTreeOnInsertion(containers[idx]);
}
}
}

View File

@ -646,20 +646,25 @@ var gHistorySwipeAnimation = {
this._canGoForward = this.canGoForward();
this._handleFastSwiping();
}
this.updateAnimation(0);
}
else {
this._startingIndex = gBrowser.webNavigation.sessionHistory.index;
this._historyIndex = this._startingIndex;
this._canGoBack = this.canGoBack();
this._canGoForward = this.canGoForward();
if (this.active) {
this._addBoxes();
this._takeSnapshot();
this._installPrevAndNextSnapshots();
this._lastSwipeDir = "";
// Get the session history from SessionStore.
let updateSessionHistory = sessionHistory => {
this._startingIndex = sessionHistory.index;
this._historyIndex = this._startingIndex;
this._canGoBack = this.canGoBack();
this._canGoForward = this.canGoForward();
if (this.active) {
this._addBoxes();
this._takeSnapshot();
this._installPrevAndNextSnapshots();
this._lastSwipeDir = "";
}
this.updateAnimation(0);
}
SessionStore.getSessionHistory(gBrowser.selectedTab, updateSessionHistory);
}
this.updateAnimation(0);
},
/**
@ -667,7 +672,7 @@ var gHistorySwipeAnimation = {
*/
stopAnimation: function HSA_stopAnimation() {
gHistorySwipeAnimation._removeBoxes();
this._historyIndex = gBrowser.webNavigation.sessionHistory.index;
this._historyIndex = this._getCurrentHistoryIndex();
},
/**
@ -726,6 +731,10 @@ var gHistorySwipeAnimation = {
}
},
_getCurrentHistoryIndex: function() {
return SessionStore.getSessionHistory(gBrowser.selectedTab).index;
},
/**
* Event handler for events relevant to the history swipe animation.
*
@ -821,10 +830,14 @@ var gHistorySwipeAnimation = {
* any. This will also result in the animation overlay to be torn down.
*/
swipeEndEventReceived: function HSA_swipeEndEventReceived() {
if (this._lastSwipeDir != "" && this._historyIndex != this._startingIndex)
this._navigateToHistoryIndex();
else
this.stopAnimation();
// Update the session history before continuing.
let updateSessionHistory = sessionHistory => {
if (this._lastSwipeDir != "" && this._historyIndex != this._startingIndex)
this._navigateToHistoryIndex();
else
this.stopAnimation();
}
SessionStore.getSessionHistory(gBrowser.selectedTab, updateSessionHistory);
},
/**
@ -836,7 +849,7 @@ var gHistorySwipeAnimation = {
*/
_doesIndexExistInHistory: function HSA__doesIndexExistInHistory(aIndex) {
try {
gBrowser.webNavigation.sessionHistory.getEntryAtIndex(aIndex, false);
return SessionStore.getSessionHistory(gBrowser.selectedTab).entries[aIndex] != null;
}
catch(ex) {
return false;
@ -959,11 +972,7 @@ var gHistorySwipeAnimation = {
* @return true if we're ready to take snapshots, false otherwise.
*/
_readyToTakeSnapshots: function HSA__readyToTakeSnapshots() {
if ((this._maxSnapshots < 1) ||
(gBrowser.webNavigation.sessionHistory.index < 0)) {
return false;
}
return true;
return (this._maxSnapshots >= 1 && this._getCurrentHistoryIndex() >= 0);
},
/**
@ -1026,7 +1035,7 @@ var gHistorySwipeAnimation = {
_assignSnapshotToCurrentBrowser:
function HSA__assignSnapshotToCurrentBrowser(aCanvas) {
let browser = gBrowser.selectedBrowser;
let currIndex = browser.webNavigation.sessionHistory.index;
let currIndex = this._getCurrentHistoryIndex();
this._removeTrackedSnapshot(currIndex, browser);
this._addSnapshotRefToArray(currIndex, browser);
@ -1059,7 +1068,7 @@ var gHistorySwipeAnimation = {
try {
let browser = gBrowser.selectedBrowser;
let snapshots = browser.snapshots;
let currIndex = browser.webNavigation.sessionHistory.index;
let currIndex = _getCurrentHistoryIndex();
// Kick off snapshot compression.
let canvas = snapshots[currIndex].image;

View File

@ -3377,7 +3377,7 @@ var E10SUINotification = {
var E10SAccessibilityCheck = {
init: function() {
Services.obs.addObserver(this, "a11y-init-or-shutdown", true);
if (Services.appinfo.accessibilityIsBlacklistedForE10S) {
if (Services.appinfo.accessibilityEnabled) {
this._showE10sAccessibilityWarning();
}
},
@ -3386,8 +3386,7 @@ var E10SAccessibilityCheck = {
observe: function(subject, topic, data) {
if (topic == "a11y-init-or-shutdown"
&& data == "1" &&
Services.appinfo.accessibilityIsBlacklistedForE10S) {
&& data == "1") {
this._showE10sAccessibilityWarning();
}
},

View File

@ -324,8 +324,6 @@ if test -n "$gonkdir" ; then
else
if test "$COMPILE_ENVIRONMENT"; then
MOZ_ANDROID_NDK
else
AC_DEFINE(ANDROID)
fi # COMPILE_ENVIRONMENT
case "$target" in
@ -335,6 +333,7 @@ else
fi
MOZ_CHROME_FILE_FORMAT=omni
ZLIB_DIR=yes
AC_DEFINE(ANDROID)
;;
*-linux*)
AC_PATH_PROG(OBJCOPY,objcopy)
@ -4218,6 +4217,7 @@ cairo-uikit)
CXXFLAGS="$CXXFLAGS $TK_CFLAGS"
MOZ_USER_DIR="Mozilla"
MOZ_FS_LAYOUT=bundle
AC_DEFINE(MOZ_SINGLE_PROCESS_APZ)
;;
cairo-android)
@ -4801,8 +4801,11 @@ MOZ_ARG_ENABLE_BOOL(android-apz,
MOZ_ANDROID_APZ=1,
MOZ_ANDROID_APZ=)
if test -n "$MOZ_ANDROID_APZ"; then
dnl Do this if defined in confvars.sh
AC_DEFINE(MOZ_ANDROID_APZ)
dnl Do this if defined in confvars.sh
AC_DEFINE(MOZ_ANDROID_APZ)
if test -z "$MOZ_B2GDROID"; then
AC_DEFINE(MOZ_SINGLE_PROCESS_APZ)
fi
fi
dnl ========================================================

View File

@ -829,7 +829,7 @@ var gDevToolsBrowser = {
broadcaster.removeAttribute("key");
}
let tabContainer = win.document.getElementById("tabbrowser-tabs");
let tabContainer = win.gBrowser.tabContainer;
tabContainer.addEventListener("TabSelect", this, false);
tabContainer.addEventListener("TabOpen", this, false);
tabContainer.addEventListener("TabClose", this, false);
@ -1024,20 +1024,17 @@ var gDevToolsBrowser = {
}
}
let mp = doc.getElementById("menuWebDeveloperPopup");
if (mp) {
let ref;
let ref;
if (prevDef != null) {
let menuitem = doc.getElementById("menuitem_" + prevDef.id);
ref = menuitem && menuitem.nextSibling ? menuitem.nextSibling : null;
} else {
ref = doc.getElementById("menu_devtools_separator");
}
if (prevDef) {
let menuitem = doc.getElementById("menuitem_" + prevDef.id);
ref = menuitem && menuitem.nextSibling ? menuitem.nextSibling : null;
} else {
ref = doc.getElementById("menu_devtools_separator");
}
if (ref) {
mp.insertBefore(elements.menuitem, ref);
}
if (ref) {
ref.parentNode.insertBefore(elements.menuitem, ref);
}
}
@ -1087,15 +1084,15 @@ var gDevToolsBrowser = {
let mbs = doc.getElementById("mainBroadcasterSet");
mbs.appendChild(fragBroadcasters);
let amp = doc.getElementById("appmenu_webDeveloper_popup");
if (amp) {
let amps = doc.getElementById("appmenu_devtools_separator");
amp.insertBefore(fragAppMenuItems, amps);
let amps = doc.getElementById("appmenu_devtools_separator");
if (amps) {
amps.parentNode.insertBefore(fragAppMenuItems, amps);
}
let mp = doc.getElementById("menuWebDeveloperPopup");
let mps = doc.getElementById("menu_devtools_separator");
mp.insertBefore(fragMenuItems, mps);
if (mps) {
mps.parentNode.insertBefore(fragMenuItems, mps);
}
},
/**
@ -1256,7 +1253,7 @@ var gDevToolsBrowser = {
}
}
let tabContainer = win.document.getElementById("tabbrowser-tabs");
let tabContainer = win.gBrowser.tabContainer;
tabContainer.removeEventListener("TabSelect", this, false);
tabContainer.removeEventListener("TabOpen", this, false);
tabContainer.removeEventListener("TabClose", this, false);
@ -1275,7 +1272,7 @@ var gDevToolsBrowser = {
for (let win of this._trackedBrowserWindows) {
let tabContainer = win.gBrowser.tabContainer;
let numPinnedTabs = tabContainer.tabbrowser._numPinnedTabs;
let numPinnedTabs = win.gBrowser._numPinnedTabs || 0;
let numTabs = tabContainer.itemCount - numPinnedTabs;
open += numTabs;

View File

@ -1089,6 +1089,10 @@ TabActor.prototype = {
},
onListWorkers: function BTA_onListWorkers(aRequest) {
if (!this.attached) {
return { error: "wrongState" };
}
if (this._workerActorList === null) {
this._workerActorList = new WorkerActorList({
type: Ci.nsIWorkerDebugger.TYPE_DEDICATED,

View File

@ -146,6 +146,7 @@ function WorkerActorList(options) {
WorkerActorList.prototype = {
getList: function () {
// Create a set of debuggers.
let dbgs = new Set();
let e = wdm.getWorkerDebuggerEnumerator();
while (e.hasMoreElements()) {
@ -155,12 +156,14 @@ WorkerActorList.prototype = {
}
}
// Delete each actor for which we don't have a debugger.
for (let [dbg, ] of this._actors) {
if (!dbgs.has(dbg)) {
this._actors.delete(dbg);
}
}
// Create an actor for each debugger for which we don't have one.
for (let dbg of dbgs) {
if (!this._actors.has(dbg)) {
this._actors.set(dbg, new WorkerActor(dbg));
@ -172,8 +175,12 @@ WorkerActorList.prototype = {
actors.push(actor);
}
this._mustNotify = true;
this._checkListening();
if (!this._mustNotify) {
if (this._onListChanged !== null) {
wdm.addListener(this);
}
this._mustNotify = true;
}
return Promise.resolve(actors);
},
@ -187,23 +194,24 @@ WorkerActorList.prototype = {
throw new Error("onListChanged must be either a function or null.");
}
this._onListChanged = onListChanged;
this._checkListening();
},
_checkListening: function () {
if (this._onListChanged !== null && this._mustNotify) {
wdm.addListener(this);
} else {
wdm.removeListener(this);
if (this._mustNotify) {
if (this._onListChanged === null && onListChanged !== null) {
wdm.addListener(this);
}
if (this._onListChanged !== null && onListChanged === null) {
wdm.removeListener(this);
}
}
this._onListChanged = onListChanged;
},
_notifyListChanged: function () {
if (this._mustNotify) {
this._onListChanged();
this._mustNotify = false;
}
this._onListChanged();
if (this._onListChanged !== null) {
wdm.removeListener(this);
}
this._mustNotify = false;
},
onRegister: function (dbg) {

View File

@ -7658,9 +7658,11 @@ nsContentUtils::ToWidgetPoint(const CSSPoint& aPoint,
const nsPoint& aOffset,
nsPresContext* aPresContext)
{
return LayoutDeviceIntPoint::FromAppUnitsRounded(
CSSPoint::ToAppUnits(aPoint) + aOffset,
aPresContext->AppUnitsPerDevPixel());
nsPoint point = CSSPoint::ToAppUnits(aPoint) + aOffset;
#if defined(MOZ_SINGLE_PROCESS_APZ)
point = point.ApplyResolution(aPresContext->PresShell()->GetCumulativeScaleResolution());
#endif
return LayoutDeviceIntPoint::FromAppUnitsRounded(point, aPresContext->AppUnitsPerDevPixel());
}
nsView*

View File

@ -225,6 +225,7 @@
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/dom/NavigatorBinding.h"
#include "mozilla/dom/ImageBitmap.h"
#include "mozilla/dom/ServiceWorkerRegistration.h"
#ifdef HAVE_SIDEBAR
#include "mozilla/dom/ExternalBinding.h"
#endif
@ -1576,6 +1577,8 @@ nsGlobalWindow::CleanUp()
}
DisableTimeChangeNotifications();
mServiceWorkerRegistrationTable.Clear();
}
void
@ -1788,6 +1791,8 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsGlobalWindow)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPerformance)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mServiceWorkerRegistrationTable)
#ifdef MOZ_WEBSPEECH
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSpeechSynthesis)
#endif
@ -1859,6 +1864,8 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsGlobalWindow)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mPerformance)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mServiceWorkerRegistrationTable)
#ifdef MOZ_WEBSPEECH
NS_IMPL_CYCLE_COLLECTION_UNLINK(mSpeechSynthesis)
#endif
@ -10232,6 +10239,24 @@ nsGlobalWindow::GetCaches(ErrorResult& aRv)
return ref.forget();
}
already_AddRefed<ServiceWorkerRegistrationMainThread>
nsPIDOMWindow::GetServiceWorkerRegistration(const nsAString& aScope)
{
RefPtr<ServiceWorkerRegistrationMainThread> registration;
if (!mServiceWorkerRegistrationTable.Get(aScope,
getter_AddRefs(registration))) {
registration = new ServiceWorkerRegistrationMainThread(this, aScope);
mServiceWorkerRegistrationTable.Put(aScope, registration);
}
return registration.forget();
}
void
nsPIDOMWindow::InvalidateServiceWorkerRegistration(const nsAString& aScope)
{
mServiceWorkerRegistrationTable.Remove(aScope);
}
void
nsGlobalWindow::FireOfflineStatusEventIfChanged()
{

View File

@ -15,6 +15,7 @@
#include "nsTArray.h"
#include "mozilla/dom/EventTarget.h"
#include "js/TypeDecls.h"
#include "nsRefPtrHashtable.h"
#define DOM_WINDOW_DESTROYED_TOPIC "dom-window-destroyed"
#define DOM_WINDOW_FROZEN_TOPIC "dom-window-frozen"
@ -37,6 +38,7 @@ namespace mozilla {
namespace dom {
class AudioContext;
class Element;
class ServiceWorkerRegistrationMainThread;
} // namespace dom
namespace gfx {
class VRHMDInfo;
@ -218,6 +220,10 @@ public:
return mServiceWorkersTestingEnabled;
}
already_AddRefed<mozilla::dom::ServiceWorkerRegistrationMainThread>
GetServiceWorkerRegistration(const nsAString& aScope);
void InvalidateServiceWorkerRegistration(const nsAString& aScope);
protected:
// Lazily instantiate an about:blank document if necessary, and if
// we have what it takes to do so.
@ -855,6 +861,11 @@ protected:
// mPerformance is only used on inner windows.
RefPtr<nsPerformance> mPerformance;
typedef nsRefPtrHashtable<nsStringHashKey,
mozilla::dom::ServiceWorkerRegistrationMainThread>
ServiceWorkerRegistrationTable;
ServiceWorkerRegistrationTable mServiceWorkerRegistrationTable;
uint32_t mModalStateDepth;
// These variables are only used on inner windows.

View File

@ -969,6 +969,11 @@ nsScriptLoader::ProcessRequest(nsScriptLoadRequest* aRequest)
// The window may have gone away by this point, in which case there's no point
// in trying to run the script.
nsCOMPtr<nsIDocument> master = mDocument->MasterDocument();
{
// Try to perform a microtask checkpoint
nsAutoMicroTask mt;
}
nsPIDOMWindow *pwin = master->GetInnerWindow();
bool runScript = !!pwin;
if (runScript) {

View File

@ -677,6 +677,7 @@ skip-if = os == "mac" # fails intermittently - bug 1101288
[test_bug761120.html]
[test_bug782342.html]
[test_bug787778.html]
[test_bug789315.html]
[test_bug789856.html]
[test_bug804395.html]
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #bug 901343, specialpowers.wrap issue createsystemxhr

View File

@ -0,0 +1,49 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=789315
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 789315</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="text/javascript">
(function() {
const observerConfig = {
childList: true,
};
var observer = new MutationObserver(onMutations);
observer.observe(document.head, observerConfig);
function onMutations(mutations) {
for (var i in mutations) {
var mutation = mutations[i];
for (var j in mutation.addedNodes) {
var addedNode = mutation.addedNodes[j];
addedNode.mutationObserverHasNotified = true;
}
}
}
})();
</script>
<link id="testnode" rel="localization" href="dummy"></link>
<script type="text/javascript">
var testNode = document.getElementById("testnode");
ok(testNode.mutationObserverHasNotified);
</script>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=789315">Mozilla Bug 789315</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
</pre>
</body>
</html>

View File

@ -927,19 +927,22 @@ Event::GetScreenCoords(nsPresContext* aPresContext,
// Doing a straight conversion from LayoutDeviceIntPoint to CSSIntPoint
// seem incorrect, but it is needed to maintain legacy functionality.
if (!aPresContext) {
WidgetGUIEvent* guiEvent = aEvent->AsGUIEvent();
if (!aPresContext || !(guiEvent && guiEvent->widget)) {
return CSSIntPoint(aPoint.x, aPoint.y);
}
LayoutDeviceIntPoint offset = aPoint;
WidgetGUIEvent* guiEvent = aEvent->AsGUIEvent();
if (guiEvent && guiEvent->widget) {
offset += guiEvent->widget->WidgetToScreenOffset();
}
nsPoint pt =
LayoutDevicePixel::ToAppUnits(offset, aPresContext->DeviceContext()->AppUnitsPerDevPixelAtUnitFullZoom());
LayoutDevicePixel::ToAppUnits(aPoint, aPresContext->DeviceContext()->AppUnitsPerDevPixelAtUnitFullZoom());
#if defined(MOZ_SINGLE_PROCESS_APZ)
if (aPresContext->PresShell()) {
pt = pt.RemoveResolution(aPresContext->PresShell()->GetCumulativeScaleResolution());
}
#endif
pt += LayoutDevicePixel::ToAppUnits(guiEvent->widget->WidgetToScreenOffset(),
aPresContext->DeviceContext()->AppUnitsPerDevPixelAtUnitFullZoom());
return CSSPixel::FromAppUnitsRounded(pt);
}

View File

@ -21,11 +21,19 @@ interface nsIServiceWorkerUnregisterCallback : nsISupports
void unregisterFailed();
};
[scriptable, builtinclass, uuid(1a1e71dd-0f78-4e2e-a2db-a946fe02cddf)]
interface nsIWorkerDebugger;
[scriptable, builtinclass, uuid(76e357ed-208d-4e4c-9165-1c4059707879)]
interface nsIServiceWorkerInfo : nsISupports
{
readonly attribute DOMString scriptSpec;
readonly attribute DOMString cacheName;
readonly attribute nsIWorkerDebugger debugger;
void attachDebugger();
void detachDebugger();
};
[scriptable, uuid(87e63548-d440-4b8a-b158-65ad1de0211E)]

View File

@ -2807,22 +2807,20 @@ ContentChild::RecvOnAppThemeChanged()
}
bool
ContentChild::RecvStartProfiler(const uint32_t& aEntries,
const double& aInterval,
nsTArray<nsCString>&& aFeatures,
nsTArray<nsCString>&& aThreadNameFilters)
ContentChild::RecvStartProfiler(const ProfilerInitParams& params)
{
nsTArray<const char*> featureArray;
for (size_t i = 0; i < aFeatures.Length(); ++i) {
featureArray.AppendElement(aFeatures[i].get());
for (size_t i = 0; i < params.features().Length(); ++i) {
featureArray.AppendElement(params.features()[i].get());
}
nsTArray<const char*> threadNameFilterArray;
for (size_t i = 0; i < aThreadNameFilters.Length(); ++i) {
threadNameFilterArray.AppendElement(aThreadNameFilters[i].get());
for (size_t i = 0; i < params.threadFilters().Length(); ++i) {
threadNameFilterArray.AppendElement(params.threadFilters()[i].get());
}
profiler_start(aEntries, aInterval, featureArray.Elements(), featureArray.Length(),
profiler_start(params.entries(), params.interval(),
featureArray.Elements(), featureArray.Length(),
threadNameFilterArray.Elements(), threadNameFilterArray.Length());
return true;

View File

@ -424,10 +424,7 @@ public:
const bool& aResult) override;
virtual bool RecvUpdateWindow(const uintptr_t& aChildId) override;
virtual bool RecvStartProfiler(const uint32_t& aEntries,
const double& aInterval,
nsTArray<nsCString>&& aFeatures,
nsTArray<nsCString>&& aThreadNameFilters) override;
virtual bool RecvStartProfiler(const ProfilerInitParams& params) override;
virtual bool RecvPauseProfiler(const bool& aPause) override;
virtual bool RecvStopProfiler() override;
virtual bool RecvGatherProfile() override;

View File

@ -1557,6 +1557,21 @@ ContentParent::Init()
Unused << SendActivateA11y();
}
#endif
#ifdef MOZ_ENABLE_PROFILER_SPS
nsCOMPtr<nsIProfiler> profiler(do_GetService("@mozilla.org/tools/profiler;1"));
bool profilerActive = false;
DebugOnly<nsresult> rv = profiler->IsActive(&profilerActive);
MOZ_ASSERT(NS_SUCCEEDED(rv));
if (profilerActive) {
nsCOMPtr<nsIProfilerStartParams> currentProfilerParams;
rv = profiler->GetStartParams(getter_AddRefs(currentProfilerParams));
MOZ_ASSERT(NS_SUCCEEDED(rv));
StartProfiler(currentProfilerParams);
}
#endif
}
void
@ -3275,13 +3290,7 @@ ContentParent::Observe(nsISupports* aSubject,
#ifdef MOZ_ENABLE_PROFILER_SPS
else if (!strcmp(aTopic, "profiler-started")) {
nsCOMPtr<nsIProfilerStartParams> params(do_QueryInterface(aSubject));
uint32_t entries;
double interval;
params->GetEntries(&entries);
params->GetInterval(&interval);
const nsTArray<nsCString>& features = params->GetFeatures();
const nsTArray<nsCString>& threadFilterNames = params->GetThreadFilterNames();
Unused << SendStartProfiler(entries, interval, features, threadFilterNames);
StartProfiler(params);
}
else if (!strcmp(aTopic, "profiler-stopped")) {
Unused << SendStopProfiler();
@ -5709,6 +5718,24 @@ ContentParent::RecvGetAndroidSystemInfo(AndroidSystemInfo* aInfo)
#endif
}
void
ContentParent::StartProfiler(nsIProfilerStartParams* aParams)
{
if (NS_WARN_IF(!aParams)) {
return;
}
ProfilerInitParams ipcParams;
ipcParams.enabled() = true;
aParams->GetEntries(&ipcParams.entries());
aParams->GetInterval(&ipcParams.interval());
ipcParams.features() = aParams->GetFeatures();
ipcParams.threadFilters() = aParams->GetThreadFilterNames();
Unused << SendStartProfiler(ipcParams);
}
} // namespace dom
} // namespace mozilla

View File

@ -935,6 +935,7 @@ private:
virtual bool RecvGamepadListenerRemoved() override;
virtual bool RecvProfile(const nsCString& aProfile) override;
virtual bool RecvGetGraphicsDeviceInitData(DeviceInitData* aOut) override;
void StartProfiler(nsIProfilerStartParams* aParams);
virtual bool RecvGetDeviceStorageLocation(const nsString& aType,
nsString* aPath) override;

View File

@ -65,6 +65,7 @@ include PBackgroundSharedTypes;
include PContentPermission;
include BrowserConfiguration;
include GraphicsMessages;
include ProfilerTypes;
// Workaround to prevent error if PContentChild.cpp & PContentBridgeParent.cpp
// are put into different UnifiedProtocolsXX.cpp files.
@ -651,8 +652,7 @@ child:
/**
* Control the Gecko Profiler in the child process.
*/
async StartProfiler(uint32_t aEntries, double aInterval, nsCString[] aFeatures,
nsCString[] aThreadNameFilters);
async StartProfiler(ProfilerInitParams params);
async StopProfiler();
async PauseProfiler(bool aPause);

View File

@ -18,6 +18,7 @@
#include "mozilla/PodOperations.h"
#include "mozilla/CDMCallbackProxy.h"
#include "MediaData.h"
#include "nsPrintfCString.h"
namespace mozilla {
@ -41,6 +42,7 @@ void
CDMProxy::Init(PromiseId aPromiseId,
const nsAString& aOrigin,
const nsAString& aTopLevelOrigin,
const nsAString& aGMPName,
bool aInPrivateBrowsing)
{
MOZ_ASSERT(NS_IsMainThread());
@ -68,10 +70,17 @@ CDMProxy::Init(PromiseId aPromiseId,
}
}
if (aGMPName.IsEmpty()) {
RejectPromise(aPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR,
nsPrintfCString("Unknown GMP for keysystem '%s'", NS_ConvertUTF16toUTF8(mKeySystem).get()));
return;
}
nsAutoPtr<InitData> data(new InitData());
data->mPromiseId = aPromiseId;
data->mOrigin = aOrigin;
data->mTopLevelOrigin = aTopLevelOrigin;
data->mGMPName = aGMPName;
data->mInPrivateBrowsing = aInPrivateBrowsing;
nsCOMPtr<nsIRunnable> task(
NS_NewRunnableMethodWithArg<nsAutoPtr<InitData>>(this,
@ -176,6 +185,7 @@ CDMProxy::gmp_Init(nsAutoPtr<InitData>&& aData)
new gmp_InitGetGMPDecryptorCallback(this, Move(aData)));
nsresult rv = mps->GetNodeId(data.mOrigin,
data.mTopLevelOrigin,
data.mGMPName,
data.mInPrivateBrowsing,
Move(callback));
if (NS_FAILED(rv)) {

View File

@ -57,6 +57,7 @@ public:
void Init(PromiseId aPromiseId,
const nsAString& aOrigin,
const nsAString& aTopLevelOrigin,
const nsAString& aGMPName,
bool aInPrivateBrowsing);
// Main thread only.
@ -186,6 +187,7 @@ private:
uint32_t mPromiseId;
nsAutoString mOrigin;
nsAutoString mTopLevelOrigin;
nsString mGMPName;
bool mInPrivateBrowsing;
};

View File

@ -141,4 +141,17 @@ CopyArrayBufferViewOrArrayBufferData(const dom::ArrayBufferViewOrArrayBuffer& aB
aOutData.AppendElements(data.mData, data.mLength);
}
nsString
KeySystemToGMPName(const nsAString& aKeySystem)
{
if (aKeySystem.EqualsLiteral("com.adobe.primetime")) {
return NS_LITERAL_STRING("gmp-eme-adobe");
}
if (aKeySystem.EqualsLiteral("org.w3.clearkey")) {
return NS_LITERAL_STRING("gmp-clearkey");
}
MOZ_ASSERT(false, "We should only call this for known GMPs");
return EmptyString();
}
} // namespace mozilla

View File

@ -104,6 +104,9 @@ struct ArrayData {
ArrayData
GetArrayBufferViewOrArrayBufferData(const dom::ArrayBufferViewOrArrayBuffer& aBufferOrView);
nsString
KeySystemToGMPName(const nsAString& aKeySystem);
} // namespace mozilla
#endif // EME_LOG_H_

View File

@ -443,6 +443,9 @@ GetSupportedConfig(mozIGeckoMediaPluginService* aGMPService,
for (const nsString& candidate : aCandidate.mInitDataTypes.Value()) {
if (candidate.EqualsLiteral("cenc")) {
initDataTypes.AppendElement(candidate);
} else if (candidate.EqualsLiteral("keyids") &&
aKeySystem.EqualsLiteral("org.w3.clearkey")) {
initDataTypes.AppendElement(candidate);
}
}
if (initDataTypes.IsEmpty()) {

View File

@ -368,6 +368,7 @@ MediaKeys::Init(ErrorResult& aRv)
mProxy->Init(mCreatePromiseId,
origin,
topLevelOrigin,
KeySystemToGMPName(mKeySystem),
inPrivateBrowsing);
return promise.forget();

View File

@ -1068,6 +1068,12 @@ GMPParent::Bridge(GMPServiceParent* aGMPServiceParent)
return true;
}
nsString
GMPParent::GetPluginBaseName() const
{
return NS_LITERAL_STRING("gmp-") + mName;
}
} // namespace gmp
} // namespace mozilla

View File

@ -124,6 +124,7 @@ public:
const nsCString& GetDisplayName() const;
const nsCString& GetVersion() const;
const uint32_t GetPluginId() const;
nsString GetPluginBaseName() const;
// Returns true if a plugin can be or is being used across multiple NodeIds.
bool CanBeSharedCrossNodeIds() const;

View File

@ -137,9 +137,11 @@ class GetNodeIdDone : public GetServiceChildCallback
{
public:
GetNodeIdDone(const nsAString& aOrigin, const nsAString& aTopLevelOrigin,
const nsAString& aGMPName,
bool aInPrivateBrowsing, UniquePtr<GetNodeIdCallback>&& aCallback)
: mOrigin(aOrigin),
mTopLevelOrigin(aTopLevelOrigin),
mGMPName(aGMPName),
mInPrivateBrowsing(aInPrivateBrowsing),
mCallback(Move(aCallback))
{
@ -154,6 +156,7 @@ public:
nsCString outId;
if (!aGMPServiceChild->SendGetGMPNodeId(mOrigin, mTopLevelOrigin,
mGMPName,
mInPrivateBrowsing, &outId)) {
mCallback->Done(NS_ERROR_FAILURE, EmptyCString());
return;
@ -165,6 +168,7 @@ public:
private:
nsString mOrigin;
nsString mTopLevelOrigin;
nsString mGMPName;
bool mInPrivateBrowsing;
UniquePtr<GetNodeIdCallback> mCallback;
};
@ -172,11 +176,12 @@ private:
NS_IMETHODIMP
GeckoMediaPluginServiceChild::GetNodeId(const nsAString& aOrigin,
const nsAString& aTopLevelOrigin,
const nsAString& aGMPName,
bool aInPrivateBrowsing,
UniquePtr<GetNodeIdCallback>&& aCallback)
{
UniquePtr<GetServiceChildCallback> callback(
new GetNodeIdDone(aOrigin, aTopLevelOrigin, aInPrivateBrowsing, Move(aCallback)));
new GetNodeIdDone(aOrigin, aTopLevelOrigin, aGMPName, aInPrivateBrowsing, Move(aCallback)));
GetServiceChild(Move(callback));
return NS_OK;
}

View File

@ -47,6 +47,7 @@ public:
nsACString& aOutVersion) override;
NS_IMETHOD GetNodeId(const nsAString& aOrigin,
const nsAString& aTopLevelOrigin,
const nsAString& aGMPName,
bool aInPrivateBrowsingMode,
UniquePtr<GetNodeIdCallback>&& aCallback) override;
NS_IMETHOD UpdateTrialCreateState(const nsAString& aKeySystem,

View File

@ -163,13 +163,13 @@ CloneAndAppend(nsIFile* aFile, const nsAString& aDir)
}
static void
MoveAndOverwrite(nsIFile* aOldStorageDir,
nsIFile* aNewStorageDir,
MoveAndOverwrite(nsIFile* aOldParentDir,
nsIFile* aNewParentDir,
const nsAString& aSubDir)
{
nsresult rv;
nsCOMPtr<nsIFile> srcDir(CloneAndAppend(aOldStorageDir, aSubDir));
nsCOMPtr<nsIFile> srcDir(CloneAndAppend(aOldParentDir, aSubDir));
if (NS_WARN_IF(!srcDir)) {
return;
}
@ -179,7 +179,13 @@ MoveAndOverwrite(nsIFile* aOldStorageDir,
return;
}
nsCOMPtr<nsIFile> dstDir(CloneAndAppend(aNewStorageDir, aSubDir));
// Ensure destination parent directory exists.
rv = aNewParentDir->Create(nsIFile::DIRECTORY_TYPE, 0700);
if (rv != NS_ERROR_FILE_ALREADY_EXISTS && NS_WARN_IF(NS_FAILED(rv))) {
return;
}
nsCOMPtr<nsIFile> dstDir(CloneAndAppend(aNewParentDir, aSubDir));
if (FileExists(dstDir)) {
// We must have migrated before already, and then ran an old version
// of Gecko again which created storage at the old location. Overwrite
@ -191,7 +197,7 @@ MoveAndOverwrite(nsIFile* aOldStorageDir,
}
}
rv = srcDir->MoveTo(aNewStorageDir, EmptyString());
rv = srcDir->MoveTo(aNewParentDir, EmptyString());
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}
@ -205,6 +211,21 @@ MigratePreGecko42StorageDir(nsIFile* aOldStorageDir,
MoveAndOverwrite(aOldStorageDir, aNewStorageDir, NS_LITERAL_STRING("storage"));
}
static void
MigratePreGecko45StorageDir(nsIFile* aStorageDirBase)
{
nsCOMPtr<nsIFile> adobeStorageDir(CloneAndAppend(aStorageDirBase, NS_LITERAL_STRING("gmp-eme-adobe")));
if (NS_WARN_IF(!adobeStorageDir)) {
return;
}
// The base storage dir in pre-45 contained "id" and "storage" subdirs.
// We assume all storage in the base storage dir that aren't known to GMP
// storage are records for the Adobe GMP.
MoveAndOverwrite(aStorageDirBase, adobeStorageDir, NS_LITERAL_STRING("id"));
MoveAndOverwrite(aStorageDirBase, adobeStorageDir, NS_LITERAL_STRING("storage"));
}
static nsresult
GMPPlatformString(nsAString& aOutPlatform)
{
@ -291,11 +312,19 @@ GeckoMediaPluginServiceParent::InitStorage()
return rv;
}
// Prior to 42, GMP storage was stored in $profile/gmp/. After 42, it's
// stored in $profile/gmp/$platform/. So we must migrate any old records
// Prior to 42, GMP storage was stored in $profileDir/gmp/. After 42, it's
// stored in $profileDir/gmp/$platform/. So we must migrate any old records
// from the old location to the new location, for forwards compatibility.
MigratePreGecko42StorageDir(gmpDirWithoutPlatform, mStorageBaseDir);
// Prior to 45, GMP storage was not separated by plugin. In 45 and after,
// it's stored in $profile/gmp/$platform/$gmpName. So we must migrate old
// records from the old location to the new location, for forwards
// compatibility. We assume all directories in the base storage dir that
// aren't known to GMP storage are records for the Adobe GMP, since it
// was first.
MigratePreGecko45StorageDir(mStorageBaseDir);
return GeckoMediaPluginService::Init();
}
@ -732,7 +761,7 @@ GeckoMediaPluginServiceParent::PathRunnable::Run()
mOperation == REMOVE_AND_DELETE_FROM_DISK,
mDefer);
}
#ifndef MOZ_WIDGET_GONK // Bug 1214967: disabled on B2G due to inscrutable test failures.
#ifndef MOZ_WIDGET_GONK // Bug 1214967: disabled on B2G due to inscrutable test failures.
// For e10s, we must fire a notification so that all ContentParents notify
// their children to update the codecs that the GMPDecoderModule can use.
NS_DispatchToMainThread(new NotifyObserversTask("gmp-changed"), NS_DISPATCH_NORMAL);
@ -1212,6 +1241,7 @@ GeckoMediaPluginServiceParent::IsPersistentStorageAllowed(const nsACString& aNod
nsresult
GeckoMediaPluginServiceParent::GetNodeId(const nsAString& aOrigin,
const nsAString& aTopLevelOrigin,
const nsAString& aGMPName,
bool aInPrivateBrowsing,
nsACString& aOutId)
{
@ -1244,11 +1274,12 @@ GeckoMediaPluginServiceParent::GetNodeId(const nsAString& aOrigin,
HashString(aTopLevelOrigin));
if (aInPrivateBrowsing) {
// For PB mode, we store the node id, indexed by the origin pair,
// so that if the same origin pair is opened in this session, it gets
// the same node id.
// For PB mode, we store the node id, indexed by the origin pair and GMP name,
// so that if the same origin pair is opened for the same GMP in this session,
// it gets the same node id.
const uint32_t pbHash = AddToHash(HashString(aGMPName), hash);
nsCString* salt = nullptr;
if (!(salt = mTempNodeIds.Get(hash))) {
if (!(salt = mTempNodeIds.Get(pbHash))) {
// No salt stored, generate and temporarily store some for this id.
nsAutoCString newSalt;
rv = GenerateRandomPathName(newSalt, NodeIdSaltLength);
@ -1256,7 +1287,7 @@ GeckoMediaPluginServiceParent::GetNodeId(const nsAString& aOrigin,
return rv;
}
salt = new nsCString(newSalt);
mTempNodeIds.Put(hash, salt);
mTempNodeIds.Put(pbHash, salt);
mPersistentStorageAllowed.Put(*salt, false);
}
aOutId = *salt;
@ -1265,18 +1296,29 @@ GeckoMediaPluginServiceParent::GetNodeId(const nsAString& aOrigin,
// Otherwise, try to see if we've previously generated and stored salt
// for this origin pair.
nsCOMPtr<nsIFile> path; // $profileDir/gmp/
nsCOMPtr<nsIFile> path; // $profileDir/gmp/$platform/
rv = GetStorageDir(getter_AddRefs(path));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = path->Append(aGMPName);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
// $profileDir/gmp/$platform/$gmpName/
rv = path->Create(nsIFile::DIRECTORY_TYPE, 0700);
if (rv != NS_ERROR_FILE_ALREADY_EXISTS && NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = path->AppendNative(NS_LITERAL_CSTRING("id"));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
// $profileDir/gmp/id/
// $profileDir/gmp/$platform/$gmpName/id/
rv = path->Create(nsIFile::DIRECTORY_TYPE, 0700);
if (rv != NS_ERROR_FILE_ALREADY_EXISTS && NS_WARN_IF(NS_FAILED(rv))) {
return rv;
@ -1285,7 +1327,7 @@ GeckoMediaPluginServiceParent::GetNodeId(const nsAString& aOrigin,
nsAutoCString hashStr;
hashStr.AppendInt((int64_t)hash);
// $profileDir/gmp/id/$hash
// $profileDir/gmp/$platform/$gmpName/id/$hash
rv = path->AppendNative(hashStr);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
@ -1322,13 +1364,13 @@ GeckoMediaPluginServiceParent::GetNodeId(const nsAString& aOrigin,
}
MOZ_ASSERT(salt.Length() == NodeIdSaltLength);
// $profileDir/gmp/id/$hash/salt
// $profileDir/gmp/$platform/$gmpName/id/$hash/salt
rv = WriteToFile(path, NS_LITERAL_CSTRING("salt"), salt);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
// $profileDir/gmp/id/$hash/origin
// $profileDir/gmp/$platform/$gmpName/id/$hash/origin
rv = WriteToFile(path,
NS_LITERAL_CSTRING("origin"),
NS_ConvertUTF16toUTF8(aOrigin));
@ -1336,7 +1378,7 @@ GeckoMediaPluginServiceParent::GetNodeId(const nsAString& aOrigin,
return rv;
}
// $profileDir/gmp/id/$hash/topLevelOrigin
// $profileDir/gmp/$platform/$gmpName/id/$hash/topLevelOrigin
rv = WriteToFile(path,
NS_LITERAL_CSTRING("topLevelOrigin"),
NS_ConvertUTF16toUTF8(aTopLevelOrigin));
@ -1360,11 +1402,12 @@ GeckoMediaPluginServiceParent::GetNodeId(const nsAString& aOrigin,
NS_IMETHODIMP
GeckoMediaPluginServiceParent::GetNodeId(const nsAString& aOrigin,
const nsAString& aTopLevelOrigin,
const nsAString& aGMPName,
bool aInPrivateBrowsing,
UniquePtr<GetNodeIdCallback>&& aCallback)
{
nsCString nodeId;
nsresult rv = GetNodeId(aOrigin, aTopLevelOrigin, aInPrivateBrowsing, nodeId);
nsresult rv = GetNodeId(aOrigin, aTopLevelOrigin, aGMPName, aInPrivateBrowsing, nodeId);
aCallback->Done(rv, nodeId);
return rv;
}
@ -1481,54 +1524,40 @@ private:
void
GeckoMediaPluginServiceParent::ClearNodeIdAndPlugin(DirectoryFilter& aFilter)
{
nsresult rv;
// $profileDir/gmp/$platform/
nsCOMPtr<nsIFile> path;
// $profileDir/gmp/
rv = GetStorageDir(getter_AddRefs(path));
nsresult rv = GetStorageDir(getter_AddRefs(path));
if (NS_FAILED(rv)) {
return;
}
// $profileDir/gmp/id/
rv = path->AppendNative(NS_LITERAL_CSTRING("id"));
if (NS_FAILED(rv)) {
// Iterate all sub-folders of $profileDir/gmp/$platform/, i.e. the dirs in which
// specific GMPs store their data.
DirectoryEnumerator iter(path, DirectoryEnumerator::DirsOnly);
for (nsCOMPtr<nsIFile> pluginDir; (pluginDir = iter.Next()) != nullptr;) {
ClearNodeIdAndPlugin(pluginDir, aFilter);
}
}
void
GeckoMediaPluginServiceParent::ClearNodeIdAndPlugin(nsIFile* aPluginStorageDir,
DirectoryFilter& aFilter)
{
// $profileDir/gmp/$platform/$gmpName/id/
nsCOMPtr<nsIFile> path = CloneAndAppend(aPluginStorageDir, NS_LITERAL_STRING("id"));
if (!path) {
return;
}
// Iterate all sub-folders of $profileDir/gmp/id/
nsCOMPtr<nsISimpleEnumerator> iter;
rv = path->GetDirectoryEntries(getter_AddRefs(iter));
if (NS_FAILED(rv)) {
return;
}
bool hasMore = false;
// Iterate all sub-folders of $profileDir/gmp/$platform/$gmpName/id/
nsTArray<nsCString> nodeIDsToClear;
while (NS_SUCCEEDED(iter->HasMoreElements(&hasMore)) && hasMore) {
nsCOMPtr<nsISupports> supports;
rv = iter->GetNext(getter_AddRefs(supports));
if (NS_FAILED(rv)) {
continue;
}
// $profileDir/gmp/id/$hash
nsCOMPtr<nsIFile> dirEntry(do_QueryInterface(supports, &rv));
if (NS_FAILED(rv)) {
continue;
}
// Skip non-directory files.
bool isDirectory = false;
rv = dirEntry->IsDirectory(&isDirectory);
if (NS_FAILED(rv) || !isDirectory) {
continue;
}
DirectoryEnumerator iter(path, DirectoryEnumerator::DirsOnly);
for (nsCOMPtr<nsIFile> dirEntry; (dirEntry = iter.Next()) != nullptr;) {
// dirEntry is the hash of origins, i.e.:
// $profileDir/gmp/$platform/$gmpName/id/$originHash/
if (!aFilter(dirEntry)) {
continue;
}
nsAutoCString salt;
if (NS_SUCCEEDED(ReadSalt(dirEntry, salt))) {
// Keep node IDs to clear data/plugins associated with them later.
@ -1542,28 +1571,23 @@ GeckoMediaPluginServiceParent::ClearNodeIdAndPlugin(DirectoryFilter& aFilter)
}
}
// Kill plugins that have node IDs to be cleared.
// Kill plugin instances that have node IDs being cleared.
KillPlugins(mPlugins, mMutex, NodeFilter(nodeIDsToClear));
// Clear all matching $profileDir/gmp/storage/$nodeId/
rv = GetStorageDir(getter_AddRefs(path));
if (NS_FAILED(rv)) {
// Clear all storage in $profileDir/gmp/$platform/$gmpName/storage/$nodeId/
path = CloneAndAppend(aPluginStorageDir, NS_LITERAL_STRING("storage"));
if (!path) {
return;
}
rv = path->AppendNative(NS_LITERAL_CSTRING("storage"));
if (NS_FAILED(rv)) {
return;
}
for (size_t i = 0; i < nodeIDsToClear.Length(); i++) {
for (const nsCString& nodeId : nodeIDsToClear) {
nsCOMPtr<nsIFile> dirEntry;
rv = path->Clone(getter_AddRefs(dirEntry));
nsresult rv = path->Clone(getter_AddRefs(dirEntry));
if (NS_FAILED(rv)) {
continue;
}
rv = dirEntry->AppendNative(nodeIDsToClear[i]);
rv = dirEntry->AppendNative(nodeId);
if (NS_FAILED(rv)) {
continue;
}
@ -1598,16 +1622,9 @@ GeckoMediaPluginServiceParent::ClearRecentHistoryOnGMPThread(PRTime aSince)
MOZ_ASSERT(NS_GetCurrentThread() == mGMPThread);
LOGD(("%s::%s: since=%lld", __CLASS__, __FUNCTION__, (int64_t)aSince));
nsCOMPtr<nsIFile> storagePath;
nsCOMPtr<nsIFile> temp;
if (NS_SUCCEEDED(GetStorageDir(getter_AddRefs(temp))) &&
NS_SUCCEEDED(temp->AppendNative(NS_LITERAL_CSTRING("storage")))) {
storagePath = temp.forget();
}
struct MTimeFilter : public DirectoryFilter {
explicit MTimeFilter(PRTime aSince, already_AddRefed<nsIFile> aPath)
: mSince(aSince), mStoragePath(aPath) {}
explicit MTimeFilter(PRTime aSince)
: mSince(aSince) {}
// Return true if any files under aPath is modified after |mSince|.
bool IsModifiedAfter(nsIFile* aPath) {
@ -1616,63 +1633,47 @@ GeckoMediaPluginServiceParent::ClearRecentHistoryOnGMPThread(PRTime aSince)
if (NS_SUCCEEDED(rv) && lastModified >= mSince) {
return true;
}
// Check sub-directories recursively
nsCOMPtr<nsISimpleEnumerator> iter;
rv = aPath->GetDirectoryEntries(getter_AddRefs(iter));
if (NS_FAILED(rv)) {
return false;
}
bool hasMore = false;
while (NS_SUCCEEDED(iter->HasMoreElements(&hasMore)) && hasMore) {
nsCOMPtr<nsISupports> supports;
rv = iter->GetNext(getter_AddRefs(supports));
if (NS_FAILED(rv)) {
continue;
}
nsCOMPtr<nsIFile> path(do_QueryInterface(supports, &rv));
if (NS_FAILED(rv)) {
continue;
}
if (IsModifiedAfter(path)) {
DirectoryEnumerator iter(aPath, DirectoryEnumerator::FilesAndDirs);
for (nsCOMPtr<nsIFile> dirEntry; (dirEntry = iter.Next()) != nullptr;) {
if (IsModifiedAfter(dirEntry)) {
return true;
}
}
return false;
}
// |aPath| is $profileDir/gmp/id/$hash
// |aPath| is $profileDir/gmp/$platform/$gmpName/id/$originHash/
virtual bool operator()(nsIFile* aPath) {
if (IsModifiedAfter(aPath)) {
return true;
}
nsAutoCString salt;
nsresult rv = ReadSalt(aPath, salt);
if (NS_FAILED(rv)) {
if (NS_FAILED(ReadSalt(aPath, salt))) {
return false;
}
// $profileDir/gmp/storage/
if (!mStoragePath) {
// $profileDir/gmp/$platform/$gmpName/id/
nsCOMPtr<nsIFile> idDir;
if (NS_FAILED(aPath->GetParent(getter_AddRefs(idDir)))) {
return false;
}
// $profileDir/gmp/storage/$nodeId/
nsCOMPtr<nsIFile> path;
rv = mStoragePath->Clone(getter_AddRefs(path));
if (NS_FAILED(rv)) {
// $profileDir/gmp/$platform/$gmpName/
nsCOMPtr<nsIFile> temp;
if (NS_FAILED(idDir->GetParent(getter_AddRefs(temp)))) {
return false;
}
rv = path->AppendNative(salt);
return NS_SUCCEEDED(rv) && IsModifiedAfter(path);
// $profileDir/gmp/$platform/$gmpName/storage/
if (NS_FAILED(temp->Append(NS_LITERAL_STRING("storage")))) {
return false;
}
// $profileDir/gmp/$platform/$gmpName/storage/$originSalt
return NS_SUCCEEDED(temp->AppendNative(salt)) && IsModifiedAfter(temp);
}
private:
const PRTime mSince;
const nsCOMPtr<nsIFile> mStoragePath;
} filter(aSince, storagePath.forget());
} filter(aSince);
ClearNodeIdAndPlugin(filter);
@ -1701,7 +1702,7 @@ GeckoMediaPluginServiceParent::ClearStorage()
// Kill plugins with valid nodeIDs.
KillPlugins(mPlugins, mMutex, &IsNodeIdValid);
nsCOMPtr<nsIFile> path; // $profileDir/gmp/
nsCOMPtr<nsIFile> path; // $profileDir/gmp/$platform/
nsresult rv = GetStorageDir(getter_AddRefs(path));
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
@ -1746,10 +1747,11 @@ GMPServiceParent::RecvLoadGMP(const nsCString& aNodeId,
bool
GMPServiceParent::RecvGetGMPNodeId(const nsString& aOrigin,
const nsString& aTopLevelOrigin,
const nsString& aGMPName,
const bool& aInPrivateBrowsing,
nsCString* aID)
{
nsresult rv = mService->GetNodeId(aOrigin, aTopLevelOrigin,
nsresult rv = mService->GetNodeId(aOrigin, aTopLevelOrigin, aGMPName,
aInPrivateBrowsing, *aID);
return NS_SUCCEEDED(rv);
}

View File

@ -41,6 +41,7 @@ public:
nsACString& aOutVersion) override;
NS_IMETHOD GetNodeId(const nsAString& aOrigin,
const nsAString& aTopLevelOrigin,
const nsAString& aGMPName,
bool aInPrivateBrowsingMode,
UniquePtr<GetNodeIdCallback>&& aCallback) override;
NS_IMETHOD UpdateTrialCreateState(const nsAString& aKeySystem,
@ -73,6 +74,7 @@ private:
size_t* aOutPluginIndex);
nsresult GetNodeId(const nsAString& aOrigin, const nsAString& aTopLevelOrigin,
const nsAString& aGMPName,
bool aInPrivateBrowsing, nsACString& aOutId);
void UnloadPlugins();
@ -95,7 +97,8 @@ private:
~DirectoryFilter() {}
};
void ClearNodeIdAndPlugin(DirectoryFilter& aFilter);
void ClearNodeIdAndPlugin(nsIFile* aPluginStorageDir,
DirectoryFilter& aFilter);
void ForgetThisSiteOnGMPThread(const nsACString& aOrigin);
void ClearRecentHistoryOnGMPThread(PRTime aSince);
@ -215,6 +218,7 @@ public:
uint32_t* aPluginId) override;
virtual bool RecvGetGMPNodeId(const nsString& aOrigin,
const nsString& aTopLevelOrigin,
const nsString& aGMPName,
const bool& aInPrivateBrowsing,
nsCString* aID) override;
static bool RecvGetGMPPluginVersionForAPI(const nsCString& aAPI,

View File

@ -32,10 +32,12 @@ extern LogModule* GetGMPLog();
namespace gmp {
// We store the records in files in the profile dir.
// $profileDir/gmp/storage/$nodeId/
// We store the records for a given GMP as files in the profile dir.
// $profileDir/gmp/$platform/$gmpName/storage/$nodeId/
static nsresult
GetGMPStorageDir(nsIFile** aTempDir, const nsCString& aNodeId)
GetGMPStorageDir(nsIFile** aTempDir,
const nsString& aGMPName,
const nsCString& aNodeId)
{
if (NS_WARN_IF(!aTempDir)) {
return NS_ERROR_INVALID_ARG;
@ -53,6 +55,16 @@ GetGMPStorageDir(nsIFile** aTempDir, const nsCString& aNodeId)
return rv;
}
rv = tmpFile->Append(aGMPName);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = tmpFile->Create(nsIFile::DIRECTORY_TYPE, 0700);
if (rv != NS_ERROR_FILE_ALREADY_EXISTS && NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = tmpFile->AppendNative(NS_LITERAL_CSTRING("storage"));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
@ -87,8 +99,10 @@ GetGMPStorageDir(nsIFile** aTempDir, const nsCString& aNodeId)
// record bytes (entire remainder of file)
class GMPDiskStorage : public GMPStorage {
public:
explicit GMPDiskStorage(const nsCString& aNodeId)
explicit GMPDiskStorage(const nsCString& aNodeId,
const nsString& aGMPName)
: mNodeId(aNodeId)
, mGMPName(aGMPName)
{
}
@ -106,29 +120,13 @@ public:
nsresult Init() {
// Build our index of records on disk.
nsCOMPtr<nsIFile> storageDir;
nsresult rv = GetGMPStorageDir(getter_AddRefs(storageDir), mNodeId);
nsresult rv = GetGMPStorageDir(getter_AddRefs(storageDir), mGMPName, mNodeId);
if (NS_WARN_IF(NS_FAILED(rv))) {
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsISimpleEnumerator> iter;
rv = storageDir->GetDirectoryEntries(getter_AddRefs(iter));
if (NS_FAILED(rv)) {
return NS_ERROR_FAILURE;
}
bool hasMore;
while (NS_SUCCEEDED(iter->HasMoreElements(&hasMore)) && hasMore) {
nsCOMPtr<nsISupports> supports;
rv = iter->GetNext(getter_AddRefs(supports));
if (NS_FAILED(rv)) {
continue;
}
nsCOMPtr<nsIFile> dirEntry(do_QueryInterface(supports, &rv));
if (NS_FAILED(rv)) {
continue;
}
DirectoryEnumerator iter(storageDir, DirectoryEnumerator::FilesAndDirs);
for (nsCOMPtr<nsIFile> dirEntry; (dirEntry = iter.Next()) != nullptr;) {
PRFileDesc* fd = nullptr;
if (NS_FAILED(dirEntry->OpenNSPRFileDesc(PR_RDONLY, 0, &fd))) {
continue;
@ -334,7 +332,7 @@ private:
nsString& aOutFilename)
{
nsCOMPtr<nsIFile> storageDir;
nsresult rv = GetGMPStorageDir(getter_AddRefs(storageDir), mNodeId);
nsresult rv = GetGMPStorageDir(getter_AddRefs(storageDir), mGMPName, mNodeId);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@ -379,7 +377,7 @@ private:
MOZ_ASSERT(aOutFD);
nsCOMPtr<nsIFile> f;
nsresult rv = GetGMPStorageDir(getter_AddRefs(f), mNodeId);
nsresult rv = GetGMPStorageDir(getter_AddRefs(f), mGMPName, mNodeId);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@ -456,7 +454,7 @@ private:
nsresult RemoveStorageFile(const nsString& aFilename)
{
nsCOMPtr<nsIFile> f;
nsresult rv = GetGMPStorageDir(getter_AddRefs(f), mNodeId);
nsresult rv = GetGMPStorageDir(getter_AddRefs(f), mGMPName, mNodeId);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@ -485,6 +483,7 @@ private:
// Hash record name to record data.
nsClassHashtable<nsCStringHashKey, Record> mRecords;
const nsAutoCString mNodeId;
const nsString mGMPName;
};
class GMPMemoryStorage : public GMPStorage {
@ -592,7 +591,8 @@ GMPStorageParent::Init()
return NS_ERROR_FAILURE;
}
if (persistent) {
UniquePtr<GMPDiskStorage> storage = MakeUnique<GMPDiskStorage>(mNodeId);
UniquePtr<GMPDiskStorage> storage =
MakeUnique<GMPDiskStorage>(mNodeId, mPlugin->GetPluginBaseName());
if (NS_FAILED(storage->Init())) {
NS_WARNING("Failed to initialize on disk GMP storage");
return NS_ERROR_FAILURE;

View File

@ -11,6 +11,7 @@
#include "nsLiteralString.h"
#include "nsCRTGlue.h"
#include "mozilla/Base64.h"
#include "nsISimpleEnumerator.h"
namespace mozilla {
@ -71,4 +72,41 @@ FileExists(nsIFile* aFile)
return aFile && NS_SUCCEEDED(aFile->Exists(&exists)) && exists;
}
DirectoryEnumerator::DirectoryEnumerator(nsIFile* aPath, Mode aMode)
: mMode(aMode)
{
aPath->GetDirectoryEntries(getter_AddRefs(mIter));
}
already_AddRefed<nsIFile>
DirectoryEnumerator::Next()
{
if (!mIter) {
return nullptr;
}
bool hasMore = false;
while (NS_SUCCEEDED(mIter->HasMoreElements(&hasMore)) && hasMore) {
nsCOMPtr<nsISupports> supports;
nsresult rv = mIter->GetNext(getter_AddRefs(supports));
if (NS_FAILED(rv)) {
continue;
}
nsCOMPtr<nsIFile> path(do_QueryInterface(supports, &rv));
if (NS_FAILED(rv)) {
continue;
}
if (mMode == DirsOnly) {
bool isDirectory = false;
rv = path->IsDirectory(&isDirectory);
if (NS_FAILED(rv) || !isDirectory) {
continue;
}
}
return path.forget();
}
return nullptr;
}
} // namespace mozilla

View File

@ -8,9 +8,11 @@
#include "mozilla/UniquePtr.h"
#include "nsTArray.h"
#include "nsCOMPtr.h"
class nsIFile;
class nsCString;
class nsISimpleEnumerator;
namespace mozilla {
@ -40,6 +42,24 @@ ToBase64(const nsTArray<uint8_t>& aBytes);
bool
FileExists(nsIFile* aFile);
// Enumerate directory entries for a specified path.
class DirectoryEnumerator {
public:
enum Mode {
DirsOnly, // Enumeration only includes directories.
FilesAndDirs // Enumeration includes directories and non-directory files.
};
DirectoryEnumerator(nsIFile* aPath, Mode aMode);
already_AddRefed<nsIFile> Next();
private:
Mode mMode;
nsCOMPtr<nsISimpleEnumerator> mIter;
};
} // namespace mozilla
#endif

View File

@ -19,6 +19,7 @@ parent:
ProcessId[] alreadyBridgedTo)
returns (ProcessId id, nsCString displayName, uint32_t pluginId);
sync GetGMPNodeId(nsString origin, nsString topLevelOrigin,
nsString gmpName,
bool inPrivateBrowsing)
returns (nsCString id);

View File

@ -52,7 +52,7 @@ native GetGMPVideoDecoderCallback(mozilla::UniquePtr<GetGMPVideoDecoderCallback>
native GetGMPVideoEncoderCallback(mozilla::UniquePtr<GetGMPVideoEncoderCallback>&&);
native GetNodeIdCallback(mozilla::UniquePtr<GetNodeIdCallback>&&);
[scriptable, uuid(661492d6-726b-4ba0-8e6e-14bfaf2b62e4)]
[scriptable, uuid(b5492915-2f0e-4973-9f91-a6fe61ac4749)]
interface mozIGeckoMediaPluginService : nsISupports
{
@ -145,6 +145,7 @@ interface mozIGeckoMediaPluginService : nsISupports
[noscript]
void getNodeId(in AString origin,
in AString topLevelOrigin,
in AString gmpName,
in bool inPrivateBrowsingMode,
in GetNodeIdCallback callback);

View File

@ -273,7 +273,7 @@ EnumerateDir(nsIFile* aPath, T&& aDirIter)
}
/**
* Enumerate files under $profileDir/gmp/$aDir/ (non-recursive).
* Enumerate files under $profileDir/gmp/$platform/gmp-fake/$aDir/ (non-recursive).
*/
template<typename T>
static nsresult
@ -283,14 +283,21 @@ EnumerateGMPStorageDir(const nsACString& aDir, T&& aDirIter)
GeckoMediaPluginServiceParent::GetSingleton();
MOZ_ASSERT(service);
// $profileDir/gmp/
// $profileDir/gmp/$platform/
nsCOMPtr<nsIFile> path;
nsresult rv = service->GetStorageDir(getter_AddRefs(path));
if (NS_FAILED(rv)) {
return rv;
}
// $profileDir/gmp/$aDir/
// $profileDir/gmp/$platform/gmp-fake/
rv = path->Append(NS_LITERAL_STRING("gmp-fake"));
if (NS_FAILED(rv)) {
return rv;
}
// $profileDir/gmp/$platform/gmp-fake/$aDir/
rv = path->AppendNative(aDir);
if (NS_FAILED(rv)) {
return rv;
@ -469,6 +476,7 @@ GetNodeId(const nsAString& aOrigin,
// GeckoMediaPluginServiceParent is synchronous.
nsresult rv = service->GetNodeId(aOrigin,
aTopLevelOrigin,
NS_LITERAL_STRING("gmp-fake"),
aInPBMode,
Move(callback));
EXPECT_TRUE(NS_SUCCEEDED(rv) && NS_SUCCEEDED(result));
@ -820,10 +828,10 @@ class GMPStorageTest : public GMPDecryptorProxyCallback
/**
* 1. Generate some storage data.
* 2. Find the max mtime |t| in $profileDir/gmp/id/.
* 2. Find the max mtime |t| in $profileDir/gmp/$platform/gmp-fake/id/.
* 3. Pass |t| to clear recent history.
* 4. Check if all directories in $profileDir/gmp/id/ and
* $profileDir/gmp/storage are removed.
* 4. Check if all directories in $profileDir/gmp/$platform/gmp-fake/id/ and
* $profileDir/gmp/$platform/gmp-fake/storage are removed.
*/
void TestClearRecentHistory1() {
AssertIsOnGMPThread();
@ -842,10 +850,10 @@ class GMPStorageTest : public GMPDecryptorProxyCallback
/**
* 1. Generate some storage data.
* 2. Find the max mtime |t| in $profileDir/gmp/storage/.
* 2. Find the max mtime |t| in $profileDir/gmp/$platform/gmp-fake/storage/.
* 3. Pass |t| to clear recent history.
* 4. Check if all directories in $profileDir/gmp/id/ and
* $profileDir/gmp/storage are removed.
* 4. Check if all directories in $profileDir/gmp/$platform/gmp-fake/id/ and
* $profileDir/gmp/$platform/gmp-fake/storage are removed.
*/
void TestClearRecentHistory2() {
AssertIsOnGMPThread();
@ -864,10 +872,10 @@ class GMPStorageTest : public GMPDecryptorProxyCallback
/**
* 1. Generate some storage data.
* 2. Find the max mtime |t| in $profileDir/gmp/storage/.
* 2. Find the max mtime |t| in $profileDir/gmp/$platform/gmp-fake/storage/.
* 3. Pass |t+1| to clear recent history.
* 4. Check if all directories in $profileDir/gmp/id/ and
* $profileDir/gmp/storage remain unchanged.
* 4. Check if all directories in $profileDir/gmp/$platform/gmp-fake/id/ and
* $profileDir/gmp/$platform/gmp-fake/storage remain unchanged.
*/
void TestClearRecentHistory3() {
AssertIsOnGMPThread();
@ -948,13 +956,13 @@ class GMPStorageTest : public GMPDecryptorProxyCallback
FileCounter c1;
nsresult rv = EnumerateGMPStorageDir(NS_LITERAL_CSTRING("id"), c1);
EXPECT_TRUE(NS_SUCCEEDED(rv));
// There should be no files under $profileDir/gmp/id/
// There should be no files under $profileDir/gmp/$platform/gmp-fake/id/
EXPECT_EQ(c1.GetCount(), 0);
FileCounter c2;
rv = EnumerateGMPStorageDir(NS_LITERAL_CSTRING("storage"), c2);
EXPECT_TRUE(NS_SUCCEEDED(rv));
// There should be no files under $profileDir/gmp/storage/
// There should be no files under $profileDir/gmp/$platform/gmp-fake/storage/
EXPECT_EQ(c2.GetCount(), 0);
SetFinished();
@ -964,13 +972,13 @@ class GMPStorageTest : public GMPDecryptorProxyCallback
FileCounter c1;
nsresult rv = EnumerateGMPStorageDir(NS_LITERAL_CSTRING("id"), c1);
EXPECT_TRUE(NS_SUCCEEDED(rv));
// There should be one directory under $profileDir/gmp/id/
// There should be one directory under $profileDir/gmp/$platform/gmp-fake/id/
EXPECT_EQ(c1.GetCount(), 1);
FileCounter c2;
rv = EnumerateGMPStorageDir(NS_LITERAL_CSTRING("storage"), c2);
EXPECT_TRUE(NS_SUCCEEDED(rv));
// There should be one directory under $profileDir/gmp/storage/
// There should be one directory under $profileDir/gmp/$platform/gmp-fake/storage/
EXPECT_EQ(c2.GetCount(), 1);
SetFinished();

View File

@ -619,6 +619,8 @@ skip-if = (os == 'win' && os_version == '5.1') || (os != 'win' && toolkit != 'go
[test_eme_session_callable_value.html]
[test_eme_canvas_blocked.html]
skip-if = toolkit == 'android' # bug 1149374
[test_eme_key_ids_initdata.html]
skip-if = toolkit == 'android' # bug 1149374
[test_eme_non_mse_fails.html]
skip-if = toolkit == 'android' # bug 1149374
[test_eme_request_notifications.html]

View File

@ -0,0 +1,111 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test Encrypted Media Extensions</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
<script type="text/javascript" src="manifest.js"></script>
<script type="text/javascript" src="eme.js"></script>
</head>
<body>
<pre id="test">
<script class="testbody" type="text/javascript">
var tests = [
{
name: "One keyId",
initData: '{"kids":["LwVHf8JLtPrv2GUXFW2v_A"]}',
expectedRequest: '{"kids":["LwVHf8JLtPrv2GUXFW2v_A"],"type":"temporary"}',
sessionType: 'temporary',
expectPass: true,
},
{
name: "Two keyIds",
initData: '{"kids":["LwVHf8JLtPrv2GUXFW2v_A", "0DdtU9od-Bh5L3xbv0Xf_A"]}',
expectedRequest: '{"kids":["LwVHf8JLtPrv2GUXFW2v_A","0DdtU9od-Bh5L3xbv0Xf_A"],"type":"temporary"}',
sessionType: 'temporary',
expectPass: true,
},
{
name: "Two keyIds, temporary session",
initData: '{"type":"temporary", "kids":["LwVHf8JLtPrv2GUXFW2v_A", "0DdtU9od-Bh5L3xbv0Xf_A"]}',
expectedRequest: '{"kids":["LwVHf8JLtPrv2GUXFW2v_A","0DdtU9od-Bh5L3xbv0Xf_A"],"type":"temporary"}',
sessionType: 'temporary',
expectPass: true,
},
{
name: "Two keyIds, persistent session, type before kids",
initData: '{"type":"persistent", "kids":["LwVHf8JLtPrv2GUXFW2v_A", "0DdtU9od-Bh5L3xbv0Xf_A"]}',
expectedRequest: '{"kids":["LwVHf8JLtPrv2GUXFW2v_A","0DdtU9od-Bh5L3xbv0Xf_A"],"type":"persistent"}',
sessionType: 'persistent',
expectPass: true,
},
{
name: "Invalid keyId",
initData: '{"kids":["0"]}',
sessionType: 'temporary',
expectPass: false,
},
{
name: "Empty keyId",
initData: '{"kids":[""]}',
sessionType: 'temporary',
expectPass: false,
},
{
name: "SessionType in license doesn't match MediaKeySession's sessionType",
initData: '{"kids":["LwVHf8JLtPrv2GUXFW2v_A"]}',
sessionType: 'persistent',
expectPass: false,
},
{
name: "One valid and one invalid kid",
initData: '{"kids":["LwVHf8JLtPrv2GUXFW2v_A", "invalid"]}',
expectedRequest: '{"kids":["LwVHf8JLtPrv2GUXFW2v_A"],"type":"temporary"}',
sessionType: 'temporary',
expectPass: true,
},
{
name: "Invalid initData",
initData: 'invalid initData',
sessionType: 'temporary',
expectPass: false,
},
];
function Test(test) {
return new Promise(function(resolve, reject) {
navigator.requestMediaKeySystemAccess('org.w3.clearkey', [{initDataTypes: ['keyids']}]).then(
(access) => access.createMediaKeys()
).then(
(mediaKeys) => {
var session = mediaKeys.createSession(test.sessionType);
var initData = new TextEncoder().encode(test.initData);
session.addEventListener("message", function(event) {
is(event.messageType, "license-request", "'" + test.name + "' MediaKeyMessage type should be license-request.");
var text = new TextDecoder().decode(event.message);
is(text, test.expectedRequest, "'" + test.name + "' got expected response.");
is(text == test.expectedRequest, test.expectPass,
"'" + test.name + "' expected to " + (test.expectPass ? "pass" : "fail"));
resolve();
});
return session.generateRequest('keyids', initData);
}
).catch((x) => {
ok(!test.expectPass, "'" + test.name + "' expected to fail.");
resolve();
});
});
}
function beginTest() {
Promise.all(tests.map(Test)).then(function() { SimpleTest.finish(); });
}
SimpleTest.waitForExplicitFinish();
SetupEMEPref(beginTest);
</script>
</pre>
</body>
</html>

View File

@ -7,6 +7,7 @@ include protocol PPluginInstance;
include protocol PPluginScriptableObject;
include protocol PCrashReporter;
include protocol PContent;
include ProfilerTypes;
using NPError from "npapi.h";
using NPNVariable from "npapi.h";
@ -93,8 +94,7 @@ child:
/**
* Control the Gecko Profiler in the plugin process.
*/
async StartProfiler(uint32_t aEntries, double aInterval, nsCString[] aFeatures,
nsCString[] aThreadNameFilters);
async StartProfiler(ProfilerInitParams params);
async StopProfiler();
async GatherProfile();

View File

@ -2524,22 +2524,20 @@ PluginModuleChild::ProcessNativeEvents() {
#endif
bool
PluginModuleChild::RecvStartProfiler(const uint32_t& aEntries,
const double& aInterval,
nsTArray<nsCString>&& aFeatures,
nsTArray<nsCString>&& aThreadNameFilters)
PluginModuleChild::RecvStartProfiler(const ProfilerInitParams& params)
{
nsTArray<const char*> featureArray;
for (size_t i = 0; i < aFeatures.Length(); ++i) {
featureArray.AppendElement(aFeatures[i].get());
for (size_t i = 0; i < params.features().Length(); ++i) {
featureArray.AppendElement(params.features()[i].get());
}
nsTArray<const char*> threadNameFilterArray;
for (size_t i = 0; i < aThreadNameFilters.Length(); ++i) {
threadNameFilterArray.AppendElement(aThreadNameFilters[i].get());
for (size_t i = 0; i < params.threadFilters().Length(); ++i) {
threadNameFilterArray.AppendElement(params.threadFilters()[i].get());
}
profiler_start(aEntries, aInterval, featureArray.Elements(), featureArray.Length(),
profiler_start(params.entries(), params.interval(),
featureArray.Elements(), featureArray.Length(),
threadNameFilterArray.Elements(), threadNameFilterArray.Length());
return true;

View File

@ -147,10 +147,7 @@ protected:
virtual bool
RecvProcessNativeEventsInInterruptCall() override;
virtual bool RecvStartProfiler(const uint32_t& aEntries,
const double& aInterval,
nsTArray<nsCString>&& aFeatures,
nsTArray<nsCString>&& aThreadNameFilters) override;
virtual bool RecvStartProfiler(const ProfilerInitParams& params) override;
virtual bool RecvStopProfiler() override;
virtual bool RecvGatherProfile() override;

View File

@ -3150,7 +3150,15 @@ PluginProfilerObserver::Observe(nsISupports *aSubject,
params->GetInterval(&interval);
const nsTArray<nsCString>& features = params->GetFeatures();
const nsTArray<nsCString>& threadFilterNames = params->GetThreadFilterNames();
Unused << mPmp->SendStartProfiler(entries, interval, features, threadFilterNames);
ProfilerInitParams ipcParams;
ipcParams.enabled() = true;
ipcParams.entries() = entries;
ipcParams.interval() = interval;
ipcParams.features() = features;
ipcParams.threadFilters() = threadFilterNames;
Unused << mPmp->SendStartProfiler(ipcParams);
} else if (!strcmp(aTopic, "profiler-stopped")) {
Unused << mPmp->SendStopProfiler();
} else if (!strcmp(aTopic, "profiler-subprocess-gather")) {

View File

@ -278,7 +278,7 @@ this.PushService = {
break;
case "clear-origin-data":
this._clearOriginData(data).catch(error => {
this._clearOriginData(aData).catch(error => {
console.error("clearOriginData: Error clearing origin data:", error);
});
break;

File diff suppressed because it is too large Load Diff

View File

@ -47,11 +47,9 @@ class ServiceWorker;
class ServiceWorkerClientInfo;
class ServiceWorkerInfo;
class ServiceWorkerJob;
class ServiceWorkerRegisterJob;
class ServiceWorkerJobQueue;
class ServiceWorkerManagerChild;
class ServiceWorkerPrivate;
class ServiceWorkerUpdateFinishCallback;
class ServiceWorkerRegistrationInfo final
: public nsIServiceWorkerRegistrationInfo
@ -79,7 +77,11 @@ public:
uint64_t mLastUpdateCheckTime;
RefPtr<ServiceWorkerRegisterJob> mUpdateJob;
// According to the spec, Soft Update shouldn't queue an update job
// if the registration queue is not empty. Because our job queue
// works slightly different, we use a flag to determine if the registration
// is already updating.
bool mUpdating;
// When unregister() is called on a registration, it is not immediately
// removed since documents may be controlled. It is marked as
@ -149,12 +151,6 @@ public:
void
NotifyListenersOnChange();
bool
IsUpdating() const;
void
AppendUpdateCallback(ServiceWorkerUpdateFinishCallback* aCallback);
};
class ServiceWorkerUpdateFinishCallback
@ -316,7 +312,9 @@ class ServiceWorkerManager final
friend class GetRegistrationsRunnable;
friend class GetRegistrationRunnable;
friend class ServiceWorkerJobQueue;
friend class ServiceWorkerInstallJob;
friend class ServiceWorkerRegisterJob;
friend class ServiceWorkerJobBase;
friend class ServiceWorkerRegistrationInfo;
friend class ServiceWorkerUnregisterJob;
@ -373,14 +371,13 @@ public:
ErrorResult& aRv);
void
SoftUpdate(nsIPrincipal* aPrincipal,
const nsACString& aScope,
ServiceWorkerUpdateFinishCallback* aCallback = nullptr);
Update(nsIPrincipal* aPrincipal,
const nsACString& aScope,
ServiceWorkerUpdateFinishCallback* aCallback);
void
SoftUpdate(const PrincipalOriginAttributes& aOriginAttributes,
const nsACString& aScope,
ServiceWorkerUpdateFinishCallback* aCallback = nullptr);
SoftUpdate(const OriginAttributes& aOriginAttributes,
const nsACString& aScope);
void
PropagateSoftUpdate(const PrincipalOriginAttributes& aOriginAttributes,
@ -489,11 +486,6 @@ private:
void
MaybeRemoveRegistrationInfo(const nsACString& aScopeKey);
void
SoftUpdate(const nsACString& aScopeKey,
const nsACString& aScope,
ServiceWorkerUpdateFinishCallback* aCallback = nullptr);
already_AddRefed<ServiceWorkerRegistrationInfo>
GetRegistration(const nsACString& aScopeKey,
const nsACString& aScope) const;
@ -525,6 +517,9 @@ private:
InvalidateServiceWorkerRegistrationWorker(ServiceWorkerRegistrationInfo* aRegistration,
WhichServiceWorker aWhichOnes);
void
NotifyServiceWorkerRegistrationRemoved(ServiceWorkerRegistrationInfo* aRegistration);
void
StartControllingADocument(ServiceWorkerRegistrationInfo* aRegistration,
nsIDocument* aDoc);

View File

@ -42,7 +42,7 @@ ServiceWorkerManagerChild::RecvNotifySoftUpdate(
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
MOZ_ASSERT(swm);
swm->SoftUpdate(aOriginAttributes, NS_ConvertUTF16toUTF8(aScope), nullptr);
swm->SoftUpdate(aOriginAttributes, NS_ConvertUTF16toUTF8(aScope));
return true;
}

View File

@ -61,6 +61,7 @@ NS_IMPL_ISUPPORTS0(KeepAliveToken)
ServiceWorkerPrivate::ServiceWorkerPrivate(ServiceWorkerInfo* aInfo)
: mInfo(aInfo)
, mIsPushWorker(false)
, mDebuggerCount(0)
, mTokenCount(0)
{
AssertIsOnMainThread();
@ -103,46 +104,64 @@ namespace {
class CheckScriptEvaluationWithCallback final : public WorkerRunnable
{
nsMainThreadPtrHandle<KeepAliveToken> mKeepAliveToken;
RefPtr<nsRunnable> mCallback;
RefPtr<LifeCycleEventCallback> mCallback;
DebugOnly<bool> mDone;
public:
CheckScriptEvaluationWithCallback(WorkerPrivate* aWorkerPrivate,
KeepAliveToken* aKeepAliveToken,
nsRunnable* aCallback)
LifeCycleEventCallback* aCallback)
: WorkerRunnable(aWorkerPrivate, WorkerThreadModifyBusyCount)
, mKeepAliveToken(new nsMainThreadPtrHolder<KeepAliveToken>(aKeepAliveToken))
, mCallback(aCallback)
, mDone(false)
{
AssertIsOnMainThread();
}
~CheckScriptEvaluationWithCallback()
{
MOZ_ASSERT(mDone);
}
bool
WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override
{
aWorkerPrivate->AssertIsOnWorkerThread();
if (aWorkerPrivate->WorkerScriptExecutedSuccessfully()) {
nsresult rv = NS_DispatchToMainThread(mCallback);
if (NS_FAILED(rv)) {
NS_WARNING("Failed to dispatch CheckScriptEvaluation callback.");
}
}
Done(aWorkerPrivate->WorkerScriptExecutedSuccessfully());
return true;
}
NS_IMETHOD
Cancel() override
{
Done(false);
return WorkerRunnable::Cancel();
}
private:
void
Done(bool aResult)
{
mDone = true;
mCallback->SetResult(aResult);
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(NS_DispatchToMainThread(mCallback)));
}
};
} // anonymous namespace
nsresult
ServiceWorkerPrivate::ContinueOnSuccessfulScriptEvaluation(nsRunnable* aCallback)
ServiceWorkerPrivate::CheckScriptEvaluation(LifeCycleEventCallback* aCallback)
{
nsresult rv = SpawnWorkerIfNeeded(LifeCycleEvent, nullptr);
NS_ENSURE_SUCCESS(rv, rv);
MOZ_ASSERT(mKeepAliveToken);
RefPtr<WorkerRunnable> r = new CheckScriptEvaluationWithCallback(mWorkerPrivate,
mKeepAliveToken,
aCallback);
mKeepAliveToken,
aCallback);
AutoJSAPI jsapi;
jsapi.Init();
if (NS_WARN_IF(!r->Dispatch(jsapi.cx()))) {
@ -352,6 +371,15 @@ public:
return DispatchLifecycleEvent(aCx, aWorkerPrivate);
}
NS_IMETHOD
Cancel() override
{
mCallback->SetResult(false);
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(NS_DispatchToMainThread(mCallback)));
return WorkerRunnable::Cancel();
}
private:
bool
DispatchLifecycleEvent(JSContext* aCx, WorkerPrivate* aWorkerPrivate);
@ -359,52 +387,116 @@ private:
};
/*
* Used to handle ExtendableEvent::waitUntil() and proceed with
* installation/activation.
* Used to handle ExtendableEvent::waitUntil() and catch abnormal worker
* termination during the execution of life cycle events. It is responsible
* with advancing the job queue for install/activate tasks.
*/
class LifecycleEventPromiseHandler final : public PromiseNativeHandler
class LifeCycleEventWatcher final : public PromiseNativeHandler,
public WorkerFeature
{
WorkerPrivate* mWorkerPrivate;
RefPtr<LifeCycleEventCallback> mCallback;
bool mDone;
virtual
~LifecycleEventPromiseHandler()
{ }
~LifeCycleEventWatcher()
{
if (mDone) {
return;
}
MOZ_ASSERT(GetCurrentThreadWorkerPrivate() == mWorkerPrivate);
// XXXcatalinb: If all the promises passed to waitUntil go out of scope,
// the resulting Promise.all will be cycle collected and it will drop its
// native handlers (including this object). Instead of waiting for a timeout
// we report the failure now.
JSContext* cx = mWorkerPrivate->GetJSContext();
ReportResult(cx, false);
}
public:
NS_DECL_ISUPPORTS
explicit LifecycleEventPromiseHandler(LifeCycleEventCallback* aCallback)
: mCallback(aCallback)
LifeCycleEventWatcher(WorkerPrivate* aWorkerPrivate,
LifeCycleEventCallback* aCallback)
: mWorkerPrivate(aWorkerPrivate)
, mCallback(aCallback)
, mDone(false)
{
MOZ_ASSERT(!NS_IsMainThread());
MOZ_ASSERT(aWorkerPrivate);
aWorkerPrivate->AssertIsOnWorkerThread();
}
bool
Init()
{
MOZ_ASSERT(mWorkerPrivate);
mWorkerPrivate->AssertIsOnWorkerThread();
JSContext* cx = mWorkerPrivate->GetJSContext();
// We need to listen for worker termination in case the event handler
// never completes or never resolves the waitUntil promise. There are
// two possible scenarios:
// 1. The keepAlive token expires and the worker is terminated, in which
// case the registration/update promise will be rejected
// 2. A new service worker is registered which will terminate the current
// installing worker.
if (NS_WARN_IF(!mWorkerPrivate->AddFeature(cx, this))) {
NS_WARNING("LifeCycleEventWatcher failed to add feature.");
ReportResult(cx, false);
return false;
}
return true;
}
bool
Notify(JSContext* aCx, Status aStatus) override
{
if (aStatus < Terminating) {
return true;
}
MOZ_ASSERT(GetCurrentThreadWorkerPrivate() == mWorkerPrivate);
ReportResult(aCx, false);
return true;
}
void
ReportResult(JSContext* aCx, bool aResult)
{
mWorkerPrivate->AssertIsOnWorkerThread();
if (mDone) {
return;
}
mDone = true;
mCallback->SetResult(aResult);
nsresult rv = NS_DispatchToMainThread(mCallback);
if (NS_WARN_IF(NS_FAILED(rv))) {
NS_RUNTIMEABORT("Failed to dispatch life cycle event handler.");
}
mWorkerPrivate->RemoveFeature(aCx, this);
}
void
ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue) override
{
WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
MOZ_ASSERT(workerPrivate);
workerPrivate->AssertIsOnWorkerThread();
MOZ_ASSERT(GetCurrentThreadWorkerPrivate() == mWorkerPrivate);
mWorkerPrivate->AssertIsOnWorkerThread();
mCallback->SetResult(true);
nsresult rv = NS_DispatchToMainThread(mCallback);
if (NS_WARN_IF(NS_FAILED(rv))) {
NS_RUNTIMEABORT("Failed to dispatch life cycle event handler.");
}
ReportResult(aCx, true);
}
void
RejectedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue) override
{
WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
MOZ_ASSERT(workerPrivate);
workerPrivate->AssertIsOnWorkerThread();
MOZ_ASSERT(GetCurrentThreadWorkerPrivate() == mWorkerPrivate);
mWorkerPrivate->AssertIsOnWorkerThread();
mCallback->SetResult(false);
nsresult rv = NS_DispatchToMainThread(mCallback);
if (NS_WARN_IF(NS_FAILED(rv))) {
NS_RUNTIMEABORT("Failed to dispatch life cycle event handler.");
}
ReportResult(aCx, false);
// Note, all WaitUntil() rejections are reported to client consoles
// by the WaitUntilHandler in ServiceWorkerEvents. This ensures that
@ -413,7 +505,7 @@ public:
}
};
NS_IMPL_ISUPPORTS0(LifecycleEventPromiseHandler)
NS_IMPL_ISUPPORTS0(LifeCycleEventWatcher)
bool
LifecycleEventWorkerRunnable::DispatchLifecycleEvent(JSContext* aCx,
@ -436,16 +528,23 @@ LifecycleEventWorkerRunnable::DispatchLifecycleEvent(JSContext* aCx,
event->SetTrusted(true);
// It is important to initialize the watcher before actually dispatching
// the event in order to catch worker termination while the event handler
// is still executing. This can happen with infinite loops, for example.
RefPtr<LifeCycleEventWatcher> watcher =
new LifeCycleEventWatcher(aWorkerPrivate, mCallback);
if (!watcher->Init()) {
return true;
}
RefPtr<Promise> waitUntil;
DispatchExtendableEventOnWorkerScope(aCx, aWorkerPrivate->GlobalScope(),
event, getter_AddRefs(waitUntil));
if (waitUntil) {
RefPtr<LifecycleEventPromiseHandler> handler =
new LifecycleEventPromiseHandler(mCallback);
waitUntil->AppendNativeHandler(handler);
waitUntil->AppendNativeHandler(watcher);
} else {
mCallback->SetResult(false);
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(NS_DispatchToMainThread(mCallback)));
watcher->ReportResult(aCx, false);
}
return true;
@ -1331,7 +1430,7 @@ ServiceWorkerPrivate::SpawnWorkerIfNeeded(WakeUpReason aWhy,
if (mWorkerPrivate) {
mWorkerPrivate->UpdateOverridenLoadGroup(aLoadGroup);
ResetIdleTimeout(aWhy);
RenewKeepAliveToken(aWhy);
return NS_OK;
}
@ -1411,7 +1510,7 @@ ServiceWorkerPrivate::SpawnWorkerIfNeeded(WakeUpReason aWhy,
}
mIsPushWorker = false;
ResetIdleTimeout(aWhy);
RenewKeepAliveToken(aWhy);
return NS_OK;
}
@ -1477,7 +1576,7 @@ void
ServiceWorkerPrivate::NoteStoppedControllingDocuments()
{
AssertIsOnMainThread();
if (mIsPushWorker) {
if (mIsPushWorker || mDebuggerCount) {
return;
}
@ -1507,6 +1606,68 @@ ServiceWorkerPrivate::Activated()
}
}
nsresult
ServiceWorkerPrivate::GetDebugger(nsIWorkerDebugger** aResult)
{
AssertIsOnMainThread();
MOZ_ASSERT(aResult);
if (!mDebuggerCount) {
return NS_OK;
}
MOZ_ASSERT(mWorkerPrivate);
nsCOMPtr<nsIWorkerDebugger> debugger = do_QueryInterface(mWorkerPrivate->Debugger());
debugger.forget(aResult);
return NS_OK;
}
nsresult
ServiceWorkerPrivate::AttachDebugger()
{
AssertIsOnMainThread();
// When the first debugger attaches to a worker, we spawn a worker if needed,
// and cancel the idle timeout. The idle timeout should not be reset until
// the last debugger detached from the worker.
if (!mDebuggerCount) {
nsresult rv = SpawnWorkerIfNeeded(AttachEvent, nullptr);
NS_ENSURE_SUCCESS(rv, rv);
mIdleWorkerTimer->Cancel();
}
++mDebuggerCount;
return NS_OK;
}
nsresult
ServiceWorkerPrivate::DetachDebugger()
{
AssertIsOnMainThread();
if (!mDebuggerCount) {
return NS_ERROR_UNEXPECTED;
}
--mDebuggerCount;
// When the last debugger detaches from a worker, we either reset the idle
// timeout, or terminate the worker if there are no more active tokens.
if (!mDebuggerCount) {
if (mTokenCount) {
ResetIdleTimeout();
} else {
TerminateWorker();
}
}
return NS_OK;
}
/* static */ void
ServiceWorkerPrivate::NoteIdleWorkerCallback(nsITimer* aTimer, void* aPrivate)
{
@ -1550,24 +1711,36 @@ ServiceWorkerPrivate::TerminateWorkerCallback(nsITimer* aTimer, void *aPrivate)
}
void
ServiceWorkerPrivate::ResetIdleTimeout(WakeUpReason aWhy)
ServiceWorkerPrivate::RenewKeepAliveToken(WakeUpReason aWhy)
{
// We should have an active worker if we're reseting the idle timeout
// We should have an active worker if we're renewing the keep alive token.
MOZ_ASSERT(mWorkerPrivate);
if (aWhy == PushEvent || aWhy == PushSubscriptionChangeEvent) {
mIsPushWorker = true;
}
// If there is at least one debugger attached to the worker, the idle worker
// timeout was canceled when the first debugger attached to the worker. It
// should not be reset until the last debugger detaches from the worker.
if (!mDebuggerCount) {
ResetIdleTimeout();
}
if (!mKeepAliveToken) {
mKeepAliveToken = new KeepAliveToken(this);
}
}
void
ServiceWorkerPrivate::ResetIdleTimeout()
{
uint32_t timeout = Preferences::GetInt("dom.serviceWorkers.idle_timeout");
DebugOnly<nsresult> rv =
mIdleWorkerTimer->InitWithFuncCallback(ServiceWorkerPrivate::NoteIdleWorkerCallback,
this, timeout,
nsITimer::TYPE_ONE_SHOT);
MOZ_ASSERT(NS_SUCCEEDED(rv));
if (!mKeepAliveToken) {
mKeepAliveToken = new KeepAliveToken(this);
}
}
void

View File

@ -72,11 +72,9 @@ public:
UniquePtr<ServiceWorkerClientInfo>&& aClientInfo);
// This is used to validate the worker script and continue the installation
// process. Note that the callback is dispatched to the main thread
// ONLY if the evaluation was successful. Failure is handled by the JS
// exception handler which will call ServiceWorkerManager::HandleError.
// process.
nsresult
ContinueOnSuccessfulScriptEvaluation(nsRunnable* aCallback);
CheckScriptEvaluation(LifeCycleEventCallback* aCallback);
nsresult
SendLifeCycleEvent(const nsAString& aEventType,
@ -137,6 +135,15 @@ public:
void
Activated();
nsresult
GetDebugger(nsIWorkerDebugger** aResult);
nsresult
AttachDebugger();
nsresult
DetachDebugger();
private:
enum WakeUpReason {
FetchEvent = 0,
@ -144,7 +151,8 @@ private:
PushSubscriptionChangeEvent,
MessageEvent,
NotificationClickEvent,
LifeCycleEvent
LifeCycleEvent,
AttachEvent
};
// Timer callbacks
@ -155,7 +163,10 @@ private:
TerminateWorkerCallback(nsITimer* aTimer, void *aPrivate);
void
ResetIdleTimeout(WakeUpReason aWhy);
RenewKeepAliveToken(WakeUpReason aWhy);
void
ResetIdleTimeout();
void
AddToken();
@ -193,6 +204,8 @@ private:
// worker a grace period after each event.
RefPtr<KeepAliveToken> mKeepAliveToken;
uint64_t mDebuggerCount;
uint64_t mTokenCount;
// Meant for keeping objects alive while handling requests from the worker

View File

@ -250,6 +250,19 @@ ServiceWorkerRegistrationMainThread::InvalidateWorkers(WhichServiceWorker aWhich
if (aWhichOnes & WhichServiceWorker::ACTIVE_WORKER) {
mActiveWorker = nullptr;
}
}
void
ServiceWorkerRegistrationMainThread::RegistrationRemoved()
{
// If the registration is being removed completely, remove it from the
// window registration hash table so that a new registration would get a new
// wrapper JS object.
nsCOMPtr<nsPIDOMWindow> window = GetOwner();
if (window) {
window->InvalidateServiceWorkerRegistration(mScope);
}
}
namespace {
@ -266,8 +279,7 @@ UpdateInternal(nsIPrincipal* aPrincipal,
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
MOZ_ASSERT(swm);
// The spec defines ServiceWorkerRegistration.update() exactly as Soft Update.
swm->SoftUpdate(aPrincipal, NS_ConvertUTF16toUTF8(aScope), aCallback);
swm->Update(aPrincipal, NS_ConvertUTF16toUTF8(aScope), aCallback);
}
class MainThreadUpdateCallback final : public ServiceWorkerUpdateFinishCallback
@ -393,14 +405,22 @@ public:
AssertIsOnMainThread();
ErrorResult result;
MutexAutoLock lock(mPromiseProxy->Lock());
if (mPromiseProxy->CleanedUp()) {
return NS_OK;
nsCOMPtr<nsIPrincipal> principal;
// UpdateInternal may try to reject the promise synchronously leading
// to a deadlock.
{
MutexAutoLock lock(mPromiseProxy->Lock());
if (mPromiseProxy->CleanedUp()) {
return NS_OK;
}
principal = mPromiseProxy->GetWorkerPrivate()->GetPrincipal();
}
MOZ_ASSERT(principal);
RefPtr<WorkerThreadUpdateCallback> cb =
new WorkerThreadUpdateCallback(mPromiseProxy);
UpdateInternal(mPromiseProxy->GetWorkerPrivate()->GetPrincipal(), mScope, cb);
UpdateInternal(principal, mScope, cb);
return NS_OK;
}
@ -857,6 +877,12 @@ public:
// FIXME(nsm);
}
void
RegistrationRemoved() override
{
AssertIsOnMainThread();
}
void
GetScope(nsAString& aScope) const override
{

View File

@ -65,6 +65,9 @@ public:
virtual void
InvalidateWorkers(WhichServiceWorker aWhichOnes) = 0;
virtual void
RegistrationRemoved() = 0;
virtual void
GetScope(nsAString& aScope) const = 0;
};
@ -106,9 +109,6 @@ public:
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ServiceWorkerRegistrationMainThread,
ServiceWorkerRegistrationBase)
ServiceWorkerRegistrationMainThread(nsPIDOMWindow* aWindow,
const nsAString& aScope);
already_AddRefed<Promise>
Update(ErrorResult& aRv);
@ -154,6 +154,9 @@ public:
void
InvalidateWorkers(WhichServiceWorker aWhichOnes) override;
void
RegistrationRemoved() override;
void
GetScope(nsAString& aScope) const override
{
@ -161,6 +164,9 @@ public:
}
private:
friend nsPIDOMWindow;
ServiceWorkerRegistrationMainThread(nsPIDOMWindow* aWindow,
const nsAString& aScope);
~ServiceWorkerRegistrationMainThread();
already_AddRefed<workers::ServiceWorker>

View File

@ -593,7 +593,9 @@ public:
AutoJSAPI jsapi;
jsapi.Init();
runnable->Dispatch(jsapi.cx());
if (!runnable->Dispatch(jsapi.cx())) {
NS_WARNING("Failed to dispatch SkipWaitingResultRunnable to the worker.");
}
return NS_OK;
}
};

View File

@ -4,6 +4,7 @@ support-files =
app/*
app2/*
chrome_helpers.js
serviceworkerinfo_iframe.html
serviceworkermanager_iframe.html
serviceworkerregistrationinfo_iframe.html
worker.js
@ -13,5 +14,6 @@ support-files =
skip-if = true #bug 1193319
[test_app_installation.html]
[test_privateBrowsing.html]
[test_serviceworkerinfo.xul]
[test_serviceworkermanager.xul]
[test_serviceworkerregistrationinfo.xul]

View File

@ -57,3 +57,18 @@ function waitForServiceWorkerRegistrationChange(registration, callback) {
registration.addListener(listener);
});
}
function waitForServiceWorkerShutdown() {
return new Promise(function (resolve) {
let observer = {
observe: function (subject, topic, data) {
if (topic !== "service-worker-shutdown") {
return;
}
SpecialPowers.removeObserver(observer, "service-worker-shutdown");
resolve();
}
};
SpecialPowers.addObserver(observer, "service-worker-shutdown", false);
});
}

View File

@ -0,0 +1,26 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<script>
window.onmessage = function (event) {
if (event.data !== "register") {
return;
}
var promise = navigator.serviceWorker.register("worker.js");
window.onmessage = function (event) {
if (event.data !== "unregister") {
return;
}
promise.then(function (registration) {
registration.unregister();
});
window.onmessage = null;
};
};
</script>
</head>
<body>
This is a test page.
</body>
<html>

View File

@ -24,13 +24,26 @@
ok(reg instanceof ServiceWorkerRegistration, "reg should be a ServiceWorkerRegistration");
var p = navigator.serviceWorker.register("install_event_worker.js", { scope: "./install_event" });
return p.then(function(swr) {
ok(reg.scope === swr.scope, "Scope for registrations should match.");
return new Promise(function(resolve, reject) {
ok(reg === swr, "register should resolve to the same registration object");
var update_found_promise = new Promise(function(resolve, reject) {
swr.addEventListener('updatefound', function(e) {
ok(true, "Received onupdatefound");
resolve();
});
});
var worker_activating = new Promise(function(res, reject) {
ok(swr.installing instanceof ServiceWorker, "There should be an installing worker if promise resolves.");
ok(swr.installing.state == "installing", "Installing worker's state should be 'installing'");
swr.installing.onstatechange = function(e) {
if (e.target.state == "activating") {
e.target.onstatechange = null;
res();
}
}
});
return Promise.all([update_found_promise, worker_activating]);
}, function(e) {
ok(false, "Unexpected Error in nextRegister! " + e);
});

View File

@ -0,0 +1,101 @@
<?xml version="1.0"?>
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<window title="Test for ServiceWorkerInfo"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
onload="test();">
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
<script type="application/javascript" src="chrome_helpers.js"/>
<script type="application/javascript">
<![CDATA[
let IFRAME_URL = EXAMPLE_URL + "serviceworkerinfo_iframe.html";
function wait_for_active_worker(registration) {
ok(registration, "Registration is valid.");
return new Promise(function(res, rej) {
if (registration.activeWorker) {
res(registration);
return;
}
let listener = {
onChange: function() {
if (registration.activeWorker) {
registration.removeListener(listener);
res(registration);
}
}
}
registration.addListener(listener);
});
}
function test() {
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({'set': [
["dom.serviceWorkers.enabled", true],
["dom.serviceWorkers.idle_extended_timeout", 1000000],
["dom.serviceWorkers.idle_timeout", 0],
["dom.serviceWorkers.testing.enabled", true],
]}, function () {
Task.spawn(function *() {
let iframe = $("iframe");
let promise = new Promise(function (resolve) {
iframe.onload = function () {
resolve();
};
});
iframe.src = IFRAME_URL;
yield promise;
info("Check that a service worker eventually shuts down.");
promise = Promise.all([
waitForRegister(EXAMPLE_URL),
waitForServiceWorkerShutdown()
]);
iframe.contentWindow.postMessage("register", "*");
let [registration] = yield promise;
// Make sure the worker is active.
registration = yield wait_for_active_worker(registration);
let activeWorker = registration.activeWorker;
ok(activeWorker !== null, "Worker is not active!");
ok(activeWorker.debugger === null);
info("Attach a debugger to the service worker, and check that the " +
"service worker is restarted.");
activeWorker.attachDebugger();
ok(activeWorker.debugger !== null);
info("Detach the debugger from the service worker, and check that " +
"the service worker eventually shuts down again.");
promise = waitForServiceWorkerShutdown();
activeWorker.detachDebugger();
yield promise;
ok(activeWorker.debugger === null);
promise = waitForUnregister(EXAMPLE_URL);
iframe.contentWindow.postMessage("unregister", "*");
registration = yield promise;
SimpleTest.finish();
});
});
}
]]>
</script>
<body xmlns="http://www.w3.org/1999/xhtml">
<p id="display"></p>
<div id="content" style="display:none;"></div>
<pre id="test"></pre>
<iframe id="iframe"></iframe>
</body>
<label id="test-result"/>
</window>

View File

@ -422,11 +422,13 @@ APZCCallbackHelper::ApplyCallbackTransform(const CSSPoint& aInput,
if (aGuid.mScrollId == FrameMetrics::NULL_SCROLL_ID) {
return input;
}
nsCOMPtr<nsIContent> content = nsLayoutUtils::FindContentFor(aGuid.mScrollId);
if (!content) {
return input;
}
#if !defined(MOZ_SINGLE_PROCESS_APZ)
// First, scale inversely by the root content document's pres shell
// resolution to cancel the scale-to-resolution transform that the
// compositor adds to the layer with the pres shell resolution. The points
@ -435,8 +437,9 @@ APZCCallbackHelper::ApplyCallbackTransform(const CSSPoint& aInput,
if (nsIPresShell* shell = GetRootContentDocumentPresShellForContent(content)) {
input = input / shell->GetResolution();
}
#endif
// Now apply the callback-transform.
// Apply the callback-transform.
// XXX: technically we need to walk all the way up the layer tree from the layer
// represented by |aGuid.mScrollId| up to the root of the layer tree and apply
// the input transforms at each level in turn. However, it is quite difficult
@ -447,9 +450,22 @@ APZCCallbackHelper::ApplyCallbackTransform(const CSSPoint& aInput,
// some things transformed improperly. In practice we should rarely hit scenarios
// where any of this matters, so I'm skipping it for now and just doing the single
// transform for the layer that the input hit.
void* property = content->GetProperty(nsGkAtoms::apzCallbackTransform);
if (property) {
CSSPoint delta = (*static_cast<CSSPoint*>(property));
#if defined(MOZ_SINGLE_PROCESS_APZ)
// The delta is in root content document coordinate space while the
// aInput point is in root document coordinate space so convert the
// delta to root document space before adding it to the aInput point.
float resolution = 1.0f;
if (nsIPresShell* shell = GetRootContentDocumentPresShellForContent(content)) {
resolution = shell->GetResolution();
}
delta.x = delta.x * resolution;
delta.y = delta.y * resolution;
#endif // MOZ_SINGLE_PROCESS_APZ
input += delta;
}
return input;

View File

@ -147,6 +147,16 @@ ChromeProcessController::HandleDoubleTap(const mozilla::CSSPoint& aPoint,
}
CSSPoint point = APZCCallbackHelper::ApplyCallbackTransform(aPoint, aGuid);
#if defined(MOZ_SINGLE_PROCESS_APZ)
// CalculateRectToZoomTo performs a hit test on the frame associated with the
// Root Content Document. Unfortunately that frame does not know about the
// resolution of the document and so we must remove it before calculating
// the zoomToRect.
nsIPresShell* presShell = document->GetShell();
const float resolution = presShell->ScaleToResolution() ? presShell->GetResolution () : 1.0f;
point.x = point.x / resolution;
point.y = point.y / resolution;
#endif // MOZ_SINGLE_PROCESS_APZ
CSSRect zoomToRect = CalculateRectToZoomTo(document, point);
uint32_t presShellId;

View File

@ -128,6 +128,16 @@ BasicLayerManager::PushGroupForLayer(gfxContext* aContext, Layer* aLayer, const
Matrix maskTransform;
RefPtr<SourceSurface> maskSurf = GetMaskForLayer(aLayer, &maskTransform);
if (maskSurf) {
// The returned transform will transform the mask to device space on the
// destination. Since the User->Device space transform will be applied
// to the mask by PopGroupAndBlend we need to adjust the transform to
// transform the mask to user space.
Matrix currentTransform = ToMatrix(group.mFinalTarget->CurrentMatrix());
currentTransform.Invert();
maskTransform = maskTransform * currentTransform;
}
if (aLayer->CanUseOpaqueSurface() &&
((didCompleteClip && aRegion.GetNumRects() == 1) ||
!aContext->CurrentMatrix().HasNonIntegerTranslation())) {
@ -172,8 +182,12 @@ BasicLayerManager::PopGroupForLayer(PushedGroup &group)
RefPtr<SourceSurface> src = sourceDT->Snapshot();
if (group.mMaskSurface) {
dt->SetTransform(group.mMaskTransform * Matrix::Translation(-group.mFinalTarget->GetDeviceOffset()));
dt->MaskSurface(SurfacePattern(src, ExtendMode::CLAMP, Matrix::Translation(group.mGroupOffset.x, group.mGroupOffset.y)),
Point finalOffset = group.mFinalTarget->GetDeviceOffset();
dt->SetTransform(group.mMaskTransform * Matrix::Translation(-finalOffset));
Matrix surfTransform = group.mMaskTransform;
surfTransform.Invert();
dt->MaskSurface(SurfacePattern(src, ExtendMode::CLAMP, surfTransform *
Matrix::Translation(group.mGroupOffset.x, group.mGroupOffset.y)),
group.mMaskSurface, Point(0, 0), DrawOptions(group.mOpacity, group.mOperator));
} else {
// For now this is required since our group offset is in device space of the final target,

View File

@ -1664,11 +1664,13 @@ CompositorParent::SetControllerForLayerTree(uint64_t aLayersId,
CompositorParent::GetAPZCTreeManager(uint64_t aLayersId)
{
EnsureLayerTreeMapReady();
const CompositorParent::LayerTreeState* state = CompositorParent::GetIndirectShadowTree(aLayersId);
if (state && state->mParent) {
return state->mParent->mApzcTreeManager;
MonitorAutoLock lock(*sIndirectLayerTreesLock);
LayerTreeMap::iterator cit = sIndirectLayerTrees.find(aLayersId);
if (sIndirectLayerTrees.end() == cit) {
return nullptr;
}
return nullptr;
LayerTreeState* lts = &cit->second;
return (lts->mParent ? lts->mParent->mApzcTreeManager.get() : nullptr);
}
float

View File

@ -37,6 +37,11 @@ struct nsPoint : public mozilla::gfx::BasePoint<nscoord, nsPoint> {
*/
MOZ_WARN_UNUSED_RESULT inline nsPoint
ScaleToOtherAppUnits(int32_t aFromAPP, int32_t aToAPP) const;
MOZ_WARN_UNUSED_RESULT inline nsPoint
RemoveResolution(const float resolution) const;
MOZ_WARN_UNUSED_RESULT inline nsPoint
ApplyResolution(const float resolution) const;
};
inline nsPoint ToAppUnits(const nsIntPoint& aPoint, nscoord aAppUnitsPerPixel);
@ -68,6 +73,28 @@ nsPoint::ScaleToOtherAppUnits(int32_t aFromAPP, int32_t aToAPP) const
return *this;
}
inline nsPoint
nsPoint::RemoveResolution(const float resolution) const {
if (resolution != 1.0f) {
nsPoint point;
point.x = NSToCoordRound(NSCoordToFloat(x) / resolution);
point.y = NSToCoordRound(NSCoordToFloat(y) / resolution);
return point;
}
return *this;
}
inline nsPoint
nsPoint::ApplyResolution(const float resolution) const {
if (resolution != 1.0f) {
nsPoint point;
point.x = NSToCoordRound(NSCoordToFloat(x) * resolution);
point.y = NSToCoordRound(NSCoordToFloat(y) * resolution);
return point;
}
return *this;
}
// app units are integer multiples of pixels, so no rounding needed
inline nsPoint
ToAppUnits(const nsIntPoint& aPoint, nscoord aAppUnitsPerPixel)

View File

@ -171,6 +171,8 @@ struct nsRect :
{
return IsEqualEdges(aRect);
}
MOZ_WARN_UNUSED_RESULT inline nsRect RemoveResolution(const float aResolution) const;
};
/*
@ -279,6 +281,25 @@ nsRect::ToInsidePixels(nscoord aAppUnitsPerPixel) const
return ScaleToInsidePixels(1.0f, 1.0f, aAppUnitsPerPixel);
}
inline nsRect
nsRect::RemoveResolution(const float aResolution) const
{
MOZ_ASSERT(aResolution > 0.0f);
nsRect rect;
rect.x = NSToCoordRound(NSCoordToFloat(x) / aResolution);
rect.y = NSToCoordRound(NSCoordToFloat(y) / aResolution);
// A 1x1 rect indicates we are just hit testing a point, so pass down a 1x1
// rect as well instead of possibly rounding the width or height to zero.
if (width == 1 && height == 1) {
rect.width = rect.height = 1;
} else {
rect.width = NSToCoordCeil(NSCoordToFloat(width) / aResolution);
rect.height = NSToCoordCeil(NSCoordToFloat(height) / aResolution);
}
return rect;
}
const mozilla::gfx::IntRect& GetMaxSizedIntRect();
// app units are integer multiples of pixels, so no rounding needed

View File

@ -16,6 +16,7 @@
#include "gfxFontConstants.h"
#include "mozilla/Preferences.h"
#include "mozilla/Services.h"
#include "mozilla/Telemetry.h"
#include "mozilla/gfx/2D.h"
#include "gfxPlatformFontList.h"
@ -427,6 +428,8 @@ gfxUserFontEntry::LoadNextSrc()
gfxUserFontData::kUnknownCompression);
mPlatformFontEntry = fe;
SetLoadState(STATUS_LOADED);
Telemetry::Accumulate(Telemetry::WEBFONT_SRCTYPE,
currSrc.mSourceType + 1);
return;
} else {
LOG(("userfonts (%p) [src %d] failed local: (%s) for (%s)\n",
@ -457,6 +460,14 @@ gfxUserFontEntry::LoadNextSrc()
if (fe) {
mPlatformFontEntry = fe;
SetLoadState(STATUS_LOADED);
if (LOG_ENABLED()) {
nsAutoCString fontURI;
currSrc.mURI->GetSpec(fontURI);
LOG(("userfonts (%p) [src %d] "
"loaded uri from cache: (%s) for (%s)\n",
mFontSet, mSrcIndex, fontURI.get(),
NS_ConvertUTF16toUTF8(mFamilyName).get()));
}
return;
}
}
@ -482,6 +493,8 @@ gfxUserFontEntry::LoadNextSrc()
if (NS_SUCCEEDED(rv) &&
LoadPlatformFont(buffer, bufferLength)) {
SetLoadState(STATUS_LOADED);
Telemetry::Accumulate(Telemetry::WEBFONT_SRCTYPE,
currSrc.mSourceType + 1);
return;
} else {
mFontSet->LogMessage(this,
@ -536,6 +549,8 @@ gfxUserFontEntry::LoadNextSrc()
// LoadPlatformFont takes ownership of the buffer, so no need
// to free it here.
SetLoadState(STATUS_LOADED);
Telemetry::Accumulate(Telemetry::WEBFONT_SRCTYPE,
currSrc.mSourceType + 1);
return;
} else {
mFontSet->LogMessage(this,
@ -577,6 +592,7 @@ gfxUserFontEntry::LoadPlatformFont(const uint8_t* aFontData, uint32_t& aLength)
gfxUserFontType fontType =
gfxFontUtils::DetermineFontDataType(aFontData, aLength);
Telemetry::Accumulate(Telemetry::WEBFONT_FONTTYPE, uint32_t(fontType));
// Unwrap/decompress/sanitize or otherwise munge the downloaded data
// to make a usable sfnt structure.
@ -589,12 +605,24 @@ gfxUserFontEntry::LoadPlatformFont(const uint8_t* aFontData, uint32_t& aLength)
// Call the OTS sanitizer; this will also decode WOFF to sfnt
// if necessary. The original data in aFontData is left unchanged.
uint32_t saneLen;
uint32_t fontCompressionRatio = 0;
const uint8_t* saneData =
SanitizeOpenTypeData(aFontData, aLength, saneLen, fontType);
if (!saneData) {
mFontSet->LogMessage(this, "rejected by sanitizer");
}
if (saneData) {
if (saneLen) {
fontCompressionRatio = uint32_t(100.0 * aLength / saneLen + 0.5);
if (fontType == GFX_USERFONT_WOFF ||
fontType == GFX_USERFONT_WOFF2) {
Telemetry::Accumulate(fontType == GFX_USERFONT_WOFF ?
Telemetry::WEBFONT_COMPRESSION_WOFF :
Telemetry::WEBFONT_COMPRESSION_WOFF2,
fontCompressionRatio);
}
}
// The sanitizer ensures that we have a valid sfnt and a usable
// name table, so this should never fail unless we're out of
// memory, and GetFullNameFromSFNT is not directly exposed to
@ -641,11 +669,11 @@ gfxUserFontEntry::LoadPlatformFont(const uint8_t* aFontData, uint32_t& aLength)
if (LOG_ENABLED()) {
nsAutoCString fontURI;
mSrcList[mSrcIndex].mURI->GetSpec(fontURI);
LOG(("userfonts (%p) [src %d] loaded uri: (%s) for (%s) (%p) gen: %8.8x\n",
LOG(("userfonts (%p) [src %d] loaded uri: (%s) for (%s) "
"(%p) gen: %8.8x compress: %d%%\n",
mFontSet, mSrcIndex, fontURI.get(),
NS_ConvertUTF16toUTF8(mFamilyName).get(),
this,
uint32_t(mFontSet->mGeneration)));
this, uint32_t(mFontSet->mGeneration), fontCompressionRatio));
}
mPlatformFontEntry = fe;
SetLoadState(STATUS_LOADED);
@ -738,7 +766,10 @@ gfxUserFontEntry::GetUserFontSets(nsTArray<gfxUserFontSet*>& aResult)
}
gfxUserFontSet::gfxUserFontSet()
: mFontFamilies(4), mLocalRulesUsed(false)
: mFontFamilies(4),
mLocalRulesUsed(false),
mDownloadCount(0),
mDownloadSize(0)
{
IncrementGeneration(true);
gfxPlatformFontList* fp = gfxPlatformFontList::PlatformFontList();

View File

@ -468,6 +468,15 @@ public:
static mozilla::LogModule* GetUserFontsLog();
// record statistics about font completion
virtual void RecordFontLoadDone(uint32_t aFontSize,
mozilla::TimeStamp aDoneTime) {}
void GetLoadStatistics(uint32_t& aLoadCount, uint64_t& aLoadSize) const {
aLoadCount = mDownloadCount;
aLoadSize = mDownloadSize;
}
protected:
// Protected destructor, to discourage deletion outside of Release():
virtual ~gfxUserFontSet();
@ -513,6 +522,10 @@ protected:
// true when local names have been looked up, false otherwise
bool mLocalRulesUsed;
// performance stats
uint32_t mDownloadCount;
uint64_t mDownloadSize;
};
// acts a placeholder until the real font is downloaded

View File

@ -19,6 +19,7 @@
# - UnicodeData.txt
# - Scripts.txt
# - BidiMirroring.txt
# - BidiBrackets.txt
# - HangulSyllableType.txt
# - ReadMe.txt (to record version/date of the UCD)
# - Unihan_Variants.txt (from Unihan.zip)
@ -334,6 +335,7 @@ my @script;
my @category;
my @combining;
my @mirror;
my @pairedBracketType;
my @hangul;
my @casemap;
my @xidmod;
@ -346,6 +348,7 @@ for (my $i = 0; $i < 0x110000; ++$i) {
$script[$i] = $scriptCode{"UNKNOWN"};
$category[$i] = $catCode{"UNASSIGNED"};
$combining[$i] = 0;
$pairedBracketType[$i] = 0;
$casemap[$i] = 0;
$xidmod[$i] = $xidmodCode{"not-chars"};
$numericvalue[$i] = -1;
@ -523,13 +526,38 @@ while (<FH>) {
s/#.*//;
if (m/([0-9A-F]{4,6});\s*([0-9A-F]{4,6})/) {
my $mirrorOffset = hex("0x$2") - hex("0x$1");
my $offsetIndex = first { $offsets[$_] eq $mirrorOffset } 0..$#offsets;
if ($offsetIndex == undef) {
my $offsetIndex = first { $offsets[$_] eq $mirrorOffset } 0..$#offsets;
if ($offsetIndex == undef) {
die "too many offset codes\n" if scalar @offsets == 31;
push @offsets, $mirrorOffset;
$offsetIndex = $#offsets;
$offsetIndex = $#offsets;
}
$mirror[hex "0x$1"] = $offsetIndex;
$mirror[hex "0x$1"] = $offsetIndex;
}
}
close FH;
# read BidiBrackets.txt
my %pairedBracketTypeCode = (
'N' => 0,
'O' => 1,
'C' => 2
);
open FH, "< $ARGV[1]/BidiBrackets.txt" or die "can't open UCD file BidiBrackets.txt\n";
push @versionInfo, "";
while (<FH>) {
chomp;
push @versionInfo, $_;
last if /Date:/;
}
while (<FH>) {
s/#.*//;
if (m/([0-9A-F]{4,6});\s*([0-9A-F]{4,6});\s*(.)/) {
my $mirroredChar = $offsets[$mirror[hex "0x$1"]] + hex "0x$1";
die "bidi bracket does not match mirrored char\n" unless $mirroredChar == hex "0x$2";
my $pbt = uc($3);
warn "unknown Bidi Bracket type" unless exists $pairedBracketTypeCode{$pbt};
$pairedBracketType[hex "0x$1"] = $pairedBracketTypeCode{$pbt};
}
}
close FH;
@ -736,27 +764,27 @@ struct nsCharProps1 {
/;
print DATA_TABLES "#ifndef ENABLE_INTL_API\n";
&genTables("CharProp1", $type, "nsCharProps1", 11, 5, \&sprintCharProps1, 1, 2, 1);
+print DATA_TABLES "#endif\n\n";
print DATA_TABLES "#endif\n\n";
sub sprintCharProps2
{
my $usv = shift;
return sprintf("{%d,%d,%d,%d,%d,%d,%d},",
$script[$usv], 0, $category[$usv],
$script[$usv], $pairedBracketType[$usv], $category[$usv],
$bidicategory[$usv], $xidmod[$usv], $numericvalue[$usv],
$verticalOrientation[$usv]);
}
$type = q/
$type = q|
struct nsCharProps2 {
unsigned char mScriptCode:8;
unsigned char mUnused:3;
unsigned char mPairedBracketType:3; // only 2 bits actually needed
unsigned char mCategory:5;
unsigned char mBidiCategory:5;
unsigned char mXidmod:4;
signed char mNumericValue:5;
unsigned char mVertOrient:2;
};
/;
|;
&genTables("CharProp2", $type, "nsCharProps2", 11, 5, \&sprintCharProps2, 16, 4, 1);
print HEADER "#pragma pack()\n\n";

View File

@ -170,6 +170,26 @@ GetScriptTagForCode(int32_t aScriptCode)
return sScriptCodeToTag[aScriptCode];
}
PairedBracketType GetPairedBracketType(uint32_t aCh)
{
#if ENABLE_INTL_API
return PairedBracketType
(u_getIntPropertyValue(aCh, UCHAR_BIDI_PAIRED_BRACKET_TYPE));
#else
return PairedBracketType(GetCharProps2(aCh).mPairedBracketType);
#endif
}
uint32_t GetPairedBracket(uint32_t aCh)
{
#if ENABLE_INTL_API
return u_getBidiPairedBracket(aCh);
#else
return GetPairedBracketType(aCh) != PAIRED_BRACKET_TYPE_NONE
? GetMirroredChar(aCh) : aCh;
#endif
}
static inline uint32_t
GetCaseMapValue(uint32_t aCh)
{

View File

@ -57,6 +57,16 @@ inline VerticalOrientation GetVerticalOrientation(uint32_t aCh) {
return VerticalOrientation(GetCharProps2(aCh).mVertOrient);
}
/* This MUST match the values assigned by genUnicodePropertyData.pl! */
enum PairedBracketType {
PAIRED_BRACKET_TYPE_NONE = 0,
PAIRED_BRACKET_TYPE_OPEN = 1,
PAIRED_BRACKET_TYPE_CLOSE = 2
};
PairedBracketType GetPairedBracketType(uint32_t aCh);
uint32_t GetPairedBracket(uint32_t aCh);
enum XidmodType {
XIDMOD_RECOMMENDED,
XIDMOD_INCLUSION,

View File

@ -11,7 +11,7 @@
*/
/*
* Created on Mon Sep 7 02:52:23 2015 from UCD data files with version info:
* Created on Tue Nov 17 07:34:16 2015 from UCD data files with version info:
*
# Date: 2015-06-16, 20:24:00 GMT [KW]
@ -38,6 +38,9 @@ Standard.
# BidiMirroring-8.0.0.txt
# Date: 2015-01-20, 18:30:00 GMT [KW, LI]
# BidiBrackets-8.0.0.txt
# Date: 2015-01-20, 19:00:00 GMT [AG, LI, KW]
# HangulSyllableType-8.0.0.txt
# Date: 2014-12-16, 23:07:45 GMT [MD]
@ -411,9 +414,9 @@ static const uint16_t sCharProp2Pages[7][2048] = {
static const nsCharProps2 sCharProp2Values[646][32] = {
{{0,0,0,18,12,-1,1},{0,0,0,18,12,-1,1},{0,0,0,18,12,-1,1},{0,0,0,18,12,-1,1},{0,0,0,18,12,-1,1},{0,0,0,18,12,-1,1},{0,0,0,18,12,-1,1},{0,0,0,18,12,-1,1},{0,0,0,18,12,-1,1},{0,0,0,8,8,-1,1},{0,0,0,7,8,-1,1},{0,0,0,8,8,-1,1},{0,0,0,9,8,-1,1},{0,0,0,7,8,-1,1},{0,0,0,18,12,-1,1},{0,0,0,18,12,-1,1},{0,0,0,18,12,-1,1},{0,0,0,18,12,-1,1},{0,0,0,18,12,-1,1},{0,0,0,18,12,-1,1},{0,0,0,18,12,-1,1},{0,0,0,18,12,-1,1},{0,0,0,18,12,-1,1},{0,0,0,18,12,-1,1},{0,0,0,18,12,-1,1},{0,0,0,18,12,-1,1},{0,0,0,18,12,-1,1},{0,0,0,18,12,-1,1},{0,0,0,7,12,-1,1},{0,0,0,7,12,-1,1},{0,0,0,7,12,-1,1},{0,0,0,8,12,-1,1}},
{{0,0,29,9,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,4,8,-1,1},{0,0,23,4,8,-1,1},{0,0,21,4,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,1,-1,1},{0,0,22,10,8,-1,1},{0,0,18,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,25,3,8,-1,1},{0,0,21,6,8,-1,1},{0,0,17,3,1,-1,1},{0,0,21,6,1,-1,1},{0,0,21,6,8,-1,1},{0,0,13,2,0,0,1},{0,0,13,2,0,1,1},{0,0,13,2,0,2,1},{0,0,13,2,0,3,1},{0,0,13,2,0,4,1},{0,0,13,2,0,5,1},{0,0,13,2,0,6,1},{0,0,13,2,0,7,1},{0,0,13,2,0,8,1},{0,0,13,2,0,9,1},{0,0,21,6,1,-1,1},{0,0,21,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,21,10,8,-1,1}},
{{0,0,21,10,8,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{0,0,22,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,18,10,8,-1,1},{0,0,24,10,8,-1,1},{0,0,16,10,0,-1,1}},
{{0,0,24,10,8,-1,1},{25,0,5,0,0,-1,1},{25,0,5,0,0,-1,1},{25,0,5,0,0,-1,1},{25,0,5,0,0,-1,1},{25,0,5,0,0,-1,1},{25,0,5,0,0,-1,1},{25,0,5,0,0,-1,1},{25,0,5,0,0,-1,1},{25,0,5,0,0,-1,1},{25,0,5,0,0,-1,1},{25,0,5,0,0,-1,1},{25,0,5,0,0,-1,1},{25,0,5,0,0,-1,1},{25,0,5,0,0,-1,1},{25,0,5,0,0,-1,1},{25,0,5,0,0,-1,1},{25,0,5,0,0,-1,1},{25,0,5,0,0,-1,1},{25,0,5,0,0,-1,1},{25,0,5,0,0,-1,1},{25,0,5,0,0,-1,1},{25,0,5,0,0,-1,1},{25,0,5,0,0,-1,1},{25,0,5,0,0,-1,1},{25,0,5,0,0,-1,1},{25,0,5,0,0,-1,1},{0,0,22,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,18,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,0,18,12,-1,1}},
{{0,0,29,9,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,4,8,-1,1},{0,0,23,4,8,-1,1},{0,0,21,4,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,1,-1,1},{0,1,22,10,8,-1,1},{0,2,18,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,25,3,8,-1,1},{0,0,21,6,8,-1,1},{0,0,17,3,1,-1,1},{0,0,21,6,1,-1,1},{0,0,21,6,8,-1,1},{0,0,13,2,0,0,1},{0,0,13,2,0,1,1},{0,0,13,2,0,2,1},{0,0,13,2,0,3,1},{0,0,13,2,0,4,1},{0,0,13,2,0,5,1},{0,0,13,2,0,6,1},{0,0,13,2,0,7,1},{0,0,13,2,0,8,1},{0,0,13,2,0,9,1},{0,0,21,6,1,-1,1},{0,0,21,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,21,10,8,-1,1}},
{{0,0,21,10,8,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{0,1,22,10,8,-1,1},{0,0,21,10,8,-1,1},{0,2,18,10,8,-1,1},{0,0,24,10,8,-1,1},{0,0,16,10,0,-1,1}},
{{0,0,24,10,8,-1,1},{25,0,5,0,0,-1,1},{25,0,5,0,0,-1,1},{25,0,5,0,0,-1,1},{25,0,5,0,0,-1,1},{25,0,5,0,0,-1,1},{25,0,5,0,0,-1,1},{25,0,5,0,0,-1,1},{25,0,5,0,0,-1,1},{25,0,5,0,0,-1,1},{25,0,5,0,0,-1,1},{25,0,5,0,0,-1,1},{25,0,5,0,0,-1,1},{25,0,5,0,0,-1,1},{25,0,5,0,0,-1,1},{25,0,5,0,0,-1,1},{25,0,5,0,0,-1,1},{25,0,5,0,0,-1,1},{25,0,5,0,0,-1,1},{25,0,5,0,0,-1,1},{25,0,5,0,0,-1,1},{25,0,5,0,0,-1,1},{25,0,5,0,0,-1,1},{25,0,5,0,0,-1,1},{25,0,5,0,0,-1,1},{25,0,5,0,0,-1,1},{25,0,5,0,0,-1,1},{0,1,22,10,8,-1,1},{0,0,25,10,8,-1,1},{0,2,18,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,0,18,12,-1,1}},
{{0,0,0,18,12,-1,1},{0,0,0,18,12,-1,1},{0,0,0,18,12,-1,1},{0,0,0,18,12,-1,1},{0,0,0,18,12,-1,1},{0,0,0,7,8,-1,1},{0,0,0,18,12,-1,1},{0,0,0,18,12,-1,1},{0,0,0,18,12,-1,1},{0,0,0,18,12,-1,1},{0,0,0,18,12,-1,1},{0,0,0,18,12,-1,1},{0,0,0,18,12,-1,1},{0,0,0,18,12,-1,1},{0,0,0,18,12,-1,1},{0,0,0,18,12,-1,1},{0,0,0,18,12,-1,1},{0,0,0,18,12,-1,1},{0,0,0,18,12,-1,1},{0,0,0,18,12,-1,1},{0,0,0,18,12,-1,1},{0,0,0,18,12,-1,1},{0,0,0,18,12,-1,1},{0,0,0,18,12,-1,1},{0,0,0,18,12,-1,1},{0,0,0,18,12,-1,1},{0,0,0,18,12,-1,1},{0,0,0,18,12,-1,1},{0,0,0,18,12,-1,1},{0,0,0,18,12,-1,1},{0,0,0,18,12,-1,1},{0,0,0,18,12,-1,1}},
{{0,0,29,6,9,-1,1},{0,0,21,10,8,-1,1},{0,0,23,4,8,-1,1},{0,0,23,4,8,-1,1},{0,0,23,4,8,-1,1},{0,0,23,4,8,-1,1},{0,0,26,10,8,-1,1},{0,0,21,10,8,-1,0},{0,0,24,10,9,-1,1},{0,0,26,10,8,-1,0},{25,0,7,0,9,-1,1},{0,0,20,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,1,18,10,-1,1},{0,0,26,10,8,-1,0},{0,0,24,10,9,-1,1},{0,0,26,4,8,-1,1},{0,0,25,4,8,-1,0},{0,0,15,2,9,2,1},{0,0,15,2,9,3,1},{0,0,24,10,9,-1,1},{0,0,5,0,9,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,1,-1,1},{0,0,24,10,9,-1,1},{0,0,15,2,9,1,1},{25,0,7,0,9,-1,1},{0,0,19,10,8,-1,1},{0,0,15,10,9,-1,0},{0,0,15,10,9,-1,0},{0,0,15,10,9,-1,0},{0,0,21,10,8,-1,1}},
{{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{0,0,25,10,8,-1,0},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,9,0,0,-1,1},{25,0,5,0,0,-1,1}},
@ -525,7 +528,7 @@ static const nsCharProps2 sCharProp2Values[646][32] = {
{{61,0,2,0,12,-1,1},{24,0,7,0,0,-1,1},{24,0,7,0,0,-1,1},{24,0,7,0,0,-1,1},{61,0,2,0,12,-1,1},{24,0,7,0,0,-1,1},{61,0,2,0,12,-1,1},{24,0,7,0,0,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{24,0,7,0,0,-1,1},{24,0,7,0,0,-1,1},{61,0,2,0,12,-1,1},{24,0,7,0,0,-1,1},{24,0,7,0,0,-1,1},{24,0,7,0,0,-1,1},{24,0,7,0,0,-1,1},{24,0,12,17,0,-1,1},{24,0,7,0,0,-1,1},{24,0,7,0,9,-1,1},{24,0,12,17,0,-1,1},{24,0,12,17,0,-1,1},{24,0,12,17,0,-1,1},{24,0,12,17,0,-1,1},{24,0,12,17,0,-1,1},{24,0,12,17,0,-1,1},{61,0,2,0,12,-1,1},{24,0,12,17,0,-1,1},{24,0,12,17,0,-1,1},{24,0,7,0,0,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1}},
{{24,0,7,0,0,-1,1},{24,0,7,0,0,-1,1},{24,0,7,0,0,-1,1},{24,0,7,0,0,-1,1},{24,0,7,0,0,-1,1},{61,0,2,0,12,-1,1},{24,0,6,0,0,-1,1},{61,0,2,0,12,-1,1},{24,0,12,17,0,-1,1},{24,0,12,17,0,-1,1},{24,0,12,17,0,-1,1},{24,0,12,17,0,-1,1},{24,0,12,17,0,-1,1},{24,0,12,17,0,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{24,0,13,0,0,0,1},{24,0,13,0,0,1,1},{24,0,13,0,0,2,1},{24,0,13,0,0,3,1},{24,0,13,0,0,4,1},{24,0,13,0,0,5,1},{24,0,13,0,0,6,1},{24,0,13,0,0,7,1},{24,0,13,0,0,8,1},{24,0,13,0,0,9,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{24,0,7,0,9,-1,1},{24,0,7,0,9,-1,1},{24,0,7,0,0,-1,1},{24,0,7,0,0,-1,1}},
{{39,0,7,0,0,-1,1},{39,0,26,0,8,-1,1},{39,0,26,0,8,-1,1},{39,0,26,0,8,-1,1},{39,0,21,0,8,-1,1},{39,0,21,0,8,-1,1},{39,0,21,0,8,-1,1},{39,0,21,0,8,-1,1},{39,0,21,0,8,-1,1},{39,0,21,0,8,-1,1},{39,0,21,0,8,-1,1},{39,0,21,0,1,-1,1},{39,0,21,0,9,-1,1},{39,0,21,0,8,-1,1},{39,0,21,0,8,-1,1},{39,0,21,0,8,-1,1},{39,0,21,0,8,-1,1},{39,0,21,0,8,-1,1},{39,0,21,0,8,-1,1},{39,0,26,0,8,-1,1},{39,0,21,0,8,-1,1},{39,0,26,0,8,-1,1},{39,0,26,0,8,-1,1},{39,0,26,0,8,-1,1},{39,0,12,17,3,-1,1},{39,0,12,17,3,-1,1},{39,0,26,0,8,-1,1},{39,0,26,0,8,-1,1},{39,0,26,0,8,-1,1},{39,0,26,0,8,-1,1},{39,0,26,0,8,-1,1},{39,0,26,0,8,-1,1}},
{{39,0,13,0,0,0,1},{39,0,13,0,0,1,1},{39,0,13,0,0,2,1},{39,0,13,0,0,3,1},{39,0,13,0,0,4,1},{39,0,13,0,0,5,1},{39,0,13,0,0,6,1},{39,0,13,0,0,7,1},{39,0,13,0,0,8,1},{39,0,13,0,0,9,1},{39,0,15,0,8,-1,1},{39,0,15,0,8,-1,1},{39,0,15,0,8,-1,1},{39,0,15,0,8,-1,1},{39,0,15,0,8,-1,1},{39,0,15,0,8,-1,1},{39,0,15,0,8,-1,1},{39,0,15,0,8,-1,1},{39,0,15,0,8,-1,1},{39,0,15,0,8,-1,1},{39,0,26,0,8,-1,1},{39,0,12,17,0,-1,1},{39,0,26,0,8,-1,1},{39,0,12,17,0,-1,1},{39,0,26,0,8,-1,1},{39,0,12,17,2,-1,1},{39,0,22,10,8,-1,1},{39,0,18,10,8,-1,1},{39,0,22,10,8,-1,1},{39,0,18,10,8,-1,1},{39,0,10,0,0,-1,1},{39,0,10,0,0,-1,1}},
{{39,0,13,0,0,0,1},{39,0,13,0,0,1,1},{39,0,13,0,0,2,1},{39,0,13,0,0,3,1},{39,0,13,0,0,4,1},{39,0,13,0,0,5,1},{39,0,13,0,0,6,1},{39,0,13,0,0,7,1},{39,0,13,0,0,8,1},{39,0,13,0,0,9,1},{39,0,15,0,8,-1,1},{39,0,15,0,8,-1,1},{39,0,15,0,8,-1,1},{39,0,15,0,8,-1,1},{39,0,15,0,8,-1,1},{39,0,15,0,8,-1,1},{39,0,15,0,8,-1,1},{39,0,15,0,8,-1,1},{39,0,15,0,8,-1,1},{39,0,15,0,8,-1,1},{39,0,26,0,8,-1,1},{39,0,12,17,0,-1,1},{39,0,26,0,8,-1,1},{39,0,12,17,0,-1,1},{39,0,26,0,8,-1,1},{39,0,12,17,2,-1,1},{39,1,22,10,8,-1,1},{39,2,18,10,8,-1,1},{39,1,22,10,8,-1,1},{39,2,18,10,8,-1,1},{39,0,10,0,0,-1,1},{39,0,10,0,0,-1,1}},
{{39,0,7,0,0,-1,1},{39,0,7,0,0,-1,1},{39,0,7,0,0,-1,1},{39,0,7,0,9,-1,1},{39,0,7,0,0,-1,1},{39,0,7,0,0,-1,1},{39,0,7,0,0,-1,1},{39,0,7,0,0,-1,1},{61,0,2,0,12,-1,1},{39,0,7,0,0,-1,1},{39,0,7,0,0,-1,1},{39,0,7,0,0,-1,1},{39,0,7,0,0,-1,1},{39,0,7,0,9,-1,1},{39,0,7,0,0,-1,1},{39,0,7,0,0,-1,1},{39,0,7,0,0,-1,1},{39,0,7,0,0,-1,1},{39,0,7,0,9,-1,1},{39,0,7,0,0,-1,1},{39,0,7,0,0,-1,1},{39,0,7,0,0,-1,1},{39,0,7,0,0,-1,1},{39,0,7,0,9,-1,1},{39,0,7,0,0,-1,1},{39,0,7,0,0,-1,1},{39,0,7,0,0,-1,1},{39,0,7,0,0,-1,1},{39,0,7,0,9,-1,1},{39,0,7,0,0,-1,1},{39,0,7,0,0,-1,1},{39,0,7,0,0,-1,1}},
{{39,0,7,0,0,-1,1},{39,0,7,0,0,-1,1},{39,0,7,0,0,-1,1},{39,0,7,0,0,-1,1},{39,0,7,0,0,-1,1},{39,0,7,0,0,-1,1},{39,0,7,0,0,-1,1},{39,0,7,0,0,-1,1},{39,0,7,0,0,-1,1},{39,0,7,0,9,-1,1},{39,0,7,0,0,-1,1},{39,0,7,0,0,-1,1},{39,0,7,0,0,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{39,0,12,17,0,-1,1},{39,0,12,17,0,-1,1},{39,0,12,17,9,-1,1},{39,0,12,17,0,-1,1},{39,0,12,17,9,-1,1},{39,0,12,17,9,-1,1},{39,0,12,17,11,-1,1},{39,0,12,17,9,-1,1},{39,0,12,17,11,-1,1},{39,0,12,17,0,-1,1},{39,0,12,17,0,-1,1},{39,0,12,17,0,-1,1},{39,0,12,17,0,-1,1},{39,0,12,17,0,-1,1},{39,0,10,0,0,-1,1}},
{{39,0,12,17,0,-1,1},{39,0,12,17,9,-1,1},{39,0,12,17,0,-1,1},{39,0,12,17,0,-1,1},{39,0,12,17,0,-1,1},{39,0,21,0,8,-1,1},{39,0,12,17,0,-1,1},{39,0,12,17,0,-1,1},{39,0,7,0,0,-1,1},{39,0,7,0,0,-1,1},{39,0,7,0,0,-1,1},{39,0,7,0,0,-1,1},{39,0,7,0,0,-1,1},{39,0,12,17,0,-1,1},{39,0,12,17,0,-1,1},{39,0,12,17,0,-1,1},{39,0,12,17,0,-1,1},{39,0,12,17,0,-1,1},{39,0,12,17,0,-1,1},{39,0,12,17,9,-1,1},{39,0,12,17,0,-1,1},{39,0,12,17,0,-1,1},{39,0,12,17,0,-1,1},{39,0,12,17,0,-1,1},{61,0,2,0,12,-1,1},{39,0,12,17,0,-1,1},{39,0,12,17,0,-1,1},{39,0,12,17,0,-1,1},{39,0,12,17,0,-1,1},{39,0,12,17,9,-1,1},{39,0,12,17,0,-1,1},{39,0,12,17,0,-1,1}},
@ -556,7 +559,7 @@ static const nsCharProps2 sCharProp2Values[646][32] = {
{{40,0,17,10,8,-1,1},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0}},
{{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0}},
{{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,21,0,8,-1,0},{40,0,21,0,8,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0},{40,0,7,0,5,-1,0}},
{{29,0,29,9,8,-1,1},{29,0,7,0,7,-1,1},{29,0,7,0,7,-1,1},{29,0,7,0,7,-1,1},{29,0,7,0,7,-1,1},{29,0,7,0,7,-1,1},{29,0,7,0,7,-1,1},{29,0,7,0,7,-1,1},{29,0,7,0,7,-1,1},{29,0,7,0,7,-1,1},{29,0,7,0,7,-1,1},{29,0,7,0,7,-1,1},{29,0,7,0,7,-1,1},{29,0,7,0,7,-1,1},{29,0,7,0,7,-1,1},{29,0,7,0,7,-1,1},{29,0,7,0,7,-1,1},{29,0,7,0,7,-1,1},{29,0,7,0,7,-1,1},{29,0,7,0,7,-1,1},{29,0,7,0,7,-1,1},{29,0,7,0,7,-1,1},{29,0,7,0,7,-1,1},{29,0,7,0,7,-1,1},{29,0,7,0,7,-1,1},{29,0,7,0,7,-1,1},{29,0,7,0,7,-1,1},{29,0,22,10,8,-1,1},{29,0,18,10,8,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1}},
{{29,0,29,9,8,-1,1},{29,0,7,0,7,-1,1},{29,0,7,0,7,-1,1},{29,0,7,0,7,-1,1},{29,0,7,0,7,-1,1},{29,0,7,0,7,-1,1},{29,0,7,0,7,-1,1},{29,0,7,0,7,-1,1},{29,0,7,0,7,-1,1},{29,0,7,0,7,-1,1},{29,0,7,0,7,-1,1},{29,0,7,0,7,-1,1},{29,0,7,0,7,-1,1},{29,0,7,0,7,-1,1},{29,0,7,0,7,-1,1},{29,0,7,0,7,-1,1},{29,0,7,0,7,-1,1},{29,0,7,0,7,-1,1},{29,0,7,0,7,-1,1},{29,0,7,0,7,-1,1},{29,0,7,0,7,-1,1},{29,0,7,0,7,-1,1},{29,0,7,0,7,-1,1},{29,0,7,0,7,-1,1},{29,0,7,0,7,-1,1},{29,0,7,0,7,-1,1},{29,0,7,0,7,-1,1},{29,1,22,10,8,-1,1},{29,2,18,10,8,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1}},
{{32,0,7,0,7,-1,1},{32,0,7,0,7,-1,1},{32,0,7,0,7,-1,1},{32,0,7,0,7,-1,1},{32,0,7,0,7,-1,1},{32,0,7,0,7,-1,1},{32,0,7,0,7,-1,1},{32,0,7,0,7,-1,1},{32,0,7,0,7,-1,1},{32,0,7,0,7,-1,1},{32,0,7,0,7,-1,1},{32,0,7,0,7,-1,1},{32,0,7,0,7,-1,1},{32,0,7,0,7,-1,1},{32,0,7,0,7,-1,1},{32,0,7,0,7,-1,1},{32,0,7,0,7,-1,1},{32,0,7,0,7,-1,1},{32,0,7,0,7,-1,1},{32,0,7,0,7,-1,1},{32,0,7,0,7,-1,1},{32,0,7,0,7,-1,1},{32,0,7,0,7,-1,1},{32,0,7,0,7,-1,1},{32,0,7,0,7,-1,1},{32,0,7,0,7,-1,1},{32,0,7,0,7,-1,1},{32,0,7,0,7,-1,1},{32,0,7,0,7,-1,1},{32,0,7,0,7,-1,1},{32,0,7,0,7,-1,1},{32,0,7,0,7,-1,1}},
{{32,0,7,0,7,-1,1},{32,0,7,0,7,-1,1},{32,0,7,0,7,-1,1},{32,0,7,0,7,-1,1},{32,0,7,0,7,-1,1},{32,0,7,0,7,-1,1},{32,0,7,0,7,-1,1},{32,0,7,0,7,-1,1},{32,0,7,0,7,-1,1},{32,0,7,0,7,-1,1},{32,0,7,0,7,-1,1},{0,0,21,0,8,-1,1},{0,0,21,0,8,-1,1},{0,0,21,0,8,-1,1},{32,0,14,0,7,-1,1},{32,0,14,0,7,-1,1},{32,0,14,0,7,-1,1},{32,0,7,0,7,-1,1},{32,0,7,0,7,-1,1},{32,0,7,0,7,-1,1},{32,0,7,0,7,-1,1},{32,0,7,0,7,-1,1},{32,0,7,0,7,-1,1},{32,0,7,0,7,-1,1},{32,0,7,0,7,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1}},
{{42,0,7,0,7,-1,1},{42,0,7,0,7,-1,1},{42,0,7,0,7,-1,1},{42,0,7,0,7,-1,1},{42,0,7,0,7,-1,1},{42,0,7,0,7,-1,1},{42,0,7,0,7,-1,1},{42,0,7,0,7,-1,1},{42,0,7,0,7,-1,1},{42,0,7,0,7,-1,1},{42,0,7,0,7,-1,1},{42,0,7,0,7,-1,1},{42,0,7,0,7,-1,1},{61,0,2,0,12,-1,1},{42,0,7,0,7,-1,1},{42,0,7,0,7,-1,1},{42,0,7,0,7,-1,1},{42,0,7,0,7,-1,1},{42,0,12,17,7,-1,1},{42,0,12,17,7,-1,1},{42,0,12,17,7,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1}},
@ -621,9 +624,9 @@ static const nsCharProps2 sCharProp2Values[646][32] = {
{{14,0,5,0,0,-1,1},{14,0,5,0,0,-1,1},{14,0,5,0,0,-1,1},{14,0,5,0,9,-1,1},{14,0,5,0,0,-1,1},{14,0,5,0,0,-1,1},{14,0,5,0,0,-1,1},{14,0,5,0,0,-1,1},{14,0,9,0,0,-1,1},{14,0,9,0,0,-1,1},{14,0,9,0,0,-1,1},{14,0,9,0,9,-1,1},{14,0,9,0,0,-1,1},{14,0,24,10,9,-1,1},{14,0,24,10,9,-1,1},{14,0,24,10,9,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{14,0,5,0,0,-1,1},{14,0,5,0,0,-1,1},{14,0,5,0,0,-1,1},{61,0,2,0,12,-1,1},{14,0,5,0,0,-1,1},{14,0,5,0,0,-1,1},{14,0,9,0,0,-1,1},{14,0,9,0,9,-1,1},{14,0,9,0,0,-1,1},{14,0,9,0,9,-1,1},{14,0,8,0,0,-1,1},{14,0,24,10,9,-1,1},{14,0,24,10,9,-1,1},{61,0,2,0,12,-1,1}},
{{0,0,29,9,9,-1,1},{0,0,29,9,9,-1,1},{0,0,29,9,9,-1,1},{0,0,29,9,9,-1,1},{0,0,29,9,9,-1,1},{0,0,29,9,9,-1,1},{0,0,29,9,9,-1,1},{0,0,29,9,9,-1,1},{0,0,29,9,9,-1,1},{0,0,29,9,9,-1,1},{0,0,29,9,9,-1,1},{0,0,1,18,10,-1,1},{1,0,1,18,1,-1,1},{1,0,1,18,1,-1,1},{0,0,1,0,10,-1,1},{0,0,1,1,10,-1,1},{0,0,17,10,1,-1,1},{0,0,17,10,9,-1,1},{0,0,17,10,8,-1,1},{0,0,17,10,8,-1,1},{0,0,17,10,8,-1,1},{0,0,17,10,8,-1,1},{0,0,21,10,8,-1,0},{0,0,21,10,9,-1,1},{0,0,20,10,8,-1,1},{0,0,19,10,1,-1,1},{0,0,22,10,8,-1,1},{0,0,20,10,8,-1,1},{0,0,20,10,8,-1,1},{0,0,19,10,8,-1,1},{0,0,22,10,8,-1,1},{0,0,20,10,8,-1,1}},
{{0,0,21,10,8,-1,0},{0,0,21,10,8,-1,0},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,9,-1,1},{0,0,21,10,9,-1,1},{0,0,21,10,9,-1,1},{0,0,21,10,1,-1,1},{0,0,27,9,8,-1,1},{0,0,28,7,8,-1,1},{0,0,1,11,10,-1,1},{0,0,1,14,10,-1,1},{0,0,1,16,10,-1,1},{0,0,1,12,10,-1,1},{0,0,1,15,10,-1,1},{0,0,29,6,9,-1,1},{0,0,21,4,8,-1,0},{0,0,21,4,8,-1,0},{0,0,21,4,8,-1,1},{0,0,21,4,9,-1,1},{0,0,21,4,9,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,9,-1,1},{0,0,21,10,9,-1,1},{0,0,21,10,8,-1,1},{0,0,20,10,8,-1,1},{0,0,19,10,8,-1,1},{0,0,21,10,8,-1,0},{0,0,21,10,9,-1,0},{0,0,21,10,8,-1,1},{0,0,21,10,9,-1,1},{0,0,16,10,3,-1,1}},
{{0,0,16,10,3,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,0},{0,0,21,10,8,-1,1},{0,0,25,6,8,-1,1},{0,0,22,10,8,-1,1},{0,0,18,10,8,-1,1},{0,0,21,10,9,-1,0},{0,0,21,10,9,-1,0},{0,0,21,10,9,-1,0},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,0},{0,0,25,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,16,10,2,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,9,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,29,9,9,-1,1}},
{{0,0,1,18,10,-1,1},{0,0,1,18,10,-1,1},{0,0,1,18,10,-1,1},{0,0,1,18,10,-1,1},{0,0,1,18,10,-1,1},{61,0,2,0,12,-1,0},{0,0,1,19,10,-1,1},{0,0,1,20,10,-1,1},{0,0,1,21,10,-1,1},{0,0,1,22,10,-1,1},{0,0,1,18,11,-1,1},{0,0,1,18,11,-1,1},{0,0,1,18,11,-1,1},{0,0,1,18,11,-1,1},{0,0,1,18,11,-1,1},{0,0,1,18,11,-1,1},{0,0,15,2,9,0,1},{25,0,6,0,9,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{0,0,15,2,9,4,1},{0,0,15,2,9,5,1},{0,0,15,2,9,6,1},{0,0,15,2,9,7,1},{0,0,15,2,9,8,1},{0,0,15,2,9,9,1},{0,0,25,3,9,-1,1},{0,0,25,3,9,-1,1},{0,0,25,10,9,-1,1},{0,0,22,10,9,-1,1},{0,0,18,10,9,-1,1},{25,0,6,0,9,-1,1}},
{{0,0,15,2,9,0,1},{0,0,15,2,9,1,1},{0,0,15,2,9,2,1},{0,0,15,2,9,3,1},{0,0,15,2,9,4,1},{0,0,15,2,9,5,1},{0,0,15,2,9,6,1},{0,0,15,2,9,7,1},{0,0,15,2,9,8,1},{0,0,15,2,9,9,1},{0,0,25,3,9,-1,1},{0,0,25,3,9,-1,1},{0,0,25,10,9,-1,1},{0,0,22,10,9,-1,1},{0,0,18,10,9,-1,1},{61,0,2,0,12,-1,1},{25,0,6,0,9,-1,1},{25,0,6,0,9,-1,1},{25,0,6,0,9,-1,1},{25,0,6,0,9,-1,1},{25,0,6,0,9,-1,1},{25,0,6,0,9,-1,1},{25,0,6,0,9,-1,1},{25,0,6,0,9,-1,1},{25,0,6,0,9,-1,1},{25,0,6,0,9,-1,1},{25,0,6,0,9,-1,1},{25,0,6,0,9,-1,1},{25,0,6,0,9,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1}},
{{0,0,16,10,3,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,0},{0,0,21,10,8,-1,1},{0,0,25,6,8,-1,1},{0,1,22,10,8,-1,1},{0,2,18,10,8,-1,1},{0,0,21,10,9,-1,0},{0,0,21,10,9,-1,0},{0,0,21,10,9,-1,0},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,0},{0,0,25,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,16,10,2,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,9,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,29,9,9,-1,1}},
{{0,0,1,18,10,-1,1},{0,0,1,18,10,-1,1},{0,0,1,18,10,-1,1},{0,0,1,18,10,-1,1},{0,0,1,18,10,-1,1},{61,0,2,0,12,-1,0},{0,0,1,19,10,-1,1},{0,0,1,20,10,-1,1},{0,0,1,21,10,-1,1},{0,0,1,22,10,-1,1},{0,0,1,18,11,-1,1},{0,0,1,18,11,-1,1},{0,0,1,18,11,-1,1},{0,0,1,18,11,-1,1},{0,0,1,18,11,-1,1},{0,0,1,18,11,-1,1},{0,0,15,2,9,0,1},{25,0,6,0,9,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{0,0,15,2,9,4,1},{0,0,15,2,9,5,1},{0,0,15,2,9,6,1},{0,0,15,2,9,7,1},{0,0,15,2,9,8,1},{0,0,15,2,9,9,1},{0,0,25,3,9,-1,1},{0,0,25,3,9,-1,1},{0,0,25,10,9,-1,1},{0,1,22,10,9,-1,1},{0,2,18,10,9,-1,1},{25,0,6,0,9,-1,1}},
{{0,0,15,2,9,0,1},{0,0,15,2,9,1,1},{0,0,15,2,9,2,1},{0,0,15,2,9,3,1},{0,0,15,2,9,4,1},{0,0,15,2,9,5,1},{0,0,15,2,9,6,1},{0,0,15,2,9,7,1},{0,0,15,2,9,8,1},{0,0,15,2,9,9,1},{0,0,25,3,9,-1,1},{0,0,25,3,9,-1,1},{0,0,25,10,9,-1,1},{0,1,22,10,9,-1,1},{0,2,18,10,9,-1,1},{61,0,2,0,12,-1,1},{25,0,6,0,9,-1,1},{25,0,6,0,9,-1,1},{25,0,6,0,9,-1,1},{25,0,6,0,9,-1,1},{25,0,6,0,9,-1,1},{25,0,6,0,9,-1,1},{25,0,6,0,9,-1,1},{25,0,6,0,9,-1,1},{25,0,6,0,9,-1,1},{25,0,6,0,9,-1,1},{25,0,6,0,9,-1,1},{25,0,6,0,9,-1,1},{25,0,6,0,9,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1}},
{{0,0,23,4,8,-1,1},{0,0,23,4,8,-1,1},{0,0,23,4,8,-1,1},{0,0,23,4,8,-1,1},{0,0,23,4,8,-1,1},{0,0,23,4,8,-1,1},{0,0,23,4,8,-1,1},{0,0,23,4,8,-1,1},{0,0,23,4,9,-1,1},{0,0,23,4,8,-1,1},{0,0,23,4,8,-1,1},{0,0,23,4,8,-1,1},{0,0,23,4,8,-1,1},{0,0,23,4,8,-1,1},{0,0,23,4,8,-1,1},{0,0,23,4,8,-1,1},{0,0,23,4,8,-1,1},{0,0,23,4,8,-1,1},{0,0,23,4,8,-1,1},{0,0,23,4,8,-1,1},{0,0,23,4,8,-1,1},{0,0,23,4,8,-1,1},{0,0,23,4,8,-1,1},{0,0,23,4,8,-1,1},{0,0,23,4,8,-1,1},{0,0,23,4,8,-1,1},{0,0,23,4,8,-1,1},{0,0,23,4,8,-1,1},{0,0,23,4,8,-1,1},{0,0,23,4,8,-1,1},{0,0,23,4,8,-1,1},{61,0,2,4,12,-1,1}},
{{61,0,2,4,12,-1,1},{61,0,2,4,12,-1,1},{61,0,2,4,12,-1,1},{61,0,2,4,12,-1,1},{61,0,2,4,12,-1,1},{61,0,2,4,12,-1,1},{61,0,2,4,12,-1,1},{61,0,2,4,12,-1,1},{61,0,2,4,12,-1,1},{61,0,2,4,12,-1,1},{61,0,2,4,12,-1,1},{61,0,2,4,12,-1,1},{61,0,2,4,12,-1,1},{61,0,2,4,12,-1,1},{61,0,2,4,12,-1,1},{61,0,2,4,12,-1,1},{1,0,12,17,7,-1,1},{1,0,12,17,7,-1,1},{1,0,12,17,7,-1,1},{1,0,12,17,7,-1,1},{1,0,12,17,7,-1,1},{1,0,12,17,7,-1,1},{1,0,12,17,7,-1,1},{1,0,12,17,7,-1,1},{1,0,12,17,7,-1,1},{1,0,12,17,7,-1,1},{1,0,12,17,7,-1,1},{1,0,12,17,7,-1,1},{1,0,12,17,7,-1,1},{1,0,11,17,8,-1,0},{1,0,11,17,8,-1,0},{1,0,11,17,8,-1,0}},
{{1,0,11,17,8,-1,0},{1,0,12,17,7,-1,1},{1,0,11,17,8,-1,0},{1,0,11,17,8,-1,0},{1,0,11,17,8,-1,0},{1,0,12,17,7,-1,1},{1,0,12,17,7,-1,1},{1,0,12,17,7,-1,1},{1,0,12,17,7,-1,1},{1,0,12,17,7,-1,1},{1,0,12,17,7,-1,1},{1,0,12,17,7,-1,1},{1,0,12,17,7,-1,1},{1,0,12,17,7,-1,1},{1,0,12,17,7,-1,1},{1,0,12,17,7,-1,1},{1,0,12,17,7,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1}},
@ -638,8 +641,8 @@ static const nsCharProps2 sCharProp2Values[646][32] = {
{{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,3,8,-1,1},{0,0,25,4,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,0},{0,0,25,10,8,-1,1}},
{{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,9,-1,1},{0,0,25,10,9,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,9,-1,1},{0,0,25,10,9,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,0},{0,0,25,10,8,-1,0},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1}},
{{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1}},
{{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,22,10,8,-1,1},{0,0,18,10,8,-1,1},{0,0,22,10,8,-1,1},{0,0,18,10,8,-1,1},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0}},
{{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,26,10,8,-1,1},{0,0,26,10,8,-1,1},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,22,10,11,-1,3},{0,0,18,10,11,-1,3},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,1},{0,0,26,10,8,-1,1},{0,0,26,10,8,-1,1},{0,0,26,10,8,-1,1},{0,0,26,10,8,-1,1},{0,0,26,10,8,-1,1},{0,0,26,10,8,-1,1},{0,0,26,10,8,-1,1},{0,0,26,10,8,-1,1},{0,0,26,10,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1}},
{{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,1,22,10,8,-1,1},{0,2,18,10,8,-1,1},{0,1,22,10,8,-1,1},{0,2,18,10,8,-1,1},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0}},
{{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,26,10,8,-1,1},{0,0,26,10,8,-1,1},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,1,22,10,11,-1,3},{0,2,18,10,11,-1,3},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,1},{0,0,26,10,8,-1,1},{0,0,26,10,8,-1,1},{0,0,26,10,8,-1,1},{0,0,26,10,8,-1,1},{0,0,26,10,8,-1,1},{0,0,26,10,8,-1,1},{0,0,26,10,8,-1,1},{0,0,26,10,8,-1,1},{0,0,26,10,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1}},
{{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1}},
{{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,0,8,-1,1},{0,0,26,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0}},
{{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,0,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1}},
@ -660,14 +663,14 @@ static const nsCharProps2 sCharProp2Values[646][32] = {
{{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,1},{0,0,26,10,8,-1,1},{0,0,26,10,8,-1,1},{0,0,26,10,8,-1,1},{0,0,26,10,8,-1,1},{0,0,26,10,8,-1,1}},
{{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,25,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0}},
{{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,0,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0}},
{{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,22,10,8,-1,1},{0,0,18,10,8,-1,1},{0,0,22,10,8,-1,1},{0,0,18,10,8,-1,1},{0,0,22,10,8,-1,1},{0,0,18,10,8,-1,1},{0,0,22,10,8,-1,1},{0,0,18,10,8,-1,1},{0,0,22,10,8,-1,1},{0,0,18,10,8,-1,1},{0,0,22,10,8,-1,1},{0,0,18,10,8,-1,1},{0,0,22,10,8,-1,1},{0,0,18,10,8,-1,1},{0,0,15,10,8,1,0},{0,0,15,10,8,2,0},{0,0,15,10,8,3,0},{0,0,15,10,8,4,0},{0,0,15,10,8,5,0},{0,0,15,10,8,6,0},{0,0,15,10,8,7,0},{0,0,15,10,8,8,0},{0,0,15,10,8,9,0},{0,0,15,10,8,-1,0}},
{{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,1,22,10,8,-1,1},{0,2,18,10,8,-1,1},{0,1,22,10,8,-1,1},{0,2,18,10,8,-1,1},{0,1,22,10,8,-1,1},{0,2,18,10,8,-1,1},{0,1,22,10,8,-1,1},{0,2,18,10,8,-1,1},{0,1,22,10,8,-1,1},{0,2,18,10,8,-1,1},{0,1,22,10,8,-1,1},{0,2,18,10,8,-1,1},{0,1,22,10,8,-1,1},{0,2,18,10,8,-1,1},{0,0,15,10,8,1,0},{0,0,15,10,8,2,0},{0,0,15,10,8,3,0},{0,0,15,10,8,4,0},{0,0,15,10,8,5,0},{0,0,15,10,8,6,0},{0,0,15,10,8,7,0},{0,0,15,10,8,8,0},{0,0,15,10,8,9,0},{0,0,15,10,8,-1,0}},
{{0,0,15,10,8,1,0},{0,0,15,10,8,2,0},{0,0,15,10,8,3,0},{0,0,15,10,8,4,0},{0,0,15,10,8,5,0},{0,0,15,10,8,6,0},{0,0,15,10,8,7,0},{0,0,15,10,8,8,0},{0,0,15,10,8,9,0},{0,0,15,10,8,-1,0},{0,0,15,10,8,1,0},{0,0,15,10,8,2,0},{0,0,15,10,8,3,0},{0,0,15,10,8,4,0},{0,0,15,10,8,5,0},{0,0,15,10,8,6,0},{0,0,15,10,8,7,0},{0,0,15,10,8,8,0},{0,0,15,10,8,9,0},{0,0,15,10,8,-1,0},{0,0,26,10,8,-1,1},{0,0,26,10,8,-1,1},{0,0,26,10,8,-1,1},{0,0,26,10,8,-1,1},{0,0,26,10,8,-1,1},{0,0,26,10,8,-1,1},{0,0,26,10,8,-1,1},{0,0,26,10,8,-1,1},{0,0,26,10,8,-1,1},{0,0,26,10,8,-1,1},{0,0,26,10,8,-1,1},{0,0,26,10,8,-1,1}},
{{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,22,10,8,-1,1},{0,0,18,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1}},
{{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,22,10,8,-1,1},{0,0,18,10,8,-1,1},{0,0,22,10,8,-1,1},{0,0,18,10,8,-1,1},{0,0,22,10,8,-1,1},{0,0,18,10,8,-1,1},{0,0,22,10,8,-1,1},{0,0,18,10,8,-1,1},{0,0,22,10,8,-1,1},{0,0,18,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1}},
{{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,1,22,10,8,-1,1},{0,2,18,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1}},
{{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,1,22,10,8,-1,1},{0,2,18,10,8,-1,1},{0,1,22,10,8,-1,1},{0,2,18,10,8,-1,1},{0,1,22,10,8,-1,1},{0,2,18,10,8,-1,1},{0,1,22,10,8,-1,1},{0,2,18,10,8,-1,1},{0,1,22,10,8,-1,1},{0,2,18,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1}},
{{46,0,26,0,8,-1,1},{46,0,26,0,8,-1,1},{46,0,26,0,8,-1,1},{46,0,26,0,8,-1,1},{46,0,26,0,8,-1,1},{46,0,26,0,8,-1,1},{46,0,26,0,8,-1,1},{46,0,26,0,8,-1,1},{46,0,26,0,8,-1,1},{46,0,26,0,8,-1,1},{46,0,26,0,8,-1,1},{46,0,26,0,8,-1,1},{46,0,26,0,8,-1,1},{46,0,26,0,8,-1,1},{46,0,26,0,8,-1,1},{46,0,26,0,8,-1,1},{46,0,26,0,8,-1,1},{46,0,26,0,8,-1,1},{46,0,26,0,8,-1,1},{46,0,26,0,8,-1,1},{46,0,26,0,8,-1,1},{46,0,26,0,8,-1,1},{46,0,26,0,8,-1,1},{46,0,26,0,8,-1,1},{46,0,26,0,8,-1,1},{46,0,26,0,8,-1,1},{46,0,26,0,8,-1,1},{46,0,26,0,8,-1,1},{46,0,26,0,8,-1,1},{46,0,26,0,8,-1,1},{46,0,26,0,8,-1,1},{46,0,26,0,8,-1,1}},
{{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,22,10,8,-1,1},{0,0,18,10,8,-1,1},{0,0,22,10,8,-1,1},{0,0,18,10,8,-1,1},{0,0,22,10,8,-1,1},{0,0,18,10,8,-1,1},{0,0,22,10,8,-1,1},{0,0,18,10,8,-1,1},{0,0,22,10,8,-1,1},{0,0,18,10,8,-1,1},{0,0,22,10,8,-1,1},{0,0,18,10,8,-1,1},{0,0,22,10,8,-1,1},{0,0,18,10,8,-1,1},{0,0,22,10,8,-1,1},{0,0,18,10,8,-1,1},{0,0,22,10,8,-1,1},{0,0,18,10,8,-1,1},{0,0,22,10,8,-1,1},{0,0,18,10,8,-1,1},{0,0,22,10,8,-1,1},{0,0,18,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1}},
{{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,22,10,8,-1,1},{0,0,18,10,8,-1,1},{0,0,22,10,8,-1,1},{0,0,18,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1}},
{{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,22,10,8,-1,1},{0,0,18,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1}},
{{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,1,22,10,8,-1,1},{0,2,18,10,8,-1,1},{0,1,22,10,8,-1,1},{0,2,18,10,8,-1,1},{0,1,22,10,8,-1,1},{0,2,18,10,8,-1,1},{0,1,22,10,8,-1,1},{0,2,18,10,8,-1,1},{0,1,22,10,8,-1,1},{0,2,18,10,8,-1,1},{0,1,22,10,8,-1,1},{0,2,18,10,8,-1,1},{0,1,22,10,8,-1,1},{0,2,18,10,8,-1,1},{0,1,22,10,8,-1,1},{0,2,18,10,8,-1,1},{0,1,22,10,8,-1,1},{0,2,18,10,8,-1,1},{0,1,22,10,8,-1,1},{0,2,18,10,8,-1,1},{0,1,22,10,8,-1,1},{0,2,18,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1}},
{{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,1,22,10,8,-1,1},{0,2,18,10,8,-1,1},{0,1,22,10,8,-1,1},{0,2,18,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1}},
{{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,1,22,10,8,-1,1},{0,2,18,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1}},
{{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,9,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1}},
{{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,9,-1,1},{0,0,25,10,9,-1,1},{0,0,25,10,9,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1}},
{{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,9,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1},{0,0,25,10,8,-1,1}},
@ -693,7 +696,7 @@ static const nsCharProps2 sCharProp2Values[646][32] = {
{{11,0,7,0,0,-1,1},{11,0,7,0,0,-1,1},{11,0,7,0,0,-1,1},{11,0,7,0,0,-1,1},{11,0,7,0,0,-1,1},{11,0,7,0,0,-1,1},{11,0,7,0,0,-1,1},{61,0,2,0,12,-1,1},{11,0,7,0,0,-1,1},{11,0,7,0,0,-1,1},{11,0,7,0,0,-1,1},{11,0,7,0,0,-1,1},{11,0,7,0,0,-1,1},{11,0,7,0,0,-1,1},{11,0,7,0,0,-1,1},{61,0,2,0,12,-1,1},{11,0,7,0,0,-1,1},{11,0,7,0,0,-1,1},{11,0,7,0,0,-1,1},{11,0,7,0,0,-1,1},{11,0,7,0,0,-1,1},{11,0,7,0,0,-1,1},{11,0,7,0,0,-1,1},{61,0,2,0,12,-1,1},{11,0,7,0,0,-1,1},{11,0,7,0,0,-1,1},{11,0,7,0,0,-1,1},{11,0,7,0,0,-1,1},{11,0,7,0,0,-1,1},{11,0,7,0,0,-1,1},{11,0,7,0,0,-1,1},{61,0,2,0,12,-1,1}},
{{8,0,12,17,4,-1,1},{8,0,12,17,4,-1,1},{8,0,12,17,4,-1,1},{8,0,12,17,4,-1,1},{8,0,12,17,4,-1,1},{8,0,12,17,4,-1,1},{8,0,12,17,4,-1,1},{8,0,12,17,4,-1,1},{8,0,12,17,4,-1,1},{8,0,12,17,4,-1,1},{8,0,12,17,4,-1,1},{8,0,12,17,4,-1,1},{8,0,12,17,4,-1,1},{8,0,12,17,4,-1,1},{8,0,12,17,4,-1,1},{8,0,12,17,4,-1,1},{8,0,12,17,4,-1,1},{8,0,12,17,4,-1,1},{8,0,12,17,4,-1,1},{8,0,12,17,4,-1,1},{8,0,12,17,4,-1,1},{8,0,12,17,4,-1,1},{8,0,12,17,4,-1,1},{8,0,12,17,4,-1,1},{8,0,12,17,4,-1,1},{8,0,12,17,4,-1,1},{8,0,12,17,4,-1,1},{8,0,12,17,4,-1,1},{8,0,12,17,4,-1,1},{8,0,12,17,4,-1,1},{8,0,12,17,4,-1,1},{8,0,12,17,4,-1,1}},
{{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,20,10,8,-1,1},{0,0,19,10,8,-1,1},{0,0,20,10,8,-1,1},{0,0,19,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,20,10,8,-1,1},{0,0,19,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,20,10,8,-1,1},{0,0,19,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,17,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,17,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,20,10,8,-1,1},{0,0,19,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1}},
{{0,0,20,10,8,-1,1},{0,0,19,10,8,-1,1},{0,0,22,10,8,-1,1},{0,0,18,10,8,-1,1},{0,0,22,10,8,-1,1},{0,0,18,10,8,-1,1},{0,0,22,10,8,-1,1},{0,0,18,10,8,-1,1},{0,0,22,10,8,-1,1},{0,0,18,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,6,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,17,10,8,-1,1},{0,0,17,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1}},
{{0,0,20,10,8,-1,1},{0,0,19,10,8,-1,1},{0,1,22,10,8,-1,1},{0,2,18,10,8,-1,1},{0,1,22,10,8,-1,1},{0,2,18,10,8,-1,1},{0,1,22,10,8,-1,1},{0,2,18,10,8,-1,1},{0,1,22,10,8,-1,1},{0,2,18,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,6,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,17,10,8,-1,1},{0,0,17,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,21,10,8,-1,1}},
{{0,0,17,10,8,-1,1},{0,0,21,10,8,-1,1},{0,0,22,10,8,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1}},
{{17,0,26,10,8,-1,0},{17,0,26,10,8,-1,0},{17,0,26,10,8,-1,0},{17,0,26,10,8,-1,0},{17,0,26,10,8,-1,0},{17,0,26,10,8,-1,0},{17,0,26,10,8,-1,0},{17,0,26,10,8,-1,0},{17,0,26,10,8,-1,0},{17,0,26,10,8,-1,0},{17,0,26,10,8,-1,0},{17,0,26,10,8,-1,0},{17,0,26,10,8,-1,0},{17,0,26,10,8,-1,0},{17,0,26,10,8,-1,0},{17,0,26,10,8,-1,0},{17,0,26,10,8,-1,0},{17,0,26,10,8,-1,0},{17,0,26,10,8,-1,0},{17,0,26,10,8,-1,0},{17,0,26,10,8,-1,0},{17,0,26,10,8,-1,0},{17,0,26,10,8,-1,0},{17,0,26,10,8,-1,0},{17,0,26,10,8,-1,0},{17,0,26,10,8,-1,0},{61,0,2,0,12,-1,0},{17,0,26,10,8,-1,0},{17,0,26,10,8,-1,0},{17,0,26,10,8,-1,0},{17,0,26,10,8,-1,0},{17,0,26,10,9,-1,0}},
{{17,0,26,10,8,-1,0},{17,0,26,10,8,-1,0},{17,0,26,10,8,-1,0},{17,0,26,10,8,-1,0},{17,0,26,10,8,-1,0},{17,0,26,10,8,-1,0},{17,0,26,10,8,-1,0},{17,0,26,10,8,-1,0},{17,0,26,10,8,-1,0},{17,0,26,10,8,-1,0},{17,0,26,10,8,-1,0},{17,0,26,10,8,-1,0},{17,0,26,10,8,-1,0},{17,0,26,10,8,-1,0},{17,0,26,10,8,-1,0},{17,0,26,10,8,-1,0},{17,0,26,10,8,-1,0},{17,0,26,10,8,-1,0},{17,0,26,10,8,-1,0},{17,0,26,10,8,-1,0},{17,0,26,10,8,-1,0},{17,0,26,10,8,-1,0},{17,0,26,10,8,-1,0},{17,0,26,10,8,-1,0},{17,0,26,10,8,-1,0},{17,0,26,10,8,-1,0},{17,0,26,10,8,-1,0},{17,0,26,10,8,-1,0},{17,0,26,10,8,-1,0},{17,0,26,10,8,-1,0},{17,0,26,10,8,-1,0},{17,0,26,10,8,-1,0}},
@ -701,7 +704,7 @@ static const nsCharProps2 sCharProp2Values[646][32] = {
{{17,0,26,10,9,-1,0},{17,0,26,10,9,-1,0},{17,0,26,10,9,-1,0},{17,0,26,10,9,-1,0},{17,0,26,10,9,-1,0},{17,0,26,10,9,-1,0},{17,0,26,10,9,-1,0},{17,0,26,10,9,-1,0},{17,0,26,10,9,-1,0},{17,0,26,10,9,-1,0},{17,0,26,10,9,-1,0},{17,0,26,10,9,-1,0},{17,0,26,10,9,-1,0},{17,0,26,10,9,-1,0},{17,0,26,10,9,-1,0},{17,0,26,10,9,-1,0},{17,0,26,10,9,-1,0},{17,0,26,10,9,-1,0},{17,0,26,10,9,-1,0},{17,0,26,10,9,-1,0},{17,0,26,10,9,-1,0},{17,0,26,10,9,-1,0},{17,0,26,10,9,-1,0},{17,0,26,10,9,-1,0},{17,0,26,10,9,-1,0},{17,0,26,10,9,-1,0},{17,0,26,10,9,-1,0},{17,0,26,10,9,-1,0},{17,0,26,10,9,-1,0},{17,0,26,10,9,-1,0},{17,0,26,10,9,-1,0},{17,0,26,10,9,-1,0}},
{{17,0,26,10,9,-1,0},{17,0,26,10,9,-1,0},{17,0,26,10,9,-1,0},{17,0,26,10,9,-1,0},{17,0,26,10,9,-1,0},{17,0,26,10,9,-1,0},{17,0,26,10,9,-1,0},{17,0,26,10,9,-1,0},{17,0,26,10,9,-1,0},{17,0,26,10,9,-1,0},{17,0,26,10,9,-1,0},{17,0,26,10,9,-1,0},{17,0,26,10,9,-1,0},{17,0,26,10,9,-1,0},{17,0,26,10,9,-1,0},{17,0,26,10,9,-1,0},{17,0,26,10,9,-1,0},{17,0,26,10,9,-1,0},{17,0,26,10,9,-1,0},{17,0,26,10,9,-1,0},{17,0,26,10,9,-1,0},{17,0,26,10,9,-1,0},{61,0,2,0,12,-1,0},{61,0,2,0,12,-1,0},{61,0,2,0,12,-1,0},{61,0,2,0,12,-1,0},{61,0,2,0,12,-1,0},{61,0,2,0,12,-1,0},{61,0,2,0,12,-1,0},{61,0,2,0,12,-1,0},{61,0,2,0,12,-1,0},{61,0,2,0,12,-1,0}},
{{61,0,2,0,12,-1,0},{61,0,2,0,12,-1,0},{61,0,2,0,12,-1,0},{61,0,2,0,12,-1,0},{61,0,2,0,12,-1,0},{61,0,2,0,12,-1,0},{61,0,2,0,12,-1,0},{61,0,2,0,12,-1,0},{61,0,2,0,12,-1,0},{61,0,2,0,12,-1,0},{61,0,2,0,12,-1,0},{61,0,2,0,12,-1,0},{61,0,2,0,12,-1,0},{61,0,2,0,12,-1,0},{61,0,2,0,12,-1,0},{61,0,2,0,12,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{61,0,2,0,12,-1,0},{61,0,2,0,12,-1,0},{61,0,2,0,12,-1,0},{61,0,2,0,12,-1,0}},
{{0,0,29,9,9,-1,0},{0,0,21,10,8,-1,2},{0,0,21,10,8,-1,2},{0,0,21,10,8,-1,0},{0,0,26,10,8,-1,0},{17,0,6,0,0,-1,0},{0,0,7,0,0,-1,0},{17,0,14,0,0,-1,0},{0,0,22,10,8,-1,3},{0,0,18,10,8,-1,3},{0,0,22,10,8,-1,3},{0,0,18,10,8,-1,3},{0,0,22,10,8,-1,3},{0,0,18,10,8,-1,3},{0,0,22,10,8,-1,3},{0,0,18,10,8,-1,3},{0,0,22,10,8,-1,3},{0,0,18,10,8,-1,3},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,22,10,8,-1,3},{0,0,18,10,8,-1,3},{0,0,22,10,8,-1,3},{0,0,18,10,8,-1,3},{0,0,22,10,8,-1,3},{0,0,18,10,8,-1,3},{0,0,22,10,8,-1,3},{0,0,18,10,8,-1,3},{0,0,17,10,8,-1,3},{0,0,22,10,8,-1,3},{0,0,18,10,8,-1,3},{0,0,18,10,8,-1,3}},
{{0,0,29,9,9,-1,0},{0,0,21,10,8,-1,2},{0,0,21,10,8,-1,2},{0,0,21,10,8,-1,0},{0,0,26,10,8,-1,0},{17,0,6,0,0,-1,0},{0,0,7,0,0,-1,0},{17,0,14,0,0,-1,0},{0,1,22,10,8,-1,3},{0,2,18,10,8,-1,3},{0,1,22,10,8,-1,3},{0,2,18,10,8,-1,3},{0,1,22,10,8,-1,3},{0,2,18,10,8,-1,3},{0,1,22,10,8,-1,3},{0,2,18,10,8,-1,3},{0,1,22,10,8,-1,3},{0,2,18,10,8,-1,3},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0},{0,1,22,10,8,-1,3},{0,2,18,10,8,-1,3},{0,1,22,10,8,-1,3},{0,2,18,10,8,-1,3},{0,1,22,10,8,-1,3},{0,2,18,10,8,-1,3},{0,1,22,10,8,-1,3},{0,2,18,10,8,-1,3},{0,0,17,10,8,-1,3},{0,0,22,10,8,-1,3},{0,0,18,10,8,-1,3},{0,0,18,10,8,-1,3}},
{{0,0,26,10,8,-1,0},{17,0,14,0,3,-1,0},{17,0,14,0,3,-1,0},{17,0,14,0,3,-1,0},{17,0,14,0,3,-1,0},{17,0,14,0,3,-1,0},{17,0,14,0,3,-1,0},{17,0,14,0,3,-1,0},{17,0,14,0,3,-1,0},{17,0,14,0,3,-1,0},{1,0,12,17,3,-1,0},{1,0,12,17,3,-1,0},{1,0,12,17,3,-1,0},{1,0,12,17,3,-1,0},{18,0,10,0,4,-1,0},{18,0,10,0,4,-1,0},{0,0,17,10,8,-1,3},{0,0,6,0,3,-1,0},{0,0,6,0,3,-1,0},{0,0,6,0,3,-1,0},{0,0,6,0,3,-1,0},{0,0,6,0,3,-1,0},{0,0,26,10,9,-1,0},{0,0,26,10,8,-1,0},{17,0,14,0,9,-1,0},{17,0,14,0,9,-1,0},{17,0,14,0,9,-1,0},{17,0,6,0,3,-1,0},{0,0,7,0,3,-1,0},{0,0,21,10,8,-1,0},{0,0,26,10,8,-1,0},{0,0,26,10,8,-1,0}},
{{61,0,2,0,12,-1,0},{20,0,7,0,0,-1,2},{20,0,7,0,0,-1,0},{20,0,7,0,0,-1,2},{20,0,7,0,0,-1,0},{20,0,7,0,0,-1,2},{20,0,7,0,0,-1,0},{20,0,7,0,0,-1,2},{20,0,7,0,0,-1,0},{20,0,7,0,0,-1,2},{20,0,7,0,0,-1,0},{20,0,7,0,0,-1,0},{20,0,7,0,0,-1,0},{20,0,7,0,0,-1,0},{20,0,7,0,0,-1,0},{20,0,7,0,0,-1,0},{20,0,7,0,0,-1,0},{20,0,7,0,0,-1,0},{20,0,7,0,0,-1,0},{20,0,7,0,0,-1,0},{20,0,7,0,0,-1,0},{20,0,7,0,0,-1,0},{20,0,7,0,0,-1,0},{20,0,7,0,0,-1,0},{20,0,7,0,0,-1,0},{20,0,7,0,0,-1,0},{20,0,7,0,0,-1,0},{20,0,7,0,0,-1,0},{20,0,7,0,0,-1,0},{20,0,7,0,0,-1,0},{20,0,7,0,0,-1,0},{20,0,7,0,0,-1,0}},
{{20,0,7,0,0,-1,0},{20,0,7,0,0,-1,0},{20,0,7,0,0,-1,0},{20,0,7,0,0,-1,2},{20,0,7,0,0,-1,0},{20,0,7,0,0,-1,0},{20,0,7,0,0,-1,0},{20,0,7,0,0,-1,0},{20,0,7,0,0,-1,0},{20,0,7,0,0,-1,0},{20,0,7,0,0,-1,0},{20,0,7,0,0,-1,0},{20,0,7,0,0,-1,0},{20,0,7,0,0,-1,0},{20,0,7,0,0,-1,0},{20,0,7,0,0,-1,0},{20,0,7,0,0,-1,0},{20,0,7,0,0,-1,0},{20,0,7,0,0,-1,0},{20,0,7,0,0,-1,0},{20,0,7,0,0,-1,0},{20,0,7,0,0,-1,0},{20,0,7,0,0,-1,0},{20,0,7,0,0,-1,0},{20,0,7,0,0,-1,0},{20,0,7,0,0,-1,0},{20,0,7,0,0,-1,0},{20,0,7,0,0,-1,0},{20,0,7,0,0,-1,0},{20,0,7,0,0,-1,0},{20,0,7,0,0,-1,0},{20,0,7,0,0,-1,0}},
@ -806,13 +809,13 @@ static const nsCharProps2 sCharProp2Values[646][32] = {
{{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{2,0,7,13,9,-1,1},{2,0,7,13,9,-1,1},{2,0,7,13,9,-1,1},{2,0,7,13,9,-1,1},{2,0,7,13,9,-1,1},{2,0,7,13,9,-1,1},{2,0,7,13,9,-1,1},{2,0,7,13,9,-1,1},{2,0,7,13,9,-1,1},{2,0,7,13,9,-1,1},{2,0,7,13,9,-1,1},{2,0,7,13,9,-1,1},{2,0,23,13,9,-1,1},{2,0,26,10,8,-1,1},{61,0,2,13,12,-1,1},{61,0,2,13,12,-1,1}},
{{1,0,12,17,10,-1,1},{1,0,12,17,10,-1,1},{1,0,12,17,10,-1,1},{1,0,12,17,10,-1,1},{1,0,12,17,10,-1,1},{1,0,12,17,10,-1,1},{1,0,12,17,10,-1,1},{1,0,12,17,10,-1,1},{1,0,12,17,10,-1,1},{1,0,12,17,10,-1,1},{1,0,12,17,10,-1,1},{1,0,12,17,10,-1,1},{1,0,12,17,10,-1,1},{1,0,12,17,10,-1,1},{1,0,12,17,10,-1,1},{1,0,12,17,10,-1,1},{0,0,21,10,9,-1,0},{0,0,21,10,9,-1,0},{0,0,21,10,9,-1,0},{0,0,21,10,9,-1,0},{0,0,21,10,9,-1,0},{0,0,21,10,9,-1,0},{0,0,21,10,9,-1,0},{0,0,22,10,9,-1,0},{0,0,18,10,9,-1,0},{0,0,21,10,9,-1,0},{61,0,2,0,12,-1,0},{61,0,2,0,12,-1,0},{61,0,2,0,12,-1,0},{61,0,2,0,12,-1,0},{61,0,2,0,12,-1,0},{61,0,2,0,12,-1,0}},
{{1,0,12,17,3,-1,1},{1,0,12,17,3,-1,1},{1,0,12,17,3,-1,1},{1,0,12,17,3,-1,1},{1,0,12,17,3,-1,1},{1,0,12,17,3,-1,1},{1,0,12,17,3,-1,1},{1,0,12,17,3,-1,1},{1,0,12,17,3,-1,1},{1,0,12,17,3,-1,1},{1,0,12,17,3,-1,1},{1,0,12,17,3,-1,1},{1,0,12,17,3,-1,1},{1,0,12,17,3,-1,1},{8,0,12,17,3,-1,1},{8,0,12,17,3,-1,1},{0,0,21,10,9,-1,0},{0,0,17,10,9,-1,0},{0,0,17,10,9,-1,0},{0,0,16,10,9,-1,0},{0,0,16,10,9,-1,0},{0,0,22,10,9,-1,0},{0,0,18,10,9,-1,0},{0,0,22,10,9,-1,0},{0,0,18,10,9,-1,0},{0,0,22,10,9,-1,0},{0,0,18,10,9,-1,0},{0,0,22,10,9,-1,0},{0,0,18,10,9,-1,0},{0,0,22,10,9,-1,0},{0,0,18,10,9,-1,0},{0,0,22,10,9,-1,0}},
{{0,0,18,10,9,-1,0},{0,0,22,10,9,-1,0},{0,0,18,10,9,-1,0},{0,0,22,10,9,-1,0},{0,0,18,10,9,-1,0},{0,0,21,10,8,-1,0},{0,0,21,10,8,-1,0},{0,0,22,10,9,-1,0},{0,0,18,10,9,-1,0},{0,0,21,10,9,-1,1},{0,0,21,10,9,-1,1},{0,0,21,10,9,-1,1},{0,0,21,10,9,-1,1},{0,0,16,10,9,-1,1},{0,0,16,10,9,-1,1},{0,0,16,10,9,-1,1},{0,0,21,6,9,-1,2},{0,0,21,10,9,-1,2},{0,0,21,6,9,-1,2},{61,0,2,0,12,-1,0},{0,0,21,10,9,-1,0},{0,0,21,6,9,-1,0},{0,0,21,10,9,-1,0},{0,0,21,10,9,-1,0},{0,0,17,10,9,-1,1},{0,0,22,10,9,-1,3},{0,0,18,10,9,-1,3},{0,0,22,10,9,-1,3},{0,0,18,10,9,-1,3},{0,0,22,10,9,-1,3},{0,0,18,10,9,-1,3},{0,0,21,4,9,-1,0}},
{{0,0,18,10,9,-1,0},{0,0,22,10,9,-1,0},{0,0,18,10,9,-1,0},{0,0,22,10,9,-1,0},{0,0,18,10,9,-1,0},{0,0,21,10,8,-1,0},{0,0,21,10,8,-1,0},{0,0,22,10,9,-1,0},{0,0,18,10,9,-1,0},{0,0,21,10,9,-1,1},{0,0,21,10,9,-1,1},{0,0,21,10,9,-1,1},{0,0,21,10,9,-1,1},{0,0,16,10,9,-1,1},{0,0,16,10,9,-1,1},{0,0,16,10,9,-1,1},{0,0,21,6,9,-1,2},{0,0,21,10,9,-1,2},{0,0,21,6,9,-1,2},{61,0,2,0,12,-1,0},{0,0,21,10,9,-1,0},{0,0,21,6,9,-1,0},{0,0,21,10,9,-1,0},{0,0,21,10,9,-1,0},{0,0,17,10,9,-1,1},{0,1,22,10,9,-1,3},{0,2,18,10,9,-1,3},{0,1,22,10,9,-1,3},{0,2,18,10,9,-1,3},{0,1,22,10,9,-1,3},{0,2,18,10,9,-1,3},{0,0,21,4,9,-1,0}},
{{0,0,21,10,9,-1,0},{0,0,21,10,9,-1,0},{0,0,25,3,9,-1,0},{0,0,17,3,9,-1,1},{0,0,25,10,9,-1,1},{0,0,25,10,9,-1,1},{0,0,25,10,9,-1,1},{61,0,2,0,12,-1,0},{0,0,21,10,9,-1,0},{0,0,23,4,9,-1,0},{0,0,21,4,9,-1,0},{0,0,21,10,9,-1,0},{61,0,2,0,12,-1,0},{61,0,2,0,12,-1,0},{61,0,2,0,12,-1,0},{61,0,2,0,12,-1,0},{2,0,7,13,9,-1,1},{2,0,7,13,9,-1,1},{2,0,7,13,9,-1,1},{2,0,7,13,3,-1,1},{2,0,7,13,9,-1,1},{61,0,2,13,12,-1,1},{2,0,7,13,9,-1,1},{2,0,7,13,9,-1,1},{2,0,7,13,9,-1,1},{2,0,7,13,9,-1,1},{2,0,7,13,9,-1,1},{2,0,7,13,9,-1,1},{2,0,7,13,9,-1,1},{2,0,7,13,9,-1,1},{2,0,7,13,9,-1,1},{2,0,7,13,9,-1,1}},
{{2,0,7,13,9,-1,1},{2,0,7,13,9,-1,1},{2,0,7,13,9,-1,1},{2,0,7,13,9,-1,1},{2,0,7,13,9,-1,1},{2,0,7,13,9,-1,1},{2,0,7,13,9,-1,1},{2,0,7,13,9,-1,1},{2,0,7,13,9,-1,1},{2,0,7,13,9,-1,1},{2,0,7,13,9,-1,1},{2,0,7,13,9,-1,1},{2,0,7,13,9,-1,1},{2,0,7,13,9,-1,1},{2,0,7,13,9,-1,1},{2,0,7,13,9,-1,1},{2,0,7,13,9,-1,1},{2,0,7,13,9,-1,1},{2,0,7,13,9,-1,1},{2,0,7,13,9,-1,1},{2,0,7,13,9,-1,1},{2,0,7,13,9,-1,1},{2,0,7,13,9,-1,1},{2,0,7,13,9,-1,1},{2,0,7,13,9,-1,1},{2,0,7,13,9,-1,1},{2,0,7,13,9,-1,1},{2,0,7,13,9,-1,1},{2,0,7,13,9,-1,1},{61,0,2,13,12,-1,1},{61,0,2,13,12,-1,1},{0,0,1,18,10,-1,1}},
{{61,0,2,0,12,-1,1},{0,0,21,10,9,-1,2},{0,0,21,10,9,-1,0},{0,0,21,4,9,-1,0},{0,0,23,4,9,-1,0},{0,0,21,4,9,-1,0},{0,0,21,10,9,-1,0},{0,0,21,10,9,-1,0},{0,0,22,10,9,-1,3},{0,0,18,10,9,-1,3},{0,0,21,10,9,-1,0},{0,0,25,3,9,-1,0},{0,0,21,6,9,-1,2},{0,0,17,3,9,-1,1},{0,0,21,6,9,-1,2},{0,0,21,6,9,-1,0},{0,0,13,2,9,0,0},{0,0,13,2,9,1,0},{0,0,13,2,9,2,0},{0,0,13,2,9,3,0},{0,0,13,2,9,4,0},{0,0,13,2,9,5,0},{0,0,13,2,9,6,0},{0,0,13,2,9,7,0},{0,0,13,2,9,8,0},{0,0,13,2,9,9,0},{0,0,21,6,9,-1,3},{0,0,21,10,9,-1,3},{0,0,25,10,9,-1,1},{0,0,25,10,9,-1,1},{0,0,25,10,9,-1,1},{0,0,21,10,9,-1,2}},
{{0,0,21,10,9,-1,0},{25,0,9,0,9,-1,0},{25,0,9,0,9,-1,0},{25,0,9,0,9,-1,0},{25,0,9,0,9,-1,0},{25,0,9,0,9,-1,0},{25,0,9,0,9,-1,0},{25,0,9,0,9,-1,0},{25,0,9,0,9,-1,0},{25,0,9,0,9,-1,0},{25,0,9,0,9,-1,0},{25,0,9,0,9,-1,0},{25,0,9,0,9,-1,0},{25,0,9,0,9,-1,0},{25,0,9,0,9,-1,0},{25,0,9,0,9,-1,0},{25,0,9,0,9,-1,0},{25,0,9,0,9,-1,0},{25,0,9,0,9,-1,0},{25,0,9,0,9,-1,0},{25,0,9,0,9,-1,0},{25,0,9,0,9,-1,0},{25,0,9,0,9,-1,0},{25,0,9,0,9,-1,0},{25,0,9,0,9,-1,0},{25,0,9,0,9,-1,0},{25,0,9,0,9,-1,0},{0,0,22,10,9,-1,3},{0,0,21,10,9,-1,0},{0,0,18,10,9,-1,3},{0,0,24,10,9,-1,0},{0,0,16,10,9,-1,3}},
{{0,0,24,10,9,-1,0},{25,0,5,0,9,-1,0},{25,0,5,0,9,-1,0},{25,0,5,0,9,-1,0},{25,0,5,0,9,-1,0},{25,0,5,0,9,-1,0},{25,0,5,0,9,-1,0},{25,0,5,0,9,-1,0},{25,0,5,0,9,-1,0},{25,0,5,0,9,-1,0},{25,0,5,0,9,-1,0},{25,0,5,0,9,-1,0},{25,0,5,0,9,-1,0},{25,0,5,0,9,-1,0},{25,0,5,0,9,-1,0},{25,0,5,0,9,-1,0},{25,0,5,0,9,-1,0},{25,0,5,0,9,-1,0},{25,0,5,0,9,-1,0},{25,0,5,0,9,-1,0},{25,0,5,0,9,-1,0},{25,0,5,0,9,-1,0},{25,0,5,0,9,-1,0},{25,0,5,0,9,-1,0},{25,0,5,0,9,-1,0},{25,0,5,0,9,-1,0},{25,0,5,0,9,-1,0},{0,0,22,10,9,-1,3},{0,0,25,10,9,-1,3},{0,0,18,10,9,-1,3},{0,0,25,10,9,-1,3},{0,0,22,10,9,-1,3}},
{{0,0,18,10,9,-1,3},{0,0,21,10,9,-1,1},{0,0,22,10,9,-1,1},{0,0,18,10,9,-1,1},{0,0,21,10,9,-1,1},{0,0,21,10,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{0,0,6,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1}},
{{61,0,2,0,12,-1,1},{0,0,21,10,9,-1,2},{0,0,21,10,9,-1,0},{0,0,21,4,9,-1,0},{0,0,23,4,9,-1,0},{0,0,21,4,9,-1,0},{0,0,21,10,9,-1,0},{0,0,21,10,9,-1,0},{0,1,22,10,9,-1,3},{0,2,18,10,9,-1,3},{0,0,21,10,9,-1,0},{0,0,25,3,9,-1,0},{0,0,21,6,9,-1,2},{0,0,17,3,9,-1,1},{0,0,21,6,9,-1,2},{0,0,21,6,9,-1,0},{0,0,13,2,9,0,0},{0,0,13,2,9,1,0},{0,0,13,2,9,2,0},{0,0,13,2,9,3,0},{0,0,13,2,9,4,0},{0,0,13,2,9,5,0},{0,0,13,2,9,6,0},{0,0,13,2,9,7,0},{0,0,13,2,9,8,0},{0,0,13,2,9,9,0},{0,0,21,6,9,-1,3},{0,0,21,10,9,-1,3},{0,0,25,10,9,-1,1},{0,0,25,10,9,-1,1},{0,0,25,10,9,-1,1},{0,0,21,10,9,-1,2}},
{{0,0,21,10,9,-1,0},{25,0,9,0,9,-1,0},{25,0,9,0,9,-1,0},{25,0,9,0,9,-1,0},{25,0,9,0,9,-1,0},{25,0,9,0,9,-1,0},{25,0,9,0,9,-1,0},{25,0,9,0,9,-1,0},{25,0,9,0,9,-1,0},{25,0,9,0,9,-1,0},{25,0,9,0,9,-1,0},{25,0,9,0,9,-1,0},{25,0,9,0,9,-1,0},{25,0,9,0,9,-1,0},{25,0,9,0,9,-1,0},{25,0,9,0,9,-1,0},{25,0,9,0,9,-1,0},{25,0,9,0,9,-1,0},{25,0,9,0,9,-1,0},{25,0,9,0,9,-1,0},{25,0,9,0,9,-1,0},{25,0,9,0,9,-1,0},{25,0,9,0,9,-1,0},{25,0,9,0,9,-1,0},{25,0,9,0,9,-1,0},{25,0,9,0,9,-1,0},{25,0,9,0,9,-1,0},{0,1,22,10,9,-1,3},{0,0,21,10,9,-1,0},{0,2,18,10,9,-1,3},{0,0,24,10,9,-1,0},{0,0,16,10,9,-1,3}},
{{0,0,24,10,9,-1,0},{25,0,5,0,9,-1,0},{25,0,5,0,9,-1,0},{25,0,5,0,9,-1,0},{25,0,5,0,9,-1,0},{25,0,5,0,9,-1,0},{25,0,5,0,9,-1,0},{25,0,5,0,9,-1,0},{25,0,5,0,9,-1,0},{25,0,5,0,9,-1,0},{25,0,5,0,9,-1,0},{25,0,5,0,9,-1,0},{25,0,5,0,9,-1,0},{25,0,5,0,9,-1,0},{25,0,5,0,9,-1,0},{25,0,5,0,9,-1,0},{25,0,5,0,9,-1,0},{25,0,5,0,9,-1,0},{25,0,5,0,9,-1,0},{25,0,5,0,9,-1,0},{25,0,5,0,9,-1,0},{25,0,5,0,9,-1,0},{25,0,5,0,9,-1,0},{25,0,5,0,9,-1,0},{25,0,5,0,9,-1,0},{25,0,5,0,9,-1,0},{25,0,5,0,9,-1,0},{0,1,22,10,9,-1,3},{0,0,25,10,9,-1,3},{0,2,18,10,9,-1,3},{0,0,25,10,9,-1,3},{0,1,22,10,9,-1,3}},
{{0,2,18,10,9,-1,3},{0,0,21,10,9,-1,1},{0,1,22,10,9,-1,1},{0,2,18,10,9,-1,1},{0,0,21,10,9,-1,1},{0,0,21,10,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{0,0,6,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1}},
{{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{22,0,7,0,9,-1,1},{0,0,6,0,9,-1,1},{0,0,6,0,9,-1,1}},
{{18,0,7,0,10,-1,1},{18,0,7,0,9,-1,1},{18,0,7,0,9,-1,1},{18,0,7,0,9,-1,1},{18,0,7,0,9,-1,1},{18,0,7,0,9,-1,1},{18,0,7,0,9,-1,1},{18,0,7,0,9,-1,1},{18,0,7,0,9,-1,1},{18,0,7,0,9,-1,1},{18,0,7,0,9,-1,1},{18,0,7,0,9,-1,1},{18,0,7,0,9,-1,1},{18,0,7,0,9,-1,1},{18,0,7,0,9,-1,1},{18,0,7,0,9,-1,1},{18,0,7,0,9,-1,1},{18,0,7,0,9,-1,1},{18,0,7,0,9,-1,1},{18,0,7,0,9,-1,1},{18,0,7,0,9,-1,1},{18,0,7,0,9,-1,1},{18,0,7,0,9,-1,1},{18,0,7,0,9,-1,1},{18,0,7,0,9,-1,1},{18,0,7,0,9,-1,1},{18,0,7,0,9,-1,1},{18,0,7,0,9,-1,1},{18,0,7,0,9,-1,1},{18,0,7,0,9,-1,1},{18,0,7,0,9,-1,1},{61,0,2,0,12,-1,1}},
{{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{18,0,7,0,9,-1,1},{18,0,7,0,9,-1,1},{18,0,7,0,9,-1,1},{18,0,7,0,9,-1,1},{18,0,7,0,9,-1,1},{18,0,7,0,9,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{18,0,7,0,9,-1,1},{18,0,7,0,9,-1,1},{18,0,7,0,9,-1,1},{18,0,7,0,9,-1,1},{18,0,7,0,9,-1,1},{18,0,7,0,9,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{18,0,7,0,9,-1,1},{18,0,7,0,9,-1,1},{18,0,7,0,9,-1,1},{18,0,7,0,9,-1,1},{18,0,7,0,9,-1,1},{18,0,7,0,9,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{18,0,7,0,9,-1,1},{18,0,7,0,9,-1,1},{18,0,7,0,9,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1},{61,0,2,0,12,-1,1}},

View File

@ -11,7 +11,7 @@
*/
/*
* Created on Thu Sep 3 14:42:28 2015 from UCD data files with version info:
* Created on Tue Nov 17 07:34:16 2015 from UCD data files with version info:
*
# Date: 2015-06-16, 20:24:00 GMT [KW]
@ -38,6 +38,9 @@ Standard.
# BidiMirroring-8.0.0.txt
# Date: 2015-01-20, 18:30:00 GMT [KW, LI]
# BidiBrackets-8.0.0.txt
# Date: 2015-01-20, 19:00:00 GMT [AG, LI, KW]
# HangulSyllableType-8.0.0.txt
# Date: 2014-12-16, 23:07:45 GMT [MD]
@ -72,7 +75,7 @@ struct nsCharProps1 {
struct nsCharProps2 {
unsigned char mScriptCode:8;
unsigned char mUnused:3;
unsigned char mPairedBracketType:3; // only 2 bits actually needed
unsigned char mCategory:5;
unsigned char mBidiCategory:5;
unsigned char mXidmod:4;

View File

@ -177,6 +177,7 @@ class ModuleNamespaceObject : public ProxyObject
static const char family;
};
public:
static const ProxyHandler proxyHandler;
};
@ -316,4 +317,11 @@ JSObject* InitExportEntryClass(JSContext* cx, HandleObject obj);
} // namespace js
template<>
inline bool
JSObject::is<js::ModuleNamespaceObject>() const
{
return js::IsDerivedProxyObject(this, &js::ModuleNamespaceObject::proxyHandler);
}
#endif /* builtin_ModuleObject_h */

View File

@ -0,0 +1,14 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// A dummy implementation of the module resolve hook used by module tests. This
// implements the bare minimum necessary to allow modules to refer to each
// other.
let moduleRepo = {};
setModuleResolveHook(function(module, specifier) {
if (specifier in moduleRepo)
return moduleRepo[specifier];
throw "Module '" + specifier + "' not found";
});

View File

@ -3,6 +3,7 @@
"use strict";
load(libdir + "asserts.js");
load(libdir + "dummyModuleResolveHook.js");
function checkModuleEval(source, result) {
let m = parseModule(source);
@ -15,19 +16,11 @@ function checkModuleSyntaxError(source) {
assertThrowsInstanceOf(() => m.declarationInstantiation(), SyntaxError);
}
let moduleRepo = new Map();
setModuleResolveHook(function(module, specifier) {
if (specifier in moduleRepo)
return moduleRepo[specifier];
throw "Module " + specifier + " not found";
});
let a = moduleRepo['a'] = parseModule("export var a = 1; export var b = 2;");
let b = moduleRepo['b'] = parseModule("export var b = 3; export var c = 4;");
let c = moduleRepo['c'] = parseModule("export * from 'a'; export * from 'b';");
let ms = [a, b, c];
ms.map((m) => m.declarationInstantiation());
ms.map((m) => m.evaluation(), moduleRepo.values());
c.declarationInstantiation();
c.evaluation();
// Check importing/exporting non-ambiguous name works.
checkModuleEval("import { a } from 'c'; a;", 1);

View File

@ -1,7 +1,4 @@
let moduleRepo = new Map();
setModuleResolveHook(function(module, specifier) {
return moduleRepo[specifier];
});
load(libdir + "dummyModuleResolveHook.js");
let a = moduleRepo['a'] = parseModule("export var a = 1; export var b = 2;");
let b = moduleRepo['b'] = parseModule("export var b = 3; export var c = 4;");
let c = moduleRepo['c'] = parseModule("export * from 'a'; export * from 'b';");

View File

@ -57,11 +57,11 @@ dbg.onDebuggerStatement = function (frame) {
f = g2.eval(
`
let moduleRepo = new Map();
let moduleRepo = {};
setModuleResolveHook(function(module, specifier) {
if (specifier in moduleRepo)
return moduleRepo[specifier];
throw "Module " + specifier + " not found";
throw "Module '" + specifier + "' not found";
});
// Set up a module to import from.

View File

@ -4,13 +4,7 @@
load(libdir + "asserts.js");
load(libdir + "iteration.js");
let moduleRepo = new Map();
setModuleResolveHook(function(module, specifier) {
if (specifier in moduleRepo)
return moduleRepo[specifier];
throw "Module " + specifier + " not found";
});
load(libdir + "dummyModuleResolveHook.js");
function parseAndEvaluate(source) {
let m = parseModule(source);

View File

@ -1,13 +1,8 @@
// Test many exports.
const count = 1024;
load(libdir + "dummyModuleResolveHook.js");
let moduleRepo = {};
setModuleResolveHook(function(module, specifier) {
if (specifier in moduleRepo)
return moduleRepo[specifier];
throw "Module " + specifier + " not found";
});
const count = 1024;
let s = "";
for (let i = 0; i < count; i++)

View File

@ -1,13 +1,8 @@
// Test importing an import many times.
const count = 1024;
load(libdir + "dummyModuleResolveHook.js");
let moduleRepo = {};
setModuleResolveHook(function(module, specifier) {
if (specifier in moduleRepo)
return moduleRepo[specifier];
throw "Module " + specifier + " not found";
});
const count = 1024;
let a = moduleRepo['a'] = parseModule("export let a = 1;");

View File

@ -1,13 +1,8 @@
// Test importing a namespace many times.
const count = 1024;
load(libdir + "dummyModuleResolveHook.js");
let moduleRepo = {};
setModuleResolveHook(function(module, specifier) {
if (specifier in moduleRepo)
return moduleRepo[specifier];
throw "Module " + specifier + " not found";
});
const count = 1024;
let a = moduleRepo['a'] = parseModule("export let a = 1;");

View File

@ -1,5 +1,7 @@
// Exercise ModuleDeclarationInstantiation() operation.
load(libdir + "dummyModuleResolveHook.js");
function testModuleEnvironment(module, expected) {
var actual = getModuleEnvironmentNames(module).sort();
assertEq(actual.length, expected.length);
@ -13,13 +15,6 @@ let m = parseModule("");
m.declarationInstantiation();
testModuleEnvironment(m, []);
let moduleRepo = new Map();
setModuleResolveHook(function(module, specifier) {
if (specifier in moduleRepo)
return moduleRepo[specifier];
throw "Module " + specifier + " not found";
});
let a = moduleRepo['a'] = parseModule("var x = 1; export { x };");
let b = moduleRepo['b'] = parseModule("import { x as y } from 'a';");

View File

@ -1,13 +1,7 @@
// Exercise ModuleEvaluation() concrete method.
load(libdir + "asserts.js");
let moduleRepo = new Map();
setModuleResolveHook(function(module, specifier) {
if (specifier in moduleRepo)
return moduleRepo[specifier];
throw "Module " + specifier + " not found";
});
load(libdir + "dummyModuleResolveHook.js");
function parseAndEvaluate(source) {
let m = parseModule(source);

View File

@ -88,7 +88,7 @@
real(Float32Array, 28, InitViaClassSpec, TYPED_ARRAY_CLASP(Float32)) \
real(Float64Array, 29, InitViaClassSpec, TYPED_ARRAY_CLASP(Float64)) \
real(Uint8ClampedArray, 30, InitViaClassSpec, TYPED_ARRAY_CLASP(Uint8Clamped)) \
real(Proxy, 31, InitProxyClass, OCLASP(Proxy)) \
real(Proxy, 31, InitProxyClass, js::ProxyClassPtr) \
real(WeakMap, 32, InitWeakMapClass, OCLASP(WeakMap)) \
real(Map, 33, InitMapClass, OCLASP(Map)) \
real(Set, 34, InitSetClass, OCLASP(Set)) \

View File

@ -151,10 +151,8 @@ DeadObjectProxy::regexp_toShared(JSContext* cx, HandleObject proxy, RegExpGuard*
const char DeadObjectProxy::family = 0;
const DeadObjectProxy DeadObjectProxy::singleton;
bool
js::IsDeadProxyObject(JSObject* obj)
{
return obj->is<ProxyObject>() &&
obj->as<ProxyObject>().handler() == &DeadObjectProxy::singleton;
return IsDerivedProxyObject(obj, &DeadObjectProxy::singleton);
}

View File

@ -717,10 +717,10 @@ js::proxy_FunToString(JSContext* cx, HandleObject proxy, unsigned indent)
return Proxy::fun_toString(cx, proxy, indent);
}
const Class js::ProxyObject::class_ =
const Class js::ProxyObject::proxyClass =
PROXY_CLASS_DEF("Proxy", JSCLASS_HAS_CACHED_PROTO(JSProto_Proxy));
const Class* const js::ProxyClassPtr = &js::ProxyObject::class_;
const Class* const js::ProxyClassPtr = &js::ProxyObject::proxyClass;
JS_FRIEND_API(JSObject*)
js::NewProxyObject(JSContext* cx, const BaseProxyHandler* handler, HandleValue priv, JSObject* proto_,
@ -738,7 +738,7 @@ void
ProxyObject::renew(JSContext* cx, const BaseProxyHandler* handler, Value priv)
{
MOZ_ASSERT_IF(IsCrossCompartmentWrapper(this), IsDeadProxyObject(this));
MOZ_ASSERT(getClass() == &ProxyObject::class_);
MOZ_ASSERT(getClass() == &ProxyObject::proxyClass);
MOZ_ASSERT(!IsWindowProxy(this));
MOZ_ASSERT(hasLazyPrototype());

View File

@ -104,22 +104,30 @@ class ProxyObject : public JSObject
void nuke(const BaseProxyHandler* handler);
static const Class class_;
// There is no class_ member to force specialization of JSObject::is<T>().
// The implementation in JSObject is incorrect for proxies since it doesn't
// take account of the handler type.
static const Class proxyClass;
};
} // namespace js
bool IsDerivedProxyObject(const JSObject* obj, const js::BaseProxyHandler* handler);
// Note: the following |JSObject::is<T>| methods are implemented in terms of
// the Is*Proxy() friend API functions to ensure the implementations are tied
// together. The exception is |JSObject::is<js::OuterWindowProxyObject>()
// const|, which uses the standard template definition, because there is no
// IsOuterWindowProxy() function in the friend API.
} // namespace js
template<>
inline bool
JSObject::is<js::ProxyObject>() const
{
// Note: this method is implemented in terms of the IsProxy() friend API
// functions to ensure the implementations are tied together.
// Note 2: this specialization isn't used for subclasses of ProxyObject
// which must supply their own implementation.
return js::IsProxy(const_cast<JSObject*>(this));
}
inline bool
js::IsDerivedProxyObject(const JSObject* obj, const js::BaseProxyHandler* handler) {
return obj->is<js::ProxyObject>() && obj->as<js::ProxyObject>().handler() == handler;
}
#endif /* vm_ProxyObject_h */

View File

@ -2244,6 +2244,13 @@ class DebugScopeProxy : public BaseProxyHandler
} /* anonymous namespace */
template<>
bool
JSObject::is<js::DebugScopeObject>() const
{
return IsDerivedProxyObject(this, &DebugScopeProxy::singleton);
}
const char DebugScopeProxy::family = 0;
const DebugScopeProxy DebugScopeProxy::singleton;
@ -2333,13 +2340,6 @@ DebugScopeObject::isOptimizedOut() const
return false;
}
bool
js::IsDebugScopeSlow(ProxyObject* proxy)
{
MOZ_ASSERT(proxy->hasClass(&ProxyObject::class_));
return proxy->handler() == &DebugScopeProxy::singleton;
}
/*****************************************************************************/
DebugScopes::DebugScopes(JSContext* cx)

View File

@ -1265,9 +1265,6 @@ class DebugScopes
static void onCompartmentUnsetIsDebuggee(JSCompartment* c);
};
extern bool
IsDebugScopeSlow(ProxyObject* proxy);
} /* namespace js */
template<>
@ -1299,13 +1296,8 @@ JSObject::is<js::ScopeObject>() const
}
template<>
inline bool
JSObject::is<js::DebugScopeObject>() const
{
// Note: don't use is<ProxyObject>() here -- it also matches subclasses!
return hasClass(&js::ProxyObject::class_) &&
IsDebugScopeSlow(&const_cast<JSObject*>(this)->as<js::ProxyObject>());
}
bool
JSObject::is<js::DebugScopeObject>() const;
template<>
inline bool

File diff suppressed because it is too large Load Diff

View File

@ -49,14 +49,6 @@
* It holds an embedding level and indicates the visual direction
* by its bit 0 (even/odd value).<p>
*
* It can also hold non-level values for the
* <code>aParaLevel</code> and <code>aEmbeddingLevels</code>
* arguments of <code>SetPara</code>; there:
* <ul>
* <li>bit 7 of an <code>aEmbeddingLevels[]</code>
* value indicates whether the using application is
* specifying the level of a character to <i>override</i> whatever the
* Bidi implementation would resolve it to.</li>
* <li><code>aParaLevel</code> can be set to the
* pseudo-level values <code>NSBIDI_DEFAULT_LTR</code>
* and <code>NSBIDI_DEFAULT_RTL</code>.</li></ul>
@ -127,64 +119,28 @@ enum nsBidiDirection {
NSBIDI_MIXED
};
typedef enum nsBidiDirection nsBidiDirection;
/* miscellaneous definitions ------------------------------------------------ */
/** option flags for WriteReverse() */
/**
* option bit for WriteReverse():
* keep combining characters after their base characters in RTL runs
*
* @see WriteReverse
*/
#define NSBIDI_KEEP_BASE_COMBINING 1
/**
* option bit for WriteReverse():
* replace characters with the "mirrored" property in RTL runs
* by their mirror-image mappings
*
* @see WriteReverse
*/
#define NSBIDI_DO_MIRRORING 2
/**
* option bit for WriteReverse():
* remove Bidi control characters
*
* @see WriteReverse
*/
#define NSBIDI_REMOVE_BIDI_CONTROLS 8
/* helper macros for each allocated array member */
#define GETDIRPROPSMEMORY(length) \
GetMemory((void **)&mDirPropsMemory, &mDirPropsSize, \
mMayAllocateText, (length))
#define GETDIRPROPSMEMORY(length) nsBidi::GetMemory((void **)&mDirPropsMemory, \
&mDirPropsSize, \
(length))
#define GETLEVELSMEMORY(length) \
GetMemory((void **)&mLevelsMemory, &mLevelsSize, \
mMayAllocateText, (length))
#define GETLEVELSMEMORY(length) nsBidi::GetMemory((void **)&mLevelsMemory, \
&mLevelsSize, \
(length))
#define GETRUNSMEMORY(length) \
GetMemory((void **)&mRunsMemory, &mRunsSize, \
mMayAllocateRuns, (length)*sizeof(Run))
#define GETRUNSMEMORY(length) nsBidi::GetMemory((void **)&mRunsMemory, \
&mRunsSize, \
(length)*sizeof(Run))
/* additional macros used by constructor - always allow allocation */
#define GETINITIALDIRPROPSMEMORY(length) \
GetMemory((void **)&mDirPropsMemory, &mDirPropsSize, \
true, (length))
#define GETISOLATESMEMORY(length) nsBidi::GetMemory((void **)&mIsolatesMemory, \
&mIsolatesSize, \
(length)*sizeof(Isolate))
#define GETINITIALLEVELSMEMORY(length) \
GetMemory((void **)&mLevelsMemory, &mLevelsSize, \
true, (length))
#define GETINITIALRUNSMEMORY(length) \
GetMemory((void **)&mRunsMemory, &mRunsSize, \
true, (length)*sizeof(Run))
#define GETINITIALISOLATESMEMORY(length) \
GetMemory((void **)&mIsolatesMemory, &mIsolatesSize, \
true, (length)*sizeof(Isolate))
#define GETOPENINGSMEMORY(length) nsBidi::GetMemory((void **)&mOpeningsMemory, \
&mOpeningsSize, \
(length)*sizeof(Opening))
/*
* Sometimes, bit values are more appropriate
@ -233,15 +189,6 @@ typedef uint8_t DirProp;
#define IS_DEFAULT_LEVEL(level) (((level)&0xfe)==0xfe)
/*
* The following bit is ORed to the property of directional control
* characters which are ignored: unmatched PDF or PDI; LRx, RLx or FSI
* which would exceed the maximum explicit bidi level.
*/
#define IGNORE_CC 0x40
#define PURE_DIRPROP(prop) ((prop)&~IGNORE_CC)
/*
* The following bit is used for the directional isolate status.
* Stack entries corresponding to isolate sequences are greater than ISOLATE.
@ -251,6 +198,9 @@ typedef uint8_t DirProp;
/* number of isolate entries allocated initially without malloc */
#define SIMPLE_ISOLATES_SIZE 5
/* number of isolate run entries for paired brackets allocated initially without malloc */
#define SIMPLE_OPENINGS_COUNT 8
/* handle surrogate pairs --------------------------------------------------- */
#define IS_FIRST_SURROGATE(uchar) (((uchar)&0xfc00)==0xd800)
@ -390,6 +340,32 @@ struct Isolate {
int16_t state;
};
// For bracket matching
#define FOUND_L DIRPROP_FLAG(L)
#define FOUND_R DIRPROP_FLAG(R)
struct Opening {
int32_t position; /* position of opening bracket */
int32_t match; /* matching char or -position of closing bracket */
int32_t contextPos; /* position of last strong char found before opening */
uint16_t flags; /* bits for L or R/AL found within the pair */
DirProp contextDir; /* L or R according to last strong char before opening */
uint8_t filler; /* to complete a nice multiple of 4 chars */
};
struct IsoRun {
int32_t contextPos; /* position of char determining context */
uint16_t start; /* index of first opening entry for this run */
uint16_t limit; /* index after last opening entry for this run */
nsBidiLevel level; /* level of this run */
DirProp lastStrong; /* bidi class of last strong char found in this run */
DirProp lastBase; /* bidi class of last base char found in this run */
DirProp contextDir; /* L or R to use as context for following openings */
};
class nsBidi;
/* Run structure for reordering --------------------------------------------- */
typedef struct Run {
@ -505,28 +481,8 @@ public:
* the desired default is used (0 for LTR or 1 for RTL).
* Any other value between 0 and <code>NSBIDI_MAX_EXPLICIT_LEVEL</code> is also valid,
* with odd levels indicating RTL.
*
* @param aEmbeddingLevels (in) may be used to preset the embedding and override levels,
* ignoring characters like LRE and PDF in the text.
* A level overrides the directional property of its corresponding
* (same index) character if the level has the
* <code>NSBIDI_LEVEL_OVERRIDE</code> bit set.<p>
* Except for that bit, it must be
* <code>aParaLevel<=aEmbeddingLevels[]<=NSBIDI_MAX_EXPLICIT_LEVEL</code>.<p>
* <strong>Caution: </strong>A copy of this pointer, not of the levels,
* will be stored in the <code>nsBidi</code> object;
* the <code>aEmbeddingLevels</code> array must not be
* deallocated before the <code>nsBidi</code> object is destroyed or reused,
* and the <code>aEmbeddingLevels</code>
* should not be modified to avoid unexpected results on subsequent Bidi operations.
* However, the <code>SetPara</code> and
* <code>SetLine</code> functions may modify some or all of the levels.<p>
* After the <code>nsBidi</code> object is reused or destroyed, the caller
* must take care of the deallocation of the <code>aEmbeddingLevels</code> array.<p>
* <strong>The <code>aEmbeddingLevels</code> array must be
* at least <code>aLength</code> long.</strong>
*/
nsresult SetPara(const char16_t *aText, int32_t aLength, nsBidiLevel aParaLevel, nsBidiLevel *aEmbeddingLevels);
nsresult SetPara(const char16_t *aText, int32_t aLength, nsBidiLevel aParaLevel);
/**
* Get the directionality of the text.
@ -548,73 +504,6 @@ public:
*/
nsresult GetParaLevel(nsBidiLevel* aParaLevel);
#ifdef FULL_BIDI_ENGINE
/**
* <code>SetLine</code> sets an <code>nsBidi</code> to
* contain the reordering information, especially the resolved levels,
* for all the characters in a line of text. This line of text is
* specified by referring to an <code>nsBidi</code> object representing
* this information for a paragraph of text, and by specifying
* a range of indexes in this paragraph.<p>
* In the new line object, the indexes will range from 0 to <code>aLimit-aStart</code>.<p>
*
* This is used after calling <code>SetPara</code>
* for a paragraph, and after line-breaking on that paragraph.
* It is not necessary if the paragraph is treated as a single line.<p>
*
* After line-breaking, rules (L1) and (L2) for the treatment of
* trailing WS and for reordering are performed on
* an <code>nsBidi</code> object that represents a line.<p>
*
* <strong>Important:</strong> the line <code>nsBidi</code> object shares data with
* <code>aParaBidi</code>.
* You must destroy or reuse this object before <code>aParaBidi</code>.
* In other words, you must destroy or reuse the <code>nsBidi</code> object for a line
* before the object for its parent paragraph.
*
* @param aParaBidi is the parent paragraph object.
*
* @param aStart is the line's first index into the paragraph text.
*
* @param aLimit is just behind the line's last index into the paragraph text
* (its last index +1).<br>
* It must be <code>0<=aStart<=aLimit<=</code>paragraph length.
*
* @see SetPara
*/
nsresult SetLine(const nsBidi* aParaBidi, int32_t aStart, int32_t aLimit);
/**
* Get the length of the text.
*
* @param aLength receives the length of the text that the nsBidi object was created for.
*/
nsresult GetLength(int32_t* aLength);
/**
* Get the level for one character.
*
* @param aCharIndex the index of a character.
*
* @param aLevel receives the level for the character at aCharIndex.
*
* @see nsBidiLevel
*/
nsresult GetLevelAt(int32_t aCharIndex, nsBidiLevel* aLevel);
/**
* Get an array of levels for each character.<p>
*
* Note that this function may allocate memory under some
* circumstances, unlike <code>GetLevelAt</code>.
*
* @param aLevels receives a pointer to the levels array for the text,
* or <code>nullptr</code> if an error occurs.
*
* @see nsBidiLevel
*/
nsresult GetLevels(nsBidiLevel** aLevels);
#endif // FULL_BIDI_ENGINE
/**
* Get the bidirectional type for one character.
*
@ -707,92 +596,6 @@ public:
*/
nsresult GetVisualRun(int32_t aRunIndex, int32_t* aLogicalStart, int32_t* aLength, nsBidiDirection* aDirection);
#ifdef FULL_BIDI_ENGINE
/**
* Get the visual position from a logical text position.
* If such a mapping is used many times on the same
* <code>nsBidi</code> object, then calling
* <code>GetLogicalMap</code> is more efficient.<p>
*
* Note that in right-to-left runs, this mapping places
* modifier letters before base characters and second surrogates
* before first ones.
*
* @param aLogicalIndex is the index of a character in the text.
*
* @param aVisualIndex will receive the visual position of this character.
*
* @see GetLogicalMap
* @see GetLogicalIndex
*/
nsresult GetVisualIndex(int32_t aLogicalIndex, int32_t* aVisualIndex);
/**
* Get the logical text position from a visual position.
* If such a mapping is used many times on the same
* <code>nsBidi</code> object, then calling
* <code>GetVisualMap</code> is more efficient.<p>
*
* This is the inverse function to <code>GetVisualIndex</code>.
*
* @param aVisualIndex is the visual position of a character.
*
* @param aLogicalIndex will receive the index of this character in the text.
*
* @see GetVisualMap
* @see GetVisualIndex
*/
nsresult GetLogicalIndex(int32_t aVisualIndex, int32_t* aLogicalIndex);
/**
* Get a logical-to-visual index map (array) for the characters in the nsBidi
* (paragraph or line) object.
*
* @param aIndexMap is a pointer to an array of <code>GetLength</code>
* indexes which will reflect the reordering of the characters.
* The array does not need to be initialized.<p>
* The index map will result in <code>aIndexMap[aLogicalIndex]==aVisualIndex</code>.<p>
*
* @see GetVisualMap
* @see GetVisualIndex
*/
nsresult GetLogicalMap(int32_t *aIndexMap);
/**
* Get a visual-to-logical index map (array) for the characters in the nsBidi
* (paragraph or line) object.
*
* @param aIndexMap is a pointer to an array of <code>GetLength</code>
* indexes which will reflect the reordering of the characters.
* The array does not need to be initialized.<p>
* The index map will result in <code>aIndexMap[aVisualIndex]==aLogicalIndex</code>.<p>
*
* @see GetLogicalMap
* @see GetLogicalIndex
*/
nsresult GetVisualMap(int32_t *aIndexMap);
/**
* This is a convenience function that does not use a nsBidi object.
* It is intended to be used for when an application has determined the levels
* of objects (character sequences) and just needs to have them reordered (L2).
* This is equivalent to using <code>GetLogicalMap</code> on a
* <code>nsBidi</code> object.
*
* @param aLevels is an array with <code>aLength</code> levels that have been determined by
* the application.
*
* @param aLength is the number of levels in the array, or, semantically,
* the number of objects to be reordered.
* It must be <code>aLength>0</code>.
*
* @param aIndexMap is a pointer to an array of <code>aLength</code>
* indexes which will reflect the reordering of the characters.
* The array does not need to be initialized.<p>
* The index map will result in <code>aIndexMap[aLogicalIndex]==aVisualIndex</code>.
*/
static nsresult ReorderLogical(const nsBidiLevel *aLevels, int32_t aLength, int32_t *aIndexMap);
#endif // FULL_BIDI_ENGINE
/**
* This is a convenience function that does not use a nsBidi object.
* It is intended to be used for when an application has determined the levels
@ -814,22 +617,6 @@ public:
*/
static nsresult ReorderVisual(const nsBidiLevel *aLevels, int32_t aLength, int32_t *aIndexMap);
#ifdef FULL_BIDI_ENGINE
/**
* Invert an index map.
* The one-to-one index mapping of the first map is inverted and written to
* the second one.
*
* @param aSrcMap is an array with <code>aLength</code> indexes
* which define the original mapping.
*
* @param aDestMap is an array with <code>aLength</code> indexes
* which will be filled with the inverse mapping.
*
* @param aLength is the length of each array.
*/
nsresult InvertMap(const int32_t *aSrcMap, int32_t *aDestMap, int32_t aLength);
#endif // FULL_BIDI_ENGINE
/**
* Reverse a Right-To-Left run of Unicode text.
*
@ -870,6 +657,45 @@ public:
protected:
friend class nsBidiPresUtils;
class BracketData {
public:
explicit BracketData(const nsBidi* aBidi);
~BracketData();
void ProcessBoundary(int32_t aLastDirControlCharPos,
nsBidiLevel aContextLevel,
nsBidiLevel aEmbeddingLevel,
const DirProp* aDirProps);
void ProcessLRI_RLI(nsBidiLevel aLevel);
void ProcessPDI();
bool AddOpening(char16_t aMatch, int32_t aPosition);
void FixN0c(int32_t aOpeningIndex, int32_t aNewPropPosition,
DirProp aNewProp, DirProp* aDirProps);
DirProp ProcessClosing(int32_t aOpenIdx, int32_t aPosition,
DirProp* aDirProps);
bool ProcessChar(int32_t aPosition, char16_t aCh, DirProp* aDirProps,
nsBidiLevel* aLevels);
private:
// array of opening entries which should be enough in most cases;
// no malloc() needed
Opening mSimpleOpenings[SIMPLE_OPENINGS_COUNT];
Opening* mOpenings; // pointer to current array of entries,
// either mSimpleOpenings or malloced array
Opening* mOpeningsMemory;
size_t mOpeningsSize;
// array of nested isolated sequence entries; can never exceed
// UBIDI_MAX_EXPLICIT_LEVEL
// + 1 for index 0
// + 1 for before the first isolated sequence
IsoRun mIsoRuns[NSBIDI_MAX_EXPLICIT_LEVEL+2];
int32_t mIsoRunLast; // index of last used entry in mIsoRuns
int32_t mOpeningsCount; // number of allocated entries in mOpenings
};
/** length of the current text */
int32_t mLength;
@ -883,9 +709,6 @@ protected:
Run* mRunsMemory;
Isolate* mIsolatesMemory;
/** indicators for whether memory may be allocated after construction */
bool mMayAllocateText, mMayAllocateRuns;
DirProp* mDirProps;
nsBidiLevel* mLevels;
@ -924,15 +747,13 @@ private:
void Init();
bool GetMemory(void **aMemory, size_t* aSize, bool aMayAllocate, size_t aSizeNeeded);
static bool GetMemory(void **aMemory, size_t* aSize, size_t aSizeNeeded);
void Free();
void GetDirProps(const char16_t *aText);
void ResolveExplicitLevels(nsBidiDirection *aDirection);
nsresult CheckExplicitLevels(nsBidiDirection *aDirection);
void ResolveExplicitLevels(nsBidiDirection *aDirection, const char16_t *aText);
nsBidiDirection DirectionFromFlags(Flags aFlags);
@ -951,10 +772,6 @@ private:
void ReorderLine(nsBidiLevel aMinLevel, nsBidiLevel aMaxLevel);
static bool PrepareReorder(const nsBidiLevel *aLevels, int32_t aLength, int32_t *aIndexMap, nsBidiLevel *aMinLevel, nsBidiLevel *aMaxLevel);
int32_t doWriteReverse(const char16_t *src, int32_t srcLength,
char16_t *dest, uint16_t options);
};
#endif // _nsBidi_h_

View File

@ -208,7 +208,7 @@ struct BidiParagraphData {
nsresult SetPara()
{
return mBidiEngine->SetPara(mBuffer.get(), BufferLength(),
mParaLevel, nullptr);
mParaLevel);
}
/**
@ -2012,7 +2012,7 @@ nsresult nsBidiPresUtils::ProcessText(const char16_t* aText,
nsAutoString textBuffer(aText, aLength);
nsresult rv = aBidiEngine->SetPara(aText, aLength, aBaseLevel, nullptr);
nsresult rv = aBidiEngine->SetPara(aText, aLength, aBaseLevel);
if (NS_FAILED(rv))
return rv;

View File

@ -698,7 +698,7 @@ nsDisplayListBuilder::WrapAGRForFrame(nsIFrame* aAnimatedGeometryRoot,
AnimatedGeometryRoot* result = nullptr;
if (!mFrameToAnimatedGeometryRootMap.Get(aAnimatedGeometryRoot, &result)) {
MOZ_ASSERT(aAnimatedGeometryRoot != RootReferenceFrame());
MOZ_ASSERT(nsLayoutUtils::IsAncestorFrameCrossDoc(RootReferenceFrame(), aAnimatedGeometryRoot));
AnimatedGeometryRoot* parent = aParent;
if (!parent) {
nsIFrame* parentFrame = nsLayoutUtils::GetCrossDocParentFrame(aAnimatedGeometryRoot);
@ -717,7 +717,7 @@ nsDisplayListBuilder::WrapAGRForFrame(nsIFrame* aAnimatedGeometryRoot,
AnimatedGeometryRoot*
nsDisplayListBuilder::FindAnimatedGeometryRootFor(nsIFrame* aFrame)
{
if (!IsForPainting()) {
if (!IsPaintingToWindow()) {
return &mRootAGR;
}
if (aFrame == mCurrentFrame) {
@ -1091,8 +1091,16 @@ IsStickyFrameActive(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, nsIFrame*
bool
nsDisplayListBuilder::IsAnimatedGeometryRoot(nsIFrame* aFrame, nsIFrame** aParent)
{
if (aFrame == mReferenceFrame)
if (aFrame == mReferenceFrame) {
return true;
}
if (!IsPaintingToWindow()) {
if (aParent) {
*aParent = nsLayoutUtils::GetCrossDocParentFrame(aFrame);
}
return false;
}
if (nsLayoutUtils::IsPopup(aFrame))
return true;
if (ActiveLayerTracker::IsOffsetOrMarginStyleAnimated(aFrame))
@ -1145,6 +1153,7 @@ nsDisplayListBuilder::IsAnimatedGeometryRoot(nsIFrame* aFrame, nsIFrame** aParen
nsIFrame*
nsDisplayListBuilder::FindAnimatedGeometryRootFrameFor(nsIFrame* aFrame)
{
MOZ_ASSERT(nsLayoutUtils::IsAncestorFrameCrossDoc(RootReferenceFrame(), aFrame));
nsIFrame* cursor = aFrame;
while (cursor != RootReferenceFrame()) {
nsIFrame* next;
@ -4557,6 +4566,21 @@ nsDisplayResolution::~nsDisplayResolution() {
}
#endif
void
nsDisplayResolution::HitTest(nsDisplayListBuilder* aBuilder,
const nsRect& aRect,
HitTestState* aState,
nsTArray<nsIFrame*> *aOutFrames)
{
#if defined(MOZ_SINGLE_PROCESS_APZ)
nsIPresShell* presShell = mFrame->PresContext()->PresShell();
nsRect rect = aRect.RemoveResolution(presShell->ScaleToResolution() ? presShell->GetResolution () : 1.0f);
mList.HitTest(aBuilder, rect, aState, aOutFrames);
#else
mList.HitTest(aBuilder, aRect, aState, aOutFrames);
#endif // MOZ_SINGLE_PROCESS_APZ
}
already_AddRefed<Layer>
nsDisplayResolution::BuildLayer(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
@ -4883,6 +4907,7 @@ nsDisplayTransform::nsDisplayTransform(nsDisplayListBuilder* aBuilder,
void
nsDisplayTransform::SetReferenceFrameToAncestor(nsDisplayListBuilder* aBuilder)
{
mAnimatedGeometryRootForChildren = mAnimatedGeometryRoot;
if (mFrame == aBuilder->RootReferenceFrame()) {
return;
}
@ -4890,7 +4915,6 @@ nsDisplayTransform::SetReferenceFrameToAncestor(nsDisplayListBuilder* aBuilder)
mReferenceFrame =
aBuilder->FindReferenceFrameFor(outerFrame);
mToReferenceFrame = mFrame->GetOffsetToCrossDoc(mReferenceFrame);
mAnimatedGeometryRootForChildren = mAnimatedGeometryRoot;
if (nsLayoutUtils::IsFixedPosFrameInDisplayPort(mFrame)) {
// This is an odd special case. If we are both IsFixedPosFrameInDisplayPort
// and transformed that we are our own AGR parent.
@ -4898,7 +4922,7 @@ nsDisplayTransform::SetReferenceFrameToAncestor(nsDisplayListBuilder* aBuilder)
// determine if we are inside a fixed pos subtree. If we use the outer AGR
// from outside the fixed pos subtree FLB can't tell that we are fixed pos.
mAnimatedGeometryRoot = mAnimatedGeometryRootForChildren;
} else {
} else if (mAnimatedGeometryRoot->mParentAGR) {
mAnimatedGeometryRoot = mAnimatedGeometryRoot->mParentAGR;
}
mVisibleRect = aBuilder->GetDirtyRect() + mToReferenceFrame;

View File

@ -3508,7 +3508,10 @@ public:
#ifdef NS_BUILD_REFCNT_LOGGING
virtual ~nsDisplayResolution();
#endif
virtual void HitTest(nsDisplayListBuilder* aBuilder,
const nsRect& aRect,
HitTestState* aState,
nsTArray<nsIFrame*> *aOutFrames) override;
virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerLayerParameters& aContainerParameters) override;

View File

@ -140,10 +140,10 @@ typedef struct CapturingContentInfo {
mozilla::StaticRefPtr<nsIContent> mContent;
} CapturingContentInfo;
// 327d78a0-0680-4709-b209-1cf9578720e6
// 5023beaa-0e54-4fc7-b9dc-0344dc4fb8be
#define NS_IPRESSHELL_IID \
{ 0x327d78a0, 0x0680, 0x4709, \
{ 0xb2, 0x09, 0x1c, 0xf9, 0x57, 0x87, 0x20, 0xe6 } }
{ 0x5023beaa, 0x0e54, 0x4fc7, \
{ 0xb9, 0xdc, 0x03, 0x44, 0xdc, 0x4f, 0xb8, 0xbe } }
// debug VerifyReflow flags
#define VERIFY_REFLOW_ON 0x01
@ -1416,6 +1416,7 @@ public:
virtual nsresult SetResolution(float aResolution) = 0;
float GetResolution() { return mResolution.valueOr(1.0); }
virtual float GetCumulativeResolution() = 0;
virtual float GetCumulativeScaleResolution() = 0;
/**
* Was the current resolution set by the user or just default initialized?

View File

@ -2111,7 +2111,11 @@ nsLayoutUtils::GetEventCoordinatesRelativeTo(nsIWidget* aWidget,
nsPresContext* presContext = aFrame->PresContext();
nsPoint pt(presContext->DevPixelsToAppUnits(aPoint.x),
presContext->DevPixelsToAppUnits(aPoint.y));
return pt - view->ViewToWidgetOffset();
pt = pt - view->ViewToWidgetOffset();
#if defined(MOZ_SINGLE_PROCESS_APZ)
pt = pt.RemoveResolution(presContext->PresShell()->GetCumulativeScaleResolution());
#endif // MOZ_SINGLE_PROCESS_APZ
return pt;
}
}
@ -2146,6 +2150,12 @@ nsLayoutUtils::GetEventCoordinatesRelativeTo(nsIWidget* aWidget,
int32_t rootAPD = rootFrame->PresContext()->AppUnitsPerDevPixel();
int32_t localAPD = aFrame->PresContext()->AppUnitsPerDevPixel();
widgetToView = widgetToView.ScaleToOtherAppUnits(rootAPD, localAPD);
#if defined(MOZ_SINGLE_PROCESS_APZ)
nsIPresShell* shell = aFrame->PresContext()->PresShell();
// XXX Bug 1224748 - Update nsLayoutUtils functions to correctly handle nsPresShell resolution
widgetToView = widgetToView.RemoveResolution(shell->GetCumulativeScaleResolution());
#endif
/* If we encountered a transform, we can't do simple arithmetic to figure
* out how to convert back to aFrame's coordinates and must use the CTM.
@ -2893,8 +2903,12 @@ nsLayoutUtils::TranslateViewToWidget(nsPresContext* aPresContext,
return LayoutDeviceIntPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
}
LayoutDeviceIntPoint relativeToViewWidget(aPresContext->AppUnitsToDevPixels(aPt.x + viewOffset.x),
aPresContext->AppUnitsToDevPixels(aPt.y + viewOffset.y));
nsPoint pt = aPt + viewOffset;
#if defined(MOZ_SINGLE_PROCESS_APZ)
pt = pt.ApplyResolution(aPresContext->PresShell()->GetCumulativeScaleResolution());
#endif // MOZ_SINGLE_PROCESS_APZ
LayoutDeviceIntPoint relativeToViewWidget(aPresContext->AppUnitsToDevPixels(pt.x),
aPresContext->AppUnitsToDevPixels(pt.y));
return relativeToViewWidget + WidgetToWidgetOffset(viewWidget, aWidget);
}

View File

@ -1084,6 +1084,20 @@ PresShell::Destroy()
LogTextPerfStats(tp, this, tp->cumulative, 0.0, eLog_totals, nullptr);
}
}
if (mPresContext) {
gfxUserFontSet* fs = mPresContext->GetUserFontSet();
if (fs) {
uint32_t fontCount;
uint64_t fontSize;
fs->GetLoadStatistics(fontCount, fontSize);
Telemetry::Accumulate(Telemetry::WEBFONT_PER_PAGE, fontCount);
Telemetry::Accumulate(Telemetry::WEBFONT_SIZE_PER_PAGE,
uint32_t(fontSize/1024));
} else {
Telemetry::Accumulate(Telemetry::WEBFONT_PER_PAGE, 0);
Telemetry::Accumulate(Telemetry::WEBFONT_SIZE_PER_PAGE, 0);
}
}
#ifdef MOZ_REFLOW_PERF
DumpReflows();
@ -5337,6 +5351,22 @@ float PresShell::GetCumulativeResolution()
return resolution;
}
float PresShell::GetCumulativeScaleResolution()
{
float resolution = 1.0;
nsIPresShell* currentShell = this;
while (currentShell) {
resolution *= currentShell->ScaleToResolution() ? currentShell->GetResolution() : 1.0f;
nsPresContext* parentCtx = currentShell->GetPresContext()->GetParentPresContext();
if (parentCtx) {
currentShell = parentCtx->PresShell();
} else {
currentShell = nullptr;
}
}
return resolution;
}
void PresShell::SetRenderingState(const RenderingState& aState)
{
if (mRenderFlags != aState.mRenderFlags) {
@ -7083,8 +7113,9 @@ PresShell::HandleEvent(nsIFrame* aFrame,
// document that is being captured.
retargetEventDoc = capturingContent->GetCrossShadowCurrentDoc();
#ifdef ANDROID
} else if (aEvent->mClass == eTouchEventClass ||
(aEvent->AsMouseEvent() && aEvent->AsMouseEvent()->inputSource == nsIDOMMouseEvent::MOZ_SOURCE_TOUCH)) {
} else if ((aEvent->mClass == eTouchEventClass) ||
(aEvent->mClass == eMouseEventClass) ||
(aEvent->mClass == eWheelEventClass)) {
retargetEventDoc = GetTouchEventTargetDocument();
#endif
}

View File

@ -218,6 +218,7 @@ public:
}
virtual bool ScaleToResolution() const override;
virtual float GetCumulativeResolution() override;
virtual float GetCumulativeScaleResolution() override;
//nsIViewObserver interface

View File

@ -5359,9 +5359,12 @@ ScrollFrameHelper::SaveState() const
pt = mRestorePos;
}
state->SetScrollState(pt);
nsIPresShell* shell = mOuter->PresContext()->PresShell();
state->SetResolution(shell->GetResolution());
state->SetScaleToResolution(shell->ScaleToResolution());
if (mIsRoot) {
// Only save resolution properties for root scroll frames
nsIPresShell* shell = mOuter->PresContext()->PresShell();
state->SetResolution(shell->GetResolution());
state->SetScaleToResolution(shell->ScaleToResolution());
}
return state;
}
@ -5372,8 +5375,9 @@ ScrollFrameHelper::RestoreState(nsPresState* aState)
mDidHistoryRestore = true;
mLastPos = mScrolledFrame ? GetLogicalScrollPosition() : nsPoint(0,0);
// Scaling-to-resolution should only be used on root scroll frames.
MOZ_ASSERT(mIsRoot || !aState->GetScaleToResolution());
// Resolution properties should only exist on root scroll frames.
MOZ_ASSERT(mIsRoot || (!aState->GetScaleToResolution() &&
aState->GetResolution() == 1.0));
if (mIsRoot) {
nsIPresShell* presShell = mOuter->PresContext()->PresShell();

View File

@ -441,6 +441,13 @@ nsSubDocumentFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
aBuilder->EnterPresShell(subdocRootFrame,
pointerEventsNone && !passPointerEventsToChildren);
#if defined(MOZ_SINGLE_PROCESS_APZ)
if (!haveDisplayPort) {
// Remove nsPresShell resolution
dirty = dirty.RemoveResolution(presShell->ScaleToResolution() ? presShell->GetResolution () : 1.0f);
}
#endif
} else {
dirty = aDirtyRect;
}

View File

@ -0,0 +1,15 @@
<!DOCTYPE html>
<meta charset="utf-8">
<style>
body { font: 32px monospace; }
div { text-align: center; unicode-bidi: bidi-override; }
</style>
<body>
<!--
http://unicode.org/reports/tr9/#N0, Example 1:
AB ( CD [ & ef ] ! ) gh
-->
<div>&#x5d1;&#x5d0;(&#x5d3;&#x5d2;[&amp;ef]!)gh</div>

Some files were not shown because too many files have changed in this diff Show More