зеркало из https://github.com/mozilla/gecko-dev.git
Merge m-c to b2g-inbound.
This commit is contained in:
Коммит
a95d50a6d2
|
@ -200,7 +200,7 @@ const PanelUI = {
|
|||
}
|
||||
},
|
||||
|
||||
isReady: function() {
|
||||
get isReady() {
|
||||
return !!this._isReady;
|
||||
},
|
||||
|
||||
|
|
|
@ -313,8 +313,17 @@
|
|||
]]></body>
|
||||
</method>
|
||||
|
||||
<method name="_shouldSetHeight">
|
||||
<body><![CDATA[
|
||||
return this.getAttribute("nosubviews") != "true";
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
<method name="_setMaxHeight">
|
||||
<body><![CDATA[
|
||||
if (!this._shouldSetHeight())
|
||||
return;
|
||||
|
||||
// Ignore the mutation that'll fire when we set the height of
|
||||
// the main view.
|
||||
this.ignoreMutations = true;
|
||||
|
@ -339,7 +348,7 @@
|
|||
<method name="_syncContainerWithMainView">
|
||||
<body><![CDATA[
|
||||
// Check that this panel is still alive:
|
||||
if (!this._panel || !this._panel.parentNode) {
|
||||
if (!this._panel || !this._panel.parentNode || !this._shouldSetHeight()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -191,7 +191,7 @@ CustomizeMode.prototype = {
|
|||
// is really not going to work. We pass "true" to ensureReady to
|
||||
// indicate that we're handling calling startBatchUpdate and
|
||||
// endBatchUpdate.
|
||||
if (!window.PanelUI.isReady()) {
|
||||
if (!window.PanelUI.isReady) {
|
||||
yield window.PanelUI.ensureReady(true);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
html {
|
||||
background-color: #111;
|
||||
background-image: url("chrome://browser/skin/devtools/noise.png");
|
||||
}
|
||||
|
||||
body {
|
||||
|
|
|
@ -5,7 +5,7 @@ support-files =
|
|||
head.js
|
||||
|
||||
[browser_layoutview.js]
|
||||
skip-if = true
|
||||
[browser_layoutview_rotate-labels-on-sides.js]
|
||||
[browser_editablemodel.js]
|
||||
[browser_editablemodel_allproperties.js]
|
||||
[browser_editablemodel_border.js]
|
||||
|
|
|
@ -1,145 +1,147 @@
|
|||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Test that editing the box-model values works as expected and test various
|
||||
// key bindings
|
||||
|
||||
const TEST_URI = "<style>" +
|
||||
"div { margin: 10px; padding: 3px }" +
|
||||
"#div1 { margin-top: 5px }" +
|
||||
"#div2 { border-bottom: 1em solid black; }" +
|
||||
"#div3 { padding: 2em; }" +
|
||||
"</style>" +
|
||||
"<div id='div1'></div><div id='div2'></div><div id='div3'></div>";
|
||||
|
||||
function getStyle(node, property) {
|
||||
return node.style.getPropertyValue(property);
|
||||
}
|
||||
|
||||
let doc;
|
||||
let inspector;
|
||||
|
||||
let test = asyncTest(function*() {
|
||||
let style = "div { margin: 10px; padding: 3px } #div1 { margin-top: 5px } #div2 { border-bottom: 1em solid black; } #div3 { padding: 2em; }";
|
||||
let html = "<style>" + style + "</style><div id='div1'></div><div id='div2'></div><div id='div3'></div>"
|
||||
yield addTab("data:text/html," + encodeURIComponent(TEST_URI));
|
||||
let {toolbox, inspector, view} = yield openLayoutView();
|
||||
|
||||
let content = yield loadTab("data:text/html," + encodeURIComponent(html));
|
||||
doc = content.document;
|
||||
|
||||
let target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||
let toolbox = yield gDevTools.showToolbox(target, "inspector");
|
||||
inspector = toolbox.getCurrentPanel();
|
||||
|
||||
inspector.sidebar.select("layoutview");
|
||||
yield inspector.sidebar.once("layoutview-ready");
|
||||
yield runTests();
|
||||
yield runTests(inspector, view);
|
||||
// TODO: Closing the toolbox in this test leaks - bug 994314
|
||||
// yield gDevTools.closeToolbox(target);
|
||||
// yield destroyToolbox(inspector);
|
||||
});
|
||||
|
||||
addTest("Test that editing margin dynamically updates the document, pressing escape cancels the changes",
|
||||
function*() {
|
||||
let node = doc.getElementById("div1");
|
||||
function*(inspector, view) {
|
||||
let node = content.document.getElementById("div1");
|
||||
is(getStyle(node, "margin-top"), "", "Should be no margin-top on the element.")
|
||||
let view = yield selectNode(node);
|
||||
yield selectNode(node, inspector);
|
||||
|
||||
let span = view.document.querySelector(".margin.top > span");
|
||||
let span = view.doc.querySelector(".margin.top > span");
|
||||
is(span.textContent, 5, "Should have the right value in the box model.");
|
||||
|
||||
EventUtils.synthesizeMouseAtCenter(span, {}, view);
|
||||
let editor = view.document.querySelector(".styleinspector-propertyeditor");
|
||||
EventUtils.synthesizeMouseAtCenter(span, {}, view.doc.defaultView);
|
||||
let editor = view.doc.querySelector(".styleinspector-propertyeditor");
|
||||
ok(editor, "Should have opened the editor.");
|
||||
is(editor.value, "5px", "Should have the right value in the editor.");
|
||||
|
||||
EventUtils.synthesizeKey("3", {}, view);
|
||||
yield waitForUpdate();
|
||||
EventUtils.synthesizeKey("3", {}, view.doc.defaultView);
|
||||
yield waitForUpdate(inspector);
|
||||
|
||||
is(getStyle(node, "margin-top"), "3px", "Should have updated the margin.");
|
||||
|
||||
EventUtils.synthesizeKey("VK_ESCAPE", {}, view);
|
||||
yield waitForUpdate();
|
||||
EventUtils.synthesizeKey("VK_ESCAPE", {}, view.doc.defaultView);
|
||||
yield waitForUpdate(inspector);
|
||||
|
||||
is(getStyle(node, "margin-top"), "", "Should be no margin-top on the element.")
|
||||
is(span.textContent, 5, "Should have the right value in the box model.");
|
||||
});
|
||||
|
||||
addTest("Test that arrow keys work correctly and pressing enter commits the changes",
|
||||
function*() {
|
||||
let node = doc.getElementById("div1");
|
||||
function*(inspector, view) {
|
||||
let node = content.document.getElementById("div1");
|
||||
is(getStyle(node, "margin-left"), "", "Should be no margin-top on the element.")
|
||||
let view = yield selectNode(node);
|
||||
yield selectNode(node, inspector);
|
||||
|
||||
let span = view.document.querySelector(".margin.left > span");
|
||||
let span = view.doc.querySelector(".margin.left > span");
|
||||
is(span.textContent, 10, "Should have the right value in the box model.");
|
||||
|
||||
EventUtils.synthesizeMouseAtCenter(span, {}, view);
|
||||
let editor = view.document.querySelector(".styleinspector-propertyeditor");
|
||||
EventUtils.synthesizeMouseAtCenter(span, {}, view.doc.defaultView);
|
||||
let editor = view.doc.querySelector(".styleinspector-propertyeditor");
|
||||
ok(editor, "Should have opened the editor.");
|
||||
is(editor.value, "10px", "Should have the right value in the editor.");
|
||||
|
||||
EventUtils.synthesizeKey("VK_UP", {}, view);
|
||||
yield waitForUpdate();
|
||||
EventUtils.synthesizeKey("VK_UP", {}, view.doc.defaultView);
|
||||
yield waitForUpdate(inspector);
|
||||
|
||||
is(editor.value, "11px", "Should have the right value in the editor.");
|
||||
is(getStyle(node, "margin-left"), "11px", "Should have updated the margin.");
|
||||
|
||||
EventUtils.synthesizeKey("VK_DOWN", {}, view);
|
||||
yield waitForUpdate();
|
||||
EventUtils.synthesizeKey("VK_DOWN", {}, view.doc.defaultView);
|
||||
yield waitForUpdate(inspector);
|
||||
|
||||
is(editor.value, "10px", "Should have the right value in the editor.");
|
||||
is(getStyle(node, "margin-left"), "10px", "Should have updated the margin.");
|
||||
|
||||
EventUtils.synthesizeKey("VK_UP", { shiftKey: true }, view);
|
||||
yield waitForUpdate();
|
||||
EventUtils.synthesizeKey("VK_UP", { shiftKey: true }, view.doc.defaultView);
|
||||
yield waitForUpdate(inspector);
|
||||
|
||||
is(editor.value, "20px", "Should have the right value in the editor.");
|
||||
is(getStyle(node, "margin-left"), "20px", "Should have updated the margin.");
|
||||
|
||||
EventUtils.synthesizeKey("VK_RETURN", {}, view);
|
||||
yield waitForUpdate();
|
||||
EventUtils.synthesizeKey("VK_RETURN", {}, view.doc.defaultView);
|
||||
|
||||
is(getStyle(node, "margin-left"), "20px", "Should be the right margin-top on the element.")
|
||||
is(span.textContent, 20, "Should have the right value in the box model.");
|
||||
});
|
||||
|
||||
addTest("Test that deleting the value removes the property but escape undoes that",
|
||||
function*() {
|
||||
let node = doc.getElementById("div1");
|
||||
function*(inspector, view) {
|
||||
let node = content.document.getElementById("div1");
|
||||
is(getStyle(node, "margin-left"), "20px", "Should be the right margin-top on the element.")
|
||||
let view = yield selectNode(node);
|
||||
yield selectNode(node, inspector);
|
||||
|
||||
let span = view.document.querySelector(".margin.left > span");
|
||||
let span = view.doc.querySelector(".margin.left > span");
|
||||
is(span.textContent, 20, "Should have the right value in the box model.");
|
||||
|
||||
EventUtils.synthesizeMouseAtCenter(span, {}, view);
|
||||
let editor = view.document.querySelector(".styleinspector-propertyeditor");
|
||||
EventUtils.synthesizeMouseAtCenter(span, {}, view.doc.defaultView);
|
||||
let editor = view.doc.querySelector(".styleinspector-propertyeditor");
|
||||
ok(editor, "Should have opened the editor.");
|
||||
is(editor.value, "20px", "Should have the right value in the editor.");
|
||||
|
||||
EventUtils.synthesizeKey("VK_DELETE", {}, view);
|
||||
yield waitForUpdate();
|
||||
EventUtils.synthesizeKey("VK_DELETE", {}, view.doc.defaultView);
|
||||
yield waitForUpdate(inspector);
|
||||
|
||||
is(editor.value, "", "Should have the right value in the editor.");
|
||||
is(getStyle(node, "margin-left"), "", "Should have updated the margin.");
|
||||
|
||||
EventUtils.synthesizeKey("VK_ESCAPE", {}, view);
|
||||
yield waitForUpdate();
|
||||
EventUtils.synthesizeKey("VK_ESCAPE", {}, view.doc.defaultView);
|
||||
yield waitForUpdate(inspector);
|
||||
|
||||
is(getStyle(node, "margin-left"), "20px", "Should be the right margin-top on the element.")
|
||||
is(span.textContent, 20, "Should have the right value in the box model.");
|
||||
});
|
||||
|
||||
addTest("Test that deleting the value removes the property",
|
||||
function*() {
|
||||
let node = doc.getElementById("div1");
|
||||
node.style.marginRight = "15px";
|
||||
let view = yield selectNode(node);
|
||||
function*(inspector, view) {
|
||||
let node = content.document.getElementById("div1");
|
||||
|
||||
let span = view.document.querySelector(".margin.right > span");
|
||||
node.style.marginRight = "15px";
|
||||
yield waitForUpdate(inspector);
|
||||
|
||||
yield selectNode(node, inspector);
|
||||
|
||||
let span = view.doc.querySelector(".margin.right > span");
|
||||
is(span.textContent, 15, "Should have the right value in the box model.");
|
||||
|
||||
EventUtils.synthesizeMouseAtCenter(span, {}, view);
|
||||
let editor = view.document.querySelector(".styleinspector-propertyeditor");
|
||||
EventUtils.synthesizeMouseAtCenter(span, {}, view.doc.defaultView);
|
||||
let editor = view.doc.querySelector(".styleinspector-propertyeditor");
|
||||
ok(editor, "Should have opened the editor.");
|
||||
is(editor.value, "15px", "Should have the right value in the editor.");
|
||||
|
||||
EventUtils.synthesizeKey("VK_DELETE", {}, view);
|
||||
yield waitForUpdate();
|
||||
EventUtils.synthesizeKey("VK_DELETE", {}, view.doc.defaultView);
|
||||
yield waitForUpdate(inspector);
|
||||
|
||||
is(editor.value, "", "Should have the right value in the editor.");
|
||||
is(getStyle(node, "margin-right"), "", "Should have updated the margin.");
|
||||
|
||||
EventUtils.synthesizeKey("VK_RETURN", {}, view);
|
||||
yield waitForUpdate();
|
||||
EventUtils.synthesizeKey("VK_RETURN", {}, view.doc.defaultView);
|
||||
|
||||
is(getStyle(node, "margin-right"), "", "Should be the right margin-top on the element.")
|
||||
is(span.textContent, 10, "Should have the right value in the box model.");
|
||||
|
|
|
@ -1,135 +1,144 @@
|
|||
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Test editing box model values when all values are set
|
||||
|
||||
const TEST_URI = "<style>" +
|
||||
"div { margin: 10px; padding: 3px }" +
|
||||
"#div1 { margin-top: 5px }" +
|
||||
"#div2 { border-bottom: 1em solid black; }" +
|
||||
"#div3 { padding: 2em; }" +
|
||||
"</style>" +
|
||||
"<div id='div1'></div><div id='div2'></div><div id='div3'></div>";
|
||||
|
||||
function getStyle(node, property) {
|
||||
return node.style.getPropertyValue(property);
|
||||
}
|
||||
|
||||
let doc;
|
||||
let inspector;
|
||||
|
||||
let test = asyncTest(function*() {
|
||||
let style = "div { margin: 10px; padding: 3px } #div1 { margin-top: 5px } #div2 { border-bottom: 1em solid black; } #div3 { padding: 2em; }";
|
||||
let html = "<style>" + style + "</style><div id='div1'></div><div id='div2'></div><div id='div3'></div>"
|
||||
yield addTab("data:text/html," + encodeURIComponent(TEST_URI));
|
||||
let {toolbox, inspector, view} = yield openLayoutView();
|
||||
|
||||
let content = yield loadTab("data:text/html," + encodeURIComponent(html));
|
||||
doc = content.document;
|
||||
|
||||
let target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||
let toolbox = yield gDevTools.showToolbox(target, "inspector");
|
||||
inspector = toolbox.getCurrentPanel();
|
||||
|
||||
inspector.sidebar.select("layoutview");
|
||||
yield inspector.sidebar.once("layoutview-ready");
|
||||
yield runTests();
|
||||
yield runTests(inspector, view);
|
||||
// TODO: Closing the toolbox in this test leaks - bug 994314
|
||||
// yield gDevTools.closeToolbox(target);
|
||||
// yield destroyToolbox(inspector);
|
||||
});
|
||||
|
||||
addTest("When all properties are set on the node editing one should work",
|
||||
function*() {
|
||||
let node = doc.getElementById("div1");
|
||||
node.style.padding = "5px";
|
||||
let view = yield selectNode(node);
|
||||
function*(inspector, view) {
|
||||
let node = content.document.getElementById("div1");
|
||||
|
||||
let span = view.document.querySelector(".padding.bottom > span");
|
||||
node.style.padding = "5px";
|
||||
yield waitForUpdate(inspector);
|
||||
|
||||
yield selectNode(node, inspector);
|
||||
|
||||
let span = view.doc.querySelector(".padding.bottom > span");
|
||||
is(span.textContent, 5, "Should have the right value in the box model.");
|
||||
|
||||
EventUtils.synthesizeMouseAtCenter(span, {}, view);
|
||||
let editor = view.document.querySelector(".styleinspector-propertyeditor");
|
||||
EventUtils.synthesizeMouseAtCenter(span, {}, view.doc.defaultView);
|
||||
let editor = view.doc.querySelector(".styleinspector-propertyeditor");
|
||||
ok(editor, "Should have opened the editor.");
|
||||
is(editor.value, "5px", "Should have the right value in the editor.");
|
||||
|
||||
EventUtils.synthesizeKey("7", {}, view);
|
||||
yield waitForUpdate();
|
||||
EventUtils.synthesizeKey("7", {}, view.doc.defaultView);
|
||||
yield waitForUpdate(inspector);
|
||||
|
||||
is(editor.value, "7", "Should have the right value in the editor.");
|
||||
is(getStyle(node, "padding-bottom"), "7px", "Should have updated the padding");
|
||||
|
||||
EventUtils.synthesizeKey("VK_RETURN", {}, view);
|
||||
yield waitForUpdate();
|
||||
EventUtils.synthesizeKey("VK_RETURN", {}, view.doc.defaultView);
|
||||
|
||||
is(getStyle(node, "padding-bottom"), "7px", "Should be the right padding.")
|
||||
is(span.textContent, 7, "Should have the right value in the box model.");
|
||||
});
|
||||
|
||||
addTest("When all properties are set on the node editing one should work",
|
||||
function*() {
|
||||
let node = doc.getElementById("div1");
|
||||
node.style.padding = "5px";
|
||||
let view = yield selectNode(node);
|
||||
function*(inspector, view) {
|
||||
let node = content.document.getElementById("div1");
|
||||
|
||||
let span = view.document.querySelector(".padding.left > span");
|
||||
node.style.padding = "5px";
|
||||
yield waitForUpdate(inspector);
|
||||
|
||||
yield selectNode(node, inspector);
|
||||
|
||||
let span = view.doc.querySelector(".padding.left > span");
|
||||
is(span.textContent, 5, "Should have the right value in the box model.");
|
||||
|
||||
EventUtils.synthesizeMouseAtCenter(span, {}, view);
|
||||
let editor = view.document.querySelector(".styleinspector-propertyeditor");
|
||||
EventUtils.synthesizeMouseAtCenter(span, {}, view.doc.defaultView);
|
||||
let editor = view.doc.querySelector(".styleinspector-propertyeditor");
|
||||
ok(editor, "Should have opened the editor.");
|
||||
is(editor.value, "5px", "Should have the right value in the editor.");
|
||||
|
||||
EventUtils.synthesizeKey("8", {}, view);
|
||||
yield waitForUpdate();
|
||||
EventUtils.synthesizeKey("8", {}, view.doc.defaultView);
|
||||
yield waitForUpdate(inspector);
|
||||
|
||||
is(editor.value, "8", "Should have the right value in the editor.");
|
||||
is(getStyle(node, "padding-left"), "8px", "Should have updated the padding");
|
||||
|
||||
EventUtils.synthesizeKey("VK_ESCAPE", {}, view);
|
||||
yield waitForUpdate();
|
||||
EventUtils.synthesizeKey("VK_ESCAPE", {}, view.doc.defaultView);
|
||||
yield waitForUpdate(inspector);
|
||||
|
||||
is(getStyle(node, "padding-left"), "5px", "Should be the right padding.")
|
||||
is(span.textContent, 5, "Should have the right value in the box model.");
|
||||
});
|
||||
|
||||
addTest("When all properties are set on the node deleting one should work",
|
||||
function*() {
|
||||
let node = doc.getElementById("div1");
|
||||
node.style.padding = "5px";
|
||||
let view = yield selectNode(node);
|
||||
function*(inspector, view) {
|
||||
let node = content.document.getElementById("div1");
|
||||
|
||||
let span = view.document.querySelector(".padding.left > span");
|
||||
node.style.padding = "5px";
|
||||
|
||||
yield selectNode(node, inspector);
|
||||
|
||||
let span = view.doc.querySelector(".padding.left > span");
|
||||
is(span.textContent, 5, "Should have the right value in the box model.");
|
||||
|
||||
EventUtils.synthesizeMouseAtCenter(span, {}, view);
|
||||
let editor = view.document.querySelector(".styleinspector-propertyeditor");
|
||||
EventUtils.synthesizeMouseAtCenter(span, {}, view.doc.defaultView);
|
||||
let editor = view.doc.querySelector(".styleinspector-propertyeditor");
|
||||
ok(editor, "Should have opened the editor.");
|
||||
is(editor.value, "5px", "Should have the right value in the editor.");
|
||||
|
||||
EventUtils.synthesizeKey("VK_DELETE", {}, view);
|
||||
yield waitForUpdate();
|
||||
EventUtils.synthesizeKey("VK_DELETE", {}, view.doc.defaultView);
|
||||
yield waitForUpdate(inspector);
|
||||
|
||||
is(editor.value, "", "Should have the right value in the editor.");
|
||||
is(getStyle(node, "padding-left"), "", "Should have updated the padding");
|
||||
|
||||
EventUtils.synthesizeKey("VK_RETURN", {}, view);
|
||||
yield waitForUpdate();
|
||||
EventUtils.synthesizeKey("VK_RETURN", {}, view.doc.defaultView);
|
||||
|
||||
is(getStyle(node, "padding-left"), "", "Should be the right padding.")
|
||||
is(span.textContent, 3, "Should have the right value in the box model.");
|
||||
});
|
||||
|
||||
addTest("When all properties are set on the node deleting one then cancelling should work",
|
||||
function*() {
|
||||
let node = doc.getElementById("div1");
|
||||
node.style.padding = "5px";
|
||||
let view = yield selectNode(node);
|
||||
function*(inspector, view) {
|
||||
let node = content.document.getElementById("div1");
|
||||
|
||||
let span = view.document.querySelector(".padding.left > span");
|
||||
node.style.padding = "5px";
|
||||
yield waitForUpdate(inspector);
|
||||
|
||||
yield selectNode(node, inspector);
|
||||
|
||||
let span = view.doc.querySelector(".padding.left > span");
|
||||
is(span.textContent, 5, "Should have the right value in the box model.");
|
||||
|
||||
EventUtils.synthesizeMouseAtCenter(span, {}, view);
|
||||
let editor = view.document.querySelector(".styleinspector-propertyeditor");
|
||||
EventUtils.synthesizeMouseAtCenter(span, {}, view.doc.defaultView);
|
||||
let editor = view.doc.querySelector(".styleinspector-propertyeditor");
|
||||
ok(editor, "Should have opened the editor.");
|
||||
is(editor.value, "5px", "Should have the right value in the editor.");
|
||||
|
||||
EventUtils.synthesizeKey("VK_DELETE", {}, view);
|
||||
yield waitForUpdate();
|
||||
EventUtils.synthesizeKey("VK_DELETE", {}, view.doc.defaultView);
|
||||
yield waitForUpdate(inspector);
|
||||
|
||||
is(editor.value, "", "Should have the right value in the editor.");
|
||||
is(getStyle(node, "padding-left"), "", "Should have updated the padding");
|
||||
|
||||
EventUtils.synthesizeKey("VK_ESCAPE", {}, view);
|
||||
yield waitForUpdate();
|
||||
EventUtils.synthesizeKey("VK_ESCAPE", {}, view.doc.defaultView);
|
||||
yield waitForUpdate(inspector);
|
||||
|
||||
is(getStyle(node, "padding-left"), "5px", "Should be the right padding.")
|
||||
is(span.textContent, 5, "Should have the right value in the box model.");
|
||||
|
|
|
@ -1,55 +1,56 @@
|
|||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Test that editing the border value in the box model applies the border style
|
||||
|
||||
const TEST_URI = "<style>" +
|
||||
"div { margin: 10px; padding: 3px }" +
|
||||
"#div1 { margin-top: 5px }" +
|
||||
"#div2 { border-bottom: 1em solid black; }" +
|
||||
"#div3 { padding: 2em; }" +
|
||||
"</style>" +
|
||||
"<div id='div1'></div><div id='div2'></div><div id='div3'></div>";
|
||||
|
||||
function getStyle(node, property) {
|
||||
return node.style.getPropertyValue(property);
|
||||
}
|
||||
|
||||
let doc;
|
||||
let inspector;
|
||||
|
||||
let test = asyncTest(function*() {
|
||||
let style = "div { margin: 10px; padding: 3px } #div1 { margin-top: 5px } #div2 { border-bottom: 1em solid black; } #div3 { padding: 2em; }";
|
||||
let html = "<style>" + style + "</style><div id='div1'></div><div id='div2'></div><div id='div3'></div>"
|
||||
yield addTab("data:text/html," + encodeURIComponent(TEST_URI));
|
||||
let {toolbox, inspector, view} = yield openLayoutView();
|
||||
|
||||
let content = yield loadTab("data:text/html," + encodeURIComponent(html));
|
||||
doc = content.document;
|
||||
|
||||
let target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||
let toolbox = yield gDevTools.showToolbox(target, "inspector");
|
||||
inspector = toolbox.getCurrentPanel();
|
||||
|
||||
inspector.sidebar.select("layoutview");
|
||||
yield inspector.sidebar.once("layoutview-ready");
|
||||
yield runTests();
|
||||
yield runTests(inspector, view);
|
||||
// TODO: Closing the toolbox in this test leaks - bug 994314
|
||||
// yield gDevTools.closeToolbox(target);
|
||||
// yield destroyToolbox(inspector);
|
||||
});
|
||||
|
||||
addTest("Test that adding a border applies a border style when necessary",
|
||||
function*() {
|
||||
let node = doc.getElementById("div1");
|
||||
function*(inspector, view) {
|
||||
let node = content.document.getElementById("div1");
|
||||
is(getStyle(node, "border-top-width"), "", "Should have the right border");
|
||||
is(getStyle(node, "border-top-style"), "", "Should have the right border");
|
||||
let view = yield selectNode(node);
|
||||
yield selectNode(node, inspector);
|
||||
|
||||
let span = view.document.querySelector(".border.top > span");
|
||||
let span = view.doc.querySelector(".border.top > span");
|
||||
is(span.textContent, 0, "Should have the right value in the box model.");
|
||||
|
||||
EventUtils.synthesizeMouseAtCenter(span, {}, view);
|
||||
let editor = view.document.querySelector(".styleinspector-propertyeditor");
|
||||
EventUtils.synthesizeMouseAtCenter(span, {}, view.doc.defaultView);
|
||||
let editor = view.doc.querySelector(".styleinspector-propertyeditor");
|
||||
ok(editor, "Should have opened the editor.");
|
||||
is(editor.value, "0", "Should have the right value in the editor.");
|
||||
|
||||
EventUtils.synthesizeKey("1", {}, view);
|
||||
yield waitForUpdate();
|
||||
EventUtils.synthesizeKey("1", {}, view.doc.defaultView);
|
||||
yield waitForUpdate(inspector);
|
||||
|
||||
is(editor.value, "1", "Should have the right value in the editor.");
|
||||
is(getStyle(node, "border-top-width"), "1px", "Should have the right border");
|
||||
is(getStyle(node, "border-top-style"), "solid", "Should have the right border");
|
||||
|
||||
EventUtils.synthesizeKey("VK_ESCAPE", {}, view);
|
||||
yield waitForUpdate();
|
||||
EventUtils.synthesizeKey("VK_ESCAPE", {}, view.doc.defaultView);
|
||||
yield waitForUpdate(inspector);
|
||||
|
||||
is(getStyle(node, "border-top-width"), "", "Should be the right padding.")
|
||||
is(getStyle(node, "border-top-style"), "", "Should have the right border");
|
||||
|
|
|
@ -1,108 +1,107 @@
|
|||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Test that units are displayed correctly when editing values in the box model
|
||||
// and that values are retrieved and parsed correctly from the back-end
|
||||
|
||||
const TEST_URI = "<style>" +
|
||||
"div { margin: 10px; padding: 3px }" +
|
||||
"#div1 { margin-top: 5px }" +
|
||||
"#div2 { border-bottom: 1em solid black; }" +
|
||||
"#div3 { padding: 2em; }" +
|
||||
"</style>" +
|
||||
"<div id='div1'></div><div id='div2'></div><div id='div3'></div>";
|
||||
|
||||
function getStyle(node, property) {
|
||||
return node.style.getPropertyValue(property);
|
||||
}
|
||||
|
||||
let doc;
|
||||
let inspector;
|
||||
|
||||
let test = asyncTest(function*() {
|
||||
let style = "div { margin: 10px; padding: 3px } #div1 { margin-top: 5px } #div2 { border-bottom: 1em solid black; } #div3 { padding: 2em; }";
|
||||
let html = "<style>" + style + "</style><div id='div1'></div><div id='div2'></div><div id='div3'></div>"
|
||||
yield addTab("data:text/html," + encodeURIComponent(TEST_URI));
|
||||
let {toolbox, inspector, view} = yield openLayoutView();
|
||||
|
||||
let content = yield loadTab("data:text/html," + encodeURIComponent(html));
|
||||
doc = content.document;
|
||||
|
||||
let target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||
let toolbox = yield gDevTools.showToolbox(target, "inspector");
|
||||
inspector = toolbox.getCurrentPanel();
|
||||
|
||||
inspector.sidebar.select("layoutview");
|
||||
yield inspector.sidebar.once("layoutview-ready");
|
||||
yield runTests();
|
||||
yield runTests(inspector, view);
|
||||
// TODO: Closing the toolbox in this test leaks - bug 994314
|
||||
// yield gDevTools.closeToolbox(target);
|
||||
// yield destroyToolbox(inspector);
|
||||
});
|
||||
|
||||
addTest("Test that entering units works",
|
||||
function*() {
|
||||
let node = doc.getElementById("div1");
|
||||
function*(inspector, view) {
|
||||
let node = content.document.getElementById("div1");
|
||||
is(getStyle(node, "padding-top"), "", "Should have the right padding");
|
||||
let view = yield selectNode(node);
|
||||
yield selectNode(node, inspector);
|
||||
|
||||
let span = view.document.querySelector(".padding.top > span");
|
||||
let span = view.doc.querySelector(".padding.top > span");
|
||||
is(span.textContent, 3, "Should have the right value in the box model.");
|
||||
|
||||
EventUtils.synthesizeMouseAtCenter(span, {}, view);
|
||||
let editor = view.document.querySelector(".styleinspector-propertyeditor");
|
||||
EventUtils.synthesizeMouseAtCenter(span, {}, view.doc.defaultView);
|
||||
let editor = view.doc.querySelector(".styleinspector-propertyeditor");
|
||||
ok(editor, "Should have opened the editor.");
|
||||
is(editor.value, "3px", "Should have the right value in the editor.");
|
||||
|
||||
EventUtils.synthesizeKey("1", {}, view);
|
||||
yield waitForUpdate();
|
||||
EventUtils.synthesizeKey("e", {}, view);
|
||||
yield waitForUpdate();
|
||||
EventUtils.synthesizeKey("1", {}, view.doc.defaultView);
|
||||
yield waitForUpdate(inspector);
|
||||
EventUtils.synthesizeKey("e", {}, view.doc.defaultView);
|
||||
yield waitForUpdate(inspector);
|
||||
|
||||
is(getStyle(node, "padding-top"), "", "An invalid value is handled cleanly");
|
||||
|
||||
EventUtils.synthesizeKey("m", {}, view);
|
||||
yield waitForUpdate();
|
||||
EventUtils.synthesizeKey("m", {}, view.doc.defaultView);
|
||||
yield waitForUpdate(inspector);
|
||||
|
||||
is(editor.value, "1em", "Should have the right value in the editor.");
|
||||
is(getStyle(node, "padding-top"), "1em", "Should have updated the padding.");
|
||||
|
||||
EventUtils.synthesizeKey("VK_RETURN", {}, view);
|
||||
yield waitForUpdate();
|
||||
EventUtils.synthesizeKey("VK_RETURN", {}, view.doc.defaultView);
|
||||
|
||||
is(getStyle(node, "padding-top"), "1em", "Should be the right padding.")
|
||||
is(span.textContent, 16, "Should have the right value in the box model.");
|
||||
});
|
||||
|
||||
addTest("Test that we pick up the value from a higher style rule",
|
||||
function*() {
|
||||
let node = doc.getElementById("div2");
|
||||
function*(inspector, view) {
|
||||
let node = content.document.getElementById("div2");
|
||||
is(getStyle(node, "border-bottom-width"), "", "Should have the right border-bottom-width");
|
||||
let view = yield selectNode(node);
|
||||
yield selectNode(node, inspector);
|
||||
|
||||
let span = view.document.querySelector(".border.bottom > span");
|
||||
let span = view.doc.querySelector(".border.bottom > span");
|
||||
is(span.textContent, 16, "Should have the right value in the box model.");
|
||||
|
||||
EventUtils.synthesizeMouseAtCenter(span, {}, view);
|
||||
let editor = view.document.querySelector(".styleinspector-propertyeditor");
|
||||
EventUtils.synthesizeMouseAtCenter(span, {}, view.doc.defaultView);
|
||||
let editor = view.doc.querySelector(".styleinspector-propertyeditor");
|
||||
ok(editor, "Should have opened the editor.");
|
||||
is(editor.value, "1em", "Should have the right value in the editor.");
|
||||
|
||||
EventUtils.synthesizeKey("0", {}, view);
|
||||
yield waitForUpdate();
|
||||
EventUtils.synthesizeKey("0", {}, view.doc.defaultView);
|
||||
yield waitForUpdate(inspector);
|
||||
|
||||
is(editor.value, "0", "Should have the right value in the editor.");
|
||||
is(getStyle(node, "border-bottom-width"), "0px", "Should have updated the border.");
|
||||
|
||||
EventUtils.synthesizeKey("VK_RETURN", {}, view);
|
||||
yield waitForUpdate();
|
||||
EventUtils.synthesizeKey("VK_RETURN", {}, view.doc.defaultView);
|
||||
|
||||
is(getStyle(node, "border-bottom-width"), "0px", "Should be the right border-bottom-width.")
|
||||
is(span.textContent, 0, "Should have the right value in the box model.");
|
||||
});
|
||||
|
||||
addTest("Test that shorthand properties are parsed correctly",
|
||||
function*() {
|
||||
let node = doc.getElementById("div3");
|
||||
function*(inspector, view) {
|
||||
let node = content.document.getElementById("div3");
|
||||
is(getStyle(node, "padding-right"), "", "Should have the right padding");
|
||||
let view = yield selectNode(node);
|
||||
yield selectNode(node, inspector);
|
||||
|
||||
let span = view.document.querySelector(".padding.right > span");
|
||||
let span = view.doc.querySelector(".padding.right > span");
|
||||
is(span.textContent, 32, "Should have the right value in the box model.");
|
||||
|
||||
EventUtils.synthesizeMouseAtCenter(span, {}, view);
|
||||
let editor = view.document.querySelector(".styleinspector-propertyeditor");
|
||||
EventUtils.synthesizeMouseAtCenter(span, {}, view.doc.defaultView);
|
||||
let editor = view.doc.querySelector(".styleinspector-propertyeditor");
|
||||
ok(editor, "Should have opened the editor.");
|
||||
is(editor.value, "2em", "Should have the right value in the editor.");
|
||||
|
||||
EventUtils.synthesizeKey("VK_RETURN", {}, view);
|
||||
yield waitForUpdate();
|
||||
EventUtils.synthesizeKey("VK_RETURN", {}, view.doc.defaultView);
|
||||
|
||||
is(getStyle(node, "padding-right"), "", "Should be the right padding.")
|
||||
is(span.textContent, 32, "Should have the right value in the box model.");
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Test that the layout-view displays the right values and that it updates when
|
||||
// the node's style is changed
|
||||
|
||||
// Expected values:
|
||||
let res1 = [
|
||||
|
@ -36,46 +42,22 @@ let res2 = [
|
|||
{selector: ".border.right > span", value: 10},
|
||||
];
|
||||
|
||||
let inspector;
|
||||
let view;
|
||||
|
||||
let test = asyncTest(function*() {
|
||||
let style = "div { position: absolute; top: 42px; left: 42px; height: 100px; width: 100px; border: 10px solid black; padding: 20px; margin: 30px auto;}";
|
||||
let html = "<style>" + style + "</style><div></div>"
|
||||
|
||||
let content = yield loadTab("data:text/html," + encodeURIComponent(html));
|
||||
let node = content.document.querySelector("div");
|
||||
ok(node, "node found");
|
||||
yield addTab("data:text/html," + encodeURIComponent(html));
|
||||
let {toolbox, inspector, view} = yield openLayoutView();
|
||||
yield selectNode("div", inspector);
|
||||
|
||||
let target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||
let toolbox = yield gDevTools.showToolbox(target, "inspector");
|
||||
inspector = toolbox.getCurrentPanel();
|
||||
yield runTests(inspector, view);
|
||||
|
||||
info("Inspector open");
|
||||
|
||||
inspector.sidebar.select("layoutview");
|
||||
yield inspector.sidebar.once("layoutview-ready");
|
||||
|
||||
inspector.selection.setNode(node);
|
||||
yield inspector.once("inspector-updated");
|
||||
|
||||
info("Layout view ready");
|
||||
|
||||
view = inspector.sidebar.getWindowForTab("layoutview");
|
||||
ok(!!view.layoutview, "LayoutView document is alive.");
|
||||
|
||||
yield runTests();
|
||||
|
||||
executeSoon(function() {
|
||||
inspector._toolbox.destroy();
|
||||
});
|
||||
|
||||
yield gDevTools.once("toolbox-destroyed");
|
||||
yield destroyToolbox(inspector);
|
||||
});
|
||||
|
||||
addTest("Test that the initial values of the box model are correct",
|
||||
function*() {
|
||||
let viewdoc = view.document;
|
||||
function*(inspector, view) {
|
||||
let viewdoc = view.doc;
|
||||
|
||||
for (let i = 0; i < res1.length; i++) {
|
||||
let elt = viewdoc.querySelector(res1[i].selector);
|
||||
|
@ -84,32 +66,16 @@ function*() {
|
|||
});
|
||||
|
||||
addTest("Test that changing the document updates the box model",
|
||||
function*() {
|
||||
let viewdoc = view.document;
|
||||
function*(inspector, view) {
|
||||
let viewdoc = view.doc;
|
||||
|
||||
let onUpdated = waitForUpdate(inspector);
|
||||
inspector.selection.node.style.height = "150px";
|
||||
inspector.selection.node.style.paddingRight = "50px";
|
||||
|
||||
yield waitForUpdate();
|
||||
yield onUpdated;
|
||||
|
||||
for (let i = 0; i < res2.length; i++) {
|
||||
let elt = viewdoc.querySelector(res2[i].selector);
|
||||
is(elt.textContent, res2[i].value, res2[i].selector + " has the right value after style update.");
|
||||
}
|
||||
});
|
||||
|
||||
addTest("Test that long labels on left/right are rotated 90 degrees",
|
||||
function*() {
|
||||
let viewdoc = view.document;
|
||||
const LONG_TEXT_ROTATE_LIMIT = 3;
|
||||
|
||||
for (let i = 0; i < res1.length; i++) {
|
||||
let elt = viewdoc.querySelector(res1[i].selector);
|
||||
let isLong = elt.textContent.length > LONG_TEXT_ROTATE_LIMIT;
|
||||
let classList = elt.parentNode.classList
|
||||
let canBeRotated = classList.contains("left") || classList.contains("right");
|
||||
let isRotated = classList.contains("rotate");
|
||||
|
||||
is(canBeRotated && isLong, isRotated, res1[i].selector + " correctly rotated.");
|
||||
}
|
||||
});
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Test that longer values are rotated on the side
|
||||
|
||||
const res1 = [
|
||||
{selector: ".margin.top > span", value: 30},
|
||||
{selector: ".margin.left > span", value: "auto"},
|
||||
{selector: ".margin.bottom > span", value: 30},
|
||||
{selector: ".margin.right > span", value: "auto"},
|
||||
{selector: ".padding.top > span", value: 20},
|
||||
{selector: ".padding.left > span", value: 2000000},
|
||||
{selector: ".padding.bottom > span", value: 20},
|
||||
{selector: ".padding.right > span", value: 20},
|
||||
{selector: ".border.top > span", value: 10},
|
||||
{selector: ".border.left > span", value: 10},
|
||||
{selector: ".border.bottom > span", value: 10},
|
||||
{selector: ".border.right > span", value: 10},
|
||||
];
|
||||
|
||||
const TEST_URI = encodeURIComponent([
|
||||
"<style>",
|
||||
"div{border:10px solid black; padding: 20px 20px 20px 2000000px; margin: 30px auto;}",
|
||||
"</style>",
|
||||
"<div></div>"
|
||||
].join(""));
|
||||
const LONG_TEXT_ROTATE_LIMIT = 3;
|
||||
|
||||
let test = asyncTest(function*() {
|
||||
yield addTab("data:text/html," + TEST_URI);
|
||||
let {toolbox, inspector, view} = yield openLayoutView();
|
||||
yield selectNode("div", inspector);
|
||||
|
||||
for (let i = 0; i < res1.length; i++) {
|
||||
let elt = view.doc.querySelector(res1[i].selector);
|
||||
let isLong = elt.textContent.length > LONG_TEXT_ROTATE_LIMIT;
|
||||
let classList = elt.parentNode.classList
|
||||
let canBeRotated = classList.contains("left") || classList.contains("right");
|
||||
let isRotated = classList.contains("rotate");
|
||||
|
||||
is(canBeRotated && isLong, isRotated, res1[i].selector + " correctly rotated.");
|
||||
}
|
||||
|
||||
yield destroyToolbox(inspector);
|
||||
});
|
|
@ -1,87 +1,242 @@
|
|||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
Cu.import("resource://gre/modules/Task.jsm");
|
||||
"use strict";
|
||||
|
||||
const Cu = Components.utils;
|
||||
let {gDevTools} = Cu.import("resource:///modules/devtools/gDevTools.jsm", {});
|
||||
let {devtools} = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
|
||||
const {Promise: promise} = Cu.import("resource://gre/modules/Promise.jsm", {});
|
||||
let TargetFactory = devtools.TargetFactory;
|
||||
let {Promise: promise} = Cu.import("resource://gre/modules/Promise.jsm", {});
|
||||
let {console} = Components.utils.import("resource://gre/modules/devtools/Console.jsm", {});
|
||||
|
||||
Services.prefs.setBoolPref("devtools.inspector.sidebarOpen", true);
|
||||
Services.prefs.setIntPref("devtools.toolbox.footer.height", 350);
|
||||
gDevTools.testing = true;
|
||||
SimpleTest.registerCleanupFunction(() => {
|
||||
Services.prefs.clearUserPref("devtools.inspector.sidebarOpen");
|
||||
Services.prefs.clearUserPref("devtools.toolbox.footer.height");
|
||||
gDevTools.testing = false;
|
||||
});
|
||||
|
||||
// All tests are async in general
|
||||
// All test are asynchronous
|
||||
waitForExplicitFinish();
|
||||
|
||||
function loadTab(url) {
|
||||
let deferred = promise.defer();
|
||||
const TEST_URL_ROOT = "http://example.com/browser/browser/devtools/layoutview/test/";
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
// Uncomment to log events
|
||||
// Services.prefs.setBoolPref("devtools.dump.emit", true);
|
||||
// Services.prefs.setBoolPref("devtools.debugger.log", true);
|
||||
|
||||
// Set the testing flag on gDevTools and reset it when the test ends
|
||||
gDevTools.testing = true;
|
||||
registerCleanupFunction(() => gDevTools.testing = false);
|
||||
|
||||
// Clean-up all prefs that might have been changed during a test run
|
||||
// (safer here because if the test fails, then the pref is never reverted)
|
||||
Services.prefs.setIntPref("devtools.toolbox.footer.height", 350);
|
||||
registerCleanupFunction(() => {
|
||||
Services.prefs.clearUserPref("devtools.dump.emit");
|
||||
Services.prefs.clearUserPref("devtools.debugger.log");
|
||||
Services.prefs.clearUserPref("devtools.toolbox.footer.height");
|
||||
Services.prefs.setCharPref("devtools.inspector.activeSidebar", "ruleview");
|
||||
});
|
||||
|
||||
// Auto close the toolbox and close the test tabs when the test ends
|
||||
registerCleanupFunction(() => {
|
||||
// For now, tests must call `yield destroyToolbox(inspector);` at the end.
|
||||
// This should normally be handled automatically here but some tests
|
||||
// are leaking when we do so (browser_editablemodel_border.js)
|
||||
// try {
|
||||
// let target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||
// gDevTools.closeToolbox(target);
|
||||
// } catch (ex) {
|
||||
// dump(ex);
|
||||
// }
|
||||
while (gBrowser.tabs.length > 1) {
|
||||
gBrowser.removeCurrentTab();
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Define an async test based on a generator function
|
||||
*/
|
||||
function asyncTest(generator) {
|
||||
return () => Task.spawn(generator).then(null, ok.bind(null, false)).then(finish);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new test tab in the browser and load the given url.
|
||||
* @param {String} url The url to be loaded in the new tab
|
||||
* @return a promise that resolves to the tab object when the url is loaded
|
||||
*/
|
||||
function addTab(url) {
|
||||
let def = promise.defer();
|
||||
|
||||
let tab = gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onload() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onload, true);
|
||||
waitForFocus(function() {
|
||||
deferred.resolve(content);
|
||||
info("URL " + url + " loading complete into new test tab");
|
||||
waitForFocus(() => {
|
||||
def.resolve(tab);
|
||||
}, content);
|
||||
}, true);
|
||||
|
||||
content.location = url;
|
||||
|
||||
return deferred.promise;
|
||||
return def.promise;
|
||||
}
|
||||
|
||||
function selectNode(aNode) {
|
||||
info("selecting node");
|
||||
let onSelect = inspector.once("layoutview-updated");
|
||||
inspector.selection.setNode(aNode, "test");
|
||||
return onSelect.then(() => {
|
||||
let view = inspector.sidebar.getWindowForTab("layoutview");
|
||||
ok(!!view.layoutview, "LayoutView document is alive.");
|
||||
/**
|
||||
* Destroy the toolbox
|
||||
* @param {InspectorPanel}
|
||||
* @return a promise that resolves when destroyed
|
||||
*/
|
||||
let destroyToolbox = Task.async(function*(inspector) {
|
||||
let onDestroyed = gDevTools.once("toolbox-destroyed");
|
||||
inspector._toolbox.destroy();
|
||||
yield onDestroyed;
|
||||
});
|
||||
|
||||
return view;
|
||||
});
|
||||
/**
|
||||
* Simple DOM node accesor function that takes either a node or a string css
|
||||
* selector as argument and returns the corresponding node
|
||||
* @param {String|DOMNode} nodeOrSelector
|
||||
* @return {DOMNode}
|
||||
*/
|
||||
function getNode(nodeOrSelector) {
|
||||
return typeof nodeOrSelector === "string" ?
|
||||
content.document.querySelector(nodeOrSelector) :
|
||||
nodeOrSelector;
|
||||
}
|
||||
|
||||
function waitForUpdate() {
|
||||
/**
|
||||
* Set the inspector's current selection to a node or to the first match of the
|
||||
* given css selector
|
||||
* @param {InspectorPanel} inspector The instance of InspectorPanel currently
|
||||
* loaded in the toolbox
|
||||
* @param {String} reason Defaults to "test" which instructs the inspector not
|
||||
* to highlight the node upon selection
|
||||
* @param {String} reason Defaults to "test" which instructs the inspector not
|
||||
* to highlight the node upon selection
|
||||
* @return a promise that resolves when the inspector is updated with the new
|
||||
* node
|
||||
*/
|
||||
function selectNode(nodeOrSelector, inspector, reason="test") {
|
||||
info("Selecting the node " + nodeOrSelector);
|
||||
let node = getNode(nodeOrSelector);
|
||||
let updated = inspector.once("inspector-updated");
|
||||
inspector.selection.setNode(node, reason);
|
||||
return updated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the toolbox, with the inspector tool visible.
|
||||
* @return a promise that resolves when the inspector is ready
|
||||
*/
|
||||
let openInspector = Task.async(function*() {
|
||||
info("Opening the inspector");
|
||||
let target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||
|
||||
let inspector, toolbox;
|
||||
|
||||
// Checking if the toolbox and the inspector are already loaded
|
||||
// The inspector-updated event should only be waited for if the inspector
|
||||
// isn't loaded yet
|
||||
toolbox = gDevTools.getToolbox(target);
|
||||
if (toolbox) {
|
||||
inspector = toolbox.getPanel("inspector");
|
||||
if (inspector) {
|
||||
info("Toolbox and inspector already open");
|
||||
return {
|
||||
toolbox: toolbox,
|
||||
inspector: inspector
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
info("Opening the toolbox");
|
||||
toolbox = yield gDevTools.showToolbox(target, "inspector");
|
||||
yield waitForToolboxFrameFocus(toolbox);
|
||||
inspector = toolbox.getPanel("inspector");
|
||||
|
||||
info("Waiting for the inspector to update");
|
||||
yield inspector.once("inspector-updated");
|
||||
|
||||
return {
|
||||
toolbox: toolbox,
|
||||
inspector: inspector
|
||||
};
|
||||
});
|
||||
|
||||
/**
|
||||
* Wait for the toolbox frame to receive focus after it loads
|
||||
* @param {Toolbox} toolbox
|
||||
* @return a promise that resolves when focus has been received
|
||||
*/
|
||||
function waitForToolboxFrameFocus(toolbox) {
|
||||
info("Making sure that the toolbox's frame is focused");
|
||||
let def = promise.defer();
|
||||
let win = toolbox.frame.contentWindow;
|
||||
waitForFocus(def.resolve, win);
|
||||
return def.promise;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the inspector's sidebar corresponding to the given id already
|
||||
* exists
|
||||
* @param {InspectorPanel}
|
||||
* @param {String}
|
||||
* @return {Boolean}
|
||||
*/
|
||||
function hasSideBarTab(inspector, id) {
|
||||
return !!inspector.sidebar.getWindowForTab(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the toolbox, with the inspector tool visible, and the layout-view
|
||||
* sidebar tab selected.
|
||||
* @return a promise that resolves when the inspector is ready and the layout
|
||||
* view is visible and ready
|
||||
*/
|
||||
let openLayoutView = Task.async(function*() {
|
||||
let {toolbox, inspector} = yield openInspector();
|
||||
|
||||
if (!hasSideBarTab(inspector, "layoutview")) {
|
||||
info("Waiting for the layoutview sidebar to be ready");
|
||||
yield inspector.sidebar.once("layoutview-ready");
|
||||
}
|
||||
|
||||
info("Selecting the layoutview sidebar");
|
||||
inspector.sidebar.select("layoutview");
|
||||
|
||||
return {
|
||||
toolbox: toolbox,
|
||||
inspector: inspector,
|
||||
view: inspector.sidebar.getWindowForTab("layoutview")["layoutview"]
|
||||
};
|
||||
});
|
||||
|
||||
/**
|
||||
* Wait for the layoutview-updated event
|
||||
* @return a promise
|
||||
*/
|
||||
function waitForUpdate(inspector) {
|
||||
return inspector.once("layoutview-updated");
|
||||
}
|
||||
|
||||
function asyncTest(testfunc) {
|
||||
return Task.async(function*() {
|
||||
let initialTab = gBrowser.selectedTab;
|
||||
|
||||
yield testfunc();
|
||||
|
||||
// Remove all tabs except for the initial tab. This is basically
|
||||
// gBrowser.removeAllTabsBut without the animation
|
||||
let tabs = gBrowser.visibleTabs;
|
||||
gBrowser.selectedTab = initialTab;
|
||||
for (let i = tabs.length - 1; i >= 0; i--) {
|
||||
if (tabs[i] != initialTab)
|
||||
gBrowser.removeTab(tabs[i]);
|
||||
}
|
||||
|
||||
// Reset the sidebar back to the default
|
||||
Services.prefs.setCharPref("devtools.inspector.activeSidebar", "ruleview");
|
||||
|
||||
finish();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* The addTest/runTests function couple provides a simple way to define
|
||||
* subsequent test cases in a test file. Example:
|
||||
*
|
||||
* addTest("what this test does", function*() {
|
||||
* ... actual code for the test ...
|
||||
* });
|
||||
* addTest("what this second test does", function*() {
|
||||
* ... actual code for the second test ...
|
||||
* });
|
||||
* runTests().then(...);
|
||||
*/
|
||||
var TESTS = [];
|
||||
|
||||
function addTest(message, func) {
|
||||
TESTS.push([message, Task.async(func)])
|
||||
}
|
||||
|
||||
var runTests = Task.async(function*() {
|
||||
let runTests = Task.async(function*(...args) {
|
||||
for (let [message, test] of TESTS) {
|
||||
info(message);
|
||||
yield test();
|
||||
info("Running new test case: " + message);
|
||||
yield test.apply(null, args);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -18,6 +18,7 @@ Cu.import("resource://gre/modules/devtools/Console.jsm");
|
|||
const {Promise: promise} = Cu.import("resource://gre/modules/Promise.jsm", {});
|
||||
const {InplaceEditor, editableItem} = devtools.require("devtools/shared/inplace-editor");
|
||||
const {parseDeclarations} = devtools.require("devtools/styleinspector/css-parsing-utils");
|
||||
const {ReflowFront} = devtools.require("devtools/server/actors/layout");
|
||||
|
||||
const NUMERIC = /^-?[\d\.]+$/;
|
||||
const LONG_TEXT_ROTATE_LIMIT = 3;
|
||||
|
@ -90,13 +91,16 @@ EditingSession.prototype = {
|
|||
let modifications = this._rules[0].startModifyingProperties();
|
||||
|
||||
for (let property of properties) {
|
||||
if (!this._modifications.has(property.name))
|
||||
this._modifications.set(property.name, this.getPropertyFromRule(this._rules[0], property.name));
|
||||
if (!this._modifications.has(property.name)) {
|
||||
this._modifications.set(property.name,
|
||||
this.getPropertyFromRule(this._rules[0], property.name));
|
||||
}
|
||||
|
||||
if (property.value == "")
|
||||
if (property.value == "") {
|
||||
modifications.removeProperty(property.name);
|
||||
else
|
||||
} else {
|
||||
modifications.setProperty(property.name, property.value, "");
|
||||
}
|
||||
}
|
||||
|
||||
return modifications.apply().then(null, console.error);
|
||||
|
@ -110,26 +114,33 @@ EditingSession.prototype = {
|
|||
let modifications = this._rules[0].startModifyingProperties();
|
||||
|
||||
for (let [property, value] of this._modifications) {
|
||||
if (value != "")
|
||||
if (value != "") {
|
||||
modifications.setProperty(property, value, "");
|
||||
else
|
||||
} else {
|
||||
modifications.removeProperty(property);
|
||||
}
|
||||
}
|
||||
|
||||
return modifications.apply().then(null, console.error);
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
this._doc = null;
|
||||
this._rules = null;
|
||||
this._modifications.clear();
|
||||
}
|
||||
};
|
||||
|
||||
function LayoutView(aInspector, aWindow)
|
||||
{
|
||||
this.inspector = aInspector;
|
||||
/**
|
||||
* The layout-view panel
|
||||
* @param {InspectorPanel} inspector An instance of the inspector-panel
|
||||
* currently loaded in the toolbox
|
||||
* @param {Window} win The window containing the panel
|
||||
*/
|
||||
function LayoutView(inspector, win) {
|
||||
this.inspector = inspector;
|
||||
|
||||
// <browser> is not always available (for Chrome targets for example)
|
||||
if (this.inspector.target.tab) {
|
||||
this.browser = aInspector.target.tab.linkedBrowser;
|
||||
}
|
||||
|
||||
this.doc = aWindow.document;
|
||||
this.doc = win.document;
|
||||
this.sizeLabel = this.doc.querySelector(".size > span");
|
||||
this.sizeHeadingLabel = this.doc.getElementById("element-size");
|
||||
|
||||
|
@ -137,13 +148,18 @@ function LayoutView(aInspector, aWindow)
|
|||
}
|
||||
|
||||
LayoutView.prototype = {
|
||||
init: function LV_init() {
|
||||
init: function() {
|
||||
this.update = this.update.bind(this);
|
||||
this.onNewNode = this.onNewNode.bind(this);
|
||||
|
||||
this.onNewSelection = this.onNewSelection.bind(this);
|
||||
this.inspector.selection.on("new-node-front", this.onNewSelection);
|
||||
|
||||
this.onNewNode = this.onNewNode.bind(this);
|
||||
this.inspector.sidebar.on("layoutview-selected", this.onNewNode);
|
||||
|
||||
this.onSidebarSelect = this.onSidebarSelect.bind(this);
|
||||
this.inspector.sidebar.on("select", this.onSidebarSelect);
|
||||
|
||||
// Store for the different dimensions of the node.
|
||||
// 'selector' refers to the element that holds the value in view.xhtml;
|
||||
// 'property' is what we are measuring;
|
||||
|
@ -206,7 +222,9 @@ LayoutView.prototype = {
|
|||
continue;
|
||||
|
||||
let dimension = this.map[i];
|
||||
editableItem({ element: this.doc.querySelector(dimension.selector) }, (element, event) => {
|
||||
editableItem({
|
||||
element: this.doc.querySelector(dimension.selector)
|
||||
}, (element, event) => {
|
||||
this.initEditor(element, event, dimension);
|
||||
});
|
||||
}
|
||||
|
@ -214,10 +232,39 @@ LayoutView.prototype = {
|
|||
this.onNewNode();
|
||||
},
|
||||
|
||||
/**
|
||||
* Start listening to reflows in the current tab.
|
||||
*/
|
||||
trackReflows: function() {
|
||||
if (!this.reflowFront) {
|
||||
let toolbox = this.inspector.toolbox;
|
||||
if (toolbox.target.form.reflowActor) {
|
||||
this.reflowFront = ReflowFront(toolbox.target.client, toolbox.target.form);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this.reflowFront.on("reflows", this.update);
|
||||
this.reflowFront.start();
|
||||
},
|
||||
|
||||
/**
|
||||
* Stop listening to reflows in the current tab.
|
||||
*/
|
||||
untrackReflows: function() {
|
||||
if (!this.reflowFront) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.reflowFront.off("reflows", this.update);
|
||||
this.reflowFront.stop();
|
||||
},
|
||||
|
||||
/**
|
||||
* Called when the user clicks on one of the editable values in the layoutview
|
||||
*/
|
||||
initEditor: function LV_initEditor(element, event, dimension) {
|
||||
initEditor: function(element, event, dimension) {
|
||||
let { property, realProperty } = dimension;
|
||||
if (!realProperty)
|
||||
realProperty = property;
|
||||
|
@ -233,17 +280,20 @@ LayoutView.prototype = {
|
|||
},
|
||||
|
||||
change: (value) => {
|
||||
if (NUMERIC.test(value))
|
||||
if (NUMERIC.test(value)) {
|
||||
value += "px";
|
||||
}
|
||||
|
||||
let properties = [
|
||||
{ name: property, value: value }
|
||||
]
|
||||
];
|
||||
|
||||
if (property.substring(0, 7) == "border-") {
|
||||
let bprop = property.substring(0, property.length - 5) + "style";
|
||||
let style = session.getProperty(bprop);
|
||||
if (!style || style == "none" || style == "hidden")
|
||||
if (!style || style == "none" || style == "hidden") {
|
||||
properties.push({ name: bprop, value: "solid" });
|
||||
}
|
||||
}
|
||||
|
||||
session.setProperties(properties);
|
||||
|
@ -251,8 +301,10 @@ LayoutView.prototype = {
|
|||
|
||||
done: (value, commit) => {
|
||||
editor.elt.parentNode.classList.remove("editing");
|
||||
if (!commit)
|
||||
if (!commit) {
|
||||
session.revert();
|
||||
session.destroy();
|
||||
}
|
||||
}
|
||||
}, event);
|
||||
},
|
||||
|
@ -260,23 +312,35 @@ LayoutView.prototype = {
|
|||
/**
|
||||
* Is the layoutview visible in the sidebar?
|
||||
*/
|
||||
isActive: function LV_isActive() {
|
||||
return this.inspector.sidebar.getCurrentTabID() == "layoutview";
|
||||
isActive: function() {
|
||||
return this.inspector &&
|
||||
this.inspector.sidebar.getCurrentTabID() == "layoutview";
|
||||
},
|
||||
|
||||
/**
|
||||
* Destroy the nodes. Remove listeners.
|
||||
*/
|
||||
destroy: function LV_destroy() {
|
||||
destroy: function() {
|
||||
this.inspector.sidebar.off("layoutview-selected", this.onNewNode);
|
||||
this.inspector.selection.off("new-node-front", this.onNewSelection);
|
||||
if (this.browser) {
|
||||
this.browser.removeEventListener("MozAfterPaint", this.update, true);
|
||||
}
|
||||
this.inspector.sidebar.off("select", this.onSidebarSelect);
|
||||
|
||||
this.sizeHeadingLabel = null;
|
||||
this.sizeLabel = null;
|
||||
this.inspector = null;
|
||||
this.doc = null;
|
||||
|
||||
if (this.reflowFront) {
|
||||
this.untrackReflows();
|
||||
this.reflowFront.destroy();
|
||||
this.reflowFront = null;
|
||||
}
|
||||
},
|
||||
|
||||
onSidebarSelect: function(e, sidebar) {
|
||||
if (sidebar !== "layoutview") {
|
||||
this.dim();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -287,7 +351,10 @@ LayoutView.prototype = {
|
|||
this.onNewNode().then(done, (err) => { console.error(err); done() });
|
||||
},
|
||||
|
||||
onNewNode: function LV_onNewNode() {
|
||||
/**
|
||||
* @return a promise that resolves when the view has been updated
|
||||
*/
|
||||
onNewNode: function() {
|
||||
if (this.isActive() &&
|
||||
this.inspector.selection.isConnected() &&
|
||||
this.inspector.selection.isElementNode()) {
|
||||
|
@ -295,41 +362,36 @@ LayoutView.prototype = {
|
|||
} else {
|
||||
this.dim();
|
||||
}
|
||||
|
||||
return this.update();
|
||||
},
|
||||
|
||||
/**
|
||||
* Hide the layout boxes. No node are selected.
|
||||
* Hide the layout boxes and stop refreshing on reflows. No node is selected
|
||||
* or the layout-view sidebar is inactive.
|
||||
*/
|
||||
dim: function LV_dim() {
|
||||
if (this.browser) {
|
||||
this.browser.removeEventListener("MozAfterPaint", this.update, true);
|
||||
}
|
||||
this.trackingPaint = false;
|
||||
dim: function() {
|
||||
this.untrackReflows();
|
||||
this.doc.body.classList.add("dim");
|
||||
this.dimmed = true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Show the layout boxes. A node is selected.
|
||||
* Show the layout boxes and start refreshing on reflows. A node is selected
|
||||
* and the layout-view side is active.
|
||||
*/
|
||||
undim: function LV_undim() {
|
||||
if (!this.trackingPaint) {
|
||||
if (this.browser) {
|
||||
this.browser.addEventListener("MozAfterPaint", this.update, true);
|
||||
}
|
||||
this.trackingPaint = true;
|
||||
}
|
||||
undim: function() {
|
||||
this.trackReflows();
|
||||
this.doc.body.classList.remove("dim");
|
||||
this.dimmed = false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Compute the dimensions of the node and update the values in
|
||||
* the layoutview/view.xhtml document. Returns a promise that will be resolved
|
||||
* when complete.
|
||||
* the layoutview/view.xhtml document.
|
||||
* @return a promise that will be resolved when complete.
|
||||
*/
|
||||
update: function LV_update() {
|
||||
update: function() {
|
||||
let lastRequest = Task.spawn((function*() {
|
||||
if (!this.isActive() ||
|
||||
!this.inspector.selection.isConnected() ||
|
||||
|
@ -415,6 +477,10 @@ LayoutView.prototype = {
|
|||
return this._lastRequest = lastRequest;
|
||||
},
|
||||
|
||||
/**
|
||||
* Show the box-model highlighter on the currently selected element
|
||||
* @param {Object} options Options passed to the highlighter actor
|
||||
*/
|
||||
showBoxModel: function(options={}) {
|
||||
let toolbox = this.inspector.toolbox;
|
||||
let nodeFront = this.inspector.selection.nodeFront;
|
||||
|
@ -422,6 +488,9 @@ LayoutView.prototype = {
|
|||
toolbox.highlighterUtils.highlightNodeFront(nodeFront, options);
|
||||
},
|
||||
|
||||
/**
|
||||
* Hide the box-model highlighter on the currently selected element
|
||||
*/
|
||||
hideBoxModel: function() {
|
||||
let toolbox = this.inspector.toolbox;
|
||||
|
||||
|
|
|
@ -191,7 +191,7 @@ ElementStyle.prototype = {
|
|||
return this.dummyElementPromise.then(() => {
|
||||
if (this.populated != populated) {
|
||||
// Don't care anymore.
|
||||
return promise.reject("unused");
|
||||
return;
|
||||
}
|
||||
|
||||
// Store the current list of rules (if any) during the population
|
||||
|
|
|
@ -37,6 +37,10 @@ registerCleanupFunction(() => {
|
|||
// Uncomment to log events
|
||||
// Services.prefs.setBoolPref("devtools.dump.emit", true);
|
||||
|
||||
// Set the testing flag on gDevTools and reset it when the test ends
|
||||
gDevTools.testing = true;
|
||||
registerCleanupFunction(() => gDevTools.testing = false);
|
||||
|
||||
// Clean-up all prefs that might have been changed during a test run
|
||||
// (safer here because if the test fails, then the pref is never reverted)
|
||||
registerCleanupFunction(() => {
|
||||
|
|
|
@ -234,6 +234,7 @@ run-if = os == "mac"
|
|||
[browser_webconsole_bug_837351_securityerrors.js]
|
||||
[browser_webconsole_bug_846918_hsts_invalid-headers.js]
|
||||
[browser_webconsole_bug_915141_toggle_response_logging_with_keyboard.js]
|
||||
[browser_webconsole_bug_1006027_message_timestamps_incorrect.js]
|
||||
[browser_webconsole_cached_autocomplete.js]
|
||||
[browser_webconsole_change_font_size.js]
|
||||
[browser_webconsole_chrome.js]
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
/* 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/. */
|
||||
|
||||
function test() {
|
||||
Task.spawn(runner).then(finishTest);
|
||||
|
||||
function* runner() {
|
||||
const {tab} = yield loadTab("data:text/html;charset=utf8,<title>Test for Bug 1006027");
|
||||
|
||||
const target = TargetFactory.forTab(tab);
|
||||
const hud = yield openConsole(tab);
|
||||
|
||||
hud.jsterm.execute("console.log('bug1006027')");
|
||||
|
||||
yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
name: "console.log",
|
||||
text: "bug1006027",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
}],
|
||||
});
|
||||
|
||||
info('hud.outputNode.textContent:\n'+hud.outputNode.textContent);
|
||||
let timestampNodes = hud.outputNode.querySelectorAll('span.timestamp');
|
||||
let aTimestampMilliseconds = Array.prototype.map.call(timestampNodes,
|
||||
function (value) {
|
||||
// We are parsing timestamps as local time, relative to the begin of the epoch.
|
||||
// This is not the correct value of the timestamp, but good enough for comparison.
|
||||
return Date.parse('T'+String.trim(value.textContent));
|
||||
});
|
||||
|
||||
let minTimestamp = Math.min.apply(null, aTimestampMilliseconds);
|
||||
let maxTimestamp = Math.max.apply(null, aTimestampMilliseconds);
|
||||
ok(Math.abs(maxTimestamp - minTimestamp) < 1000, "console.log message timestamp spread < 1000ms confirmed");
|
||||
}
|
||||
}
|
||||
|
|
@ -231,7 +231,7 @@ panelview:not([mainview]) .toolbarbutton-text,
|
|||
|
||||
#PanelUI-contents {
|
||||
display: block;
|
||||
flex: auto;
|
||||
flex: 1 0 auto;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
padding: .5em 0;
|
||||
|
@ -787,7 +787,7 @@ menuitem.panel-subview-footer@menuStateActive@,
|
|||
}
|
||||
|
||||
/* Popups with only one item don't have a footer */
|
||||
menupopup[placespopup=true][singleitempopup=true] > hbox > .popup-internal-box > .arrowscrollbox-scrollbox > .scrollbox-innerbox,
|
||||
#BMB_bookmarksPopup menupopup[placespopup=true][singleitempopup=true] > hbox > .popup-internal-box > .arrowscrollbox-scrollbox > .scrollbox-innerbox,
|
||||
/* These popups never have a footer */
|
||||
#BMB_bookmarksToolbarPopup > hbox > .popup-internal-box > .arrowscrollbox-scrollbox > .scrollbox-innerbox,
|
||||
#BMB_unsortedBookmarksPopup > hbox > .popup-internal-box > .arrowscrollbox-scrollbox > .scrollbox-innerbox {
|
||||
|
|
|
@ -1024,22 +1024,100 @@ $(filter %.s,$(CSRCS:%.c=%.s)): %.s: %.c $(call mkdir_deps,$(MDDEPDIR))
|
|||
$(REPORT_BUILD)
|
||||
$(CC) -S $(COMPILE_CFLAGS) $($(notdir $<)_FLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS)
|
||||
|
||||
$(filter %.i,$(CPPSRCS:%.cpp=%.i)): %.i: %.cpp $(call mkdir_deps,$(MDDEPDIR))
|
||||
ifneq (,$(filter %.i,$(MAKECMDGOALS)))
|
||||
# Call as $(call _group_srcs,extension,$(SRCS)) - this will create a list
|
||||
# of the full sources, as well as the $(notdir) version. So:
|
||||
# foo.cpp sub/bar.cpp
|
||||
# becomes:
|
||||
# foo.cpp sub/bar.cpp bar.cpp
|
||||
#
|
||||
# This way we can match both 'make sub/bar.i' and 'make bar.i'
|
||||
_group_srcs = $(sort $(patsubst %.$1,%.i,$(filter %.$1,$2 $(notdir $2))))
|
||||
_PREPROCESSED_CPP_FILES := $(call _group_srcs,cpp,$(CPPSRCS))
|
||||
_PREPROCESSED_CC_FILES := $(call _group_srcs,cc,$(CPPSRCS))
|
||||
_PREPROCESSED_C_FILES := $(call _group_srcs,c,$(CSRCS))
|
||||
_PREPROCESSED_CMM_FILES := $(call _group_srcs,mm,$(CMMSRCS))
|
||||
|
||||
# Hack up VPATH so we can reach the sources. Eg: 'make Parser.i' may need to
|
||||
# reach $(srcdir)/frontend/Parser.i
|
||||
VPATH += $(addprefix $(srcdir)/,$(sort $(dir $(CPPSRCS) $(CSRCS) $(CMMSRCS))))
|
||||
|
||||
# Make preprocessed files PHONY so they are always executed, since they are
|
||||
# manual targets and we don't necessarily write to $@.
|
||||
.PHONY: $(_PREPROCESSED_CPP_FILES) $(_PREPROCESSED_CC_FILES) $(_PREPROCESSED_C_FILES) $(_PREPROCESSED_CMM_FILES)
|
||||
|
||||
$(_PREPROCESSED_CPP_FILES): %.i: %.cpp $(call mkdir_deps,$(MDDEPDIR))
|
||||
$(REPORT_BUILD)
|
||||
$(addprefix $(MKDIR) -p ,$(filter-out .,$(@D)))
|
||||
$(CCC) -C $(PREPROCESS_OPTION)$@ $(COMPILE_CXXFLAGS) $($(notdir $<)_FLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS)
|
||||
|
||||
$(filter %.i,$(CPPSRCS:%.cc=%.i)): %.i: %.cc $(call mkdir_deps,$(MDDEPDIR))
|
||||
$(_PREPROCESSED_CC_FILES): %.i: %.cc $(call mkdir_deps,$(MDDEPDIR))
|
||||
$(REPORT_BUILD)
|
||||
$(addprefix $(MKDIR) -p ,$(filter-out .,$(@D)))
|
||||
$(CCC) -C $(PREPROCESS_OPTION)$@ $(COMPILE_CXXFLAGS) $($(notdir $<)_FLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS)
|
||||
|
||||
$(filter %.i,$(CSRCS:%.c=%.i)): %.i: %.c $(call mkdir_deps,$(MDDEPDIR))
|
||||
$(_PREPROCESSED_C_FILES): %.i: %.c $(call mkdir_deps,$(MDDEPDIR))
|
||||
$(REPORT_BUILD)
|
||||
$(addprefix $(MKDIR) -p ,$(filter-out .,$(@D)))
|
||||
$(CC) -C $(PREPROCESS_OPTION)$@ $(COMPILE_CFLAGS) $($(notdir $<)_FLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS)
|
||||
|
||||
$(filter %.i,$(CMMSRCS:%.mm=%.i)): %.i: %.mm $(call mkdir_deps,$(MDDEPDIR))
|
||||
$(_PREPROCESSED_CMM_FILES): %.i: %.mm $(call mkdir_deps,$(MDDEPDIR))
|
||||
$(REPORT_BUILD)
|
||||
$(addprefix $(MKDIR) -p ,$(filter-out .,$(@D)))
|
||||
$(CCC) -C $(PREPROCESS_OPTION)$@ $(COMPILE_CXXFLAGS) $(COMPILE_CMMFLAGS) $($(notdir $<)_FLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS)
|
||||
|
||||
# Default to pre-processing the actual unified file. This can be overridden
|
||||
# at the command-line to pre-process only the individual source file.
|
||||
PP_UNIFIED ?= 1
|
||||
|
||||
# PP_REINVOKE gets set on the sub-make to prevent us from going in an
|
||||
# infinite loop if the filename doesn't exist in the unified source files.
|
||||
ifndef PP_REINVOKE
|
||||
|
||||
MATCH_cpp = \(cpp\|cc\)
|
||||
UPPER_c = C
|
||||
UPPER_cpp = CPP
|
||||
UPPER_mm = CMM
|
||||
|
||||
# When building with PP_UNIFIED=0, we also have to look in the Unified files to
|
||||
# find a matching pathname.
|
||||
_get_all_sources = $1 $(if $(filter Unified%,$1),$(shell sed -n 's/\#include "\(.*\)"$$/\1/p' $(filter Unified%,$1)))
|
||||
all_cpp_sources := $(call _get_all_sources,$(CPPSRCS))
|
||||
all_mm_sources := $(call _get_all_sources,$(CMMSRCS))
|
||||
all_c_sources := $(call _get_all_sources,$(CSRCS))
|
||||
all_sources := $(all_cpp_sources) $(all_cmm_sources) $(all_c_sources)
|
||||
|
||||
# The catch-all %.i rule runs when we pass in a .i filename that doesn't match
|
||||
# one of the *SRCS variables. The two code paths depend on whether or not
|
||||
# we are requesting a unified file (PP_UNIFIED=1, the default) or not:
|
||||
#
|
||||
# PP_UNIFIED=1:
|
||||
# - Look for it in any of the Unified files, and re-exec make with
|
||||
# Unified_foo0.i as the target. This gets us the full unified preprocessed
|
||||
# file.
|
||||
#
|
||||
# PP_UNIFIED=0:
|
||||
# - If the .i filename is in *SRCS, or in a Unified filename, then we re-exec
|
||||
# make with that filename as the target. The *SRCS variables are modified
|
||||
# to have the Unified sources appended to them so that the static pattern
|
||||
# rules will match.
|
||||
%.i: FORCE
|
||||
ifeq ($(PP_UNIFIED),1)
|
||||
@$(MAKE) PP_REINVOKE=1 \
|
||||
$(or $(addsuffix .i, \
|
||||
$(foreach type,c cpp mm, \
|
||||
$(if $(filter Unified%,$($(UPPER_$(type))SRCS)), \
|
||||
$(shell grep -l '#include "\(.*/\)\?$(basename $@).$(or $(MATCH_$(type)),$(type))"' Unified*.$(type) | sed 's/\.$(type)$$//') \
|
||||
))),$(error "File not found for preprocessing: $@"))
|
||||
else
|
||||
@$(MAKE) PP_REINVOKE=1 $@ \
|
||||
$(foreach type,c cpp mm,$(UPPER_$(type))SRCS="$(all_$(type)_sources)")
|
||||
endif
|
||||
|
||||
endif
|
||||
|
||||
endif
|
||||
|
||||
$(RESFILE): %.res: %.rc
|
||||
$(REPORT_BUILD)
|
||||
@echo Creating Resource file: $@
|
||||
|
|
|
@ -1315,9 +1315,6 @@ QtSparql/qsparqlresult.h
|
|||
#if MOZ_TREE_PIXMAN!=1
|
||||
pixman.h
|
||||
#endif
|
||||
#if MOZ_ENABLE_MEEGOTOUCHSHARE
|
||||
shareuiinterface.h
|
||||
#endif
|
||||
#if MOZ_NATIVE_LIBVPX==1
|
||||
vpx/vpx_codec.h
|
||||
vpx/vpx_decoder.h
|
||||
|
|
|
@ -747,6 +747,7 @@ GK_ATOM(oninvalid, "oninvalid")
|
|||
GK_ATOM(onkeydown, "onkeydown")
|
||||
GK_ATOM(onkeypress, "onkeypress")
|
||||
GK_ATOM(onkeyup, "onkeyup")
|
||||
GK_ATOM(onlanguagechange, "onlanguagechange")
|
||||
GK_ATOM(onlevelchange, "onlevelchange")
|
||||
GK_ATOM(onLoad, "onLoad")
|
||||
GK_ATOM(onload, "onload")
|
||||
|
|
|
@ -1859,14 +1859,13 @@ MediaCacheStream::NotifyDataEnded(nsresult aStatus)
|
|||
|
||||
FlushPartialBlockInternal(true);
|
||||
|
||||
if (!mDidNotifyDataEnded) {
|
||||
MediaCache::ResourceStreamIterator iter(mResourceID);
|
||||
while (MediaCacheStream* stream = iter.Next()) {
|
||||
if (NS_SUCCEEDED(aStatus)) {
|
||||
// We read the whole stream, so remember the true length
|
||||
stream->mStreamLength = mChannelOffset;
|
||||
}
|
||||
NS_ASSERTION(!stream->mDidNotifyDataEnded, "Stream already ended!");
|
||||
MediaCache::ResourceStreamIterator iter(mResourceID);
|
||||
while (MediaCacheStream* stream = iter.Next()) {
|
||||
if (NS_SUCCEEDED(aStatus)) {
|
||||
// We read the whole stream, so remember the true length
|
||||
stream->mStreamLength = mChannelOffset;
|
||||
}
|
||||
if (!stream->mDidNotifyDataEnded) {
|
||||
stream->mDidNotifyDataEnded = true;
|
||||
stream->mNotifyDataEndedStatus = aStatus;
|
||||
stream->mClient->CacheClientNotifyDataEnded(aStatus);
|
||||
|
@ -1877,6 +1876,15 @@ MediaCacheStream::NotifyDataEnded(nsresult aStatus)
|
|||
gMediaCache->QueueUpdate();
|
||||
}
|
||||
|
||||
void
|
||||
MediaCacheStream::NotifyChannelRecreated()
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
|
||||
ReentrantMonitorAutoEnter mon(gMediaCache->GetReentrantMonitor());
|
||||
mChannelEnded = false;
|
||||
mDidNotifyDataEnded = false;
|
||||
}
|
||||
|
||||
MediaCacheStream::~MediaCacheStream()
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
|
||||
|
|
|
@ -272,6 +272,10 @@ public:
|
|||
// Notifies the cache that the channel has closed with the given status.
|
||||
void NotifyDataEnded(nsresult aStatus);
|
||||
|
||||
// Notifies the stream that the channel is reopened. The stream should
|
||||
// reset variables such as |mDidNotifyDataEnded|.
|
||||
void NotifyChannelRecreated();
|
||||
|
||||
// These methods can be called on any thread.
|
||||
// Cached blocks associated with this stream will not be evicted
|
||||
// while the stream is pinned.
|
||||
|
|
|
@ -487,8 +487,7 @@ ChannelMediaResource::OnChannelRedirect(nsIChannel* aOld, nsIChannel* aNew,
|
|||
uint32_t aFlags)
|
||||
{
|
||||
mChannel = aNew;
|
||||
SetupChannelHeaders();
|
||||
return NS_OK;
|
||||
return SetupChannelHeaders();
|
||||
}
|
||||
|
||||
struct CopySegmentClosure {
|
||||
|
@ -609,7 +608,8 @@ nsresult ChannelMediaResource::OpenChannel(nsIStreamListener** aStreamListener)
|
|||
*aStreamListener = mListener;
|
||||
NS_ADDREF(*aStreamListener);
|
||||
} else {
|
||||
mChannel->SetNotificationCallbacks(mListener.get());
|
||||
nsresult rv = mChannel->SetNotificationCallbacks(mListener.get());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIStreamListener> listener = mListener.get();
|
||||
|
||||
|
@ -624,21 +624,22 @@ nsresult ChannelMediaResource::OpenChannel(nsIStreamListener** aStreamListener)
|
|||
new nsCORSListenerProxy(mListener,
|
||||
element->NodePrincipal(),
|
||||
false);
|
||||
nsresult rv = crossSiteListener->Init(mChannel);
|
||||
listener = crossSiteListener;
|
||||
NS_ENSURE_TRUE(crossSiteListener, NS_ERROR_OUT_OF_MEMORY);
|
||||
rv = crossSiteListener->Init(mChannel);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
listener = crossSiteListener;
|
||||
} else {
|
||||
nsresult rv = nsContentUtils::GetSecurityManager()->
|
||||
rv = nsContentUtils::GetSecurityManager()->
|
||||
CheckLoadURIWithPrincipal(element->NodePrincipal(),
|
||||
mURI,
|
||||
nsIScriptSecurityManager::STANDARD);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
SetupChannelHeaders();
|
||||
rv = SetupChannelHeaders();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsresult rv = mChannel->AsyncOpen(listener, nullptr);
|
||||
rv = mChannel->AsyncOpen(listener, nullptr);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
// Tell the media element that we are fetching data from a channel.
|
||||
element->DownloadResumed(true);
|
||||
|
@ -647,7 +648,7 @@ nsresult ChannelMediaResource::OpenChannel(nsIStreamListener** aStreamListener)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
void ChannelMediaResource::SetupChannelHeaders()
|
||||
nsresult ChannelMediaResource::SetupChannelHeaders()
|
||||
{
|
||||
// Always use a byte range request even if we're reading from the start
|
||||
// of the resource.
|
||||
|
@ -668,22 +669,21 @@ void ChannelMediaResource::SetupChannelHeaders()
|
|||
if (!mByteRange.IsNull()) {
|
||||
rangeString.AppendInt(mByteRange.mEnd);
|
||||
}
|
||||
hc->SetRequestHeader(NS_LITERAL_CSTRING("Range"), rangeString, false);
|
||||
nsresult rv = hc->SetRequestHeader(NS_LITERAL_CSTRING("Range"), rangeString, false);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Send Accept header for video and audio types only (Bug 489071)
|
||||
NS_ASSERTION(NS_IsMainThread(), "Don't call on non-main thread");
|
||||
MediaDecoderOwner* owner = mDecoder->GetMediaOwner();
|
||||
if (!owner) {
|
||||
return;
|
||||
}
|
||||
NS_ENSURE_TRUE(owner, NS_ERROR_FAILURE);
|
||||
dom::HTMLMediaElement* element = owner->GetMediaElement();
|
||||
if (!element) {
|
||||
return;
|
||||
}
|
||||
NS_ENSURE_TRUE(element, NS_ERROR_FAILURE);
|
||||
element->SetRequestHeaders(hc);
|
||||
} else {
|
||||
NS_ASSERTION(mOffset == 0, "Don't know how to seek on this channel type");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult ChannelMediaResource::Close()
|
||||
|
@ -946,6 +946,9 @@ ChannelMediaResource::RecreateChannel()
|
|||
"When recreating a channel, we should know the Content-Type.");
|
||||
mChannel->SetContentType(GetContentType());
|
||||
|
||||
// Tell the cache to reset the download status when the channel is reopened.
|
||||
mCacheStream.NotifyChannelRecreated();
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
|
|
@ -639,7 +639,7 @@ protected:
|
|||
nsresult OpenChannel(nsIStreamListener** aStreamListener);
|
||||
nsresult RecreateChannel();
|
||||
// Add headers to HTTP request. Main thread only.
|
||||
void SetupChannelHeaders();
|
||||
nsresult SetupChannelHeaders();
|
||||
// Closes the channel. Main thread only.
|
||||
void CloseChannel();
|
||||
|
||||
|
|
|
@ -62,6 +62,7 @@ AudioOutputObserver::AudioOutputObserver()
|
|||
|
||||
AudioOutputObserver::~AudioOutputObserver()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -70,6 +71,7 @@ AudioOutputObserver::Clear()
|
|||
while (mPlayoutFifo->size() > 0) {
|
||||
(void) mPlayoutFifo->Pop();
|
||||
}
|
||||
mSaved = nullptr;
|
||||
}
|
||||
|
||||
FarEndAudioChunk *
|
||||
|
|
|
@ -24,10 +24,8 @@
|
|||
#ifdef MOZ_ENABLE_DBUS
|
||||
#include "nsDBusHandlerApp.h"
|
||||
#endif
|
||||
#if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_ENABLE_MEEGOTOUCHSHARE)
|
||||
#include "nsExternalSharingAppService.h"
|
||||
#endif
|
||||
#if defined(MOZ_WIDGET_ANDROID)
|
||||
#include "nsExternalSharingAppService.h"
|
||||
#include "nsExternalURLHandlerService.h"
|
||||
#endif
|
||||
|
||||
|
@ -85,10 +83,8 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(PlatformLocalHandlerApp_t)
|
|||
#ifdef MOZ_ENABLE_DBUS
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsDBusHandlerApp)
|
||||
#endif
|
||||
#if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_ENABLE_MEEGOTOUCHSHARE)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsExternalSharingAppService)
|
||||
#endif
|
||||
#if defined(MOZ_WIDGET_ANDROID)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsExternalSharingAppService)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsExternalURLHandlerService)
|
||||
#endif
|
||||
|
||||
|
@ -115,10 +111,8 @@ NS_DEFINE_NAMED_CID(NS_LOCALHANDLERAPP_CID);
|
|||
#ifdef MOZ_ENABLE_DBUS
|
||||
NS_DEFINE_NAMED_CID(NS_DBUSHANDLERAPP_CID);
|
||||
#endif
|
||||
#if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_ENABLE_MEEGOTOUCHSHARE)
|
||||
NS_DEFINE_NAMED_CID(NS_EXTERNALSHARINGAPPSERVICE_CID);
|
||||
#endif
|
||||
#if defined(MOZ_WIDGET_ANDROID)
|
||||
NS_DEFINE_NAMED_CID(NS_EXTERNALSHARINGAPPSERVICE_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_EXTERNALURLHANDLERSERVICE_CID);
|
||||
#endif
|
||||
NS_DEFINE_NAMED_CID(NS_SHENTRY_CID);
|
||||
|
@ -144,10 +138,8 @@ const mozilla::Module::CIDEntry kDocShellCIDs[] = {
|
|||
#ifdef MOZ_ENABLE_DBUS
|
||||
{ &kNS_DBUSHANDLERAPP_CID, false, nullptr, nsDBusHandlerAppConstructor },
|
||||
#endif
|
||||
#if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_ENABLE_MEEGOTOUCHSHARE)
|
||||
{ &kNS_EXTERNALSHARINGAPPSERVICE_CID, false, nullptr, nsExternalSharingAppServiceConstructor },
|
||||
#endif
|
||||
#if defined(MOZ_WIDGET_ANDROID)
|
||||
{ &kNS_EXTERNALSHARINGAPPSERVICE_CID, false, nullptr, nsExternalSharingAppServiceConstructor },
|
||||
{ &kNS_EXTERNALURLHANDLERSERVICE_CID, false, nullptr, nsExternalURLHandlerServiceConstructor },
|
||||
#endif
|
||||
{ &kNS_SHENTRY_CID, false, nullptr, nsSHEntryConstructor },
|
||||
|
@ -197,10 +189,8 @@ const mozilla::Module::ContractIDEntry kDocShellContracts[] = {
|
|||
#ifdef MOZ_ENABLE_DBUS
|
||||
{ NS_DBUSHANDLERAPP_CONTRACTID, &kNS_DBUSHANDLERAPP_CID },
|
||||
#endif
|
||||
#if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_ENABLE_MEEGOTOUCHSHARE)
|
||||
{ NS_EXTERNALSHARINGAPPSERVICE_CONTRACTID, &kNS_EXTERNALSHARINGAPPSERVICE_CID },
|
||||
#endif
|
||||
#if defined(MOZ_WIDGET_ANDROID)
|
||||
{ NS_EXTERNALSHARINGAPPSERVICE_CONTRACTID, &kNS_EXTERNALSHARINGAPPSERVICE_CID },
|
||||
{ NS_EXTERNALURLHANDLERSERVICE_CONTRACTID, &kNS_EXTERNALURLHANDLERSERVICE_CID },
|
||||
#endif
|
||||
{ NS_SHENTRY_CONTRACTID, &kNS_SHENTRY_CID },
|
||||
|
|
|
@ -326,6 +326,11 @@ this.PermissionsTable = { geolocation: {
|
|||
privileged: PROMPT_ACTION,
|
||||
certified: PROMPT_ACTION
|
||||
},
|
||||
"feature-detection": {
|
||||
app: DENY_ACTION,
|
||||
privileged: ALLOW_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -396,8 +396,8 @@ ArchiveZipFile::CreateSlice(uint64_t aStart,
|
|||
return t.forget();
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION(ArchiveZipFile,
|
||||
mArchiveReader)
|
||||
NS_IMPL_CYCLE_COLLECTION_INHERITED(ArchiveZipFile, nsDOMFileCC,
|
||||
mArchiveReader)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ArchiveZipFile)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMFile)
|
||||
|
|
|
@ -141,7 +141,7 @@ public:
|
|||
ConsoleCallData()
|
||||
: mMethodName(Console::MethodLog)
|
||||
, mPrivate(false)
|
||||
, mTimeStamp(JS_Now())
|
||||
, mTimeStamp(JS_Now() / PR_USEC_PER_MSEC)
|
||||
, mMonotonicTimer(0)
|
||||
{
|
||||
MOZ_COUNT_CTOR(ConsoleCallData);
|
||||
|
|
|
@ -351,59 +351,87 @@ Navigator::GetAppName(nsAString& aAppName)
|
|||
}
|
||||
|
||||
/**
|
||||
* JS property navigator.language, exposed to web content.
|
||||
* Take first value from Accept-Languages (HTTP header), which is
|
||||
* the "content language" freely set by the user in the Pref window.
|
||||
* Returns the value of Accept-Languages (HTTP header) as a nsTArray of
|
||||
* languages. The value is set in the preference by the user ("Content
|
||||
* Languages").
|
||||
*
|
||||
* Do not use UI language (chosen app locale) here.
|
||||
* See RFC 2616, Section 15.1.4 "Privacy Issues Connected to Accept Headers"
|
||||
* "en", "en-US" and "i-cherokee" and "" are valid languages tokens.
|
||||
*
|
||||
* "en", "en-US" and "i-cherokee" and "" are valid.
|
||||
* Fallback in case of invalid pref should be "" (empty string), to
|
||||
* let site do fallback, e.g. to site's local language.
|
||||
* An empty array will be returned if there is no valid languages.
|
||||
*/
|
||||
NS_IMETHODIMP
|
||||
Navigator::GetLanguage(nsAString& aLanguage)
|
||||
void
|
||||
Navigator::GetAcceptLanguages(nsTArray<nsString>& aLanguages)
|
||||
{
|
||||
// E.g. "de-de, en-us,en".
|
||||
const nsAdoptingString& acceptLang =
|
||||
Preferences::GetLocalizedString("intl.accept_languages");
|
||||
|
||||
// Take everything before the first "," or ";", without trailing space.
|
||||
// Split values on commas.
|
||||
nsCharSeparatedTokenizer langTokenizer(acceptLang, ',');
|
||||
const nsSubstring &firstLangPart = langTokenizer.nextToken();
|
||||
nsCharSeparatedTokenizer qTokenizer(firstLangPart, ';');
|
||||
aLanguage.Assign(qTokenizer.nextToken());
|
||||
while (langTokenizer.hasMoreTokens()) {
|
||||
nsDependentSubstring lang = langTokenizer.nextToken();
|
||||
|
||||
// Checks and fixups:
|
||||
// replace "_" with "-" to avoid POSIX/Windows "en_US" notation.
|
||||
if (aLanguage.Length() > 2 && aLanguage[2] == char16_t('_')) {
|
||||
aLanguage.Replace(2, 1, char16_t('-')); // TODO replace all
|
||||
}
|
||||
|
||||
// Use uppercase for country part, e.g. "en-US", not "en-us", see BCP47
|
||||
// only uppercase 2-letter country codes, not "zh-Hant", "de-DE-x-goethe".
|
||||
if (aLanguage.Length() <= 2) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCharSeparatedTokenizer localeTokenizer(aLanguage, '-');
|
||||
int32_t pos = 0;
|
||||
bool first = true;
|
||||
while (localeTokenizer.hasMoreTokens()) {
|
||||
const nsSubstring& code = localeTokenizer.nextToken();
|
||||
|
||||
if (code.Length() == 2 && !first) {
|
||||
nsAutoString upper(code);
|
||||
ToUpperCase(upper);
|
||||
aLanguage.Replace(pos, code.Length(), upper);
|
||||
// Replace "_" with "-" to avoid POSIX/Windows "en_US" notation.
|
||||
// NOTE: we should probably rely on the pref being set correctly.
|
||||
if (lang.Length() > 2 && lang[2] == char16_t('_')) {
|
||||
lang.Replace(2, 1, char16_t('-'));
|
||||
}
|
||||
|
||||
pos += code.Length() + 1; // 1 is the separator
|
||||
first = false;
|
||||
// Use uppercase for country part, e.g. "en-US", not "en-us", see BCP47
|
||||
// only uppercase 2-letter country codes, not "zh-Hant", "de-DE-x-goethe".
|
||||
// NOTE: we should probably rely on the pref being set correctly.
|
||||
if (lang.Length() > 2) {
|
||||
nsCharSeparatedTokenizer localeTokenizer(lang, '-');
|
||||
int32_t pos = 0;
|
||||
bool first = true;
|
||||
while (localeTokenizer.hasMoreTokens()) {
|
||||
const nsSubstring& code = localeTokenizer.nextToken();
|
||||
|
||||
if (code.Length() == 2 && !first) {
|
||||
nsAutoString upper(code);
|
||||
ToUpperCase(upper);
|
||||
lang.Replace(pos, code.Length(), upper);
|
||||
}
|
||||
|
||||
pos += code.Length() + 1; // 1 is the separator
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
|
||||
aLanguages.AppendElement(lang);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Do not use UI language (chosen app locale) here but the first value set in
|
||||
* the Accept Languages header, see ::GetAcceptLanguages().
|
||||
*
|
||||
* See RFC 2616, Section 15.1.4 "Privacy Issues Connected to Accept Headers" for
|
||||
* the reasons why.
|
||||
*/
|
||||
NS_IMETHODIMP
|
||||
Navigator::GetLanguage(nsAString& aLanguage)
|
||||
{
|
||||
nsTArray<nsString> languages;
|
||||
GetLanguages(languages);
|
||||
if (languages.Length() >= 1) {
|
||||
aLanguage.Assign(languages[0]);
|
||||
} else {
|
||||
aLanguage.Truncate();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
Navigator::GetLanguages(nsTArray<nsString>& aLanguages)
|
||||
{
|
||||
GetAcceptLanguages(aLanguages);
|
||||
|
||||
// The returned value is cached by the binding code. The window listen to the
|
||||
// accept languages change and will clear the cache when needed. It has to
|
||||
// take care of dispatching the DOM event already and the invalidation and the
|
||||
// event has to be timed correctly.
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -1443,6 +1471,52 @@ Navigator::GetDataStores(const nsAString& aName, ErrorResult& aRv)
|
|||
return GetDataStores(mWindow, aName, aRv);
|
||||
}
|
||||
|
||||
already_AddRefed<Promise>
|
||||
Navigator::GetFeature(const nsAString& aName)
|
||||
{
|
||||
nsCOMPtr<nsIGlobalObject> go = do_QueryInterface(mWindow);
|
||||
nsRefPtr<Promise> p = new Promise(go);
|
||||
|
||||
#if defined(XP_LINUX)
|
||||
if (aName.EqualsLiteral("hardware.memory")) {
|
||||
static int memLevel = 1;
|
||||
if (memLevel == 1) {
|
||||
FILE* f = fopen("/proc/meminfo", "r");
|
||||
if (!f) {
|
||||
p->MaybeReject(NS_LITERAL_STRING("CannotOpenMeminfo"));
|
||||
return p.forget();
|
||||
}
|
||||
|
||||
int memTotal;
|
||||
int n = fscanf(f, "MemTotal: %d kB\n", &memTotal);
|
||||
fclose(f);
|
||||
|
||||
if (memTotal == 0 || n != 1) {
|
||||
p->MaybeReject(NS_LITERAL_STRING("Abnormal"));
|
||||
return p.forget();
|
||||
}
|
||||
// From KB to MB
|
||||
memTotal /= 1024;
|
||||
|
||||
// round the value up to the next power of two
|
||||
while (memLevel <= memTotal) {
|
||||
memLevel *= 2;
|
||||
}
|
||||
}
|
||||
p->MaybeResolve(memLevel);
|
||||
} // hardware.memory
|
||||
else
|
||||
#endif
|
||||
{
|
||||
// resolve with <undefined> because the feature name is not supported
|
||||
p->MaybeResolve(JS::UndefinedHandleValue);
|
||||
}
|
||||
|
||||
return p.forget();
|
||||
|
||||
}
|
||||
|
||||
|
||||
PowerManager*
|
||||
Navigator::GetMozPower(ErrorResult& aRv)
|
||||
{
|
||||
|
@ -2416,6 +2490,15 @@ Navigator::HasNetworkStatsSupport(JSContext* /* unused */, JSObject* aGlobal)
|
|||
return CheckPermission(win, "networkstats-manage");
|
||||
}
|
||||
|
||||
/* static */
|
||||
bool
|
||||
Navigator::HasFeatureDetectionSupport(JSContext* /* unused */, JSObject* aGlobal)
|
||||
{
|
||||
nsCOMPtr<nsPIDOMWindow> win = GetWindowFromGlobal(aGlobal);
|
||||
return CheckPermission(win, "feature-detection");
|
||||
}
|
||||
|
||||
|
||||
/* static */
|
||||
already_AddRefed<nsPIDOMWindow>
|
||||
Navigator::GetWindowFromGlobal(JSObject* aGlobal)
|
||||
|
|
|
@ -164,6 +164,10 @@ public:
|
|||
|
||||
already_AddRefed<Promise> GetDataStores(const nsAString &aName,
|
||||
ErrorResult& aRv);
|
||||
|
||||
// Feature Detection API
|
||||
already_AddRefed<Promise> GetFeature(const nsAString &aName);
|
||||
|
||||
bool Vibrate(uint32_t aDuration);
|
||||
bool Vibrate(const nsTArray<uint32_t>& aDuration);
|
||||
uint32_t MaxTouchPoints();
|
||||
|
@ -251,6 +255,8 @@ public:
|
|||
JS::MutableHandle<JSPropertyDescriptor> aDesc);
|
||||
void GetOwnPropertyNames(JSContext* aCx, nsTArray<nsString>& aNames,
|
||||
ErrorResult& aRv);
|
||||
void GetLanguages(nsTArray<nsString>& aLanguages);
|
||||
void GetAcceptLanguages(nsTArray<nsString>& aLanguages);
|
||||
|
||||
// WebIDL helper methods
|
||||
static bool HasBatterySupport(JSContext* /* unused*/, JSObject* /*unused */);
|
||||
|
@ -315,6 +321,8 @@ public:
|
|||
|
||||
static bool HasNetworkStatsSupport(JSContext* aCx, JSObject* aGlobal);
|
||||
|
||||
static bool HasFeatureDetectionSupport(JSContext* aCx, JSObject* aGlobal);
|
||||
|
||||
nsPIDOMWindow* GetParentObject() const
|
||||
{
|
||||
return GetWindow();
|
||||
|
|
|
@ -570,14 +570,6 @@ WrapNative(JSContext *cx, nsISupports *native,
|
|||
return WrapNative(cx, native, nullptr, nullptr, vp, aAllowWrapping);
|
||||
}
|
||||
|
||||
static inline nsresult
|
||||
WrapNative(JSContext *cx, nsISupports *native,
|
||||
nsWrapperCache *cache, bool aAllowWrapping,
|
||||
JS::MutableHandle<JS::Value> vp)
|
||||
{
|
||||
return WrapNative(cx, native, cache, nullptr, vp, aAllowWrapping);
|
||||
}
|
||||
|
||||
// Helper to handle torn-down inner windows.
|
||||
static inline nsresult
|
||||
SetParentToWindow(nsGlobalWindow *win, JSObject **parent)
|
||||
|
|
|
@ -218,6 +218,7 @@
|
|||
#include "nsITabChild.h"
|
||||
#include "mozilla/dom/MediaQueryList.h"
|
||||
#include "mozilla/dom/ScriptSettings.h"
|
||||
#include "mozilla/dom/NavigatorBinding.h"
|
||||
#ifdef HAVE_SIDEBAR
|
||||
#include "mozilla/dom/ExternalBinding.h"
|
||||
#endif
|
||||
|
@ -1137,6 +1138,8 @@ nsGlobalWindow::nsGlobalWindow(nsGlobalWindow *aOuterWindow)
|
|||
// events. Use a strong reference.
|
||||
os->AddObserver(mObserver, "dom-storage2-changed", false);
|
||||
}
|
||||
|
||||
Preferences::AddStrongObserver(mObserver, "intl.accept_languages");
|
||||
}
|
||||
} else {
|
||||
// |this| is an outer window. Outer windows start out frozen and
|
||||
|
@ -1419,6 +1422,8 @@ nsGlobalWindow::CleanUp()
|
|||
mIdleService->RemoveIdleObserver(mObserver, MIN_IDLE_NOTIFICATION_TIME_S);
|
||||
}
|
||||
|
||||
Preferences::RemoveObserver(mObserver, "intl.accept_languages");
|
||||
|
||||
// Drop its reference to this dying window, in case for some bogus reason
|
||||
// the object stays around.
|
||||
mObserver->Forget();
|
||||
|
@ -11219,6 +11224,32 @@ nsGlobalWindow::Observe(nsISupports* aSubject, const char* aTopic,
|
|||
}
|
||||
#endif // MOZ_B2G
|
||||
|
||||
if (!nsCRT::strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID)) {
|
||||
MOZ_ASSERT(!nsCRT::strcmp(NS_ConvertUTF16toUTF8(aData).get(), "intl.accept_languages"));
|
||||
MOZ_ASSERT(IsInnerWindow());
|
||||
|
||||
// The user preferred languages have changed, we need to fire an event on
|
||||
// Window object and invalidate the cache for navigator.languages. It is
|
||||
// done for every change which can be a waste of cycles but those should be
|
||||
// fairly rare.
|
||||
// We MUST invalidate navigator.languages before sending the event in the
|
||||
// very likely situation where an event handler will try to read its value.
|
||||
|
||||
if (mNavigator) {
|
||||
NavigatorBinding::ClearCachedLanguagesValue(mNavigator);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMEvent> event;
|
||||
NS_NewDOMEvent(getter_AddRefs(event), this, nullptr, nullptr);
|
||||
nsresult rv = event->InitEvent(NS_LITERAL_STRING("languagechange"), false, false);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
event->SetTrusted(true);
|
||||
|
||||
bool dummy;
|
||||
return DispatchEvent(event, &dummy);
|
||||
}
|
||||
|
||||
NS_WARNING("unrecognized topic in nsGlobalWindow::Observe");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
|
|
@ -31,6 +31,8 @@ support-files =
|
|||
[test_gsp-qualified.html]
|
||||
[test_gsp-quirks.html]
|
||||
[test_gsp-standards.html]
|
||||
[test_getFeature_with_perm.html]
|
||||
[test_getFeature_without_perm.html]
|
||||
[test_history_document_open.html]
|
||||
[test_history_state_null.html]
|
||||
[test_innersize_scrollport.html]
|
||||
|
@ -45,6 +47,7 @@ support-files =
|
|||
[test_messageChannel_unshipped.html]
|
||||
[test_named_frames.html]
|
||||
[test_navigator_resolve_identity.html]
|
||||
[test_navigator_language.html]
|
||||
[test_nondomexception.html]
|
||||
[test_openDialogChromeOnly.html]
|
||||
[test_postMessage_solidus.html]
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=979109
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for Bug 979109</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=983502">Mozilla Bug 983502</a>
|
||||
<script type="application/javascript">
|
||||
|
||||
function testSupported() {
|
||||
var mem;
|
||||
navigator.getFeature("hardware.memory").then(function(mem) {
|
||||
|
||||
var isLinux = (navigator.platform.indexOf('Linux') != -1);
|
||||
var isAndroid = !!navigator.userAgent.contains("Android");
|
||||
var isB2G = !isAndroid && /Mobile|Tablet/.test(navigator.userAgent);
|
||||
|
||||
if (isLinux) {
|
||||
info("It is Linux version:");
|
||||
}
|
||||
if (isAndroid) {
|
||||
info("It is Android version");
|
||||
}
|
||||
if (isB2G) {
|
||||
info("It is B2G version");
|
||||
}
|
||||
|
||||
if (isLinux || isAndroid || isB2G) {
|
||||
ok(typeof mem === 'number' && (mem) % 1 === 0, "We should receive an integer on this platform");
|
||||
ok(mem > 0, "hardware.memory is supported on this platform. mem=" + mem + "MiB");
|
||||
} else {
|
||||
ok(typeof mem === 'undefined', "hardware.memory is not support on this platform");
|
||||
}
|
||||
|
||||
SimpleTest.finish();
|
||||
|
||||
},function(mem) {
|
||||
ok(false, "The Promise should not be rejected");
|
||||
});
|
||||
}
|
||||
|
||||
function testNotSupported() {
|
||||
var tv;
|
||||
navigator.getFeature("hardware.tv").then(function(tv) {
|
||||
ok(typeof tv === 'undefined', "Resolve the Promise with undefined value (hardware.tv)");
|
||||
testSupported();
|
||||
},function(tv) {
|
||||
ok(false, "The Promise should not be rejected")
|
||||
});
|
||||
}
|
||||
|
||||
SpecialPowers.pushPermissions([
|
||||
{type: "feature-detection", allow: 1, context: document}
|
||||
], function() {
|
||||
ok('getFeature' in navigator, "navigator.getFeature should exist");
|
||||
testNotSupported();
|
||||
ok(true, "Test DONE");
|
||||
});
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,21 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=979109
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for Bug 979109</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=983502">Mozilla Bug 983502</a>
|
||||
<script type="application/javascript">
|
||||
|
||||
|
||||
is("getFeature" in navigator, false, "getFeature should not exist without permission");
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,227 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=889335
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for NavigatorLanguage</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=889335">Mozilla Bug 889335</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
<script type="application/javascript;version=1.7">
|
||||
"use strict";
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
/** Test for NavigatorLanguage **/
|
||||
var prefValue = null;
|
||||
var actualLanguageChangesFromHandler = 0;
|
||||
var actualLanguageChangesFromAVL = 0;
|
||||
var expectedLanguageChanges = 0;
|
||||
|
||||
function setUp() {
|
||||
try {
|
||||
prefValue = SpecialPowers.getCharPref('intl.accept_languages');
|
||||
} catch (e) {
|
||||
}
|
||||
}
|
||||
|
||||
function tearDown() {
|
||||
SpecialPowers.setCharPref('intl.accept_languages', prefValue);
|
||||
}
|
||||
|
||||
var testValues = [
|
||||
{ accept_languages: 'foo', language: 'foo', languages: ['foo'] },
|
||||
{ accept_languages: '', language: '', languages: [] },
|
||||
{ accept_languages: 'foo,bar', language: 'foo', languages: [ 'foo', 'bar' ] },
|
||||
{ accept_languages: ' foo , bar ', language: 'foo', languages: [ 'foo', 'bar' ] },
|
||||
{ accept_languages: ' foo ; bar ', language: 'foo ; bar', languages: [ 'foo ; bar' ] },
|
||||
{ accept_languages: '_foo_', language: '_foo_', languages: ['_foo_'] },
|
||||
{ accept_languages: 'en_', language: 'en-', languages: ['en-'] },
|
||||
{ accept_languages: 'en__', language: 'en-_', languages: ['en-_'] },
|
||||
{ accept_languages: 'en_US, fr_FR', language: 'en-US', languages: ['en-US', 'fr-FR'] },
|
||||
{ accept_languages: 'en_US_CA', language: 'en-US_CA', languages: ['en-US_CA'] },
|
||||
{ accept_languages: 'en_us-ca', language: 'en-US-CA', languages: ['en-US-CA'] },
|
||||
{ accept_languages: 'en_us-cal, en_us-c', language: 'en-US-cal', languages: ['en-US-cal', 'en-US-c'] },
|
||||
];
|
||||
|
||||
var currentTestIdx = 0;
|
||||
var tests = [];
|
||||
function nextTest() {
|
||||
currentTestIdx++;
|
||||
if (currentTestIdx >= tests.length) {
|
||||
tearDown();
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
tests[currentTestIdx]();
|
||||
}
|
||||
|
||||
// Check that the API is there.
|
||||
tests.push(function testAPIPresence() {
|
||||
ok('language' in window.navigator);
|
||||
ok('languages' in window.navigator);
|
||||
ok('onlanguagechange' in window);
|
||||
|
||||
nextTest();
|
||||
});
|
||||
|
||||
// Check that calling navigator.languages return the same array, unless there
|
||||
// was a change.
|
||||
tests.push(function testArrayCached() {
|
||||
var previous = navigator.languages;
|
||||
is(navigator.languages, navigator.languages, "navigator.languages is cached");
|
||||
is(navigator.languages, previous, "navigator.languages is cached");
|
||||
|
||||
window.onlanguagechange = function() {
|
||||
isnot(navigator.languages, previous, "navigator.languages cached value was updated");
|
||||
window.onlanguagechange = null;
|
||||
|
||||
nextTest();
|
||||
}
|
||||
|
||||
setTimeout(function() {
|
||||
SpecialPowers.setCharPref('intl.accept_languages', 'testArrayCached');
|
||||
}, 0);
|
||||
});
|
||||
|
||||
// Test that event handler inside the <body> works as expected and that the
|
||||
// event has the expected properties.
|
||||
tests.push(function testEventProperties() {
|
||||
document.body.setAttribute('onlanguagechange',
|
||||
"document.body.removeAttribute('onlanguagechange');" +
|
||||
"is(event.cancelable, false); is(event.bubbles, false);" +
|
||||
"nextTest();");
|
||||
|
||||
setTimeout(function() {
|
||||
SpecialPowers.setCharPref('intl.accept_languages', 'testEventProperties');
|
||||
}, 0);
|
||||
});
|
||||
|
||||
// Check that the returned values such as the behavior when the underlying
|
||||
// languages change.
|
||||
tests.push(function testBasicBehaviour() {
|
||||
function checkIfDoneAndProceed() {
|
||||
if (actualLanguageChangesFromHandler == actualLanguageChangesFromAVL) {
|
||||
if (genEvents.next().done) {
|
||||
window.onlanguagechange = null;
|
||||
window.removeEventListener('languagechange', languageChangeAVL);
|
||||
nextTest();
|
||||
}
|
||||
}
|
||||
}
|
||||
window.onlanguagechange = function() {
|
||||
actualLanguageChangesFromHandler++;
|
||||
checkIfDoneAndProceed();
|
||||
}
|
||||
function languageChangeAVL() {
|
||||
actualLanguageChangesFromAVL++;
|
||||
checkIfDoneAndProceed();
|
||||
}
|
||||
window.addEventListener('languagechange', languageChangeAVL);
|
||||
|
||||
function* testEvents() {
|
||||
for (var i = 0; i < testValues.length; ++i) {
|
||||
var data = testValues[i];
|
||||
setTimeout(function(data) {
|
||||
SpecialPowers.setCharPref('intl.accept_languages', data.accept_languages);
|
||||
}, 0, data);
|
||||
expectedLanguageChanges++;
|
||||
yield undefined;
|
||||
|
||||
is(actualLanguageChangesFromAVL, expectedLanguageChanges);
|
||||
is(actualLanguageChangesFromHandler, expectedLanguageChanges);
|
||||
|
||||
is(navigator.language, data.language);
|
||||
is(navigator.languages.length, data.languages.length);
|
||||
if (navigator.languages.length > 0) {
|
||||
is(navigator.languages[0], navigator.language)
|
||||
}
|
||||
for (var j = 0; j < navigator.languages.length; ++j) {
|
||||
is(navigator.languages[j], data.languages[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var genEvents = testEvents();
|
||||
genEvents.next();
|
||||
});
|
||||
|
||||
// Check that the orientationchange event isn't sent twice if the preference
|
||||
// is set to the same value.
|
||||
tests.push(function testOnlyFireIfRealChange() {
|
||||
function* changeLanguage() {
|
||||
setTimeout(function() {
|
||||
SpecialPowers.setCharPref('intl.accept_languages', 'fr-CA');
|
||||
});
|
||||
yield undefined;
|
||||
|
||||
setTimeout(function() {
|
||||
// Twice the same change, should fire only one event.
|
||||
SpecialPowers.setCharPref('intl.accept_languages', 'fr-CA');
|
||||
setTimeout(function() {
|
||||
// A real change to tell the test it should now count how many changes were
|
||||
// received until now.
|
||||
SpecialPowers.setCharPref('intl.accept_languages', 'fr-FR');
|
||||
});
|
||||
});
|
||||
yield undefined;
|
||||
}
|
||||
|
||||
var genChanges = changeLanguage();
|
||||
|
||||
var doubleEventCount = 0;
|
||||
window.onlanguagechange = function() {
|
||||
if (navigator.language == 'fr-FR') {
|
||||
is(1, doubleEventCount);
|
||||
window.onlanguagechange = null;
|
||||
nextTest();
|
||||
return;
|
||||
}
|
||||
|
||||
if (navigator.language == 'fr-CA') {
|
||||
doubleEventCount++;
|
||||
}
|
||||
genChanges.next();
|
||||
}
|
||||
|
||||
genChanges.next();
|
||||
});
|
||||
|
||||
// Check that there is no crash when a change happen after a window listening
|
||||
// to them is killed.
|
||||
tests.push(function testThatAddingAnEventDoesNotHaveSideEffects() {
|
||||
var frame = document.createElement('iframe');
|
||||
frame.src = 'data:text/html,<script>window.onlanguagechange=function(){}<\/script>';
|
||||
document.body.appendChild(frame);
|
||||
|
||||
frame.contentWindow.onload = function() {
|
||||
document.body.removeChild(frame);
|
||||
frame = null;
|
||||
|
||||
SpecialPowers.exactGC(window, function() {
|
||||
// This should not crash.
|
||||
SpecialPowers.setCharPref('intl.accept_languages', 'en-GB');
|
||||
|
||||
nextTest();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// There is one test using document.body.
|
||||
addLoadEvent(function() {
|
||||
setUp();
|
||||
tests[0]();
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -22,7 +22,7 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(DataStore)
|
|||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION(DataStore, mStore)
|
||||
NS_IMPL_CYCLE_COLLECTION_INHERITED(DataStore, DOMEventTargetHelper, mStore)
|
||||
|
||||
DataStore::DataStore(nsPIDOMWindow* aWindow)
|
||||
: DOMEventTargetHelper(aWindow)
|
||||
|
@ -185,4 +185,4 @@ DataStore::SetDataStoreImpl(DataStoreImpl& aStore, ErrorResult& aRv)
|
|||
}
|
||||
|
||||
} //namespace dom
|
||||
} //namespace mozilla
|
||||
} //namespace mozilla
|
||||
|
|
|
@ -3,13 +3,12 @@
|
|||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for DataStore - basic operation on a readonly db</title>
|
||||
<script type="text/javascript" src="file_basic_common.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="container"></div>
|
||||
<script type="application/javascript;version=1.7">
|
||||
|
||||
var gStore;
|
||||
|
||||
function is(a, b, msg) {
|
||||
alert((a === b ? 'OK' : 'KO') + ' ' + msg)
|
||||
}
|
||||
|
@ -26,124 +25,6 @@
|
|||
alert('DONE');
|
||||
}
|
||||
|
||||
function testGetDataStores() {
|
||||
navigator.getDataStores('foo').then(function(stores) {
|
||||
is(stores.length, 1, "getDataStores('foo') returns 1 element");
|
||||
is(stores[0].name, 'foo', 'The dataStore.name is foo');
|
||||
is(stores[0].readOnly, false, 'The dataStore foo is not in readonly');
|
||||
|
||||
var store = stores[0];
|
||||
ok("get" in store, "store.get exists");
|
||||
ok("put" in store, "store.put exists");
|
||||
ok("add" in store, "store.add exists");
|
||||
ok("remove" in store, "store.remove exists");
|
||||
ok("clear" in store, "store.clear exists");
|
||||
ok("revisionId" in store, "store.revisionId exists");
|
||||
ok("getLength" in store, "store.getLength exists");
|
||||
ok("sync" in store, "store.sync exists");
|
||||
|
||||
gStore = stores[0];
|
||||
|
||||
runTest();
|
||||
}, cbError);
|
||||
}
|
||||
|
||||
function testStoreGet(id, value) {
|
||||
gStore.get(id).then(function(what) {
|
||||
ok(true, "store.get() retrieves data");
|
||||
is(what, value, "store.get(" + id + ") returns " + value);
|
||||
}, function() {
|
||||
ok(false, "store.get(" + id + ") retrieves data");
|
||||
}).then(runTest, cbError);
|
||||
}
|
||||
|
||||
function testStoreAdd(value) {
|
||||
return gStore.add(value).then(function(what) {
|
||||
ok(true, "store.add() is called");
|
||||
ok(what > 0, "store.add() returns something");
|
||||
return what;
|
||||
}, cbError);
|
||||
}
|
||||
|
||||
function testStorePut(value, id) {
|
||||
return gStore.put(value, id).then(function() {
|
||||
ok(true, "store.put() is called");
|
||||
}, cbError);
|
||||
}
|
||||
|
||||
function testStoreGetLength(number) {
|
||||
return gStore.getLength().then(function(n) {
|
||||
is(number, n, "store.getLength() returns the right number");
|
||||
}, cbError);
|
||||
}
|
||||
|
||||
function testStoreRemove(id) {
|
||||
return gStore.remove(id).then(function() {
|
||||
ok(true, "store.remove() is called");
|
||||
}, cbError);
|
||||
}
|
||||
|
||||
function testStoreClear() {
|
||||
return gStore.clear().then(function() {
|
||||
ok(true, "store.clear() is called");
|
||||
}, cbError);
|
||||
}
|
||||
|
||||
var tests = [
|
||||
// Test for GetDataStore
|
||||
testGetDataStores,
|
||||
|
||||
// Unknown ID
|
||||
function() { testStoreGet(42, undefined); },
|
||||
function() { testStoreGet(42, undefined); }, // twice
|
||||
|
||||
// Add + Get - number
|
||||
function() { testStoreAdd(42).then(function(id) {
|
||||
gId = id; runTest(); }, cbError); },
|
||||
function() { testStoreGet(gId, 42); },
|
||||
|
||||
// Add + Get - boolean
|
||||
function() { testStoreAdd(true).then(function(id) {
|
||||
gId = id; runTest(); }, cbError); },
|
||||
function() { testStoreGet(gId, true); },
|
||||
|
||||
// Add + Get - string
|
||||
function() { testStoreAdd("hello world").then(function(id) {
|
||||
gId = id; runTest(); }, cbError); },
|
||||
function() { testStoreGet(gId, "hello world"); },
|
||||
|
||||
// Put + Get - string
|
||||
function() { testStorePut("hello world 2", gId).then(function() {
|
||||
runTest(); }, cbError); },
|
||||
function() { testStoreGet(gId, "hello world 2"); },
|
||||
|
||||
// getLength
|
||||
function() { testStoreGetLength(3).then(function() { runTest(); }, cbError); },
|
||||
|
||||
// Remove
|
||||
function() { testStoreRemove(gId).then(function(what) {
|
||||
runTest(); }, cbError); },
|
||||
function() { testStoreGet(gId, undefined); },
|
||||
|
||||
// Remove - wrong ID
|
||||
function() { testStoreRemove(gId).then(function(what) {
|
||||
runTest(); }, cbError); },
|
||||
|
||||
// Clear
|
||||
function() { testStoreClear().then(function(what) {
|
||||
runTest(); }, cbError); },
|
||||
];
|
||||
|
||||
function runTest() {
|
||||
if (!tests.length) {
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
|
||||
var test = tests.shift();
|
||||
test();
|
||||
}
|
||||
|
||||
runTest();
|
||||
</script>
|
||||
</body>
|
||||
|
|
|
@ -0,0 +1,119 @@
|
|||
var gStore;
|
||||
|
||||
function testGetDataStores() {
|
||||
navigator.getDataStores('foo').then(function(stores) {
|
||||
is(stores.length, 1, "getDataStores('foo') returns 1 element");
|
||||
is(stores[0].name, 'foo', 'The dataStore.name is foo');
|
||||
is(stores[0].readOnly, false, 'The dataStore foo is not in readonly');
|
||||
|
||||
var store = stores[0];
|
||||
ok("get" in store, "store.get exists");
|
||||
ok("put" in store, "store.put exists");
|
||||
ok("add" in store, "store.add exists");
|
||||
ok("remove" in store, "store.remove exists");
|
||||
ok("clear" in store, "store.clear exists");
|
||||
ok("revisionId" in store, "store.revisionId exists");
|
||||
ok("getLength" in store, "store.getLength exists");
|
||||
ok("sync" in store, "store.sync exists");
|
||||
|
||||
gStore = stores[0];
|
||||
|
||||
runTest();
|
||||
}, cbError);
|
||||
}
|
||||
|
||||
function testStoreGet(id, value) {
|
||||
gStore.get(id).then(function(what) {
|
||||
ok(true, "store.get() retrieves data");
|
||||
is(what, value, "store.get(" + id + ") returns " + value);
|
||||
}, function() {
|
||||
ok(false, "store.get(" + id + ") retrieves data");
|
||||
}).then(runTest, cbError);
|
||||
}
|
||||
|
||||
function testStoreAdd(value) {
|
||||
return gStore.add(value).then(function(what) {
|
||||
ok(true, "store.add() is called");
|
||||
ok(what > 0, "store.add() returns something");
|
||||
return what;
|
||||
}, cbError);
|
||||
}
|
||||
|
||||
function testStorePut(value, id) {
|
||||
return gStore.put(value, id).then(function() {
|
||||
ok(true, "store.put() is called");
|
||||
}, cbError);
|
||||
}
|
||||
|
||||
function testStoreGetLength(number) {
|
||||
return gStore.getLength().then(function(n) {
|
||||
is(number, n, "store.getLength() returns the right number");
|
||||
}, cbError);
|
||||
}
|
||||
|
||||
function testStoreRemove(id) {
|
||||
return gStore.remove(id).then(function() {
|
||||
ok(true, "store.remove() is called");
|
||||
}, cbError);
|
||||
}
|
||||
|
||||
function testStoreClear() {
|
||||
return gStore.clear().then(function() {
|
||||
ok(true, "store.clear() is called");
|
||||
}, cbError);
|
||||
}
|
||||
|
||||
var tests = [
|
||||
// Test for GetDataStore
|
||||
testGetDataStores,
|
||||
|
||||
// Unknown ID
|
||||
function() { testStoreGet(42, undefined); },
|
||||
function() { testStoreGet(42, undefined); }, // twice
|
||||
|
||||
// Add + Get - number
|
||||
function() { testStoreAdd(42).then(function(id) {
|
||||
gId = id; runTest(); }, cbError); },
|
||||
function() { testStoreGet(gId, 42); },
|
||||
|
||||
// Add + Get - boolean
|
||||
function() { testStoreAdd(true).then(function(id) {
|
||||
gId = id; runTest(); }, cbError); },
|
||||
function() { testStoreGet(gId, true); },
|
||||
|
||||
// Add + Get - string
|
||||
function() { testStoreAdd("hello world").then(function(id) {
|
||||
gId = id; runTest(); }, cbError); },
|
||||
function() { testStoreGet(gId, "hello world"); },
|
||||
|
||||
// Put + Get - string
|
||||
function() { testStorePut("hello world 2", gId).then(function() {
|
||||
runTest(); }, cbError); },
|
||||
function() { testStoreGet(gId, "hello world 2"); },
|
||||
|
||||
// getLength
|
||||
function() { testStoreGetLength(3).then(function() { runTest(); }, cbError); },
|
||||
|
||||
// Remove
|
||||
function() { testStoreRemove(gId).then(function(what) {
|
||||
runTest(); }, cbError); },
|
||||
function() { testStoreGet(gId, undefined); },
|
||||
|
||||
// Remove - wrong ID
|
||||
function() { testStoreRemove(gId).then(function(what) {
|
||||
runTest(); }, cbError); },
|
||||
|
||||
// Clear
|
||||
function() { testStoreClear().then(function(what) {
|
||||
runTest(); }, cbError); },
|
||||
];
|
||||
|
||||
function runTest() {
|
||||
if (!tests.length) {
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
|
||||
var test = tests.shift();
|
||||
test();
|
||||
}
|
|
@ -1,137 +1,19 @@
|
|||
var gStore;
|
||||
function is(a, b, msg) {
|
||||
postMessage((a === b ? 'OK' : 'KO') + ' ' + msg)
|
||||
}
|
||||
|
||||
function is(a, b, msg) {
|
||||
postMessage((a === b ? 'OK' : 'KO') + ' ' + msg)
|
||||
}
|
||||
function ok(a, msg) {
|
||||
postMessage((a ? 'OK' : 'KO')+ ' ' + msg)
|
||||
}
|
||||
|
||||
function ok(a, msg) {
|
||||
postMessage((a ? 'OK' : 'KO')+ ' ' + msg)
|
||||
}
|
||||
function cbError() {
|
||||
postMessage('KO error');
|
||||
}
|
||||
|
||||
function cbError() {
|
||||
postMessage('KO error');
|
||||
}
|
||||
function finish() {
|
||||
postMessage('DONE');
|
||||
}
|
||||
|
||||
function finish() {
|
||||
postMessage('DONE');
|
||||
}
|
||||
importScripts("file_basic_common.js");
|
||||
|
||||
function testGetDataStores() {
|
||||
navigator.getDataStores('foo').then(function(stores) {
|
||||
is(stores.length, 1, "getDataStores('foo') returns 1 element");
|
||||
is(stores[0].name, 'foo', 'The dataStore.name is foo');
|
||||
is(stores[0].readOnly, false, 'The dataStore foo is not in readonly');
|
||||
|
||||
var store = stores[0];
|
||||
ok("get" in store, "store.get exists");
|
||||
ok("put" in store, "store.put exists");
|
||||
ok("add" in store, "store.add exists");
|
||||
ok("remove" in store, "store.remove exists");
|
||||
ok("clear" in store, "store.clear exists");
|
||||
ok("revisionId" in store, "store.revisionId exists");
|
||||
ok("getLength" in store, "store.getLength exists");
|
||||
ok("sync" in store, "store.sync exists");
|
||||
|
||||
gStore = stores[0];
|
||||
|
||||
runTest();
|
||||
}, cbError);
|
||||
}
|
||||
|
||||
function testStoreGet(id, value) {
|
||||
gStore.get(id).then(function(what) {
|
||||
ok(true, "store.get() retrieves data");
|
||||
is(what, value, "store.get(" + id + ") returns " + value);
|
||||
}, function() {
|
||||
ok(false, "store.get(" + id + ") retrieves data");
|
||||
}).then(runTest, cbError);
|
||||
}
|
||||
|
||||
function testStoreAdd(value) {
|
||||
return gStore.add(value).then(function(what) {
|
||||
ok(true, "store.add() is called");
|
||||
ok(what > 0, "store.add() returns something");
|
||||
return what;
|
||||
}, cbError);
|
||||
}
|
||||
|
||||
function testStorePut(value, id) {
|
||||
return gStore.put(value, id).then(function() {
|
||||
ok(true, "store.put() is called");
|
||||
}, cbError);
|
||||
}
|
||||
|
||||
function testStoreGetLength(number) {
|
||||
return gStore.getLength().then(function(n) {
|
||||
is(number, n, "store.getLength() returns the right number");
|
||||
}, cbError);
|
||||
}
|
||||
|
||||
function testStoreRemove(id) {
|
||||
return gStore.remove(id).then(function() {
|
||||
ok(true, "store.remove() is called");
|
||||
}, cbError);
|
||||
}
|
||||
|
||||
function testStoreClear() {
|
||||
return gStore.clear().then(function() {
|
||||
ok(true, "store.clear() is called");
|
||||
}, cbError);
|
||||
}
|
||||
|
||||
var tests = [
|
||||
// Test for GetDataStore
|
||||
testGetDataStores,
|
||||
|
||||
// Unknown ID
|
||||
function() { testStoreGet(42, undefined); },
|
||||
function() { testStoreGet(42, undefined); }, // twice
|
||||
|
||||
// Add + Get - number
|
||||
function() { testStoreAdd(42).then(function(id) {
|
||||
gId = id; runTest(); }, cbError); },
|
||||
function() { testStoreGet(gId, 42); },
|
||||
|
||||
// Add + Get - boolean
|
||||
function() { testStoreAdd(true).then(function(id) {
|
||||
gId = id; runTest(); }, cbError); },
|
||||
function() { testStoreGet(gId, true); },
|
||||
|
||||
// Add + Get - string
|
||||
function() { testStoreAdd("hello world").then(function(id) {
|
||||
gId = id; runTest(); }, cbError); },
|
||||
function() { testStoreGet(gId, "hello world"); },
|
||||
|
||||
// Put + Get - string
|
||||
function() { testStorePut("hello world 2", gId).then(function() {
|
||||
runTest(); }, cbError); },
|
||||
function() { testStoreGet(gId, "hello world 2"); },
|
||||
|
||||
// getLength
|
||||
function() { testStoreGetLength(3).then(function() { runTest(); }, cbError); },
|
||||
|
||||
// Remove
|
||||
function() { testStoreRemove(gId).then(function(what) {
|
||||
runTest(); }, cbError); },
|
||||
function() { testStoreGet(gId, undefined); },
|
||||
|
||||
// Remove - wrong ID
|
||||
function() { testStoreRemove(gId).then(function(what) {
|
||||
runTest(); }, cbError); },
|
||||
|
||||
// Clear
|
||||
function() { testStoreClear().then(function(what) {
|
||||
runTest(); }, cbError); },
|
||||
];
|
||||
|
||||
function runTest() {
|
||||
if (!tests.length) {
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
|
||||
var test = tests.shift();
|
||||
test();
|
||||
}
|
||||
|
||||
runTest();
|
||||
runTest();
|
||||
|
|
|
@ -3,16 +3,12 @@
|
|||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for DataStore - sync</title>
|
||||
<script type="text/javascript" src="file_sync_common.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="container"></div>
|
||||
<script type="application/javascript;version=1.7">
|
||||
|
||||
var gStore;
|
||||
var gRevisions = [];
|
||||
var gCursor;
|
||||
var gExpectedEvents = true;
|
||||
|
||||
function is(a, b, msg) {
|
||||
alert((a === b ? 'OK' : 'KO') + ' ' + msg)
|
||||
}
|
||||
|
@ -29,463 +25,6 @@
|
|||
alert('DONE');
|
||||
}
|
||||
|
||||
function testGetDataStores() {
|
||||
navigator.getDataStores('foo').then(function(stores) {
|
||||
is(stores.length, 1, "getDataStores('foo') returns 1 element");
|
||||
|
||||
gStore = stores[0];
|
||||
gRevisions.push(gStore.revisionId);
|
||||
|
||||
gStore.onchange = function(aEvent) {
|
||||
ok(gExpectedEvents, "Events received!");
|
||||
runTest();
|
||||
}
|
||||
|
||||
runTest();
|
||||
}, cbError);
|
||||
}
|
||||
|
||||
function testBasicInterface() {
|
||||
var cursor = gStore.sync();
|
||||
ok(cursor, "Cursor is created");
|
||||
is(cursor.store, gStore, "Cursor.store is the store");
|
||||
|
||||
ok("next" in cursor, "Cursor.next exists");
|
||||
ok("close" in cursor, "Cursor.close exists");
|
||||
|
||||
cursor.close();
|
||||
|
||||
runTest();
|
||||
}
|
||||
|
||||
function testCursor(cursor, steps) {
|
||||
if (!steps.length) {
|
||||
runTest();
|
||||
return;
|
||||
}
|
||||
|
||||
var step = steps.shift();
|
||||
cursor.next().then(function(data) {
|
||||
ok(!!data, "Cursor.next returns data");
|
||||
is(data.operation, step.operation, "Waiting for operation: '" + step.operation + "' received '" + data.operation + "'");
|
||||
|
||||
|
||||
switch (data.operation) {
|
||||
case 'clear':
|
||||
is (data.id, null, "'clear' operation wants a null id");
|
||||
break;
|
||||
|
||||
case 'done':
|
||||
is(/[0-9a-zA-Z]{8}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{12}/.test(data.revisionId), true, "done has a valid revisionId");
|
||||
is (data.revisionId, gRevisions[gRevisions.length-1], "Last revision matches");
|
||||
is (data.id, null, "'done' operation wants a null id");
|
||||
break;
|
||||
|
||||
case 'add':
|
||||
case 'update':
|
||||
if ('id' in step) {
|
||||
is(data.id, step.id, "next() add: id matches: " + data.id + " " + step.id);
|
||||
}
|
||||
|
||||
if ('data' in step) {
|
||||
is(data.data, step.data, "next() add: data matches: " + data.data + " " + step.data);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'remove':
|
||||
if ('id' in step) {
|
||||
is(data.id, step.id, "next() add: id matches: " + data.id + " " + step.id);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
testCursor(cursor, steps);
|
||||
});
|
||||
}
|
||||
|
||||
var tests = [
|
||||
// Test for GetDataStore
|
||||
testGetDataStores,
|
||||
|
||||
// interface test
|
||||
testBasicInterface,
|
||||
|
||||
// empty DataStore
|
||||
function() {
|
||||
var cursor = gStore.sync();
|
||||
var steps = [ { operation: 'clear' },
|
||||
{ operation: 'done' },
|
||||
{ operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
gExpectedEvents = false;
|
||||
var cursor = gStore.sync('wrong revision ID');
|
||||
var steps = [ { operation: 'clear' },
|
||||
{ operation: 'done' },
|
||||
{ operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
var cursor = gStore.sync(gRevisions[0]);
|
||||
var steps = [ { operation: 'done' },
|
||||
{ operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
// Test add from scratch
|
||||
function() {
|
||||
gExpectedEvents = true;
|
||||
|
||||
gStore.add(1).then(function(id) {
|
||||
gRevisions.push(gStore.revisionId);
|
||||
ok(true, "Item: " + id + " added");
|
||||
});
|
||||
},
|
||||
|
||||
function() {
|
||||
gStore.add(2,"foobar").then(function(id) {
|
||||
gRevisions.push(gStore.revisionId);
|
||||
ok(true, "Item: " + id + " added");
|
||||
});
|
||||
},
|
||||
|
||||
function() {
|
||||
gStore.add(3,3).then(function(id) {
|
||||
gRevisions.push(gStore.revisionId);
|
||||
ok(true, "Item: " + id + " added");
|
||||
});
|
||||
},
|
||||
|
||||
function() {
|
||||
gExpectedEvents = false;
|
||||
var cursor = gStore.sync();
|
||||
var steps = [ { operation: 'clear', },
|
||||
{ operation: 'add', id: 1, data: 1 },
|
||||
{ operation: 'add', id: 3, data: 3 },
|
||||
{ operation: 'add', id: 'foobar', data: 2 },
|
||||
{ operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
var cursor = gStore.sync('wrong revision ID');
|
||||
var steps = [ { operation: 'clear', },
|
||||
{ operation: 'add', id: 1, data: 1 },
|
||||
{ operation: 'add', id: 3, data: 3 },
|
||||
{ operation: 'add', id: 'foobar', data: 2 },
|
||||
{ operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
var cursor = gStore.sync(gRevisions[0]);
|
||||
var steps = [ { operation: 'add', id: 1, data: 1 },
|
||||
{ operation: 'add', id: 'foobar', data: 2 },
|
||||
{ operation: 'add', id: 3, data: 3 },
|
||||
{ operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
var cursor = gStore.sync(gRevisions[1]);
|
||||
var steps = [ { operation: 'add', id: 'foobar', data: 2 },
|
||||
{ operation: 'add', id: 3, data: 3 },
|
||||
{ operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
var cursor = gStore.sync(gRevisions[2]);
|
||||
var steps = [ { operation: 'add', id: 3, data: 3 },
|
||||
{ operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
var cursor = gStore.sync(gRevisions[3]);
|
||||
var steps = [ { operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
// Test after an update
|
||||
function() {
|
||||
gExpectedEvents = true;
|
||||
gStore.put(123, 1).then(function() {
|
||||
gRevisions.push(gStore.revisionId);
|
||||
});
|
||||
},
|
||||
|
||||
function() {
|
||||
gExpectedEvents = false;
|
||||
var cursor = gStore.sync();
|
||||
var steps = [ { operation: 'clear', },
|
||||
{ operation: 'add', id: 1, data: 123 },
|
||||
{ operation: 'add', id: 3, data: 3 },
|
||||
{ operation: 'add', id: 'foobar', data: 2 },
|
||||
{ operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
var cursor = gStore.sync('wrong revision ID');
|
||||
var steps = [ { operation: 'clear', },
|
||||
{ operation: 'add', id: 1, data: 123 },
|
||||
{ operation: 'add', id: 3, data: 3 },
|
||||
{ operation: 'add', id: 'foobar', data: 2 },
|
||||
{ operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
var cursor = gStore.sync(gRevisions[0]);
|
||||
var steps = [ { operation: 'add', id: 1, data: 123 },
|
||||
{ operation: 'add', id: 'foobar', data: 2 },
|
||||
{ operation: 'add', id: 3, data: 3 },
|
||||
{ operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
var cursor = gStore.sync(gRevisions[1]);
|
||||
var steps = [ { operation: 'add', id: 'foobar', data: 2 },
|
||||
{ operation: 'add', id: 3, data: 3 },
|
||||
{ operation: 'update', id: 1, data: 123 },
|
||||
{ operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
var cursor = gStore.sync(gRevisions[2]);
|
||||
var steps = [ { operation: 'add', id: 3, data: 3 },
|
||||
{ operation: 'update', id: 1, data: 123 },
|
||||
{ operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
var cursor = gStore.sync(gRevisions[3]);
|
||||
var steps = [ { operation: 'update', id: 1, data: 123 },
|
||||
{ operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
var cursor = gStore.sync(gRevisions[4]);
|
||||
var steps = [ { operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
// Test after a remove
|
||||
function() {
|
||||
gExpectedEvents = true;
|
||||
gStore.remove(3).then(function() {
|
||||
gRevisions.push(gStore.revisionId);
|
||||
});
|
||||
},
|
||||
|
||||
function() {
|
||||
gExpectedEvents = false;
|
||||
var cursor = gStore.sync();
|
||||
var steps = [ { operation: 'clear', },
|
||||
{ operation: 'add', id: 1, data: 123 },
|
||||
{ operation: 'add', id: 'foobar', data: 2 },
|
||||
{ operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
var cursor = gStore.sync('wrong revision ID');
|
||||
var steps = [ { operation: 'clear', },
|
||||
{ operation: 'add', id: 1, data: 123 },
|
||||
{ operation: 'add', id: 'foobar', data: 2 },
|
||||
{ operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
var cursor = gStore.sync(gRevisions[0]);
|
||||
var steps = [ { operation: 'add', id: 1, data: 123 },
|
||||
{ operation: 'add', id: 'foobar', data: 2 },
|
||||
{ operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
var cursor = gStore.sync(gRevisions[1]);
|
||||
var steps = [ { operation: 'add', id: 'foobar', data: 2 },
|
||||
{ operation: 'update', id: 1, data: 123 },
|
||||
{ operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
var cursor = gStore.sync(gRevisions[2]);
|
||||
var steps = [ { operation: 'update', id: 1, data: 123 },
|
||||
{ operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
var cursor = gStore.sync(gRevisions[3]);
|
||||
var steps = [ { operation: 'update', id: 1, data: 123 },
|
||||
{ operation: 'remove', id: 3 },
|
||||
{ operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
var cursor = gStore.sync(gRevisions[4]);
|
||||
var steps = [ { operation: 'remove', id: 3 },
|
||||
{ operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
var cursor = gStore.sync(gRevisions[5]);
|
||||
var steps = [ { operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
// New events when the cursor is active
|
||||
function() {
|
||||
gCursor = gStore.sync();
|
||||
var steps = [ { operation: 'clear', },
|
||||
{ operation: 'add', id: 1, data: 123 },
|
||||
{ operation: 'add', id: 'foobar', data: 2 } ];
|
||||
testCursor(gCursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
gStore.add(42, 2).then(function(id) {
|
||||
ok(true, "Item: " + id + " added");
|
||||
gRevisions.push(gStore.revisionId);
|
||||
runTest();
|
||||
});
|
||||
},
|
||||
|
||||
function() {
|
||||
var steps = [ { operation: 'clear', },
|
||||
{ operation: 'add', id: 1, data: 123 },
|
||||
{ operation: 'add', id: 2, data: 42 },
|
||||
{ operation: 'add', id: 'foobar', data: 2 } ]
|
||||
testCursor(gCursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
gStore.put(43, 2).then(function(id) {
|
||||
gRevisions.push(gStore.revisionId);
|
||||
runTest();
|
||||
});
|
||||
},
|
||||
|
||||
function() {
|
||||
var steps = [ { operation: 'clear', },
|
||||
{ operation: 'add', id: 1, data: 123 },
|
||||
{ operation: 'add', id: 2, data: 43 },
|
||||
{ operation: 'add', id: 'foobar', data: 2 } ]
|
||||
testCursor(gCursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
gStore.remove(2).then(function(id) {
|
||||
gRevisions.push(gStore.revisionId);
|
||||
runTest();
|
||||
});
|
||||
},
|
||||
|
||||
function() {
|
||||
var steps = [ { operation: 'clear', },
|
||||
{ operation: 'add', id: 1, data: 123 },
|
||||
{ operation: 'add', id: 'foobar', data: 2 } ]
|
||||
testCursor(gCursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
gStore.add(42).then(function(id) {
|
||||
ok(true, "Item: " + id + " added");
|
||||
gRevisions.push(gStore.revisionId);
|
||||
runTest();
|
||||
});
|
||||
},
|
||||
|
||||
function() {
|
||||
var steps = [ { operation: 'clear', },
|
||||
{ operation: 'add', id: 1, data: 123 },
|
||||
{ operation: 'add', id: 4, data: 42 },
|
||||
{ operation: 'add', id: 'foobar', data: 2 } ]
|
||||
testCursor(gCursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
gStore.clear().then(function() {
|
||||
gRevisions.push(gStore.revisionId);
|
||||
runTest();
|
||||
});
|
||||
},
|
||||
|
||||
function() {
|
||||
var steps = [ { operation: 'clear' } ];
|
||||
testCursor(gCursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
gStore.add(42).then(function(id) {
|
||||
ok(true, "Item: " + id + " added");
|
||||
gRevisions.push(gStore.revisionId);
|
||||
runTest();
|
||||
});
|
||||
},
|
||||
|
||||
function() {
|
||||
var steps = [ { operation: 'clear', },
|
||||
{ operation: 'add', id: 5, data: 42 } ];
|
||||
testCursor(gCursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
gStore.clear().then(function() {
|
||||
gRevisions.push(gStore.revisionId);
|
||||
runTest();
|
||||
});
|
||||
},
|
||||
|
||||
function() {
|
||||
gStore.add(42).then(function(id) {
|
||||
ok(true, "Item: " + id + " added");
|
||||
gRevisions.push(gStore.revisionId);
|
||||
runTest();
|
||||
});
|
||||
},
|
||||
|
||||
function() {
|
||||
var steps = [ { operation: 'clear' },
|
||||
{ operation: 'add', id: 6, data: 42 },
|
||||
{ operation: 'done'} ];
|
||||
testCursor(gCursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
gExpectedEvents = true;
|
||||
gStore.add(42).then(function(id) {
|
||||
});
|
||||
}
|
||||
];
|
||||
|
||||
function runTest() {
|
||||
if (!tests.length) {
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
|
||||
var test = tests.shift();
|
||||
test();
|
||||
}
|
||||
|
||||
runTest();
|
||||
</script>
|
||||
</body>
|
||||
|
|
|
@ -0,0 +1,461 @@
|
|||
var gStore;
|
||||
var gRevisions = [];
|
||||
var gCursor;
|
||||
var gExpectedEvents = true;
|
||||
|
||||
function testGetDataStores() {
|
||||
navigator.getDataStores('foo').then(function(stores) {
|
||||
is(stores.length, 1, "getDataStores('foo') returns 1 element");
|
||||
|
||||
gStore = stores[0];
|
||||
gRevisions.push(gStore.revisionId);
|
||||
|
||||
gStore.onchange = function(aEvent) {
|
||||
ok(gExpectedEvents, "Events received!");
|
||||
runTest();
|
||||
}
|
||||
|
||||
runTest();
|
||||
}, cbError);
|
||||
}
|
||||
|
||||
function testBasicInterface() {
|
||||
var cursor = gStore.sync();
|
||||
ok(cursor, "Cursor is created");
|
||||
is(cursor.store, gStore, "Cursor.store is the store");
|
||||
|
||||
ok("next" in cursor, "Cursor.next exists");
|
||||
ok("close" in cursor, "Cursor.close exists");
|
||||
|
||||
cursor.close();
|
||||
|
||||
runTest();
|
||||
}
|
||||
|
||||
function testCursor(cursor, steps) {
|
||||
if (!steps.length) {
|
||||
runTest();
|
||||
return;
|
||||
}
|
||||
|
||||
var step = steps.shift();
|
||||
cursor.next().then(function(data) {
|
||||
ok(!!data, "Cursor.next returns data");
|
||||
is(data.operation, step.operation, "Waiting for operation: '" + step.operation + "' received '" + data.operation + "'");
|
||||
|
||||
|
||||
switch (data.operation) {
|
||||
case 'clear':
|
||||
is (data.id, null, "'clear' operation wants a null id");
|
||||
break;
|
||||
|
||||
case 'done':
|
||||
is(/[0-9a-zA-Z]{8}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{12}/.test(data.revisionId), true, "done has a valid revisionId");
|
||||
is (data.revisionId, gRevisions[gRevisions.length-1], "Last revision matches");
|
||||
is (data.id, null, "'done' operation wants a null id");
|
||||
break;
|
||||
|
||||
case 'add':
|
||||
case 'update':
|
||||
if ('id' in step) {
|
||||
is(data.id, step.id, "next() add: id matches: " + data.id + " " + step.id);
|
||||
}
|
||||
|
||||
if ('data' in step) {
|
||||
is(data.data, step.data, "next() add: data matches: " + data.data + " " + step.data);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'remove':
|
||||
if ('id' in step) {
|
||||
is(data.id, step.id, "next() add: id matches: " + data.id + " " + step.id);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
testCursor(cursor, steps);
|
||||
});
|
||||
}
|
||||
|
||||
var tests = [
|
||||
// Test for GetDataStore
|
||||
testGetDataStores,
|
||||
|
||||
// interface test
|
||||
testBasicInterface,
|
||||
|
||||
// empty DataStore
|
||||
function() {
|
||||
var cursor = gStore.sync();
|
||||
var steps = [ { operation: 'clear' },
|
||||
{ operation: 'done' },
|
||||
{ operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
gExpectedEvents = false;
|
||||
var cursor = gStore.sync('wrong revision ID');
|
||||
var steps = [ { operation: 'clear' },
|
||||
{ operation: 'done' },
|
||||
{ operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
var cursor = gStore.sync(gRevisions[0]);
|
||||
var steps = [ { operation: 'done' },
|
||||
{ operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
// Test add from scratch
|
||||
function() {
|
||||
gExpectedEvents = true;
|
||||
|
||||
gStore.add(1).then(function(id) {
|
||||
gRevisions.push(gStore.revisionId);
|
||||
ok(true, "Item: " + id + " added");
|
||||
});
|
||||
},
|
||||
|
||||
function() {
|
||||
gStore.add(2,"foobar").then(function(id) {
|
||||
gRevisions.push(gStore.revisionId);
|
||||
ok(true, "Item: " + id + " added");
|
||||
});
|
||||
},
|
||||
|
||||
function() {
|
||||
gStore.add(3,3).then(function(id) {
|
||||
gRevisions.push(gStore.revisionId);
|
||||
ok(true, "Item: " + id + " added");
|
||||
});
|
||||
},
|
||||
|
||||
function() {
|
||||
gExpectedEvents = false;
|
||||
var cursor = gStore.sync();
|
||||
var steps = [ { operation: 'clear', },
|
||||
{ operation: 'add', id: 1, data: 1 },
|
||||
{ operation: 'add', id: 3, data: 3 },
|
||||
{ operation: 'add', id: 'foobar', data: 2 },
|
||||
{ operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
var cursor = gStore.sync('wrong revision ID');
|
||||
var steps = [ { operation: 'clear', },
|
||||
{ operation: 'add', id: 1, data: 1 },
|
||||
{ operation: 'add', id: 3, data: 3 },
|
||||
{ operation: 'add', id: 'foobar', data: 2 },
|
||||
{ operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
var cursor = gStore.sync(gRevisions[0]);
|
||||
var steps = [ { operation: 'add', id: 1, data: 1 },
|
||||
{ operation: 'add', id: 'foobar', data: 2 },
|
||||
{ operation: 'add', id: 3, data: 3 },
|
||||
{ operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
var cursor = gStore.sync(gRevisions[1]);
|
||||
var steps = [ { operation: 'add', id: 'foobar', data: 2 },
|
||||
{ operation: 'add', id: 3, data: 3 },
|
||||
{ operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
var cursor = gStore.sync(gRevisions[2]);
|
||||
var steps = [ { operation: 'add', id: 3, data: 3 },
|
||||
{ operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
var cursor = gStore.sync(gRevisions[3]);
|
||||
var steps = [ { operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
// Test after an update
|
||||
function() {
|
||||
gExpectedEvents = true;
|
||||
gStore.put(123, 1).then(function() {
|
||||
gRevisions.push(gStore.revisionId);
|
||||
});
|
||||
},
|
||||
|
||||
function() {
|
||||
gExpectedEvents = false;
|
||||
var cursor = gStore.sync();
|
||||
var steps = [ { operation: 'clear', },
|
||||
{ operation: 'add', id: 1, data: 123 },
|
||||
{ operation: 'add', id: 3, data: 3 },
|
||||
{ operation: 'add', id: 'foobar', data: 2 },
|
||||
{ operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
var cursor = gStore.sync('wrong revision ID');
|
||||
var steps = [ { operation: 'clear', },
|
||||
{ operation: 'add', id: 1, data: 123 },
|
||||
{ operation: 'add', id: 3, data: 3 },
|
||||
{ operation: 'add', id: 'foobar', data: 2 },
|
||||
{ operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
var cursor = gStore.sync(gRevisions[0]);
|
||||
var steps = [ { operation: 'add', id: 1, data: 123 },
|
||||
{ operation: 'add', id: 'foobar', data: 2 },
|
||||
{ operation: 'add', id: 3, data: 3 },
|
||||
{ operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
var cursor = gStore.sync(gRevisions[1]);
|
||||
var steps = [ { operation: 'add', id: 'foobar', data: 2 },
|
||||
{ operation: 'add', id: 3, data: 3 },
|
||||
{ operation: 'update', id: 1, data: 123 },
|
||||
{ operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
var cursor = gStore.sync(gRevisions[2]);
|
||||
var steps = [ { operation: 'add', id: 3, data: 3 },
|
||||
{ operation: 'update', id: 1, data: 123 },
|
||||
{ operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
var cursor = gStore.sync(gRevisions[3]);
|
||||
var steps = [ { operation: 'update', id: 1, data: 123 },
|
||||
{ operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
var cursor = gStore.sync(gRevisions[4]);
|
||||
var steps = [ { operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
// Test after a remove
|
||||
function() {
|
||||
gExpectedEvents = true;
|
||||
gStore.remove(3).then(function() {
|
||||
gRevisions.push(gStore.revisionId);
|
||||
});
|
||||
},
|
||||
|
||||
function() {
|
||||
gExpectedEvents = false;
|
||||
var cursor = gStore.sync();
|
||||
var steps = [ { operation: 'clear', },
|
||||
{ operation: 'add', id: 1, data: 123 },
|
||||
{ operation: 'add', id: 'foobar', data: 2 },
|
||||
{ operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
var cursor = gStore.sync('wrong revision ID');
|
||||
var steps = [ { operation: 'clear', },
|
||||
{ operation: 'add', id: 1, data: 123 },
|
||||
{ operation: 'add', id: 'foobar', data: 2 },
|
||||
{ operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
var cursor = gStore.sync(gRevisions[0]);
|
||||
var steps = [ { operation: 'add', id: 1, data: 123 },
|
||||
{ operation: 'add', id: 'foobar', data: 2 },
|
||||
{ operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
var cursor = gStore.sync(gRevisions[1]);
|
||||
var steps = [ { operation: 'add', id: 'foobar', data: 2 },
|
||||
{ operation: 'update', id: 1, data: 123 },
|
||||
{ operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
var cursor = gStore.sync(gRevisions[2]);
|
||||
var steps = [ { operation: 'update', id: 1, data: 123 },
|
||||
{ operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
var cursor = gStore.sync(gRevisions[3]);
|
||||
var steps = [ { operation: 'update', id: 1, data: 123 },
|
||||
{ operation: 'remove', id: 3 },
|
||||
{ operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
var cursor = gStore.sync(gRevisions[4]);
|
||||
var steps = [ { operation: 'remove', id: 3 },
|
||||
{ operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
var cursor = gStore.sync(gRevisions[5]);
|
||||
var steps = [ { operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
// New events when the cursor is active
|
||||
function() {
|
||||
gCursor = gStore.sync();
|
||||
var steps = [ { operation: 'clear', },
|
||||
{ operation: 'add', id: 1, data: 123 },
|
||||
{ operation: 'add', id: 'foobar', data: 2 } ];
|
||||
testCursor(gCursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
gStore.add(42, 2).then(function(id) {
|
||||
ok(true, "Item: " + id + " added");
|
||||
gRevisions.push(gStore.revisionId);
|
||||
runTest();
|
||||
});
|
||||
},
|
||||
|
||||
function() {
|
||||
var steps = [ { operation: 'clear', },
|
||||
{ operation: 'add', id: 1, data: 123 },
|
||||
{ operation: 'add', id: 2, data: 42 },
|
||||
{ operation: 'add', id: 'foobar', data: 2 } ]
|
||||
testCursor(gCursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
gStore.put(43, 2).then(function(id) {
|
||||
gRevisions.push(gStore.revisionId);
|
||||
runTest();
|
||||
});
|
||||
},
|
||||
|
||||
function() {
|
||||
var steps = [ { operation: 'clear', },
|
||||
{ operation: 'add', id: 1, data: 123 },
|
||||
{ operation: 'add', id: 2, data: 43 },
|
||||
{ operation: 'add', id: 'foobar', data: 2 } ]
|
||||
testCursor(gCursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
gStore.remove(2).then(function(id) {
|
||||
gRevisions.push(gStore.revisionId);
|
||||
runTest();
|
||||
});
|
||||
},
|
||||
|
||||
function() {
|
||||
var steps = [ { operation: 'clear', },
|
||||
{ operation: 'add', id: 1, data: 123 },
|
||||
{ operation: 'add', id: 'foobar', data: 2 } ]
|
||||
testCursor(gCursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
gStore.add(42).then(function(id) {
|
||||
ok(true, "Item: " + id + " added");
|
||||
gRevisions.push(gStore.revisionId);
|
||||
runTest();
|
||||
});
|
||||
},
|
||||
|
||||
function() {
|
||||
var steps = [ { operation: 'clear', },
|
||||
{ operation: 'add', id: 1, data: 123 },
|
||||
{ operation: 'add', id: 4, data: 42 },
|
||||
{ operation: 'add', id: 'foobar', data: 2 } ]
|
||||
testCursor(gCursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
gStore.clear().then(function() {
|
||||
gRevisions.push(gStore.revisionId);
|
||||
runTest();
|
||||
});
|
||||
},
|
||||
|
||||
function() {
|
||||
var steps = [ { operation: 'clear' } ];
|
||||
testCursor(gCursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
gStore.add(42).then(function(id) {
|
||||
ok(true, "Item: " + id + " added");
|
||||
gRevisions.push(gStore.revisionId);
|
||||
runTest();
|
||||
});
|
||||
},
|
||||
|
||||
function() {
|
||||
var steps = [ { operation: 'clear', },
|
||||
{ operation: 'add', id: 5, data: 42 } ];
|
||||
testCursor(gCursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
gStore.clear().then(function() {
|
||||
gRevisions.push(gStore.revisionId);
|
||||
runTest();
|
||||
});
|
||||
},
|
||||
|
||||
function() {
|
||||
gStore.add(42).then(function(id) {
|
||||
ok(true, "Item: " + id + " added");
|
||||
gRevisions.push(gStore.revisionId);
|
||||
runTest();
|
||||
});
|
||||
},
|
||||
|
||||
function() {
|
||||
var steps = [ { operation: 'clear' },
|
||||
{ operation: 'add', id: 6, data: 42 },
|
||||
{ operation: 'done'} ];
|
||||
testCursor(gCursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
gExpectedEvents = true;
|
||||
gStore.add(42).then(function(id) {
|
||||
});
|
||||
}
|
||||
];
|
||||
|
||||
function runTest() {
|
||||
if (!tests.length) {
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
|
||||
var test = tests.shift();
|
||||
test();
|
||||
}
|
|
@ -1,474 +1,19 @@
|
|||
var gStore;
|
||||
var gRevisions = [];
|
||||
var gCursor;
|
||||
var gExpectedEvents = true;
|
||||
function is(a, b, msg) {
|
||||
postMessage((a === b ? 'OK' : 'KO') + ' ' + msg)
|
||||
}
|
||||
|
||||
function is(a, b, msg) {
|
||||
postMessage((a === b ? 'OK' : 'KO') + ' ' + msg)
|
||||
}
|
||||
function ok(a, msg) {
|
||||
postMessage((a ? 'OK' : 'KO')+ ' ' + msg)
|
||||
}
|
||||
|
||||
function ok(a, msg) {
|
||||
postMessage((a ? 'OK' : 'KO')+ ' ' + msg)
|
||||
}
|
||||
function cbError() {
|
||||
postMessage('KO error');
|
||||
}
|
||||
|
||||
function cbError() {
|
||||
postMessage('KO error');
|
||||
}
|
||||
function finish() {
|
||||
postMessage('DONE');
|
||||
}
|
||||
|
||||
function finish() {
|
||||
postMessage('DONE');
|
||||
}
|
||||
importScripts("file_sync_common.js");
|
||||
|
||||
function testGetDataStores() {
|
||||
navigator.getDataStores('foo').then(function(stores) {
|
||||
is(stores.length, 1, "getDataStores('foo') returns 1 element");
|
||||
|
||||
gStore = stores[0];
|
||||
gRevisions.push(gStore.revisionId);
|
||||
|
||||
gStore.onchange = function(aEvent) {
|
||||
ok(gExpectedEvents, "Events received!");
|
||||
runTest();
|
||||
}
|
||||
|
||||
runTest();
|
||||
}, cbError);
|
||||
}
|
||||
|
||||
function testBasicInterface() {
|
||||
var cursor = gStore.sync();
|
||||
ok(cursor, "Cursor is created");
|
||||
is(cursor.store, gStore, "Cursor.store is the store");
|
||||
|
||||
ok("next" in cursor, "Cursor.next exists");
|
||||
ok("close" in cursor, "Cursor.close exists");
|
||||
|
||||
cursor.close();
|
||||
|
||||
runTest();
|
||||
}
|
||||
|
||||
function testCursor(cursor, steps) {
|
||||
if (!steps.length) {
|
||||
runTest();
|
||||
return;
|
||||
}
|
||||
|
||||
var step = steps.shift();
|
||||
cursor.next().then(function(data) {
|
||||
ok(!!data, "Cursor.next returns data");
|
||||
is(data.operation, step.operation, "Waiting for operation: '" + step.operation + "' received '" + data.operation + "'");
|
||||
|
||||
|
||||
switch (data.operation) {
|
||||
case 'done':
|
||||
is(/[0-9a-zA-Z]{8}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{12}/.test(data.revisionId), true, "done has a valid revisionId");
|
||||
is (data.revisionId, gRevisions[gRevisions.length-1], "Last revision matches");
|
||||
break;
|
||||
|
||||
case 'add':
|
||||
case 'update':
|
||||
if ('id' in step) {
|
||||
is(data.id, step.id, "next() add: id matches: " + data.id + " " + step.id);
|
||||
}
|
||||
|
||||
if ('data' in step) {
|
||||
is(data.data, step.data, "next() add: data matches: " + data.data + " " + step.data);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'remove':
|
||||
if ('id' in step) {
|
||||
is(data.id, step.id, "next() add: id matches: " + data.id + " " + step.id);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
testCursor(cursor, steps);
|
||||
});
|
||||
}
|
||||
|
||||
var tests = [
|
||||
// Test for GetDataStore
|
||||
testGetDataStores,
|
||||
|
||||
// interface test
|
||||
testBasicInterface,
|
||||
|
||||
// empty DataStore
|
||||
function() {
|
||||
var cursor = gStore.sync();
|
||||
var steps = [ { operation: 'clear' },
|
||||
{ operation: 'done' },
|
||||
{ operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
gExpectedEvents = false;
|
||||
var cursor = gStore.sync('wrong revision ID');
|
||||
var steps = [ { operation: 'clear' },
|
||||
{ operation: 'done' },
|
||||
{ operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
var cursor = gStore.sync(gRevisions[0]);
|
||||
var steps = [ { operation: 'done' },
|
||||
{ operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
// Test add from scratch
|
||||
function() {
|
||||
gExpectedEvents = true;
|
||||
|
||||
gStore.add(1).then(function(id) {
|
||||
gRevisions.push(gStore.revisionId);
|
||||
ok(true, "Item: " + id + " added");
|
||||
});
|
||||
},
|
||||
|
||||
function() {
|
||||
gStore.add(2,"foobar").then(function(id) {
|
||||
gRevisions.push(gStore.revisionId);
|
||||
ok(true, "Item: " + id + " added");
|
||||
});
|
||||
},
|
||||
|
||||
function() {
|
||||
gStore.add(3,3).then(function(id) {
|
||||
gRevisions.push(gStore.revisionId);
|
||||
ok(true, "Item: " + id + " added");
|
||||
});
|
||||
},
|
||||
|
||||
function() {
|
||||
gExpectedEvents = false;
|
||||
var cursor = gStore.sync();
|
||||
var steps = [ { operation: 'clear', },
|
||||
{ operation: 'add', id: 1, data: 1 },
|
||||
{ operation: 'add', id: 3, data: 3 },
|
||||
{ operation: 'add', id: 'foobar', data: 2 },
|
||||
{ operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
var cursor = gStore.sync('wrong revision ID');
|
||||
var steps = [ { operation: 'clear', },
|
||||
{ operation: 'add', id: 1, data: 1 },
|
||||
{ operation: 'add', id: 3, data: 3 },
|
||||
{ operation: 'add', id: 'foobar', data: 2 },
|
||||
{ operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
var cursor = gStore.sync(gRevisions[0]);
|
||||
var steps = [ { operation: 'add', id: 1, data: 1 },
|
||||
{ operation: 'add', id: 'foobar', data: 2 },
|
||||
{ operation: 'add', id: 3, data: 3 },
|
||||
{ operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
var cursor = gStore.sync(gRevisions[1]);
|
||||
var steps = [ { operation: 'add', id: 'foobar', data: 2 },
|
||||
{ operation: 'add', id: 3, data: 3 },
|
||||
{ operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
var cursor = gStore.sync(gRevisions[2]);
|
||||
var steps = [ { operation: 'add', id: 3, data: 3 },
|
||||
{ operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
var cursor = gStore.sync(gRevisions[3]);
|
||||
var steps = [ { operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
// Test after an update
|
||||
function() {
|
||||
gExpectedEvents = true;
|
||||
gStore.put(123, 1).then(function() {
|
||||
gRevisions.push(gStore.revisionId);
|
||||
});
|
||||
},
|
||||
|
||||
function() {
|
||||
gExpectedEvents = false;
|
||||
var cursor = gStore.sync();
|
||||
var steps = [ { operation: 'clear', },
|
||||
{ operation: 'add', id: 1, data: 123 },
|
||||
{ operation: 'add', id: 3, data: 3 },
|
||||
{ operation: 'add', id: 'foobar', data: 2 },
|
||||
{ operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
var cursor = gStore.sync('wrong revision ID');
|
||||
var steps = [ { operation: 'clear', },
|
||||
{ operation: 'add', id: 1, data: 123 },
|
||||
{ operation: 'add', id: 3, data: 3 },
|
||||
{ operation: 'add', id: 'foobar', data: 2 },
|
||||
{ operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
var cursor = gStore.sync(gRevisions[0]);
|
||||
var steps = [ { operation: 'add', id: 1, data: 123 },
|
||||
{ operation: 'add', id: 'foobar', data: 2 },
|
||||
{ operation: 'add', id: 3, data: 3 },
|
||||
{ operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
var cursor = gStore.sync(gRevisions[1]);
|
||||
var steps = [ { operation: 'add', id: 'foobar', data: 2 },
|
||||
{ operation: 'add', id: 3, data: 3 },
|
||||
{ operation: 'update', id: 1, data: 123 },
|
||||
{ operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
var cursor = gStore.sync(gRevisions[2]);
|
||||
var steps = [ { operation: 'add', id: 3, data: 3 },
|
||||
{ operation: 'update', id: 1, data: 123 },
|
||||
{ operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
var cursor = gStore.sync(gRevisions[3]);
|
||||
var steps = [ { operation: 'update', id: 1, data: 123 },
|
||||
{ operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
var cursor = gStore.sync(gRevisions[4]);
|
||||
var steps = [ { operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
// Test after a remove
|
||||
function() {
|
||||
gExpectedEvents = true;
|
||||
gStore.remove(3).then(function() {
|
||||
gRevisions.push(gStore.revisionId);
|
||||
});
|
||||
},
|
||||
|
||||
function() {
|
||||
gExpectedEvents = false;
|
||||
var cursor = gStore.sync();
|
||||
var steps = [ { operation: 'clear', },
|
||||
{ operation: 'add', id: 1, data: 123 },
|
||||
{ operation: 'add', id: 'foobar', data: 2 },
|
||||
{ operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
var cursor = gStore.sync('wrong revision ID');
|
||||
var steps = [ { operation: 'clear', },
|
||||
{ operation: 'add', id: 1, data: 123 },
|
||||
{ operation: 'add', id: 'foobar', data: 2 },
|
||||
{ operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
var cursor = gStore.sync(gRevisions[0]);
|
||||
var steps = [ { operation: 'add', id: 1, data: 123 },
|
||||
{ operation: 'add', id: 'foobar', data: 2 },
|
||||
{ operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
var cursor = gStore.sync(gRevisions[1]);
|
||||
var steps = [ { operation: 'add', id: 'foobar', data: 2 },
|
||||
{ operation: 'update', id: 1, data: 123 },
|
||||
{ operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
var cursor = gStore.sync(gRevisions[2]);
|
||||
var steps = [ { operation: 'update', id: 1, data: 123 },
|
||||
{ operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
var cursor = gStore.sync(gRevisions[3]);
|
||||
var steps = [ { operation: 'update', id: 1, data: 123 },
|
||||
{ operation: 'remove', id: 3 },
|
||||
{ operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
var cursor = gStore.sync(gRevisions[4]);
|
||||
var steps = [ { operation: 'remove', id: 3 },
|
||||
{ operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
var cursor = gStore.sync(gRevisions[5]);
|
||||
var steps = [ { operation: 'done' }];
|
||||
testCursor(cursor, steps);
|
||||
},
|
||||
|
||||
// New events when the cursor is active
|
||||
function() {
|
||||
gCursor = gStore.sync();
|
||||
var steps = [ { operation: 'clear', },
|
||||
{ operation: 'add', id: 1, data: 123 },
|
||||
{ operation: 'add', id: 'foobar', data: 2 } ];
|
||||
testCursor(gCursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
gStore.add(42, 2).then(function(id) {
|
||||
ok(true, "Item: " + id + " added");
|
||||
gRevisions.push(gStore.revisionId);
|
||||
runTest();
|
||||
});
|
||||
},
|
||||
|
||||
function() {
|
||||
var steps = [ { operation: 'clear', },
|
||||
{ operation: 'add', id: 1, data: 123 },
|
||||
{ operation: 'add', id: 2, data: 42 },
|
||||
{ operation: 'add', id: 'foobar', data: 2 } ]
|
||||
testCursor(gCursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
gStore.put(43, 2).then(function(id) {
|
||||
gRevisions.push(gStore.revisionId);
|
||||
runTest();
|
||||
});
|
||||
},
|
||||
|
||||
function() {
|
||||
var steps = [ { operation: 'clear', },
|
||||
{ operation: 'add', id: 1, data: 123 },
|
||||
{ operation: 'add', id: 2, data: 43 },
|
||||
{ operation: 'add', id: 'foobar', data: 2 } ]
|
||||
testCursor(gCursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
gStore.remove(2).then(function(id) {
|
||||
gRevisions.push(gStore.revisionId);
|
||||
runTest();
|
||||
});
|
||||
},
|
||||
|
||||
function() {
|
||||
var steps = [ { operation: 'clear', },
|
||||
{ operation: 'add', id: 1, data: 123 },
|
||||
{ operation: 'add', id: 'foobar', data: 2 } ]
|
||||
testCursor(gCursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
gStore.add(42).then(function(id) {
|
||||
ok(true, "Item: " + id + " added");
|
||||
gRevisions.push(gStore.revisionId);
|
||||
runTest();
|
||||
});
|
||||
},
|
||||
|
||||
function() {
|
||||
var steps = [ { operation: 'clear', },
|
||||
{ operation: 'add', id: 1, data: 123 },
|
||||
{ operation: 'add', id: 4, data: 42 },
|
||||
{ operation: 'add', id: 'foobar', data: 2 } ]
|
||||
testCursor(gCursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
gStore.clear().then(function() {
|
||||
gRevisions.push(gStore.revisionId);
|
||||
runTest();
|
||||
});
|
||||
},
|
||||
|
||||
function() {
|
||||
var steps = [ { operation: 'clear' } ];
|
||||
testCursor(gCursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
gStore.add(42).then(function(id) {
|
||||
ok(true, "Item: " + id + " added");
|
||||
gRevisions.push(gStore.revisionId);
|
||||
runTest();
|
||||
});
|
||||
},
|
||||
|
||||
function() {
|
||||
var steps = [ { operation: 'clear', },
|
||||
{ operation: 'add', id: 5, data: 42 } ];
|
||||
testCursor(gCursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
gStore.clear().then(function() {
|
||||
gRevisions.push(gStore.revisionId);
|
||||
runTest();
|
||||
});
|
||||
},
|
||||
|
||||
function() {
|
||||
gStore.add(42).then(function(id) {
|
||||
ok(true, "Item: " + id + " added");
|
||||
gRevisions.push(gStore.revisionId);
|
||||
runTest();
|
||||
});
|
||||
},
|
||||
|
||||
function() {
|
||||
var steps = [ { operation: 'clear' },
|
||||
{ operation: 'add', id: 6, data: 42 },
|
||||
{ operation: 'done'} ];
|
||||
testCursor(gCursor, steps);
|
||||
},
|
||||
|
||||
function() {
|
||||
gExpectedEvents = true;
|
||||
gStore.add(42).then(function(id) {
|
||||
});
|
||||
}
|
||||
];
|
||||
|
||||
function runTest() {
|
||||
if (!tests.length) {
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
|
||||
var test = tests.shift();
|
||||
test();
|
||||
}
|
||||
|
||||
runTest();
|
||||
runTest();
|
||||
|
|
|
@ -26,6 +26,8 @@ support-files =
|
|||
file_event_maker.html
|
||||
file_event_receiver.html
|
||||
file_transactions.html
|
||||
file_basic_common.js
|
||||
file_sync_common.js
|
||||
|
||||
[test_app_install.html]
|
||||
[test_readonly.html]
|
||||
|
|
|
@ -464,6 +464,10 @@ WINDOW_EVENT(hashchange,
|
|||
NS_HASHCHANGE,
|
||||
EventNameType_XUL | EventNameType_HTMLBodyOrFramesetOnly,
|
||||
NS_EVENT)
|
||||
WINDOW_EVENT(languagechange,
|
||||
NS_LANGUAGECHANGE,
|
||||
EventNameType_HTMLBodyOrFramesetOnly,
|
||||
NS_EVENT)
|
||||
// XXXbz Should the onmessage attribute on <body> really not work? If so, do we
|
||||
// need a different macro to flag things like that (IDL, but not content
|
||||
// attributes on body/frameset), or is just using EventNameType_None enough?
|
||||
|
|
|
@ -24,7 +24,7 @@ interface nsIVariant;
|
|||
* @see <http://www.whatwg.org/html/#window>
|
||||
*/
|
||||
|
||||
[scriptable, uuid(8c115ab3-cf96-492c-850c-3b18056b45e2)]
|
||||
[scriptable, uuid(fbefa573-0ba2-4d15-befb-d60277643a0b)]
|
||||
interface nsIDOMWindow : nsISupports
|
||||
{
|
||||
// the current browsing context
|
||||
|
@ -478,6 +478,7 @@ interface nsIDOMWindow : nsISupports
|
|||
[implicit_jscontext] attribute jsval onbeforeprint;
|
||||
[implicit_jscontext] attribute jsval onbeforeunload;
|
||||
[implicit_jscontext] attribute jsval onhashchange;
|
||||
[implicit_jscontext] attribute jsval onlanguagechange;
|
||||
[implicit_jscontext] attribute jsval onmessage;
|
||||
[implicit_jscontext] attribute jsval onoffline;
|
||||
[implicit_jscontext] attribute jsval ononline;
|
||||
|
|
|
@ -737,7 +737,6 @@ static const dom::ConstantSpec gWinProperties[] =
|
|||
INT_CONSTANT(DACL_SECURITY_INFORMATION),
|
||||
|
||||
// Errors
|
||||
INT_CONSTANT(ERROR_SUCCESS),
|
||||
INT_CONSTANT(ERROR_INVALID_HANDLE),
|
||||
INT_CONSTANT(ERROR_ACCESS_DENIED),
|
||||
INT_CONSTANT(ERROR_DIR_NOT_EMPTY),
|
||||
|
|
|
@ -123,6 +123,7 @@ interface WindowEventHandlers {
|
|||
attribute EventHandler onbeforeprint;
|
||||
attribute OnBeforeUnloadEventHandler onbeforeunload;
|
||||
attribute EventHandler onhashchange;
|
||||
attribute EventHandler onlanguagechange;
|
||||
attribute EventHandler onmessage;
|
||||
attribute EventHandler onoffline;
|
||||
attribute EventHandler ononline;
|
||||
|
|
|
@ -28,6 +28,7 @@ Navigator implements NavigatorLanguage;
|
|||
Navigator implements NavigatorOnLine;
|
||||
Navigator implements NavigatorContentUtils;
|
||||
Navigator implements NavigatorStorageUtils;
|
||||
Navigator implements NavigatorFeatures;
|
||||
|
||||
[NoInterfaceObject]
|
||||
interface NavigatorID {
|
||||
|
@ -52,6 +53,7 @@ interface NavigatorID {
|
|||
[NoInterfaceObject]
|
||||
interface NavigatorLanguage {
|
||||
readonly attribute DOMString? language;
|
||||
[Pure, Cached, Frozen] readonly attribute sequence<DOMString> languages;
|
||||
};
|
||||
|
||||
[NoInterfaceObject]
|
||||
|
@ -79,6 +81,12 @@ interface NavigatorStorageUtils {
|
|||
//void yieldForStorageUpdates();
|
||||
};
|
||||
|
||||
[NoInterfaceObject]
|
||||
interface NavigatorFeatures {
|
||||
[Func="Navigator::HasFeatureDetectionSupport"]
|
||||
Promise getFeature(DOMString name);
|
||||
};
|
||||
|
||||
// Things that definitely need to be in the spec and and are not for some
|
||||
// reason. See https://www.w3.org/Bugs/Public/show_bug.cgi?id=22406
|
||||
partial interface Navigator {
|
||||
|
|
|
@ -497,7 +497,7 @@ LoadJSGCMemoryOptions(const char* aPrefName, void* /* aClosure */)
|
|||
continue;
|
||||
}
|
||||
|
||||
matchName.RebindLiteral(PREF_MEM_OPTIONS_PREFIX
|
||||
matchName.RebindLiteral(PREF_MEM_OPTIONS_PREFIX
|
||||
"gc_high_frequency_time_limit_ms");
|
||||
if (memPrefName == matchName || (!rts && index == 2)) {
|
||||
UpdateCommonJSGCMemoryOption(rts, matchName,
|
||||
|
@ -1276,12 +1276,11 @@ RuntimeService::RegisterWorker(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
|
|||
}
|
||||
}
|
||||
|
||||
bool isSharedWorker = aWorkerPrivate->IsSharedWorker();
|
||||
|
||||
const nsCString& sharedWorkerName = aWorkerPrivate->SharedWorkerName();
|
||||
nsCString sharedWorkerScriptSpec;
|
||||
|
||||
if (isSharedWorker) {
|
||||
bool isSharedOrServiceWorker = aWorkerPrivate->IsSharedWorker() ||
|
||||
aWorkerPrivate->IsServiceWorker();
|
||||
if (isSharedOrServiceWorker) {
|
||||
AssertIsOnMainThread();
|
||||
|
||||
nsCOMPtr<nsIURI> scriptURI = aWorkerPrivate->GetResolvedScriptURI();
|
||||
|
@ -1326,7 +1325,9 @@ RuntimeService::RegisterWorker(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
|
|||
domainInfo->mActiveWorkers.AppendElement(aWorkerPrivate);
|
||||
}
|
||||
|
||||
if (isSharedWorker) {
|
||||
if (isSharedOrServiceWorker) {
|
||||
const nsCString& sharedWorkerName = aWorkerPrivate->SharedWorkerName();
|
||||
|
||||
nsAutoCString key;
|
||||
GenerateSharedWorkerKey(sharedWorkerScriptSpec, sharedWorkerName, key);
|
||||
MOZ_ASSERT(!domainInfo->mSharedWorkerInfos.Get(key));
|
||||
|
@ -1466,7 +1467,7 @@ RuntimeService::UnregisterWorker(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
|
|||
if (parent) {
|
||||
parent->RemoveChildWorker(aCx, aWorkerPrivate);
|
||||
}
|
||||
else if (aWorkerPrivate->IsSharedWorker()) {
|
||||
else if (aWorkerPrivate->IsSharedWorker() || aWorkerPrivate->IsServiceWorker()) {
|
||||
mWindowMap.Enumerate(RemoveSharedWorkerFromWindowMap, aWorkerPrivate);
|
||||
}
|
||||
else {
|
||||
|
@ -1944,7 +1945,7 @@ RuntimeService::RemoveSharedWorkerFromWindowMap(
|
|||
|
||||
auto workerPrivate = static_cast<WorkerPrivate*>(aUserArg);
|
||||
|
||||
MOZ_ASSERT(workerPrivate->IsSharedWorker());
|
||||
MOZ_ASSERT(workerPrivate->IsSharedWorker() || workerPrivate->IsServiceWorker());
|
||||
|
||||
if (aData->RemoveElement(workerPrivate)) {
|
||||
MOZ_ASSERT(!aData->Contains(workerPrivate), "Added worker more than once!");
|
||||
|
@ -2119,7 +2120,7 @@ RuntimeService::CreateSharedWorker(const GlobalObject& aGlobal,
|
|||
ErrorResult rv;
|
||||
workerPrivate =
|
||||
WorkerPrivate::Constructor(aGlobal, aScriptURL, false,
|
||||
WorkerPrivate::WorkerTypeShared, aName,
|
||||
WorkerTypeShared, aName,
|
||||
&loadInfo, rv);
|
||||
NS_ENSURE_TRUE(workerPrivate, rv.ErrorCode());
|
||||
|
||||
|
@ -2160,7 +2161,8 @@ RuntimeService::ForgetSharedWorker(WorkerPrivate* aWorkerPrivate)
|
|||
{
|
||||
AssertIsOnMainThread();
|
||||
MOZ_ASSERT(aWorkerPrivate);
|
||||
MOZ_ASSERT(aWorkerPrivate->IsSharedWorker());
|
||||
MOZ_ASSERT(aWorkerPrivate->IsSharedWorker() ||
|
||||
aWorkerPrivate->IsServiceWorker());
|
||||
|
||||
MutexAutoLock lock(mMutex);
|
||||
|
||||
|
|
|
@ -1315,7 +1315,7 @@ private:
|
|||
return true;
|
||||
}
|
||||
|
||||
if (aWorkerPrivate->IsSharedWorker()) {
|
||||
if (aWorkerPrivate->IsSharedWorker() || aWorkerPrivate->IsServiceWorker()) {
|
||||
aWorkerPrivate->BroadcastErrorToSharedWorkers(aCx, mMessage, mFilename,
|
||||
mLine, mLineNumber,
|
||||
mColumnNumber, mFlags);
|
||||
|
@ -2116,9 +2116,9 @@ WorkerPrivateParent<Derived>::WorkerPrivateParent(
|
|||
{
|
||||
SetIsDOMBinding();
|
||||
|
||||
MOZ_ASSERT_IF(IsSharedWorker(), !aSharedWorkerName.IsVoid() &&
|
||||
NS_IsMainThread());
|
||||
MOZ_ASSERT_IF(!IsSharedWorker(), aSharedWorkerName.IsEmpty());
|
||||
MOZ_ASSERT_IF(!IsDedicatedWorker(),
|
||||
!aSharedWorkerName.IsVoid() && NS_IsMainThread());
|
||||
MOZ_ASSERT_IF(IsDedicatedWorker(), aSharedWorkerName.IsEmpty());
|
||||
|
||||
if (aLoadInfo.mWindow) {
|
||||
AssertIsOnMainThread();
|
||||
|
@ -2347,7 +2347,7 @@ WorkerPrivateParent<Derived>::NotifyPrivate(JSContext* aCx, Status aStatus)
|
|||
mParentStatus = aStatus;
|
||||
}
|
||||
|
||||
if (IsSharedWorker()) {
|
||||
if (IsSharedWorker() || IsServiceWorker()) {
|
||||
RuntimeService* runtime = RuntimeService::GetService();
|
||||
MOZ_ASSERT(runtime);
|
||||
|
||||
|
@ -2399,7 +2399,7 @@ WorkerPrivateParent<Derived>::Suspend(JSContext* aCx, nsPIDOMWindow* aWindow)
|
|||
|
||||
// Shared workers are only suspended if all of their owning documents are
|
||||
// suspended.
|
||||
if (IsSharedWorker()) {
|
||||
if (IsSharedWorker() || IsServiceWorker()) {
|
||||
AssertIsOnMainThread();
|
||||
MOZ_ASSERT(mSharedWorkers.Count());
|
||||
|
||||
|
@ -2480,10 +2480,10 @@ WorkerPrivateParent<Derived>::Resume(JSContext* aCx, nsPIDOMWindow* aWindow)
|
|||
{
|
||||
AssertIsOnParentThread();
|
||||
MOZ_ASSERT(aCx);
|
||||
MOZ_ASSERT_IF(!IsSharedWorker(), mParentSuspended);
|
||||
MOZ_ASSERT_IF(IsDedicatedWorker(), mParentSuspended);
|
||||
|
||||
// Shared workers are resumed if any of their owning documents are resumed.
|
||||
if (IsSharedWorker()) {
|
||||
if (IsSharedWorker() || IsServiceWorker()) {
|
||||
AssertIsOnMainThread();
|
||||
MOZ_ASSERT(mSharedWorkers.Count());
|
||||
|
||||
|
@ -3034,14 +3034,16 @@ WorkerPrivateParent<Derived>::RegisterSharedWorker(JSContext* aCx,
|
|||
{
|
||||
AssertIsOnMainThread();
|
||||
MOZ_ASSERT(aSharedWorker);
|
||||
MOZ_ASSERT(IsSharedWorker());
|
||||
MOZ_ASSERT(IsSharedWorker() || IsServiceWorker());
|
||||
MOZ_ASSERT(!mSharedWorkers.Get(aSharedWorker->Serial()));
|
||||
|
||||
nsRefPtr<MessagePortRunnable> runnable =
|
||||
new MessagePortRunnable(ParentAsWorkerPrivate(), aSharedWorker->Serial(),
|
||||
true);
|
||||
if (!runnable->Dispatch(aCx)) {
|
||||
return false;
|
||||
if (IsSharedWorker()) {
|
||||
nsRefPtr<MessagePortRunnable> runnable =
|
||||
new MessagePortRunnable(ParentAsWorkerPrivate(), aSharedWorker->Serial(),
|
||||
true);
|
||||
if (!runnable->Dispatch(aCx)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
mSharedWorkers.Put(aSharedWorker->Serial(), aSharedWorker);
|
||||
|
@ -3063,7 +3065,7 @@ WorkerPrivateParent<Derived>::UnregisterSharedWorker(
|
|||
{
|
||||
AssertIsOnMainThread();
|
||||
MOZ_ASSERT(aSharedWorker);
|
||||
MOZ_ASSERT(IsSharedWorker());
|
||||
MOZ_ASSERT(IsSharedWorker() || IsServiceWorker());
|
||||
MOZ_ASSERT(mSharedWorkers.Get(aSharedWorker->Serial()));
|
||||
|
||||
nsRefPtr<MessagePortRunnable> runnable =
|
||||
|
@ -3241,7 +3243,7 @@ WorkerPrivateParent<Derived>::GetAllSharedWorkers(
|
|||
nsTArray<nsRefPtr<SharedWorker>>& aSharedWorkers)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
MOZ_ASSERT(IsSharedWorker());
|
||||
MOZ_ASSERT(IsSharedWorker() || IsServiceWorker());
|
||||
|
||||
struct Helper
|
||||
{
|
||||
|
@ -3274,7 +3276,7 @@ WorkerPrivateParent<Derived>::CloseSharedWorkersForWindow(
|
|||
nsPIDOMWindow* aWindow)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
MOZ_ASSERT(IsSharedWorker());
|
||||
MOZ_ASSERT(IsSharedWorker() || IsServiceWorker());
|
||||
MOZ_ASSERT(aWindow);
|
||||
|
||||
struct Closure
|
||||
|
@ -3327,7 +3329,7 @@ WorkerPrivateParent<Derived>::WorkerScriptLoaded()
|
|||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
if (IsSharedWorker()) {
|
||||
if (IsSharedWorker() || IsServiceWorker()) {
|
||||
// No longer need to hold references to the window or document we came from.
|
||||
mLoadInfo.mWindow = nullptr;
|
||||
mLoadInfo.mScriptContext = nullptr;
|
||||
|
@ -3561,8 +3563,8 @@ WorkerPrivate::WorkerPrivate(JSContext* aCx,
|
|||
, mPRThread(nullptr)
|
||||
#endif
|
||||
{
|
||||
MOZ_ASSERT_IF(IsSharedWorker(), !aSharedWorkerName.IsVoid());
|
||||
MOZ_ASSERT_IF(!IsSharedWorker(), aSharedWorkerName.IsEmpty());
|
||||
MOZ_ASSERT_IF(!IsDedicatedWorker(), !aSharedWorkerName.IsVoid());
|
||||
MOZ_ASSERT_IF(IsDedicatedWorker(), aSharedWorkerName.IsEmpty());
|
||||
|
||||
if (aParent) {
|
||||
aParent->AssertIsOnWorkerThread();
|
||||
|
@ -3649,9 +3651,9 @@ WorkerPrivate::Constructor(const GlobalObject& aGlobal,
|
|||
|
||||
JSContext* cx = aGlobal.GetContext();
|
||||
|
||||
MOZ_ASSERT_IF(aWorkerType == WorkerTypeShared,
|
||||
MOZ_ASSERT_IF(aWorkerType != WorkerTypeDedicated,
|
||||
!aSharedWorkerName.IsVoid());
|
||||
MOZ_ASSERT_IF(aWorkerType != WorkerTypeShared,
|
||||
MOZ_ASSERT_IF(aWorkerType == WorkerTypeDedicated,
|
||||
aSharedWorkerName.IsEmpty());
|
||||
|
||||
Maybe<LoadInfo> stackLoadInfo;
|
||||
|
|
|
@ -62,6 +62,13 @@ class WorkerGlobalScope;
|
|||
class WorkerPrivate;
|
||||
class WorkerRunnable;
|
||||
|
||||
enum WorkerType
|
||||
{
|
||||
WorkerTypeDedicated,
|
||||
WorkerTypeShared,
|
||||
WorkerTypeService
|
||||
};
|
||||
|
||||
// SharedMutex is a small wrapper around an (internal) reference-counted Mutex
|
||||
// object. It exists to avoid changing a lot of code to use Mutex* instead of
|
||||
// Mutex&.
|
||||
|
@ -194,12 +201,6 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
enum WorkerType
|
||||
{
|
||||
WorkerTypeDedicated,
|
||||
WorkerTypeShared
|
||||
};
|
||||
|
||||
protected:
|
||||
typedef mozilla::ErrorResult ErrorResult;
|
||||
|
||||
|
@ -638,7 +639,7 @@ public:
|
|||
}
|
||||
|
||||
// The ability to be a chrome worker is orthogonal to the type of
|
||||
// worker [Dedicated|Shared].
|
||||
// worker [Dedicated|Shared|Service].
|
||||
bool
|
||||
IsChromeWorker() const
|
||||
{
|
||||
|
@ -657,6 +658,12 @@ public:
|
|||
return mWorkerType == WorkerTypeShared;
|
||||
}
|
||||
|
||||
bool
|
||||
IsServiceWorker() const
|
||||
{
|
||||
return mWorkerType == WorkerTypeService;
|
||||
}
|
||||
|
||||
const nsCString&
|
||||
SharedWorkerName() const
|
||||
{
|
||||
|
|
|
@ -285,7 +285,7 @@ GLContext::GLContext(const SurfaceCaps& caps,
|
|||
mNeedsTextureSizeChecks(false),
|
||||
mWorkAroundDriverBugs(true)
|
||||
{
|
||||
mOwningThread = NS_GetCurrentThread();
|
||||
mOwningThreadId = PlatformThread::CurrentId();
|
||||
}
|
||||
|
||||
GLContext::~GLContext() {
|
||||
|
@ -2108,20 +2108,7 @@ GLContext::IsOffscreenSizeAllowed(const IntSize& aSize) const {
|
|||
bool
|
||||
GLContext::IsOwningThreadCurrent()
|
||||
{
|
||||
return NS_GetCurrentThread() == mOwningThread;
|
||||
}
|
||||
|
||||
void
|
||||
GLContext::DispatchToOwningThread(nsIRunnable *event)
|
||||
{
|
||||
// Before dispatching, we need to ensure we're not in the middle of
|
||||
// shutting down. Dispatching runnables in the middle of shutdown
|
||||
// (that is, when the main thread is no longer get-able) can cause them
|
||||
// to leak. See Bug 741319, and Bug 744115.
|
||||
nsCOMPtr<nsIThread> mainThread;
|
||||
if (NS_SUCCEEDED(NS_GetMainThread(getter_AddRefs(mainThread)))) {
|
||||
mOwningThread->Dispatch(event, NS_DISPATCH_NORMAL);
|
||||
}
|
||||
return PlatformThread::CurrentId() == mOwningThreadId;
|
||||
}
|
||||
|
||||
GLBlitHelper*
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include "SurfaceTypes.h"
|
||||
#include "GLScreenBuffer.h"
|
||||
#include "GLContextSymbols.h"
|
||||
#include "base/platform_thread.h" // for PlatformThreadId
|
||||
#include "mozilla/GenericRefCounted.h"
|
||||
#include "mozilla/Scoped.h"
|
||||
#include "gfx2DGlue.h"
|
||||
|
@ -2569,7 +2570,6 @@ public:
|
|||
* executing thread.
|
||||
*/
|
||||
bool IsOwningThreadCurrent();
|
||||
void DispatchToOwningThread(nsIRunnable *event);
|
||||
|
||||
static void PlatformStartup();
|
||||
|
||||
|
@ -2733,8 +2733,8 @@ public:
|
|||
protected:
|
||||
nsRefPtr<GLContext> mSharedContext;
|
||||
|
||||
// The thread on which this context was created.
|
||||
nsCOMPtr<nsIThread> mOwningThread;
|
||||
// The thread id which this context was created.
|
||||
PlatformThreadId mOwningThreadId;
|
||||
|
||||
GLContextSymbols mSymbols;
|
||||
|
||||
|
|
|
@ -1015,6 +1015,9 @@ EraseLayerState(uint64_t aId)
|
|||
CompositorParent::DeallocateLayerTreeId(uint64_t aId)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
// Here main thread notifies compositor to remove an element from
|
||||
// sIndirectLayerTrees. This removed element might be queried soon.
|
||||
// Checking the elements of sIndirectLayerTrees exist or not before using.
|
||||
CompositorLoop()->PostTask(FROM_HERE,
|
||||
NewRunnableFunction(&EraseLayerState, aId));
|
||||
}
|
||||
|
@ -1236,9 +1239,15 @@ CrossProcessCompositorParent::AllocPLayerTransactionParent(const nsTArray<Layers
|
|||
{
|
||||
MOZ_ASSERT(aId != 0);
|
||||
|
||||
if (sIndirectLayerTrees[aId].mLayerManager) {
|
||||
sIndirectLayerTrees[aId].mCrossProcessParent = this;
|
||||
LayerManagerComposite* lm = sIndirectLayerTrees[aId].mLayerManager;
|
||||
CompositorParent::LayerTreeState* state = nullptr;
|
||||
LayerTreeMap::iterator itr = sIndirectLayerTrees.find(aId);
|
||||
if (sIndirectLayerTrees.end() != itr) {
|
||||
state = &itr->second;
|
||||
}
|
||||
|
||||
if (state && state->mLayerManager) {
|
||||
state->mCrossProcessParent = this;
|
||||
LayerManagerComposite* lm = state->mLayerManager;
|
||||
*aTextureFactoryIdentifier = lm->GetCompositor()->GetTextureFactoryIdentifier();
|
||||
*aSuccess = true;
|
||||
LayerTransactionParent* p = new LayerTransactionParent(lm, this, aId);
|
||||
|
@ -1267,7 +1276,13 @@ CrossProcessCompositorParent::DeallocPLayerTransactionParent(PLayerTransactionPa
|
|||
bool
|
||||
CrossProcessCompositorParent::RecvNotifyChildCreated(const uint64_t& child)
|
||||
{
|
||||
sIndirectLayerTrees[child].mParent->NotifyChildCreated(child);
|
||||
const CompositorParent::LayerTreeState* state = CompositorParent::GetIndirectShadowTree(child);
|
||||
if (!state) {
|
||||
return false;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(state->mParent);
|
||||
state->mParent->NotifyChildCreated(child);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1281,9 +1296,13 @@ CrossProcessCompositorParent::ShadowLayersUpdated(
|
|||
uint64_t id = aLayerTree->GetId();
|
||||
|
||||
MOZ_ASSERT(id != 0);
|
||||
MOZ_ASSERT(sIndirectLayerTrees[id].mParent);
|
||||
|
||||
sIndirectLayerTrees[id].mParent->ScheduleRotationOnCompositorThread(aTargetConfig, aIsFirstPaint);
|
||||
const CompositorParent::LayerTreeState* state = CompositorParent::GetIndirectShadowTree(id);
|
||||
if (!state) {
|
||||
return;
|
||||
}
|
||||
MOZ_ASSERT(state->mParent);
|
||||
state->mParent->ScheduleRotationOnCompositorThread(aTargetConfig, aIsFirstPaint);
|
||||
|
||||
Layer* shadowRoot = aLayerTree->GetRoot();
|
||||
if (shadowRoot) {
|
||||
|
@ -1291,7 +1310,7 @@ CrossProcessCompositorParent::ShadowLayersUpdated(
|
|||
}
|
||||
UpdateIndirectTree(id, shadowRoot, aTargetConfig);
|
||||
|
||||
sIndirectLayerTrees[id].mParent->NotifyShadowTreeTransaction(id, aIsFirstPaint, aScheduleComposite);
|
||||
state->mParent->NotifyShadowTreeTransaction(id, aIsFirstPaint, aScheduleComposite);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1308,7 +1327,13 @@ CrossProcessCompositorParent::SetTestSampleTime(
|
|||
{
|
||||
uint64_t id = aLayerTree->GetId();
|
||||
MOZ_ASSERT(id != 0);
|
||||
return sIndirectLayerTrees[id].mParent->SetTestSampleTime(aLayerTree, aTime);
|
||||
const CompositorParent::LayerTreeState* state = CompositorParent::GetIndirectShadowTree(id);
|
||||
if (!state) {
|
||||
return false;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(state->mParent);
|
||||
return state->mParent->SetTestSampleTime(aLayerTree, aTime);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1316,14 +1341,26 @@ CrossProcessCompositorParent::LeaveTestMode(LayerTransactionParent* aLayerTree)
|
|||
{
|
||||
uint64_t id = aLayerTree->GetId();
|
||||
MOZ_ASSERT(id != 0);
|
||||
sIndirectLayerTrees[id].mParent->LeaveTestMode(aLayerTree);
|
||||
const CompositorParent::LayerTreeState* state = CompositorParent::GetIndirectShadowTree(id);
|
||||
if (!state) {
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(state->mParent);
|
||||
state->mParent->LeaveTestMode(aLayerTree);
|
||||
}
|
||||
|
||||
AsyncCompositionManager*
|
||||
CrossProcessCompositorParent::GetCompositionManager(LayerTransactionParent* aLayerTree)
|
||||
{
|
||||
uint64_t id = aLayerTree->GetId();
|
||||
return sIndirectLayerTrees[id].mParent->GetCompositionManager(aLayerTree);
|
||||
const CompositorParent::LayerTreeState* state = CompositorParent::GetIndirectShadowTree(id);
|
||||
if (!state) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(state->mParent);
|
||||
return state->mParent->GetCompositionManager(aLayerTree);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -1222,7 +1222,7 @@ const char* gfxFontUtils::gMSFontNameCharsets[] =
|
|||
/* [3] ENCODING_ID_MICROSOFT_PRC */ nullptr ,
|
||||
/* [4] ENCODING_ID_MICROSOFT_BIG5 */ "Big5" ,
|
||||
/* [5] ENCODING_ID_MICROSOFT_WANSUNG */ nullptr ,
|
||||
/* [6] ENCODING_ID_MICROSOFT_JOHAB */ "x-johab" ,
|
||||
/* [6] ENCODING_ID_MICROSOFT_JOHAB */ nullptr ,
|
||||
/* [7] reserved */ nullptr ,
|
||||
/* [8] reserved */ nullptr ,
|
||||
/* [9] reserved */ nullptr ,
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
#include <windows.h>
|
||||
#include <hidsdi.h>
|
||||
#include <stdio.h>
|
||||
#include <Xinput.h>
|
||||
#include <xinput.h>
|
||||
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsIObserver.h"
|
||||
|
@ -745,7 +745,7 @@ WindowsGamepadService::GetRawGamepad(HANDLE handle)
|
|||
}
|
||||
}
|
||||
|
||||
gamepad.numAxes = std::min(axes.Length(), kMaxAxes);
|
||||
gamepad.numAxes = std::min<size_t>(axes.Length(), kMaxAxes);
|
||||
for (unsigned i = 0; i < gamepad.numAxes; i++) {
|
||||
if (i >= kMaxAxes) {
|
||||
break;
|
||||
|
|
|
@ -73,8 +73,11 @@ interface nsIScriptableUnicodeConverter : nsISupports
|
|||
/**
|
||||
* Internal use
|
||||
*
|
||||
* When this attribute is set, all charsets may be accessed but only
|
||||
* by Gecko-canonical name.
|
||||
* When this attribute is set, all encodings may be accessed. Alias
|
||||
* resolution is not performed for non-Encoding Standard encodings.
|
||||
* MailNews callers should perform alias resolution first (e.g. using
|
||||
* nsICharsetConverterManager::getCharsetAlias()) and use the result
|
||||
* with this API.
|
||||
*/
|
||||
attribute boolean isInternal;
|
||||
};
|
||||
|
|
|
@ -58,9 +58,7 @@ UNIFIED_SOURCES += [
|
|||
UNIFIED_SOURCES += [
|
||||
'../ucvko/nsCP949ToUnicode.cpp',
|
||||
'../ucvko/nsISO2022KRToUnicode.cpp',
|
||||
'../ucvko/nsJohabToUnicode.cpp',
|
||||
'../ucvko/nsUnicodeToCP949.cpp',
|
||||
'../ucvko/nsUnicodeToJohab.cpp',
|
||||
]
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
|
@ -110,7 +108,6 @@ UNIFIED_SOURCES += [
|
|||
'../ucvlatin/nsMacIcelandicToUnicode.cpp',
|
||||
'../ucvlatin/nsMacRomanianToUnicode.cpp',
|
||||
'../ucvlatin/nsMacTurkishToUnicode.cpp',
|
||||
'../ucvlatin/nsT61ToUnicode.cpp',
|
||||
'../ucvlatin/nsTCVN5712ToUnicode.cpp',
|
||||
'../ucvlatin/nsTIS620ToUnicode.cpp',
|
||||
'../ucvlatin/nsUnicodeToARMSCII8.cpp',
|
||||
|
@ -159,7 +156,6 @@ UNIFIED_SOURCES += [
|
|||
'../ucvlatin/nsUnicodeToMacIcelandic.cpp',
|
||||
'../ucvlatin/nsUnicodeToMacRomanian.cpp',
|
||||
'../ucvlatin/nsUnicodeToMacTurkish.cpp',
|
||||
'../ucvlatin/nsUnicodeToT61.cpp',
|
||||
'../ucvlatin/nsUnicodeToTCVN5712.cpp',
|
||||
'../ucvlatin/nsUnicodeToTIS620.cpp',
|
||||
'../ucvlatin/nsUnicodeToUserDefined.cpp',
|
||||
|
|
|
@ -256,20 +256,47 @@ nsresult
|
|||
nsScriptableUnicodeConverter::InitConverter()
|
||||
{
|
||||
mEncoder = nullptr;
|
||||
mDecoder = nullptr;
|
||||
|
||||
nsAutoCString encoding;
|
||||
if (mIsInternal) {
|
||||
encoding.Assign(mCharset);
|
||||
// Better have a valid encoding name at this point! Otherwise, we'll
|
||||
// crash with MOZ_ASSERT in debug builds. However, since this code
|
||||
// might be called by severely misguided extensions in opt builds, the
|
||||
// error condition is tested for below.
|
||||
mEncoder = EncodingUtils::EncoderForEncoding(mCharset);
|
||||
mDecoder = EncodingUtils::DecoderForEncoding(mCharset);
|
||||
if (!mEncoder || !mDecoder) {
|
||||
// For compatibility with legacy extensions, let's try to see if the label
|
||||
// happens to be ASCII-case-insensitively an encoding. This should allow
|
||||
// for things like "utf-7" and "x-Mac-Hebrew".
|
||||
nsAutoCString contractId;
|
||||
nsAutoCString label(mCharset);
|
||||
EncodingUtils::TrimSpaceCharacters(label);
|
||||
// Let's try in lower case if we didn't get an decoder. E.g. x-mac-ce
|
||||
// and x-imap4-modified-utf7 are all lower case.
|
||||
ToLowerCase(label);
|
||||
if (label.EqualsLiteral("replacement")) {
|
||||
// reject "replacement"
|
||||
return NS_ERROR_UCONV_NOCONV;
|
||||
}
|
||||
} else {
|
||||
contractId.AssignLiteral(NS_UNICODEENCODER_CONTRACTID_BASE);
|
||||
contractId.Append(label);
|
||||
mEncoder = do_CreateInstance(contractId.get());
|
||||
contractId.AssignLiteral(NS_UNICODEDECODER_CONTRACTID_BASE);
|
||||
contractId.Append(label);
|
||||
mDecoder = do_CreateInstance(contractId.get());
|
||||
if (!mDecoder) {
|
||||
// The old code seemed to want both a decoder and an encoder. Since some
|
||||
// internal encodings will be decoder-only in the future, let's relax
|
||||
// this. Note that the other methods check mEncoder for null anyway.
|
||||
// Let's try the upper case. E.g. UTF-7 and ISO-2022-CN have upper
|
||||
// case Gecko-canonical names.
|
||||
ToUpperCase(label);
|
||||
contractId.AssignLiteral(NS_UNICODEENCODER_CONTRACTID_BASE);
|
||||
contractId.Append(label);
|
||||
mEncoder = do_CreateInstance(contractId.get());
|
||||
contractId.AssignLiteral(NS_UNICODEDECODER_CONTRACTID_BASE);
|
||||
contractId.Append(label);
|
||||
mDecoder = do_CreateInstance(contractId.get());
|
||||
// If still no decoder, use the normal non-internal case below.
|
||||
}
|
||||
}
|
||||
|
||||
if (!mDecoder) {
|
||||
if (!EncodingUtils::FindEncodingForLabelNoReplacement(mCharset, encoding)) {
|
||||
return NS_ERROR_UCONV_NOCONV;
|
||||
}
|
||||
|
@ -285,6 +312,10 @@ nsScriptableUnicodeConverter::InitConverter()
|
|||
mDecoder->SetInputErrorBehavior(nsIUnicodeDecoder::kOnError_Signal);
|
||||
}
|
||||
|
||||
if (!mEncoder) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return mEncoder->SetOutputErrorBehavior(nsIUnicodeEncoder::kOnError_Replace,
|
||||
nullptr,
|
||||
(char16_t)'?');
|
||||
|
|
|
@ -73,7 +73,6 @@
|
|||
#include "nsVISCIIToUnicode.h"
|
||||
#include "nsVPSToUnicode.h"
|
||||
#include "nsUTF16ToUnicode.h"
|
||||
#include "nsT61ToUnicode.h"
|
||||
#include "nsUserDefinedToUnicode.h"
|
||||
#include "nsUnicodeToAscii.h"
|
||||
#include "nsUnicodeToISO88592.h"
|
||||
|
@ -120,7 +119,6 @@
|
|||
#include "nsUnicodeToVISCII.h"
|
||||
#include "nsUnicodeToVPS.h"
|
||||
#include "nsUnicodeToUTF16.h"
|
||||
#include "nsUnicodeToT61.h"
|
||||
#include "nsUnicodeToUserDefined.h"
|
||||
#include "nsMacArabicToUnicode.h"
|
||||
#include "nsMacDevanagariToUnicode.h"
|
||||
|
@ -178,8 +176,6 @@
|
|||
// ucvko
|
||||
#include "nsUCvKOCID.h"
|
||||
#include "nsUCvKODll.h"
|
||||
#include "nsJohabToUnicode.h"
|
||||
#include "nsUnicodeToJohab.h"
|
||||
#include "nsCP949ToUnicode.h"
|
||||
#include "nsUnicodeToCP949.h"
|
||||
#include "nsISO2022KRToUnicode.h"
|
||||
|
@ -250,7 +246,6 @@ NS_UCONV_REG_UNREG("x-viet-vps", NS_VPSTOUNICODE_CID, NS_UNICODETOVPS_CID)
|
|||
NS_UCONV_REG_UNREG("UTF-16", NS_UTF16TOUNICODE_CID, NS_UNICODETOUTF16_CID)
|
||||
NS_UCONV_REG_UNREG("UTF-16BE", NS_UTF16BETOUNICODE_CID, NS_UNICODETOUTF16BE_CID)
|
||||
NS_UCONV_REG_UNREG("UTF-16LE", NS_UTF16LETOUNICODE_CID, NS_UNICODETOUTF16LE_CID)
|
||||
NS_UCONV_REG_UNREG("T.61-8bit", NS_T61TOUNICODE_CID, NS_UNICODETOT61_CID)
|
||||
NS_UCONV_REG_UNREG("x-user-defined", NS_USERDEFINEDTOUNICODE_CID, NS_UNICODETOUSERDEFINED_CID)
|
||||
NS_UCONV_REG_UNREG("x-mac-arabic" , NS_MACARABICTOUNICODE_CID, NS_UNICODETOMACARABIC_CID)
|
||||
NS_UCONV_REG_UNREG("x-mac-devanagari" , NS_MACDEVANAGARITOUNICODE_CID, NS_UNICODETOMACDEVANAGARI_CID)
|
||||
|
@ -285,7 +280,6 @@ NS_UCONV_REG_UNREG_ENCODER("hkscs-1" , NS_UNICODETOHKSCS_CID)
|
|||
|
||||
// ucvko
|
||||
NS_UCONV_REG_UNREG("EUC-KR", NS_EUCKRTOUNICODE_CID, NS_UNICODETOEUCKR_CID)
|
||||
NS_UCONV_REG_UNREG("x-johab", NS_JOHABTOUNICODE_CID, NS_UNICODETOJOHAB_CID)
|
||||
NS_UCONV_REG_UNREG_DECODER("ISO-2022-KR", NS_ISO2022KRTOUNICODE_CID)
|
||||
|
||||
// ucvcn
|
||||
|
@ -445,10 +439,6 @@ const uint16_t g_HangulNullMapping[] ={
|
|||
0x0001, 0x0004, 0x0005, 0x0008, 0x0000, 0xAC00, 0xD7A3, 0xAC00
|
||||
};
|
||||
|
||||
const uint16_t g_ufJohabJamoMapping[] ={
|
||||
#include "johabjamo.uf"
|
||||
};
|
||||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsTextToSubURI)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsUTF8ConverterService)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsConverterInputStream)
|
||||
|
@ -516,7 +506,6 @@ NS_DEFINE_NAMED_CID(NS_VPSTOUNICODE_CID);
|
|||
NS_DEFINE_NAMED_CID(NS_UTF16TOUNICODE_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_UTF16BETOUNICODE_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_UTF16LETOUNICODE_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_T61TOUNICODE_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_USERDEFINEDTOUNICODE_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_MACARABICTOUNICODE_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_MACDEVANAGARITOUNICODE_CID);
|
||||
|
@ -571,7 +560,6 @@ NS_DEFINE_NAMED_CID(NS_UNICODETOVPS_CID);
|
|||
NS_DEFINE_NAMED_CID(NS_UNICODETOUTF16BE_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_UNICODETOUTF16LE_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_UNICODETOUTF16_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_UNICODETOT61_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_UNICODETOUSERDEFINED_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_UNICODETOMACARABIC_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_UNICODETOMACDEVANAGARI_CID);
|
||||
|
@ -607,8 +595,6 @@ NS_DEFINE_NAMED_CID(NS_UNICODETOHKSCS_CID);
|
|||
NS_DEFINE_NAMED_CID(NS_BIG5HKSCSTOUNICODE_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_EUCKRTOUNICODE_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_UNICODETOEUCKR_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_JOHABTOUNICODE_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_UNICODETOJOHAB_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_ISO2022KRTOUNICODE_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_GB2312TOUNICODE_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_UNICODETOGB2312_CID);
|
||||
|
@ -682,7 +668,6 @@ static const mozilla::Module::CIDEntry kUConvCIDs[] = {
|
|||
{ &kNS_UTF16TOUNICODE_CID, false, nullptr, nsUTF16ToUnicodeConstructor },
|
||||
{ &kNS_UTF16BETOUNICODE_CID, false, nullptr, nsUTF16BEToUnicodeConstructor },
|
||||
{ &kNS_UTF16LETOUNICODE_CID, false, nullptr, nsUTF16LEToUnicodeConstructor },
|
||||
{ &kNS_T61TOUNICODE_CID, false, nullptr, nsT61ToUnicodeConstructor },
|
||||
{ &kNS_USERDEFINEDTOUNICODE_CID, false, nullptr, nsUserDefinedToUnicodeConstructor },
|
||||
{ &kNS_MACARABICTOUNICODE_CID, false, nullptr, nsMacArabicToUnicodeConstructor },
|
||||
{ &kNS_MACDEVANAGARITOUNICODE_CID, false, nullptr, nsMacDevanagariToUnicodeConstructor },
|
||||
|
@ -737,7 +722,6 @@ static const mozilla::Module::CIDEntry kUConvCIDs[] = {
|
|||
{ &kNS_UNICODETOUTF16BE_CID, false, nullptr, nsUnicodeToUTF16BEConstructor },
|
||||
{ &kNS_UNICODETOUTF16LE_CID, false, nullptr, nsUnicodeToUTF16LEConstructor },
|
||||
{ &kNS_UNICODETOUTF16_CID, false, nullptr, nsUnicodeToUTF16Constructor },
|
||||
{ &kNS_UNICODETOT61_CID, false, nullptr, nsUnicodeToT61Constructor },
|
||||
{ &kNS_UNICODETOUSERDEFINED_CID, false, nullptr, nsUnicodeToUserDefinedConstructor },
|
||||
{ &kNS_UNICODETOMACARABIC_CID, false, nullptr, nsUnicodeToMacArabicConstructor },
|
||||
{ &kNS_UNICODETOMACDEVANAGARI_CID, false, nullptr, nsUnicodeToMacDevanagariConstructor },
|
||||
|
@ -773,8 +757,6 @@ static const mozilla::Module::CIDEntry kUConvCIDs[] = {
|
|||
{ &kNS_BIG5HKSCSTOUNICODE_CID, false, nullptr, nsBIG5HKSCSToUnicodeConstructor },
|
||||
{ &kNS_EUCKRTOUNICODE_CID, false, nullptr, nsCP949ToUnicodeConstructor },
|
||||
{ &kNS_UNICODETOEUCKR_CID, false, nullptr, nsUnicodeToCP949Constructor },
|
||||
{ &kNS_JOHABTOUNICODE_CID, false, nullptr, nsJohabToUnicodeConstructor },
|
||||
{ &kNS_UNICODETOJOHAB_CID, false, nullptr, nsUnicodeToJohabConstructor },
|
||||
{ &kNS_ISO2022KRTOUNICODE_CID, false, nullptr, nsISO2022KRToUnicodeConstructor },
|
||||
{ &kNS_GB2312TOUNICODE_CID, false, nullptr, nsGB18030ToUnicodeConstructor },
|
||||
{ &kNS_UNICODETOGB2312_CID, false, nullptr, nsUnicodeToGB2312V2Constructor },
|
||||
|
@ -850,7 +832,6 @@ static const mozilla::Module::ContractIDEntry kUConvContracts[] = {
|
|||
{ NS_UNICODEDECODER_CONTRACTID_BASE "UTF-16", &kNS_UTF16TOUNICODE_CID },
|
||||
{ NS_UNICODEDECODER_CONTRACTID_BASE "UTF-16BE", &kNS_UTF16BETOUNICODE_CID },
|
||||
{ NS_UNICODEDECODER_CONTRACTID_BASE "UTF-16LE", &kNS_UTF16LETOUNICODE_CID },
|
||||
{ NS_UNICODEDECODER_CONTRACTID_BASE "T.61-8bit", &kNS_T61TOUNICODE_CID },
|
||||
{ NS_UNICODEDECODER_CONTRACTID_BASE "x-user-defined", &kNS_USERDEFINEDTOUNICODE_CID },
|
||||
{ NS_UNICODEDECODER_CONTRACTID_BASE "x-mac-arabic", &kNS_MACARABICTOUNICODE_CID },
|
||||
{ NS_UNICODEDECODER_CONTRACTID_BASE "x-mac-devanagari", &kNS_MACDEVANAGARITOUNICODE_CID },
|
||||
|
@ -905,7 +886,6 @@ static const mozilla::Module::ContractIDEntry kUConvContracts[] = {
|
|||
{ NS_UNICODEENCODER_CONTRACTID_BASE "UTF-16BE", &kNS_UNICODETOUTF16BE_CID },
|
||||
{ NS_UNICODEENCODER_CONTRACTID_BASE "UTF-16LE", &kNS_UNICODETOUTF16LE_CID },
|
||||
{ NS_UNICODEENCODER_CONTRACTID_BASE "UTF-16", &kNS_UNICODETOUTF16_CID },
|
||||
{ NS_UNICODEENCODER_CONTRACTID_BASE "T.61-8bit", &kNS_UNICODETOT61_CID },
|
||||
{ NS_UNICODEENCODER_CONTRACTID_BASE "x-user-defined", &kNS_UNICODETOUSERDEFINED_CID },
|
||||
{ NS_UNICODEENCODER_CONTRACTID_BASE "x-mac-arabic", &kNS_UNICODETOMACARABIC_CID },
|
||||
{ NS_UNICODEENCODER_CONTRACTID_BASE "x-mac-devanagari", &kNS_UNICODETOMACDEVANAGARI_CID },
|
||||
|
@ -941,8 +921,6 @@ static const mozilla::Module::ContractIDEntry kUConvContracts[] = {
|
|||
{ NS_UNICODEDECODER_CONTRACTID_BASE "Big5-HKSCS", &kNS_BIG5HKSCSTOUNICODE_CID },
|
||||
{ NS_UNICODEDECODER_CONTRACTID_BASE "EUC-KR", &kNS_EUCKRTOUNICODE_CID },
|
||||
{ NS_UNICODEENCODER_CONTRACTID_BASE "EUC-KR", &kNS_UNICODETOEUCKR_CID },
|
||||
{ NS_UNICODEDECODER_CONTRACTID_BASE "x-johab", &kNS_JOHABTOUNICODE_CID },
|
||||
{ NS_UNICODEENCODER_CONTRACTID_BASE "x-johab", &kNS_UNICODETOJOHAB_CID },
|
||||
{ NS_UNICODEDECODER_CONTRACTID_BASE "ISO-2022-KR", &kNS_ISO2022KRTOUNICODE_CID },
|
||||
{ NS_UNICODEDECODER_CONTRACTID_BASE "GB2312", &kNS_GB2312TOUNICODE_CID },
|
||||
{ NS_UNICODEENCODER_CONTRACTID_BASE "GB2312", &kNS_UNICODETOGB2312_CID },
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
// Test case-insensitive internal encoding handling in nsIScriptableUConv
|
||||
|
||||
load('CharsetConversionTests.js');
|
||||
|
||||
const inString = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff";
|
||||
|
||||
const expectedString = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u00c4\ufb1f\u00c7\u00c9\u00d1\u00d6\u00dc\u00e1\u00e0\u00e2\u00e4\u00e3\u00e5\u00e7\u00e9\u00e8\u00ea\u00eb\u00ed\u00ec\u00ee\u00ef\u00f1\u00f3\u00f2\u00f4\u00f6\u00f5\u00fa\u00f9\u00fb\u00fc !\"#$%\u20aa'()*+,-./0123456789:;<=>?\ufffd\u201e\uf89b\uf89c\uf89d\uf89e\u05bc\ufb4b\ufb35\u2026\u00a0\u05b8\u05b7\u05b5\u05b6\u05b4\u2013\u2014\u201c\u201d\u2018\u2019\ufb2a\ufb2b\u05bf\u05b0\u05b2\u05b1\u05bb\u05b9\ufffd\u05b3\u05d0\u05d1\u05d2\u05d3\u05d4\u05d5\u05d6\u05d7\u05d8\u05d9\u05da\u05db\u05dc\u05dd\u05de\u05df\u05e0\u05e1\u05e2\u05e3\u05e4\u05e5\u05e6\u05e7\u05e8\u05e9\u05ea}]{[|";
|
||||
|
||||
const aliases = [ "x-Mac-Hebrew" ];
|
||||
|
||||
function run_test() {
|
||||
testDecodeAliasesInternal();
|
||||
}
|
|
@ -145,3 +145,4 @@ support-files =
|
|||
[test_encode_x_mac_ukrainian.js]
|
||||
[test_utf8_illegals.js]
|
||||
[test_input_stream.js]
|
||||
[test_bug1008832.js]
|
||||
|
|
|
@ -1,79 +0,0 @@
|
|||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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/. */
|
||||
/*========================================================
|
||||
This is a Generated file. Please don't edit it.
|
||||
|
||||
The tool which used to generate this file is called umaptable.
|
||||
You can find this tool under mozilla/intl/uconv/tools/umaptable.c.
|
||||
If you have any problem of this file. Please contact
|
||||
Netscape Client International Team or
|
||||
ftang@netscape <Frank Tang>
|
||||
|
||||
Note manually added by Jungshik Shin <jshin@mailaps.org>
|
||||
|
||||
The table was generated by filtering JOHAB.TXT at
|
||||
http://jshin.net/faq/JOHAB.TXT.gz
|
||||
|
||||
gunzip -c JOHAB.TXT.gz | egrep '^0x.... +0x31(3[1-F]|[45][0-F]|6[0-3])' \
|
||||
| umaptable -uf
|
||||
|
||||
Table in Debug form
|
||||
Begin of Item 0000
|
||||
Format 0
|
||||
srcBegin = 313A
|
||||
srcEnd = 3140
|
||||
destBegin = 844A
|
||||
End of Item 0000
|
||||
|
||||
Begin of Item 0001
|
||||
Format 1
|
||||
srcBegin = 3131
|
||||
srcEnd = 3163
|
||||
mappingOffset = 0000
|
||||
Mapping =
|
||||
8841 8C41 8444 9041 8446 8447 9441 9841
|
||||
9C41 FFFD FFFD FFFD FFFD FFFD FFFD FFFD
|
||||
A041 A441 A841 8454 AC41 B041 B441 B841
|
||||
BC41 C041 C441 C841 CC41 D041 8461 8481
|
||||
84A1 84C1 84E1 8541 8561 8581 85A1 85C1
|
||||
85E1 8641 8661 8681 86A1 86C1 86E1 8741
|
||||
8761 8781 87A1
|
||||
End of Item 0001
|
||||
|
||||
========================================================*/
|
||||
/* Offset=0x0000 ItemOfList */
|
||||
0x0002,
|
||||
/*-------------------------------------------------------*/
|
||||
/* Offset=0x0001 offsetToFormatArray */
|
||||
0x0004,
|
||||
/*-------------------------------------------------------*/
|
||||
/* Offset=0x0002 offsetToMapCellArray */
|
||||
0x0005,
|
||||
/*-------------------------------------------------------*/
|
||||
/* Offset=0x0003 offsetToMappingTable */
|
||||
0x000B,
|
||||
/*-------------------------------------------------------*/
|
||||
/* Offset=0x0004 Start of Format Array */
|
||||
/* Total of Format 0 : 0x0001 */
|
||||
/* Total of Format 1 : 0x0001 */
|
||||
/* Total of Format 2 : 0x0000 */
|
||||
/* Total of Format 3 : 0x0000 */
|
||||
|
||||
0x0010,
|
||||
/*-------------------------------------------------------*/
|
||||
/* Offset=0x0005 Start of MapCell Array */
|
||||
/* 0000 */ 0x313A, 0x3140, 0x844A,
|
||||
/* 0001 */ 0x3131, 0x3163, 0x0000,
|
||||
/*-------------------------------------------------------*/
|
||||
/* Offset=0x000B Start of MappingTable */
|
||||
|
||||
/* 0000 */ 0x8841, 0x8C41, 0x8444, 0x9041, 0x8446, 0x8447, 0x9441, 0x9841,
|
||||
/* 0008 */ 0x9C41, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
|
||||
/* 0010 */ 0xA041, 0xA441, 0xA841, 0x8454, 0xAC41, 0xB041, 0xB441, 0xB841,
|
||||
/* 0018 */ 0xBC41, 0xC041, 0xC441, 0xC841, 0xCC41, 0xD041, 0x8461, 0x8481,
|
||||
/* 0020 */ 0x84A1, 0x84C1, 0x84E1, 0x8541, 0x8561, 0x8581, 0x85A1, 0x85C1,
|
||||
/* 0028 */ 0x85E1, 0x8641, 0x8661, 0x8681, 0x86A1, 0x86C1, 0x86E1, 0x8741,
|
||||
/* 0030 */ 0x8761, 0x8781, 0x87A1,
|
||||
/* End of table Total Length = 0x003E * 2 */
|
|
@ -1,355 +0,0 @@
|
|||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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/. */
|
||||
/*========================================================
|
||||
This is a Generated file. Please don't edit it.
|
||||
|
||||
The tool which used to generate this file is called umaptable.
|
||||
You can find this tool under mozilla/intl/uconv/tools/umaptable.c.
|
||||
If you have any problem of this file. Please contact
|
||||
Netscape Client International Team or
|
||||
ftang@netscape <Frank Tang>
|
||||
|
||||
Note manually added by Jungshik Shin <jshin@mailaps.org>
|
||||
|
||||
The table was generated by filtering JOHAB.TXT at
|
||||
http://jshin.net/faq/JOHAB.TXT.gz
|
||||
|
||||
gunzip -c JOHAB.TXT.gz | egrep '^0x.... +0x31(3[1-F]|[45][0-F]|6[0-3])' \
|
||||
| umaptable -ut
|
||||
|
||||
Table in Debug form
|
||||
Begin of Item 0000
|
||||
Format 0
|
||||
srcBegin = 844A
|
||||
srcEnd = 8450
|
||||
destBegin = 313A
|
||||
End of Item 0000
|
||||
|
||||
Begin of Item 0001
|
||||
Format 1
|
||||
srcBegin = 8444
|
||||
srcEnd = 8447
|
||||
mappingOffset = 0000
|
||||
Mapping =
|
||||
3133 FFFD 3135 3136
|
||||
End of Item 0001
|
||||
|
||||
Begin of Item 0002
|
||||
Format 2
|
||||
srcBegin = 8454
|
||||
destBegin = 3144
|
||||
End of Item 0002
|
||||
|
||||
Begin of Item 0003
|
||||
Format 2
|
||||
srcBegin = 8461
|
||||
destBegin = 314F
|
||||
End of Item 0003
|
||||
|
||||
Begin of Item 0004
|
||||
Format 2
|
||||
srcBegin = 8481
|
||||
destBegin = 3150
|
||||
End of Item 0004
|
||||
|
||||
Begin of Item 0005
|
||||
Format 2
|
||||
srcBegin = 84A1
|
||||
destBegin = 3151
|
||||
End of Item 0005
|
||||
|
||||
Begin of Item 0006
|
||||
Format 2
|
||||
srcBegin = 84C1
|
||||
destBegin = 3152
|
||||
End of Item 0006
|
||||
|
||||
Begin of Item 0007
|
||||
Format 2
|
||||
srcBegin = 84E1
|
||||
destBegin = 3153
|
||||
End of Item 0007
|
||||
|
||||
Begin of Item 0008
|
||||
Format 2
|
||||
srcBegin = 8541
|
||||
destBegin = 3154
|
||||
End of Item 0008
|
||||
|
||||
Begin of Item 0009
|
||||
Format 2
|
||||
srcBegin = 8561
|
||||
destBegin = 3155
|
||||
End of Item 0009
|
||||
|
||||
Begin of Item 000A
|
||||
Format 2
|
||||
srcBegin = 8581
|
||||
destBegin = 3156
|
||||
End of Item 000A
|
||||
|
||||
Begin of Item 000B
|
||||
Format 2
|
||||
srcBegin = 85A1
|
||||
destBegin = 3157
|
||||
End of Item 000B
|
||||
|
||||
Begin of Item 000C
|
||||
Format 2
|
||||
srcBegin = 85C1
|
||||
destBegin = 3158
|
||||
End of Item 000C
|
||||
|
||||
Begin of Item 000D
|
||||
Format 2
|
||||
srcBegin = 85E1
|
||||
destBegin = 3159
|
||||
End of Item 000D
|
||||
|
||||
Begin of Item 000E
|
||||
Format 2
|
||||
srcBegin = 8641
|
||||
destBegin = 315A
|
||||
End of Item 000E
|
||||
|
||||
Begin of Item 000F
|
||||
Format 2
|
||||
srcBegin = 8661
|
||||
destBegin = 315B
|
||||
End of Item 000F
|
||||
|
||||
Begin of Item 0010
|
||||
Format 2
|
||||
srcBegin = 8681
|
||||
destBegin = 315C
|
||||
End of Item 0010
|
||||
|
||||
Begin of Item 0011
|
||||
Format 2
|
||||
srcBegin = 86A1
|
||||
destBegin = 315D
|
||||
End of Item 0011
|
||||
|
||||
Begin of Item 0012
|
||||
Format 2
|
||||
srcBegin = 86C1
|
||||
destBegin = 315E
|
||||
End of Item 0012
|
||||
|
||||
Begin of Item 0013
|
||||
Format 2
|
||||
srcBegin = 86E1
|
||||
destBegin = 315F
|
||||
End of Item 0013
|
||||
|
||||
Begin of Item 0014
|
||||
Format 2
|
||||
srcBegin = 8741
|
||||
destBegin = 3160
|
||||
End of Item 0014
|
||||
|
||||
Begin of Item 0015
|
||||
Format 2
|
||||
srcBegin = 8761
|
||||
destBegin = 3161
|
||||
End of Item 0015
|
||||
|
||||
Begin of Item 0016
|
||||
Format 2
|
||||
srcBegin = 8781
|
||||
destBegin = 3162
|
||||
End of Item 0016
|
||||
|
||||
Begin of Item 0017
|
||||
Format 2
|
||||
srcBegin = 87A1
|
||||
destBegin = 3163
|
||||
End of Item 0017
|
||||
|
||||
Begin of Item 0018
|
||||
Format 2
|
||||
srcBegin = 8841
|
||||
destBegin = 3131
|
||||
End of Item 0018
|
||||
|
||||
Begin of Item 0019
|
||||
Format 2
|
||||
srcBegin = 8C41
|
||||
destBegin = 3132
|
||||
End of Item 0019
|
||||
|
||||
Begin of Item 001A
|
||||
Format 2
|
||||
srcBegin = 9041
|
||||
destBegin = 3134
|
||||
End of Item 001A
|
||||
|
||||
Begin of Item 001B
|
||||
Format 2
|
||||
srcBegin = 9441
|
||||
destBegin = 3137
|
||||
End of Item 001B
|
||||
|
||||
Begin of Item 001C
|
||||
Format 2
|
||||
srcBegin = 9841
|
||||
destBegin = 3138
|
||||
End of Item 001C
|
||||
|
||||
Begin of Item 001D
|
||||
Format 2
|
||||
srcBegin = 9C41
|
||||
destBegin = 3139
|
||||
End of Item 001D
|
||||
|
||||
Begin of Item 001E
|
||||
Format 2
|
||||
srcBegin = A041
|
||||
destBegin = 3141
|
||||
End of Item 001E
|
||||
|
||||
Begin of Item 001F
|
||||
Format 2
|
||||
srcBegin = A441
|
||||
destBegin = 3142
|
||||
End of Item 001F
|
||||
|
||||
Begin of Item 0020
|
||||
Format 2
|
||||
srcBegin = A841
|
||||
destBegin = 3143
|
||||
End of Item 0020
|
||||
|
||||
Begin of Item 0021
|
||||
Format 2
|
||||
srcBegin = AC41
|
||||
destBegin = 3145
|
||||
End of Item 0021
|
||||
|
||||
Begin of Item 0022
|
||||
Format 2
|
||||
srcBegin = B041
|
||||
destBegin = 3146
|
||||
End of Item 0022
|
||||
|
||||
Begin of Item 0023
|
||||
Format 2
|
||||
srcBegin = B441
|
||||
destBegin = 3147
|
||||
End of Item 0023
|
||||
|
||||
Begin of Item 0024
|
||||
Format 2
|
||||
srcBegin = B841
|
||||
destBegin = 3148
|
||||
End of Item 0024
|
||||
|
||||
Begin of Item 0025
|
||||
Format 2
|
||||
srcBegin = BC41
|
||||
destBegin = 3149
|
||||
End of Item 0025
|
||||
|
||||
Begin of Item 0026
|
||||
Format 2
|
||||
srcBegin = C041
|
||||
destBegin = 314A
|
||||
End of Item 0026
|
||||
|
||||
Begin of Item 0027
|
||||
Format 2
|
||||
srcBegin = C441
|
||||
destBegin = 314B
|
||||
End of Item 0027
|
||||
|
||||
Begin of Item 0028
|
||||
Format 2
|
||||
srcBegin = C841
|
||||
destBegin = 314C
|
||||
End of Item 0028
|
||||
|
||||
Begin of Item 0029
|
||||
Format 2
|
||||
srcBegin = CC41
|
||||
destBegin = 314D
|
||||
End of Item 0029
|
||||
|
||||
Begin of Item 002A
|
||||
Format 2
|
||||
srcBegin = D041
|
||||
destBegin = 314E
|
||||
End of Item 002A
|
||||
|
||||
========================================================*/
|
||||
/* Offset=0x0000 ItemOfList */
|
||||
0x002B,
|
||||
/*-------------------------------------------------------*/
|
||||
/* Offset=0x0001 offsetToFormatArray */
|
||||
0x0004,
|
||||
/*-------------------------------------------------------*/
|
||||
/* Offset=0x0002 offsetToMapCellArray */
|
||||
0x000F,
|
||||
/*-------------------------------------------------------*/
|
||||
/* Offset=0x0003 offsetToMappingTable */
|
||||
0x0090,
|
||||
/*-------------------------------------------------------*/
|
||||
/* Offset=0x0004 Start of Format Array */
|
||||
/* Total of Format 0 : 0x0001 */
|
||||
/* Total of Format 1 : 0x0001 */
|
||||
/* Total of Format 2 : 0x0029 */
|
||||
/* Total of Format 3 : 0x0000 */
|
||||
|
||||
0x2210, 0x2222, 0x2222, 0x2222, 0x2222, 0x2222, 0x2222, 0x2222,
|
||||
0x2222, 0x2222, 0x0222,
|
||||
/*-------------------------------------------------------*/
|
||||
/* Offset=0x000F Start of MapCell Array */
|
||||
/* 0000 */ 0x844A, 0x8450, 0x313A,
|
||||
/* 0001 */ 0x8444, 0x8447, 0x0000,
|
||||
/* 0002 */ 0x8454, 0x0000, 0x3144,
|
||||
/* 0003 */ 0x8461, 0x0000, 0x314F,
|
||||
/* 0004 */ 0x8481, 0x0000, 0x3150,
|
||||
/* 0005 */ 0x84A1, 0x0000, 0x3151,
|
||||
/* 0006 */ 0x84C1, 0x0000, 0x3152,
|
||||
/* 0007 */ 0x84E1, 0x0000, 0x3153,
|
||||
/* 0008 */ 0x8541, 0x0000, 0x3154,
|
||||
/* 0009 */ 0x8561, 0x0000, 0x3155,
|
||||
/* 000A */ 0x8581, 0x0000, 0x3156,
|
||||
/* 000B */ 0x85A1, 0x0000, 0x3157,
|
||||
/* 000C */ 0x85C1, 0x0000, 0x3158,
|
||||
/* 000D */ 0x85E1, 0x0000, 0x3159,
|
||||
/* 000E */ 0x8641, 0x0000, 0x315A,
|
||||
/* 000F */ 0x8661, 0x0000, 0x315B,
|
||||
/* 0010 */ 0x8681, 0x0000, 0x315C,
|
||||
/* 0011 */ 0x86A1, 0x0000, 0x315D,
|
||||
/* 0012 */ 0x86C1, 0x0000, 0x315E,
|
||||
/* 0013 */ 0x86E1, 0x0000, 0x315F,
|
||||
/* 0014 */ 0x8741, 0x0000, 0x3160,
|
||||
/* 0015 */ 0x8761, 0x0000, 0x3161,
|
||||
/* 0016 */ 0x8781, 0x0000, 0x3162,
|
||||
/* 0017 */ 0x87A1, 0x0000, 0x3163,
|
||||
/* 0018 */ 0x8841, 0x0000, 0x3131,
|
||||
/* 0019 */ 0x8C41, 0x0000, 0x3132,
|
||||
/* 001A */ 0x9041, 0x0000, 0x3134,
|
||||
/* 001B */ 0x9441, 0x0000, 0x3137,
|
||||
/* 001C */ 0x9841, 0x0000, 0x3138,
|
||||
/* 001D */ 0x9C41, 0x0000, 0x3139,
|
||||
/* 001E */ 0xA041, 0x0000, 0x3141,
|
||||
/* 001F */ 0xA441, 0x0000, 0x3142,
|
||||
/* 0020 */ 0xA841, 0x0000, 0x3143,
|
||||
/* 0021 */ 0xAC41, 0x0000, 0x3145,
|
||||
/* 0022 */ 0xB041, 0x0000, 0x3146,
|
||||
/* 0023 */ 0xB441, 0x0000, 0x3147,
|
||||
/* 0024 */ 0xB841, 0x0000, 0x3148,
|
||||
/* 0025 */ 0xBC41, 0x0000, 0x3149,
|
||||
/* 0026 */ 0xC041, 0x0000, 0x314A,
|
||||
/* 0027 */ 0xC441, 0x0000, 0x314B,
|
||||
/* 0028 */ 0xC841, 0x0000, 0x314C,
|
||||
/* 0029 */ 0xCC41, 0x0000, 0x314D,
|
||||
/* 002A */ 0xD041, 0x0000, 0x314E,
|
||||
/*-------------------------------------------------------*/
|
||||
/* Offset=0x0090 Start of MappingTable */
|
||||
|
||||
/* 0000 */ 0x3133, 0xFFFD, 0x3135, 0x3136,
|
||||
/* End of table Total Length = 0x0094 * 2 */
|
|
@ -1,59 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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/. */
|
||||
|
||||
#include "nsJohabToUnicode.h"
|
||||
#include "nsUCvKODll.h"
|
||||
#include "nsUCConstructors.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Global functions and data [declaration]
|
||||
|
||||
static const uScanClassID g_JOHABScanClassIDs[] = {
|
||||
u1ByteCharset,
|
||||
uJohabHangulCharset,
|
||||
u2BytesCharset,
|
||||
uJohabSymbolCharset,
|
||||
uJohabSymbolCharset
|
||||
};
|
||||
|
||||
static const uRange g_JOHABRanges[] = {
|
||||
{ 0x00, 0x7E },
|
||||
{ 0x84, 0xD3 },
|
||||
{ 0x84, 0xD3 },
|
||||
{ 0xD8, 0xDE },
|
||||
{ 0xE0, 0xF9 }
|
||||
};
|
||||
|
||||
static const uint16_t g_utJohabJamoMapping[] ={
|
||||
#include "johabjamo.ut"
|
||||
};
|
||||
|
||||
static const uint16_t *g_JOHABMappingTableSet [] ={
|
||||
g_ASCIIMappingTable,
|
||||
g_HangulNullMapping,
|
||||
g_utJohabJamoMapping,
|
||||
g_utKSC5601Mapping,
|
||||
g_utKSC5601Mapping
|
||||
};
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Class nsJohabToUnicode [implementation]
|
||||
|
||||
nsresult
|
||||
nsJohabToUnicodeConstructor(nsISupports *aOuter, REFNSIID aIID,
|
||||
void **aResult)
|
||||
{
|
||||
Telemetry::Accumulate(Telemetry::DECODER_INSTANTIATED_JOHAB, true);
|
||||
return CreateMultiTableDecoder(sizeof(g_JOHABRanges) / sizeof(g_JOHABRanges[0]),
|
||||
(const uRange*) &g_JOHABRanges,
|
||||
(uScanClassID*) &g_JOHABScanClassIDs,
|
||||
(uMappingTable**) &g_JOHABMappingTableSet, 1,
|
||||
aOuter, aIID, aResult);
|
||||
}
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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/. */
|
||||
|
||||
#ifndef nsJohabToUnicode_h___
|
||||
#define nsJohabToUnicode_h___
|
||||
|
||||
#include "nsID.h"
|
||||
|
||||
class nsISupports;
|
||||
|
||||
/**
|
||||
* A character set converter from Johab to Unicode.
|
||||
*
|
||||
* @created 06/Apr/1999
|
||||
* @author Catalin Rotaru [CATA]
|
||||
*/
|
||||
nsresult
|
||||
nsJohabToUnicodeConstructor(nsISupports *aOuter, REFNSIID aIID,
|
||||
void **aResult);
|
||||
|
||||
#endif /* nsJohabToUnicode_h___ */
|
|
@ -28,14 +28,4 @@
|
|||
#define NS_UNICODETOISO2022KR_CID \
|
||||
{ 0xba6151a0, 0x1dfa, 0x11d3, {0xb3, 0xbf, 0x0, 0x80, 0x5f, 0x8a, 0x66, 0x70}}
|
||||
|
||||
// Class ID for our UnicodeToJohab charset converter
|
||||
// {D9B1F97E-CFA0-80b6-FB92-9972E48E3DCC}
|
||||
#define NS_UNICODETOJOHAB_CID \
|
||||
{ 0xd9b1f97e, 0xcfa0, 0x80b6, {0xfb, 0x92, 0x99, 0x72, 0xe4, 0x8e, 0x3d, 0xcc}}
|
||||
|
||||
// Class ID for our JohabToUnicode charset converter
|
||||
// {D9B1F97F-CFA0-80b6-FB92-9972E48E3DCC}
|
||||
#define NS_JOHABTOUNICODE_CID \
|
||||
{ 0xd9b1f97f, 0xcfa0, 0x80b6, {0xfb, 0x92, 0x99, 0x72, 0xe4, 0x8e, 0x3d, 0xcc}}
|
||||
|
||||
#endif /* nsUCvKOCID_h___ */
|
||||
|
|
|
@ -10,6 +10,5 @@ extern const uint16_t g_utKSC5601Mapping[];
|
|||
extern const uint16_t g_ufKSC5601Mapping[];
|
||||
extern const uint16_t g_ASCIIMappingTable[];
|
||||
extern const uint16_t g_HangulNullMapping[];
|
||||
extern const uint16_t g_ufJohabJamoMapping[];
|
||||
|
||||
#endif /* nsUCvKODll_h_ */
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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/. */
|
||||
|
||||
#include "nsUnicodeToJohab.h"
|
||||
#include "nsUCvKODll.h"
|
||||
#include "nsUCConstructors.h"
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Global functions and data [declaration]
|
||||
|
||||
static const uint16_t *g_JohabMappingTable[4] = {
|
||||
g_ASCIIMappingTable,
|
||||
g_HangulNullMapping,
|
||||
g_ufJohabJamoMapping,
|
||||
g_ufKSC5601Mapping
|
||||
};
|
||||
|
||||
static const uScanClassID g_JohabScanClassTable[4] = {
|
||||
u1ByteCharset,
|
||||
uJohabHangulCharset,
|
||||
u2BytesCharset,
|
||||
uJohabSymbolCharset
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Class nsUnicodeToJohab [implementation]
|
||||
|
||||
nsresult
|
||||
nsUnicodeToJohabConstructor(nsISupports *aOuter, REFNSIID aIID,
|
||||
void **aResult) {
|
||||
|
||||
return CreateMultiTableEncoder(sizeof(g_JohabScanClassTable) / sizeof(g_JohabScanClassTable[0]),
|
||||
(uScanClassID*) g_JohabScanClassTable,
|
||||
(uMappingTable**) g_JohabMappingTable,
|
||||
2 /* max length = src * 2*/,
|
||||
aOuter, aIID, aResult);
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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/. */
|
||||
|
||||
#ifndef nsUnicodeToJohab_h___
|
||||
#define nsUnicodeToJohab_h___
|
||||
|
||||
#include "nsID.h"
|
||||
|
||||
class nsISupports;
|
||||
|
||||
/**
|
||||
* A character set converter from Unicode to Johab.
|
||||
*
|
||||
*/
|
||||
nsresult
|
||||
nsUnicodeToJohabConstructor(nsISupports *aOuter, REFNSIID aIID,
|
||||
void **aResult);
|
||||
|
||||
#endif /* nsUnicodeToJohab_h___ */
|
|
@ -1,36 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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/. */
|
||||
|
||||
#include "nsUCConstructors.h"
|
||||
#include "nsT61ToUnicode.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Global functions and data [declaration]
|
||||
|
||||
nsresult
|
||||
nsT61ToUnicodeConstructor(nsISupports *aOuter, REFNSIID aIID,
|
||||
void **aResult)
|
||||
{
|
||||
static const uint16_t g_T61MappingTable[] = {
|
||||
#include "t61.ut"
|
||||
};
|
||||
|
||||
static const int16_t g_T61ShiftInTable[] = {
|
||||
3,
|
||||
ShiftInCell(u1ByteChar, 1, 0x00, 0xBF),
|
||||
ShiftInCell(u1ByteChar, 1, 0xD0, 0xFF),
|
||||
ShiftInCell(u2BytesChar, 2, 0xC0, 0xCF)
|
||||
};
|
||||
|
||||
Telemetry::Accumulate(Telemetry::DECODER_INSTANTIATED_T61, true);
|
||||
return CreateTableDecoder(uMultibytesCharset,
|
||||
(uShiftInTable*) &g_T61ShiftInTable,
|
||||
(uMappingTable*) &g_T61MappingTable, 1,
|
||||
aOuter, aIID, aResult);
|
||||
}
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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/. */
|
||||
|
||||
#ifndef nsT61ToUnicode_h___
|
||||
#define nsT61ToUnicode_h___
|
||||
|
||||
#include "nsISupports.h"
|
||||
|
||||
/**
|
||||
* A character set converter from T61 to Unicode.
|
||||
*
|
||||
* @created 18/Mar/1998
|
||||
* @author Catalin Rotaru [CATA]
|
||||
*/
|
||||
nsresult
|
||||
nsT61ToUnicodeConstructor(nsISupports *aOuter, REFNSIID aIID,
|
||||
void **aResult);
|
||||
|
||||
#endif /* nsT61ToUnicode_h___ */
|
|
@ -420,11 +420,6 @@
|
|||
#define NS_UNICODETOUTF16BE_CID \
|
||||
{ 0xba6151ad, 0x1dfa, 0x11d3, {0xb3, 0xbf, 0x0, 0x80, 0x5f, 0x8a, 0x66, 0x70}}
|
||||
|
||||
// Class ID for our UnicodeToT61 charset converter
|
||||
// {BA6151AF-1DFA-11d3-B3BF-00805F8A6670}
|
||||
#define NS_UNICODETOT61_CID \
|
||||
{ 0xba6151af, 0x1dfa, 0x11d3, {0xb3, 0xbf, 0x0, 0x80, 0x5f, 0x8a, 0x66, 0x70}}
|
||||
|
||||
// Class ID for our ISO885910ToUnicode charset converter
|
||||
// {BA6151B0-1DFA-11d3-B3BF-00805F8A6670}
|
||||
#define NS_ISO885910TOUNICODE_CID \
|
||||
|
@ -445,11 +440,6 @@
|
|||
#define NS_UTF16BETOUNICODE_CID \
|
||||
{ 0xba6151b2, 0x1dfa, 0x11d3, {0xb3, 0xbf, 0x0, 0x80, 0x5f, 0x8a, 0x66, 0x70}}
|
||||
|
||||
// Class ID for our T61ToUnicode charset converter
|
||||
// {BA6151B4-1DFA-11d3-B3BF-00805F8A6670}
|
||||
#define NS_T61TOUNICODE_CID \
|
||||
{ 0xba6151b4, 0x1dfa, 0x11d3, {0xb3, 0xbf, 0x0, 0x80, 0x5f, 0x8a, 0x66, 0x70}}
|
||||
|
||||
// Class ID for our UnicodeToUTF16LE charset converter
|
||||
// {BA6151B5-1DFA-11d3-B3BF-00805F8A6670}
|
||||
#define NS_UNICODETOUTF16LE_CID \
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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/. */
|
||||
|
||||
#include "nsUCConstructors.h"
|
||||
#include "nsUnicodeToT61.h"
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Global functions and data [declaration]
|
||||
|
||||
nsresult
|
||||
nsUnicodeToT61Constructor(nsISupports *aOuter, REFNSIID aIID,
|
||||
void **aResult)
|
||||
{
|
||||
static const uint16_t g_T61MappingTable[] = {
|
||||
#include "t61.uf"
|
||||
};
|
||||
|
||||
static const int16_t g_T61ShiftOutTable[] = {
|
||||
3,
|
||||
ShiftOutCell(u1ByteChar, 1, 0x00, 0x00, 0x00, 0xBF),
|
||||
ShiftOutCell(u1ByteChar, 1, 0x00, 0xD0, 0x00, 0xFF),
|
||||
ShiftOutCell(u2BytesChar, 2, 0xC0, 0x41, 0xCF, 0x7A)
|
||||
};
|
||||
|
||||
return CreateTableEncoder(uMultibytesCharset,
|
||||
(uShiftOutTable*) &g_T61ShiftOutTable,
|
||||
(uMappingTable*) &g_T61MappingTable, 2,
|
||||
aOuter, aIID, aResult);
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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/. */
|
||||
|
||||
#ifndef nsUnicodeToT61_h___
|
||||
#define nsUnicodeToT61_h___
|
||||
|
||||
#include "nsISupports.h"
|
||||
|
||||
/**
|
||||
* A character set converter from Unicode to T61.
|
||||
*
|
||||
* @created 05/Apr/1999
|
||||
* @author Catalin Rotaru [CATA]
|
||||
*/
|
||||
nsresult
|
||||
nsUnicodeToT61Constructor(nsISupports *aOuter, REFNSIID aIID,
|
||||
void **aResult);
|
||||
|
||||
#endif /* nsUnicodeToT61_h___ */
|
|
@ -1,231 +0,0 @@
|
|||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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/. */
|
||||
/*========================================================
|
||||
This is a Generated file. Please don't edit it.
|
||||
|
||||
The tool which used to generate this file is called fromu.
|
||||
If you have any problem of this file. Please contact
|
||||
Netscape Client International Team or
|
||||
ftang@netscape <Frank Tang>
|
||||
|
||||
Table in Debug form
|
||||
Begin of Item 0000
|
||||
Format 0
|
||||
srcBegin = 0000
|
||||
srcEnd = 0023
|
||||
destBegin = 0000
|
||||
End of Item 0000
|
||||
|
||||
Begin of Item 0001
|
||||
Format 0
|
||||
srcBegin = 0025
|
||||
srcEnd = 005D
|
||||
destBegin = 0025
|
||||
End of Item 0001
|
||||
|
||||
Begin of Item 0002
|
||||
Format 0
|
||||
srcBegin = 0061
|
||||
srcEnd = 007D
|
||||
destBegin = 0061
|
||||
End of Item 0002
|
||||
|
||||
Begin of Item 0003
|
||||
Format 2
|
||||
srcBegin = 0024
|
||||
destBegin = 00A4
|
||||
End of Item 0003
|
||||
|
||||
Begin of Item 0004
|
||||
Format 1
|
||||
srcBegin = 005E
|
||||
srcEnd = 0060
|
||||
mappingOffset = 0000
|
||||
Mapping =
|
||||
C320 005F C120
|
||||
End of Item 0004
|
||||
|
||||
Begin of Item 0005
|
||||
Format 1
|
||||
srcBegin = 007E
|
||||
srcEnd = 007F
|
||||
mappingOffset = 0003
|
||||
Mapping =
|
||||
C420 007F
|
||||
End of Item 0005
|
||||
|
||||
Begin of Item 0006
|
||||
Format 1
|
||||
srcBegin = 00A0
|
||||
srcEnd = 017E
|
||||
mappingOffset = 0005
|
||||
Mapping =
|
||||
00A0 00A1 00A2 00A3 FFFD 00A5 00D7 00A7
|
||||
C820 00D3 00E3 00AB 00D6 00FF 00D2 C520
|
||||
00B0 00B1 00B2 00B3 C220 00B5 00B6 00B7
|
||||
CB20 00D1 00EB 00BB 00BC 00BD 00BE 00BF
|
||||
C141 C241 C341 C441 C841 CA41 00E1 CB43
|
||||
C145 C245 C345 C845 C149 C249 C349 C849
|
||||
FFFD C44E C14F C24F C34F C44F C84F 00B4
|
||||
00E9 C155 C255 C355 C855 C259 00EC 00FB
|
||||
C161 C261 C361 C461 C861 CA61 00F1 CB63
|
||||
C165 C265 C365 C865 C169 C269 C369 C869
|
||||
00F3 C46E C16F C26F C36F C46F C86F 00B8
|
||||
00F9 C175 C275 C375 C875 C279 00FC C879
|
||||
C541 C561 C641 C661 CE41 CE61 C243 C263
|
||||
C343 C363 C743 C763 CF43 CF63 CF44 CF64
|
||||
00E2 00F2 C545 C565 FFFD FFFD C745 C765
|
||||
CE45 CE65 CF45 CF65 C347 C367 C647 C667
|
||||
C747 C767 CB47 FFFD C348 C368 00E4 00F4
|
||||
C449 C469 C549 C569 FFFD FFFD CE49 CE69
|
||||
C749 00F5 00E6 00F6 C34A C36A CB4B CB6B
|
||||
00F0 C24C C26C CB4C CB6C CF4C CF6C 00E7
|
||||
00F7 00E8 00F8 C24E C26E FFFD CB6E CF4E
|
||||
CF6E 00EF 00EE 00FE C54F C56F FFFD FFFD
|
||||
CD4F CD6F 00EA 00FA C252 C272 CB52 CB72
|
||||
CF52 CF72 C253 C273 C353 C373 CB53 CB73
|
||||
CF53 CF73 CB54 CB74 CF54 CF74 00ED 00FD
|
||||
C455 C475 C555 C575 C655 C675 CA55 CA75
|
||||
CD55 CD75 CE55 CE75 C357 C377 C359 C379
|
||||
C859 FFFD C27A C75A C77A CF5A CF7A
|
||||
End of Item 0006
|
||||
|
||||
Begin of Item 0007
|
||||
Format 2
|
||||
srcBegin = 01F5
|
||||
destBegin = C267
|
||||
End of Item 0007
|
||||
|
||||
Begin of Item 0008
|
||||
Format 2
|
||||
srcBegin = 02C7
|
||||
destBegin = CF20
|
||||
End of Item 0008
|
||||
|
||||
Begin of Item 0009
|
||||
Format 1
|
||||
srcBegin = 02D8
|
||||
srcEnd = 02DD
|
||||
mappingOffset = 00E4
|
||||
Mapping =
|
||||
C620 C720 CA20 CE20 FFFD CD20
|
||||
End of Item 0009
|
||||
|
||||
Begin of Item 000A
|
||||
Format 1
|
||||
srcBegin = 2015
|
||||
srcEnd = 201D
|
||||
mappingOffset = 00EA
|
||||
Mapping =
|
||||
00D0 FFFD FFFD 00A9 00B9 FFFD FFFD 00AA
|
||||
00BA
|
||||
End of Item 000A
|
||||
|
||||
Begin of Item 000B
|
||||
Format 1
|
||||
srcBegin = 2122
|
||||
srcEnd = 2126
|
||||
mappingOffset = 00F3
|
||||
Mapping =
|
||||
00D4 FFFD FFFD FFFD 00E0
|
||||
End of Item 000B
|
||||
|
||||
Begin of Item 000C
|
||||
Format 1
|
||||
srcBegin = 215B
|
||||
srcEnd = 215E
|
||||
mappingOffset = 00F8
|
||||
Mapping =
|
||||
00DC 00DD 00DE 00DF
|
||||
End of Item 000C
|
||||
|
||||
Begin of Item 000D
|
||||
Format 1
|
||||
srcBegin = 2190
|
||||
srcEnd = 2193
|
||||
mappingOffset = 00FC
|
||||
Mapping =
|
||||
00AC 00AD 00AE 00AF
|
||||
End of Item 000D
|
||||
|
||||
Begin of Item 000E
|
||||
Format 2
|
||||
srcBegin = 266A
|
||||
destBegin = 00D5
|
||||
End of Item 000E
|
||||
|
||||
========================================================*/
|
||||
/* Offset=0x0000 ItemOfList */
|
||||
0x000F,
|
||||
/*-------------------------------------------------------*/
|
||||
/* Offset=0x0001 offsetToFormatArray */
|
||||
0x0004,
|
||||
/*-------------------------------------------------------*/
|
||||
/* Offset=0x0002 offsetToMapCellArray */
|
||||
0x0008,
|
||||
/*-------------------------------------------------------*/
|
||||
/* Offset=0x0003 offsetToMappingTable */
|
||||
0x0035,
|
||||
/*-------------------------------------------------------*/
|
||||
/* Offset=0x0004 Start of Format Array */
|
||||
/* Total of Format 0 : 0x0003 */
|
||||
/* Total of Format 1 : 0x0008 */
|
||||
/* Total of Format 2 : 0x0004 */
|
||||
/* Total of Format 3 : 0x0000 */
|
||||
|
||||
0x2000, 0x2111, 0x1112, 0x0211,
|
||||
/*-------------------------------------------------------*/
|
||||
/* Offset=0x0008 Start of MapCell Array */
|
||||
/* 0000 */ 0x0000, 0x0023, 0x0000,
|
||||
/* 0001 */ 0x0025, 0x005D, 0x0025,
|
||||
/* 0002 */ 0x0061, 0x007D, 0x0061,
|
||||
/* 0003 */ 0x0024, 0x0000, 0x00A4,
|
||||
/* 0004 */ 0x005E, 0x0060, 0x0000,
|
||||
/* 0005 */ 0x007E, 0x007F, 0x0003,
|
||||
/* 0006 */ 0x00A0, 0x017E, 0x0005,
|
||||
/* 0007 */ 0x01F5, 0x0000, 0xC267,
|
||||
/* 0008 */ 0x02C7, 0x0000, 0xCF20,
|
||||
/* 0009 */ 0x02D8, 0x02DD, 0x00E4,
|
||||
/* 000A */ 0x2015, 0x201D, 0x00EA,
|
||||
/* 000B */ 0x2122, 0x2126, 0x00F3,
|
||||
/* 000C */ 0x215B, 0x215E, 0x00F8,
|
||||
/* 000D */ 0x2190, 0x2193, 0x00FC,
|
||||
/* 000E */ 0x266A, 0x0000, 0x00D5,
|
||||
/*-------------------------------------------------------*/
|
||||
/* Offset=0x0035 Start of MappingTable */
|
||||
|
||||
/* 0000 */ 0xC320, 0x005F, 0xC120, 0xC420, 0x007F, 0x00A0, 0x00A1, 0x00A2,
|
||||
/* 0008 */ 0x00A3, 0xFFFD, 0x00A5, 0x00D7, 0x00A7, 0xC820, 0x00D3, 0x00E3,
|
||||
/* 0010 */ 0x00AB, 0x00D6, 0x00FF, 0x00D2, 0xC520, 0x00B0, 0x00B1, 0x00B2,
|
||||
/* 0018 */ 0x00B3, 0xC220, 0x00B5, 0x00B6, 0x00B7, 0xCB20, 0x00D1, 0x00EB,
|
||||
/* 0020 */ 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF, 0xC141, 0xC241, 0xC341,
|
||||
/* 0028 */ 0xC441, 0xC841, 0xCA41, 0x00E1, 0xCB43, 0xC145, 0xC245, 0xC345,
|
||||
/* 0030 */ 0xC845, 0xC149, 0xC249, 0xC349, 0xC849, 0xFFFD, 0xC44E, 0xC14F,
|
||||
/* 0038 */ 0xC24F, 0xC34F, 0xC44F, 0xC84F, 0x00B4, 0x00E9, 0xC155, 0xC255,
|
||||
/* 0040 */ 0xC355, 0xC855, 0xC259, 0x00EC, 0x00FB, 0xC161, 0xC261, 0xC361,
|
||||
/* 0048 */ 0xC461, 0xC861, 0xCA61, 0x00F1, 0xCB63, 0xC165, 0xC265, 0xC365,
|
||||
/* 0050 */ 0xC865, 0xC169, 0xC269, 0xC369, 0xC869, 0x00F3, 0xC46E, 0xC16F,
|
||||
/* 0058 */ 0xC26F, 0xC36F, 0xC46F, 0xC86F, 0x00B8, 0x00F9, 0xC175, 0xC275,
|
||||
/* 0060 */ 0xC375, 0xC875, 0xC279, 0x00FC, 0xC879, 0xC541, 0xC561, 0xC641,
|
||||
/* 0068 */ 0xC661, 0xCE41, 0xCE61, 0xC243, 0xC263, 0xC343, 0xC363, 0xC743,
|
||||
/* 0070 */ 0xC763, 0xCF43, 0xCF63, 0xCF44, 0xCF64, 0x00E2, 0x00F2, 0xC545,
|
||||
/* 0078 */ 0xC565, 0xFFFD, 0xFFFD, 0xC745, 0xC765, 0xCE45, 0xCE65, 0xCF45,
|
||||
/* 0080 */ 0xCF65, 0xC347, 0xC367, 0xC647, 0xC667, 0xC747, 0xC767, 0xCB47,
|
||||
/* 0088 */ 0xFFFD, 0xC348, 0xC368, 0x00E4, 0x00F4, 0xC449, 0xC469, 0xC549,
|
||||
/* 0090 */ 0xC569, 0xFFFD, 0xFFFD, 0xCE49, 0xCE69, 0xC749, 0x00F5, 0x00E6,
|
||||
/* 0098 */ 0x00F6, 0xC34A, 0xC36A, 0xCB4B, 0xCB6B, 0x00F0, 0xC24C, 0xC26C,
|
||||
/* 00A0 */ 0xCB4C, 0xCB6C, 0xCF4C, 0xCF6C, 0x00E7, 0x00F7, 0x00E8, 0x00F8,
|
||||
/* 00A8 */ 0xC24E, 0xC26E, 0xFFFD, 0xCB6E, 0xCF4E, 0xCF6E, 0x00EF, 0x00EE,
|
||||
/* 00B0 */ 0x00FE, 0xC54F, 0xC56F, 0xFFFD, 0xFFFD, 0xCD4F, 0xCD6F, 0x00EA,
|
||||
/* 00B8 */ 0x00FA, 0xC252, 0xC272, 0xCB52, 0xCB72, 0xCF52, 0xCF72, 0xC253,
|
||||
/* 00C0 */ 0xC273, 0xC353, 0xC373, 0xCB53, 0xCB73, 0xCF53, 0xCF73, 0xCB54,
|
||||
/* 00C8 */ 0xCB74, 0xCF54, 0xCF74, 0x00ED, 0x00FD, 0xC455, 0xC475, 0xC555,
|
||||
/* 00D0 */ 0xC575, 0xC655, 0xC675, 0xCA55, 0xCA75, 0xCD55, 0xCD75, 0xCE55,
|
||||
/* 00D8 */ 0xCE75, 0xC357, 0xC377, 0xC359, 0xC379, 0xC859, 0xFFFD, 0xC27A,
|
||||
/* 00E0 */ 0xC75A, 0xC77A, 0xCF5A, 0xCF7A, 0xC620, 0xC720, 0xCA20, 0xCE20,
|
||||
/* 00E8 */ 0xFFFD, 0xCD20, 0x00D0, 0xFFFD, 0xFFFD, 0x00A9, 0x00B9, 0xFFFD,
|
||||
/* 00F0 */ 0xFFFD, 0x00AA, 0x00BA, 0x00D4, 0xFFFD, 0xFFFD, 0xFFFD, 0x00E0,
|
||||
/* 00F8 */ 0x00DC, 0x00DD, 0x00DE, 0x00DF, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
|
||||
/* End of table Total Length = 0x0135 * 2 */
|
|
@ -1,544 +0,0 @@
|
|||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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/. */
|
||||
/*========================================================
|
||||
This is a Generated file. Please don't edit it.
|
||||
|
||||
The tool which used to generate this file is called fromu.
|
||||
If you have any problem of this file. Please contact
|
||||
Netscape Client International Team or
|
||||
ftang@netscape <Frank Tang>
|
||||
|
||||
Table in Debug form
|
||||
Begin of Item 0000
|
||||
Format 0
|
||||
srcBegin = 0000
|
||||
srcEnd = 007F
|
||||
destBegin = 0000
|
||||
End of Item 0000
|
||||
|
||||
Begin of Item 0001
|
||||
Format 1
|
||||
srcBegin = 00A0
|
||||
srcEnd = 00BF
|
||||
mappingOffset = 0000
|
||||
Mapping =
|
||||
00A0 00A1 00A2 00A3 0024 00A5 FFFD 00A7
|
||||
FFFD 2018 201C 00AB 2190 2191 2192 2193
|
||||
00B0 00B1 00B2 00B3 00D7 00B5 00B6 00B7
|
||||
00F7 2019 201D 00BB 00BC 00BD 00BE 00BF
|
||||
End of Item 0001
|
||||
|
||||
Begin of Item 0002
|
||||
Format 1
|
||||
srcBegin = 00D0
|
||||
srcEnd = 00FF
|
||||
mappingOffset = 0020
|
||||
Mapping =
|
||||
2015 00B9 00AE 00A9 2122 266A 00AC 00A6
|
||||
FFFD FFFD FFFD FFFD 215B 215C 215D 215E
|
||||
2126 00C6 0110 00AA 0126 FFFD 0132 013F
|
||||
0141 00D8 0152 00BA 00DE 0166 014A 0149
|
||||
0138 00E6 0111 00F0 0127 0131 0133 0140
|
||||
0142 00F8 0153 00DF 00FE 0167 014B 00AD
|
||||
End of Item 0002
|
||||
|
||||
Begin of Item 0003
|
||||
Format 2
|
||||
srcBegin = C120
|
||||
destBegin = 0060
|
||||
End of Item 0003
|
||||
|
||||
Begin of Item 0004
|
||||
Format 1
|
||||
srcBegin = C141
|
||||
srcEnd = C155
|
||||
mappingOffset = 0050
|
||||
Mapping =
|
||||
00C0 FFFD FFFD FFFD 00C8 FFFD FFFD FFFD
|
||||
00CC FFFD FFFD FFFD FFFD FFFD 00D2 FFFD
|
||||
FFFD FFFD FFFD FFFD 00D9
|
||||
End of Item 0004
|
||||
|
||||
Begin of Item 0005
|
||||
Format 1
|
||||
srcBegin = C161
|
||||
srcEnd = C175
|
||||
mappingOffset = 0065
|
||||
Mapping =
|
||||
00E0 FFFD FFFD FFFD 00E8 FFFD FFFD FFFD
|
||||
00EC FFFD FFFD FFFD FFFD FFFD 00F2 FFFD
|
||||
FFFD FFFD FFFD FFFD 00F9
|
||||
End of Item 0005
|
||||
|
||||
Begin of Item 0006
|
||||
Format 2
|
||||
srcBegin = C220
|
||||
destBegin = 00B4
|
||||
End of Item 0006
|
||||
|
||||
Begin of Item 0007
|
||||
Format 1
|
||||
srcBegin = C241
|
||||
srcEnd = C27A
|
||||
mappingOffset = 007A
|
||||
Mapping =
|
||||
00C1 FFFD 0106 FFFD 00C9 FFFD FFFD FFFD
|
||||
00CD FFFD FFFD 0139 FFFD 0143 00D3 FFFD
|
||||
FFFD 0154 015A FFFD 00DA FFFD FFFD FFFD
|
||||
00DD 017B FFFD FFFD FFFD FFFD FFFD FFFD
|
||||
00E1 FFFD 0107 FFFD 00E9 FFFD 01F5 FFFD
|
||||
00ED FFFD FFFD 013A FFFD 0144 00F3 FFFD
|
||||
FFFD 0155 015B FFFD 00FA FFFD FFFD FFFD
|
||||
00FD 017A
|
||||
End of Item 0007
|
||||
|
||||
Begin of Item 0008
|
||||
Format 2
|
||||
srcBegin = C320
|
||||
destBegin = 005E
|
||||
End of Item 0008
|
||||
|
||||
Begin of Item 0009
|
||||
Format 1
|
||||
srcBegin = C341
|
||||
srcEnd = C379
|
||||
mappingOffset = 00B4
|
||||
Mapping =
|
||||
00C2 FFFD 0108 FFFD 00CA FFFD 011C 0124
|
||||
00CE 0134 FFFD FFFD FFFD FFFD 00D4 FFFD
|
||||
FFFD FFFD 015C FFFD 00DB FFFD 0174 FFFD
|
||||
0176 FFFD FFFD FFFD FFFD FFFD FFFD FFFD
|
||||
00E2 FFFD 0109 FFFD 00EA FFFD 011D 0125
|
||||
00EE 0135 FFFD FFFD FFFD FFFD 00F4 FFFD
|
||||
FFFD FFFD 015D FFFD 00FB FFFD 0175 FFFD
|
||||
0177
|
||||
End of Item 0009
|
||||
|
||||
Begin of Item 000A
|
||||
Format 2
|
||||
srcBegin = C420
|
||||
destBegin = 007E
|
||||
End of Item 000A
|
||||
|
||||
Begin of Item 000B
|
||||
Format 1
|
||||
srcBegin = C441
|
||||
srcEnd = C455
|
||||
mappingOffset = 00ED
|
||||
Mapping =
|
||||
00C3 FFFD FFFD FFFD FFFD FFFD FFFD FFFD
|
||||
0128 FFFD FFFD FFFD FFFD 00D1 00D5 FFFD
|
||||
FFFD FFFD FFFD FFFD 0168
|
||||
End of Item 000B
|
||||
|
||||
Begin of Item 000C
|
||||
Format 1
|
||||
srcBegin = C461
|
||||
srcEnd = C475
|
||||
mappingOffset = 0102
|
||||
Mapping =
|
||||
00E3 FFFD FFFD FFFD FFFD FFFD FFFD FFFD
|
||||
0129 FFFD FFFD FFFD FFFD 00F1 00F5 FFFD
|
||||
FFFD FFFD FFFD FFFD 0169
|
||||
End of Item 000C
|
||||
|
||||
Begin of Item 000D
|
||||
Format 2
|
||||
srcBegin = C520
|
||||
destBegin = 00AF
|
||||
End of Item 000D
|
||||
|
||||
Begin of Item 000E
|
||||
Format 1
|
||||
srcBegin = C541
|
||||
srcEnd = C555
|
||||
mappingOffset = 0117
|
||||
Mapping =
|
||||
0100 FFFD FFFD FFFD 0112 FFFD FFFD FFFD
|
||||
012A FFFD FFFD FFFD FFFD FFFD 014C FFFD
|
||||
FFFD FFFD FFFD FFFD 016A
|
||||
End of Item 000E
|
||||
|
||||
Begin of Item 000F
|
||||
Format 1
|
||||
srcBegin = C561
|
||||
srcEnd = C575
|
||||
mappingOffset = 012C
|
||||
Mapping =
|
||||
0101 FFFD FFFD FFFD 0113 FFFD FFFD FFFD
|
||||
012B FFFD FFFD FFFD FFFD FFFD 014D FFFD
|
||||
FFFD FFFD FFFD FFFD 016B
|
||||
End of Item 000F
|
||||
|
||||
Begin of Item 0010
|
||||
Format 2
|
||||
srcBegin = C620
|
||||
destBegin = 02D8
|
||||
End of Item 0010
|
||||
|
||||
Begin of Item 0011
|
||||
Format 1
|
||||
srcBegin = C641
|
||||
srcEnd = C647
|
||||
mappingOffset = 0141
|
||||
Mapping =
|
||||
0102 FFFD FFFD FFFD FFFD FFFD 011E
|
||||
End of Item 0011
|
||||
|
||||
Begin of Item 0012
|
||||
Format 2
|
||||
srcBegin = C655
|
||||
destBegin = 016C
|
||||
End of Item 0012
|
||||
|
||||
Begin of Item 0013
|
||||
Format 1
|
||||
srcBegin = C661
|
||||
srcEnd = C667
|
||||
mappingOffset = 0148
|
||||
Mapping =
|
||||
0103 FFFD FFFD FFFD FFFD FFFD 011F
|
||||
End of Item 0013
|
||||
|
||||
Begin of Item 0014
|
||||
Format 2
|
||||
srcBegin = C675
|
||||
destBegin = 016D
|
||||
End of Item 0014
|
||||
|
||||
Begin of Item 0015
|
||||
Format 2
|
||||
srcBegin = C720
|
||||
destBegin = 02D9
|
||||
End of Item 0015
|
||||
|
||||
Begin of Item 0016
|
||||
Format 1
|
||||
srcBegin = C743
|
||||
srcEnd = C749
|
||||
mappingOffset = 014F
|
||||
Mapping =
|
||||
010A FFFD 0116 FFFD 0120 FFFD 0130
|
||||
End of Item 0016
|
||||
|
||||
Begin of Item 0017
|
||||
Format 1
|
||||
srcBegin = C75A
|
||||
srcEnd = C767
|
||||
mappingOffset = 0156
|
||||
Mapping =
|
||||
017B FFFD FFFD FFFD FFFD FFFD FFFD FFFD
|
||||
FFFD 010B FFFD 0117 FFFD 0121
|
||||
End of Item 0017
|
||||
|
||||
Begin of Item 0018
|
||||
Format 2
|
||||
srcBegin = C77A
|
||||
destBegin = 017C
|
||||
End of Item 0018
|
||||
|
||||
Begin of Item 0019
|
||||
Format 2
|
||||
srcBegin = C820
|
||||
destBegin = 00A8
|
||||
End of Item 0019
|
||||
|
||||
Begin of Item 001A
|
||||
Format 1
|
||||
srcBegin = C841
|
||||
srcEnd = C879
|
||||
mappingOffset = 0164
|
||||
Mapping =
|
||||
00C4 FFFD FFFD FFFD 00CB FFFD FFFD FFFD
|
||||
00CF FFFD FFFD FFFD FFFD FFFD 00D6 FFFD
|
||||
FFFD FFFD FFFD FFFD 00DC FFFD FFFD FFFD
|
||||
0178 FFFD FFFD FFFD FFFD FFFD FFFD FFFD
|
||||
00E4 FFFD FFFD FFFD 00EB FFFD FFFD FFFD
|
||||
00EF FFFD FFFD FFFD FFFD FFFD 00F6 FFFD
|
||||
FFFD FFFD FFFD FFFD 00FC FFFD FFFD FFFD
|
||||
00FF
|
||||
End of Item 001A
|
||||
|
||||
Begin of Item 001B
|
||||
Format 2
|
||||
srcBegin = CA20
|
||||
destBegin = 02DA
|
||||
End of Item 001B
|
||||
|
||||
Begin of Item 001C
|
||||
Format 2
|
||||
srcBegin = CA41
|
||||
destBegin = 00C5
|
||||
End of Item 001C
|
||||
|
||||
Begin of Item 001D
|
||||
Format 2
|
||||
srcBegin = CA55
|
||||
destBegin = 016E
|
||||
End of Item 001D
|
||||
|
||||
Begin of Item 001E
|
||||
Format 2
|
||||
srcBegin = CA61
|
||||
destBegin = 00E5
|
||||
End of Item 001E
|
||||
|
||||
Begin of Item 001F
|
||||
Format 2
|
||||
srcBegin = CA75
|
||||
destBegin = 016F
|
||||
End of Item 001F
|
||||
|
||||
Begin of Item 0020
|
||||
Format 2
|
||||
srcBegin = CB20
|
||||
destBegin = 00B8
|
||||
End of Item 0020
|
||||
|
||||
Begin of Item 0021
|
||||
Format 1
|
||||
srcBegin = CB43
|
||||
srcEnd = CB54
|
||||
mappingOffset = 019D
|
||||
Mapping =
|
||||
00C7 FFFD FFFD FFFD 0122 FFFD FFFD FFFD
|
||||
0136 013B FFFD FFFD FFFD FFFD FFFD 0156
|
||||
015E 0162
|
||||
End of Item 0021
|
||||
|
||||
Begin of Item 0022
|
||||
Format 1
|
||||
srcBegin = CB63
|
||||
srcEnd = CB74
|
||||
mappingOffset = 01AF
|
||||
Mapping =
|
||||
00E7 FFFD FFFD FFFD FFFD FFFD FFFD FFFD
|
||||
0137 013C FFFD 0146 FFFD FFFD FFFD 0157
|
||||
015F 0163
|
||||
End of Item 0022
|
||||
|
||||
Begin of Item 0023
|
||||
Format 2
|
||||
srcBegin = CD20
|
||||
destBegin = 02DD
|
||||
End of Item 0023
|
||||
|
||||
Begin of Item 0024
|
||||
Format 1
|
||||
srcBegin = CD4F
|
||||
srcEnd = CD55
|
||||
mappingOffset = 01C1
|
||||
Mapping =
|
||||
0150 FFFD FFFD FFFD FFFD FFFD 0170
|
||||
End of Item 0024
|
||||
|
||||
Begin of Item 0025
|
||||
Format 1
|
||||
srcBegin = CD6F
|
||||
srcEnd = CD75
|
||||
mappingOffset = 01C8
|
||||
Mapping =
|
||||
0151 FFFD FFFD FFFD FFFD FFFD 0171
|
||||
End of Item 0025
|
||||
|
||||
Begin of Item 0026
|
||||
Format 2
|
||||
srcBegin = CE20
|
||||
destBegin = 02DB
|
||||
End of Item 0026
|
||||
|
||||
Begin of Item 0027
|
||||
Format 1
|
||||
srcBegin = CE41
|
||||
srcEnd = CE49
|
||||
mappingOffset = 01CF
|
||||
Mapping =
|
||||
0104 FFFD FFFD FFFD 0118 FFFD FFFD FFFD
|
||||
012E
|
||||
End of Item 0027
|
||||
|
||||
Begin of Item 0028
|
||||
Format 2
|
||||
srcBegin = CE55
|
||||
destBegin = 0172
|
||||
End of Item 0028
|
||||
|
||||
Begin of Item 0029
|
||||
Format 1
|
||||
srcBegin = CE61
|
||||
srcEnd = CE69
|
||||
mappingOffset = 01D8
|
||||
Mapping =
|
||||
0105 FFFD FFFD FFFD 0119 FFFD FFFD FFFD
|
||||
012F
|
||||
End of Item 0029
|
||||
|
||||
Begin of Item 002A
|
||||
Format 2
|
||||
srcBegin = CE75
|
||||
destBegin = 0173
|
||||
End of Item 002A
|
||||
|
||||
Begin of Item 002B
|
||||
Format 2
|
||||
srcBegin = CF20
|
||||
destBegin = 02C7
|
||||
End of Item 002B
|
||||
|
||||
Begin of Item 002C
|
||||
Format 1
|
||||
srcBegin = CF43
|
||||
srcEnd = CF7A
|
||||
mappingOffset = 01E1
|
||||
Mapping =
|
||||
010C 010E 011A FFFD FFFD FFFD FFFD FFFD
|
||||
FFFD 013D FFFD 0147 FFFD FFFD FFFD 0158
|
||||
0160 0164 FFFD FFFD FFFD FFFD FFFD 017D
|
||||
FFFD FFFD FFFD FFFD FFFD FFFD FFFD FFFD
|
||||
010D 010F 011B FFFD FFFD FFFD FFFD FFFD
|
||||
FFFD 013E FFFD 0148 FFFD FFFD FFFD 0159
|
||||
0161 0165 FFFD FFFD FFFD FFFD FFFD 017E
|
||||
End of Item 002C
|
||||
|
||||
========================================================*/
|
||||
/* Offset=0x0000 ItemOfList */
|
||||
0x002D,
|
||||
/*-------------------------------------------------------*/
|
||||
/* Offset=0x0001 offsetToFormatArray */
|
||||
0x0004,
|
||||
/*-------------------------------------------------------*/
|
||||
/* Offset=0x0002 offsetToMapCellArray */
|
||||
0x0010,
|
||||
/*-------------------------------------------------------*/
|
||||
/* Offset=0x0003 offsetToMappingTable */
|
||||
0x0097,
|
||||
/*-------------------------------------------------------*/
|
||||
/* Offset=0x0004 Start of Format Array */
|
||||
/* Total of Format 0 : 0x0001 */
|
||||
/* Total of Format 1 : 0x0016 */
|
||||
/* Total of Format 2 : 0x0016 */
|
||||
/* Total of Format 3 : 0x0000 */
|
||||
|
||||
0x2110, 0x1211, 0x1212, 0x1121, 0x1212, 0x1122, 0x2122, 0x2222,
|
||||
0x2112, 0x1211, 0x2212, 0x0001,
|
||||
/*-------------------------------------------------------*/
|
||||
/* Offset=0x0010 Start of MapCell Array */
|
||||
/* 0000 */ 0x0000, 0x007F, 0x0000,
|
||||
/* 0001 */ 0x00A0, 0x00BF, 0x0000,
|
||||
/* 0002 */ 0x00D0, 0x00FF, 0x0020,
|
||||
/* 0003 */ 0xC120, 0x0000, 0x0060,
|
||||
/* 0004 */ 0xC141, 0xC155, 0x0050,
|
||||
/* 0005 */ 0xC161, 0xC175, 0x0065,
|
||||
/* 0006 */ 0xC220, 0x0000, 0x00B4,
|
||||
/* 0007 */ 0xC241, 0xC27A, 0x007A,
|
||||
/* 0008 */ 0xC320, 0x0000, 0x005E,
|
||||
/* 0009 */ 0xC341, 0xC379, 0x00B4,
|
||||
/* 000A */ 0xC420, 0x0000, 0x007E,
|
||||
/* 000B */ 0xC441, 0xC455, 0x00ED,
|
||||
/* 000C */ 0xC461, 0xC475, 0x0102,
|
||||
/* 000D */ 0xC520, 0x0000, 0x00AF,
|
||||
/* 000E */ 0xC541, 0xC555, 0x0117,
|
||||
/* 000F */ 0xC561, 0xC575, 0x012C,
|
||||
/* 0010 */ 0xC620, 0x0000, 0x02D8,
|
||||
/* 0011 */ 0xC641, 0xC647, 0x0141,
|
||||
/* 0012 */ 0xC655, 0x0000, 0x016C,
|
||||
/* 0013 */ 0xC661, 0xC667, 0x0148,
|
||||
/* 0014 */ 0xC675, 0x0000, 0x016D,
|
||||
/* 0015 */ 0xC720, 0x0000, 0x02D9,
|
||||
/* 0016 */ 0xC743, 0xC749, 0x014F,
|
||||
/* 0017 */ 0xC75A, 0xC767, 0x0156,
|
||||
/* 0018 */ 0xC77A, 0x0000, 0x017C,
|
||||
/* 0019 */ 0xC820, 0x0000, 0x00A8,
|
||||
/* 001A */ 0xC841, 0xC879, 0x0164,
|
||||
/* 001B */ 0xCA20, 0x0000, 0x02DA,
|
||||
/* 001C */ 0xCA41, 0x0000, 0x00C5,
|
||||
/* 001D */ 0xCA55, 0x0000, 0x016E,
|
||||
/* 001E */ 0xCA61, 0x0000, 0x00E5,
|
||||
/* 001F */ 0xCA75, 0x0000, 0x016F,
|
||||
/* 0020 */ 0xCB20, 0x0000, 0x00B8,
|
||||
/* 0021 */ 0xCB43, 0xCB54, 0x019D,
|
||||
/* 0022 */ 0xCB63, 0xCB74, 0x01AF,
|
||||
/* 0023 */ 0xCD20, 0x0000, 0x02DD,
|
||||
/* 0024 */ 0xCD4F, 0xCD55, 0x01C1,
|
||||
/* 0025 */ 0xCD6F, 0xCD75, 0x01C8,
|
||||
/* 0026 */ 0xCE20, 0x0000, 0x02DB,
|
||||
/* 0027 */ 0xCE41, 0xCE49, 0x01CF,
|
||||
/* 0028 */ 0xCE55, 0x0000, 0x0172,
|
||||
/* 0029 */ 0xCE61, 0xCE69, 0x01D8,
|
||||
/* 002A */ 0xCE75, 0x0000, 0x0173,
|
||||
/* 002B */ 0xCF20, 0x0000, 0x02C7,
|
||||
/* 002C */ 0xCF43, 0xCF7A, 0x01E1,
|
||||
/*-------------------------------------------------------*/
|
||||
/* Offset=0x0097 Start of MappingTable */
|
||||
|
||||
/* 0000 */ 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x0024, 0x00A5, 0xFFFD, 0x00A7,
|
||||
/* 0008 */ 0xFFFD, 0x2018, 0x201C, 0x00AB, 0x2190, 0x2191, 0x2192, 0x2193,
|
||||
/* 0010 */ 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00D7, 0x00B5, 0x00B6, 0x00B7,
|
||||
/* 0018 */ 0x00F7, 0x2019, 0x201D, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
|
||||
/* 0020 */ 0x2015, 0x00B9, 0x00AE, 0x00A9, 0x2122, 0x266A, 0x00AC, 0x00A6,
|
||||
/* 0028 */ 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x215B, 0x215C, 0x215D, 0x215E,
|
||||
/* 0030 */ 0x2126, 0x00C6, 0x0110, 0x00AA, 0x0126, 0xFFFD, 0x0132, 0x013F,
|
||||
/* 0038 */ 0x0141, 0x00D8, 0x0152, 0x00BA, 0x00DE, 0x0166, 0x014A, 0x0149,
|
||||
/* 0040 */ 0x0138, 0x00E6, 0x0111, 0x00F0, 0x0127, 0x0131, 0x0133, 0x0140,
|
||||
/* 0048 */ 0x0142, 0x00F8, 0x0153, 0x00DF, 0x00FE, 0x0167, 0x014B, 0x00AD,
|
||||
/* 0050 */ 0x00C0, 0xFFFD, 0xFFFD, 0xFFFD, 0x00C8, 0xFFFD, 0xFFFD, 0xFFFD,
|
||||
/* 0058 */ 0x00CC, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x00D2, 0xFFFD,
|
||||
/* 0060 */ 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x00D9, 0x00E0, 0xFFFD, 0xFFFD,
|
||||
/* 0068 */ 0xFFFD, 0x00E8, 0xFFFD, 0xFFFD, 0xFFFD, 0x00EC, 0xFFFD, 0xFFFD,
|
||||
/* 0070 */ 0xFFFD, 0xFFFD, 0xFFFD, 0x00F2, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
|
||||
/* 0078 */ 0xFFFD, 0x00F9, 0x00C1, 0xFFFD, 0x0106, 0xFFFD, 0x00C9, 0xFFFD,
|
||||
/* 0080 */ 0xFFFD, 0xFFFD, 0x00CD, 0xFFFD, 0xFFFD, 0x0139, 0xFFFD, 0x0143,
|
||||
/* 0088 */ 0x00D3, 0xFFFD, 0xFFFD, 0x0154, 0x015A, 0xFFFD, 0x00DA, 0xFFFD,
|
||||
/* 0090 */ 0xFFFD, 0xFFFD, 0x00DD, 0x017B, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
|
||||
/* 0098 */ 0xFFFD, 0xFFFD, 0x00E1, 0xFFFD, 0x0107, 0xFFFD, 0x00E9, 0xFFFD,
|
||||
/* 00A0 */ 0x01F5, 0xFFFD, 0x00ED, 0xFFFD, 0xFFFD, 0x013A, 0xFFFD, 0x0144,
|
||||
/* 00A8 */ 0x00F3, 0xFFFD, 0xFFFD, 0x0155, 0x015B, 0xFFFD, 0x00FA, 0xFFFD,
|
||||
/* 00B0 */ 0xFFFD, 0xFFFD, 0x00FD, 0x017A, 0x00C2, 0xFFFD, 0x0108, 0xFFFD,
|
||||
/* 00B8 */ 0x00CA, 0xFFFD, 0x011C, 0x0124, 0x00CE, 0x0134, 0xFFFD, 0xFFFD,
|
||||
/* 00C0 */ 0xFFFD, 0xFFFD, 0x00D4, 0xFFFD, 0xFFFD, 0xFFFD, 0x015C, 0xFFFD,
|
||||
/* 00C8 */ 0x00DB, 0xFFFD, 0x0174, 0xFFFD, 0x0176, 0xFFFD, 0xFFFD, 0xFFFD,
|
||||
/* 00D0 */ 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x00E2, 0xFFFD, 0x0109, 0xFFFD,
|
||||
/* 00D8 */ 0x00EA, 0xFFFD, 0x011D, 0x0125, 0x00EE, 0x0135, 0xFFFD, 0xFFFD,
|
||||
/* 00E0 */ 0xFFFD, 0xFFFD, 0x00F4, 0xFFFD, 0xFFFD, 0xFFFD, 0x015D, 0xFFFD,
|
||||
/* 00E8 */ 0x00FB, 0xFFFD, 0x0175, 0xFFFD, 0x0177, 0x00C3, 0xFFFD, 0xFFFD,
|
||||
/* 00F0 */ 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x0128, 0xFFFD, 0xFFFD,
|
||||
/* 00F8 */ 0xFFFD, 0xFFFD, 0x00D1, 0x00D5, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
|
||||
/* 0100 */ 0xFFFD, 0x0168, 0x00E3, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
|
||||
/* 0108 */ 0xFFFD, 0xFFFD, 0x0129, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x00F1,
|
||||
/* 0110 */ 0x00F5, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x0169, 0x0100,
|
||||
/* 0118 */ 0xFFFD, 0xFFFD, 0xFFFD, 0x0112, 0xFFFD, 0xFFFD, 0xFFFD, 0x012A,
|
||||
/* 0120 */ 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x014C, 0xFFFD, 0xFFFD,
|
||||
/* 0128 */ 0xFFFD, 0xFFFD, 0xFFFD, 0x016A, 0x0101, 0xFFFD, 0xFFFD, 0xFFFD,
|
||||
/* 0130 */ 0x0113, 0xFFFD, 0xFFFD, 0xFFFD, 0x012B, 0xFFFD, 0xFFFD, 0xFFFD,
|
||||
/* 0138 */ 0xFFFD, 0xFFFD, 0x014D, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
|
||||
/* 0140 */ 0x016B, 0x0102, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x011E,
|
||||
/* 0148 */ 0x0103, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x011F, 0x010A,
|
||||
/* 0150 */ 0xFFFD, 0x0116, 0xFFFD, 0x0120, 0xFFFD, 0x0130, 0x017B, 0xFFFD,
|
||||
/* 0158 */ 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x010B,
|
||||
/* 0160 */ 0xFFFD, 0x0117, 0xFFFD, 0x0121, 0x00C4, 0xFFFD, 0xFFFD, 0xFFFD,
|
||||
/* 0168 */ 0x00CB, 0xFFFD, 0xFFFD, 0xFFFD, 0x00CF, 0xFFFD, 0xFFFD, 0xFFFD,
|
||||
/* 0170 */ 0xFFFD, 0xFFFD, 0x00D6, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
|
||||
/* 0178 */ 0x00DC, 0xFFFD, 0xFFFD, 0xFFFD, 0x0178, 0xFFFD, 0xFFFD, 0xFFFD,
|
||||
/* 0180 */ 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x00E4, 0xFFFD, 0xFFFD, 0xFFFD,
|
||||
/* 0188 */ 0x00EB, 0xFFFD, 0xFFFD, 0xFFFD, 0x00EF, 0xFFFD, 0xFFFD, 0xFFFD,
|
||||
/* 0190 */ 0xFFFD, 0xFFFD, 0x00F6, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
|
||||
/* 0198 */ 0x00FC, 0xFFFD, 0xFFFD, 0xFFFD, 0x00FF, 0x00C7, 0xFFFD, 0xFFFD,
|
||||
/* 01A0 */ 0xFFFD, 0x0122, 0xFFFD, 0xFFFD, 0xFFFD, 0x0136, 0x013B, 0xFFFD,
|
||||
/* 01A8 */ 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x0156, 0x015E, 0x0162, 0x00E7,
|
||||
/* 01B0 */ 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x0137,
|
||||
/* 01B8 */ 0x013C, 0xFFFD, 0x0146, 0xFFFD, 0xFFFD, 0xFFFD, 0x0157, 0x015F,
|
||||
/* 01C0 */ 0x0163, 0x0150, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x0170,
|
||||
/* 01C8 */ 0x0151, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x0171, 0x0104,
|
||||
/* 01D0 */ 0xFFFD, 0xFFFD, 0xFFFD, 0x0118, 0xFFFD, 0xFFFD, 0xFFFD, 0x012E,
|
||||
/* 01D8 */ 0x0105, 0xFFFD, 0xFFFD, 0xFFFD, 0x0119, 0xFFFD, 0xFFFD, 0xFFFD,
|
||||
/* 01E0 */ 0x012F, 0x010C, 0x010E, 0x011A, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
|
||||
/* 01E8 */ 0xFFFD, 0xFFFD, 0x013D, 0xFFFD, 0x0147, 0xFFFD, 0xFFFD, 0xFFFD,
|
||||
/* 01F0 */ 0x0158, 0x0160, 0x0164, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
|
||||
/* 01F8 */ 0x017D, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
|
||||
/* 0200 */ 0xFFFD, 0x010D, 0x010F, 0x011B, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
|
||||
/* 0208 */ 0xFFFD, 0xFFFD, 0x013E, 0xFFFD, 0x0148, 0xFFFD, 0xFFFD, 0xFFFD,
|
||||
/* 0210 */ 0x0159, 0x0161, 0x0165, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
|
||||
/* 0218 */ 0x017E,
|
||||
/* End of table Total Length = 0x02B0 * 2 */
|
|
@ -118,27 +118,6 @@ CreateTableEncoder(uScanClassID aScanClass,
|
|||
aOuter, aIID, aResult);
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
CreateTableDecoder(uScanClassID aScanClass,
|
||||
uShiftInTable * aShiftInTable,
|
||||
uMappingTable * aMappingTable,
|
||||
uint32_t aMaxLengthFactor,
|
||||
nsISupports* aOuter,
|
||||
REFNSIID aIID,
|
||||
void** aResult)
|
||||
{
|
||||
if (aOuter)
|
||||
return NS_ERROR_NO_AGGREGATION;
|
||||
|
||||
nsTableDecoderSupport* decoder =
|
||||
new nsTableDecoderSupport(aScanClass, aShiftInTable, aMappingTable,
|
||||
aMaxLengthFactor);
|
||||
if (!decoder)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
return StabilizedQueryInterface(decoder, aIID, aResult);
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
CreateOneByteDecoder(uMappingTable * aMappingTable,
|
||||
|
||||
|
|
|
@ -61,15 +61,6 @@ CreateTableEncoder(uScanClassID aScanClass,
|
|||
REFNSIID aIID,
|
||||
void** aResult);
|
||||
|
||||
NS_METHOD
|
||||
CreateTableDecoder(uScanClassID aScanClass,
|
||||
uShiftInTable * aShiftInTable,
|
||||
uMappingTable * aMappingTable,
|
||||
uint32_t aMaxLengthFactor,
|
||||
nsISupports* aOuter,
|
||||
REFNSIID aIID,
|
||||
void** aResult);
|
||||
|
||||
NS_METHOD
|
||||
CreateOneByteDecoder(uMappingTable * aMappingTable,
|
||||
nsISupports* aOuter,
|
||||
|
|
|
@ -384,6 +384,7 @@ selfhosted_out_h_deps := \
|
|||
$(srcdir)/js.msg \
|
||||
$(srcdir)/builtin/embedjs.py \
|
||||
$(srcdir)/builtin/TypedObjectConstants.h \
|
||||
$(srcdir)/builtin/SelfHostingDefines.h \
|
||||
$(NULL)
|
||||
|
||||
SELFHOSTED_DEFINES += $(DEFINES) $(ACDEFINES)
|
||||
|
|
|
@ -160,7 +160,7 @@ function loadCallgraph(file)
|
|||
suppressedFunctions[name] = true;
|
||||
}
|
||||
|
||||
for (var gcName of [ 'jsgc.cpp:void Collect(JSRuntime*, uint8, int64, uint32, uint32)',
|
||||
for (var gcName of [ 'void js::gc::GCRuntime::collect(uint8, int64, uint32, uint32)',
|
||||
'void js::MinorGC(JSRuntime*, uint32)' ])
|
||||
{
|
||||
assert(gcName in mangledName);
|
||||
|
|
|
@ -43,6 +43,7 @@ namespace gc {
|
|||
typedef Vector<JS::Zone *, 4, SystemAllocPolicy> ZoneVector;
|
||||
|
||||
class MarkingValidator;
|
||||
class AutoPrepareForTracing;
|
||||
|
||||
struct ConservativeGCData
|
||||
{
|
||||
|
@ -88,8 +89,77 @@ class GCRuntime
|
|||
{
|
||||
public:
|
||||
GCRuntime(JSRuntime *rt);
|
||||
bool init(uint32_t maxbytes);
|
||||
void finish();
|
||||
|
||||
void setGCZeal(uint8_t zeal, uint32_t frequency);
|
||||
template <typename T> bool addRoot(T *rp, const char *name, JSGCRootType rootType);
|
||||
void removeRoot(void *rp);
|
||||
void setMarkStackLimit(size_t limit);
|
||||
|
||||
bool isHeapBusy() { return heapState != js::Idle; }
|
||||
bool isHeapMajorCollecting() { return heapState == js::MajorCollecting; }
|
||||
bool isHeapMinorCollecting() { return heapState == js::MinorCollecting; }
|
||||
bool isHeapCollecting() { return isHeapMajorCollecting() || isHeapMinorCollecting(); }
|
||||
|
||||
bool triggerGC(JS::gcreason::Reason reason);
|
||||
bool triggerZoneGC(Zone *zone, JS::gcreason::Reason reason);
|
||||
void maybeGC(Zone *zone);
|
||||
void minorGC(JS::gcreason::Reason reason);
|
||||
void minorGC(JSContext *cx, JS::gcreason::Reason reason);
|
||||
void gcIfNeeded(JSContext *cx);
|
||||
void collect(bool incremental, int64_t budget, JSGCInvocationKind gckind,
|
||||
JS::gcreason::Reason reason);
|
||||
void gcSlice(JSGCInvocationKind gckind, JS::gcreason::Reason reason, int64_t millis);
|
||||
void runDebugGC();
|
||||
|
||||
private:
|
||||
// For ArenaLists::allocateFromArenaInline()
|
||||
friend class ArenaLists;
|
||||
Chunk *pickChunk(Zone *zone);
|
||||
|
||||
inline bool wantBackgroundAllocation() const;
|
||||
|
||||
bool initGCZeal();
|
||||
void recordNativeStackTopForGC();
|
||||
void requestInterrupt(JS::gcreason::Reason reason);
|
||||
bool gcCycle(bool incremental, int64_t budget, JSGCInvocationKind gckind,
|
||||
JS::gcreason::Reason reason);
|
||||
void budgetIncrementalGC(int64_t *budget);
|
||||
void resetIncrementalGC(const char *reason);
|
||||
void incrementalCollectSlice(int64_t budget, JS::gcreason::Reason reason,
|
||||
JSGCInvocationKind gckind);
|
||||
void pushZealSelectedObjects();
|
||||
bool beginMarkPhase();
|
||||
bool shouldPreserveJITCode(JSCompartment *comp, int64_t currentTime);
|
||||
bool drainMarkStack(SliceBudget &sliceBudget, gcstats::Phase phase);
|
||||
template <class CompartmentIterT> void markWeakReferences(gcstats::Phase phase);
|
||||
void markWeakReferencesInCurrentGroup(gcstats::Phase phase);
|
||||
template <class ZoneIterT, class CompartmentIterT> void markGrayReferences();
|
||||
void markGrayReferencesInCurrentGroup();
|
||||
void beginSweepPhase(bool lastGC);
|
||||
void findZoneGroups();
|
||||
void getNextZoneGroup();
|
||||
void endMarkingZoneGroup();
|
||||
void beginSweepingZoneGroup();
|
||||
bool releaseObservedTypes();
|
||||
void endSweepingZoneGroup();
|
||||
bool sweepPhase(SliceBudget &sliceBudget);
|
||||
void endSweepPhase(JSGCInvocationKind gckind, bool lastGC);
|
||||
void sweepZones(FreeOp *fop, bool lastGC);
|
||||
|
||||
void computeNonIncrementalMarkingForValidation();
|
||||
void validateIncrementalMarking();
|
||||
void finishMarkingValidation();
|
||||
|
||||
#ifdef DEBUG
|
||||
void checkForCompartmentMismatches();
|
||||
void markAllWeakReferences(gcstats::Phase phase);
|
||||
void markAllGrayReferences();
|
||||
#endif
|
||||
|
||||
public: // Internal state, public for now
|
||||
JSRuntime *rt;
|
||||
|
||||
/* Embedders can use this zone however they wish. */
|
||||
JS::Zone *systemZone;
|
||||
|
@ -228,7 +298,7 @@ class GCRuntime
|
|||
*/
|
||||
JS::Zone *zoneGroups;
|
||||
JS::Zone *currentZoneGroup;
|
||||
int sweepPhase;
|
||||
int finalizePhase;
|
||||
JS::Zone *sweepZone;
|
||||
int sweepKindIndex;
|
||||
bool abortSweepAfterCurrentGroup;
|
||||
|
@ -326,11 +396,11 @@ class GCRuntime
|
|||
bool validate;
|
||||
bool fullCompartmentChecks;
|
||||
|
||||
JSGCCallback callback;
|
||||
JSGCCallback gcCallback;
|
||||
JS::GCSliceCallback sliceCallback;
|
||||
JSFinalizeCallback finalizeCallback;
|
||||
|
||||
void *callbackData;
|
||||
void *gcCallbackData;
|
||||
|
||||
/*
|
||||
* Malloc counter to measure memory pressure for GC scheduling. It runs
|
||||
|
@ -377,11 +447,13 @@ class GCRuntime
|
|||
PRLock *lock;
|
||||
mozilla::DebugOnly<PRThread *> lockOwner;
|
||||
|
||||
js::GCHelperThread helperThread;
|
||||
|
||||
ConservativeGCData conservativeGC;
|
||||
|
||||
friend class js::GCHelperThread;
|
||||
|
||||
js::GCHelperThread helperThread;
|
||||
|
||||
ConservativeGCData conservativeGC;
|
||||
friend class js::gc::AutoPrepareForTracing; /* For recordNativeStackTopForGC(). */
|
||||
friend class js::gc::MarkingValidator;
|
||||
};
|
||||
|
||||
} /* namespace gc */
|
||||
|
|
|
@ -34,6 +34,7 @@ void SetGCZeal(JSRuntime *, uint8_t, uint32_t);
|
|||
|
||||
namespace gc {
|
||||
class Cell;
|
||||
class Collector;
|
||||
class MinorCollectionTracer;
|
||||
} /* namespace gc */
|
||||
|
||||
|
@ -150,6 +151,27 @@ class Nursery
|
|||
return ((JS::shadow::Runtime *)runtime_)->gcNurseryEnd_;
|
||||
}
|
||||
|
||||
#ifdef JS_GC_ZEAL
|
||||
/*
|
||||
* In debug and zeal builds, these bytes indicate the state of an unused
|
||||
* segment of nursery-allocated memory.
|
||||
*/
|
||||
void enterZealMode() {
|
||||
if (isEnabled())
|
||||
numActiveChunks_ = NumNurseryChunks;
|
||||
}
|
||||
void leaveZealMode() {
|
||||
if (isEnabled()) {
|
||||
JS_ASSERT(isEmpty());
|
||||
setCurrentChunk(0);
|
||||
currentStart_ = start();
|
||||
}
|
||||
}
|
||||
#else
|
||||
void enterZealMode() {}
|
||||
void leaveZealMode() {}
|
||||
#endif
|
||||
|
||||
private:
|
||||
/*
|
||||
* The start and end pointers are stored under the runtime so that we can
|
||||
|
@ -289,30 +311,8 @@ class Nursery
|
|||
|
||||
static void MinorGCCallback(JSTracer *trc, void **thingp, JSGCTraceKind kind);
|
||||
|
||||
#ifdef JS_GC_ZEAL
|
||||
/*
|
||||
* In debug and zeal builds, these bytes indicate the state of an unused
|
||||
* segment of nursery-allocated memory.
|
||||
*/
|
||||
void enterZealMode() {
|
||||
if (isEnabled())
|
||||
numActiveChunks_ = NumNurseryChunks;
|
||||
}
|
||||
void leaveZealMode() {
|
||||
if (isEnabled()) {
|
||||
JS_ASSERT(isEmpty());
|
||||
setCurrentChunk(0);
|
||||
currentStart_ = start();
|
||||
}
|
||||
}
|
||||
#else
|
||||
void enterZealMode() {}
|
||||
void leaveZealMode() {}
|
||||
#endif
|
||||
|
||||
friend class gc::MinorCollectionTracer;
|
||||
friend class jit::MacroAssembler;
|
||||
friend void SetGCZeal(JSRuntime *, uint8_t, uint32_t);
|
||||
};
|
||||
|
||||
} /* namespace js */
|
||||
|
|
|
@ -102,6 +102,7 @@ struct Zone : public JS::shadow::Zone,
|
|||
{
|
||||
private:
|
||||
friend bool js::CurrentThreadCanAccessZone(Zone *zone);
|
||||
friend class js::gc::GCRuntime;
|
||||
|
||||
public:
|
||||
js::Allocator allocator;
|
||||
|
@ -321,6 +322,7 @@ struct Zone : public JS::shadow::Zone,
|
|||
|
||||
private:
|
||||
void sweepBreakpoints(js::FreeOp *fop);
|
||||
void sweepCompartments(js::FreeOp *fop, bool keepAtleastOne, bool lastGC);
|
||||
|
||||
#ifdef JS_ION
|
||||
js::jit::JitZone *jitZone_;
|
||||
|
|
|
@ -6337,9 +6337,6 @@ IonBuilder::pushDOMTypeBarrier(MInstruction *ins, types::TemporaryTypeSet *obser
|
|||
MDefinition* replace = ins;
|
||||
if (jitinfo->returnType() != JSVAL_TYPE_DOUBLE ||
|
||||
observed->getKnownMIRType() != MIRType_Int32) {
|
||||
JS_ASSERT(jitinfo->returnType() == JSVAL_TYPE_UNKNOWN ||
|
||||
observed->getKnownMIRType() == MIRType_Value ||
|
||||
MIRTypeFromValueType(jitinfo->returnType()) == observed->getKnownMIRType());
|
||||
replace = ensureDefiniteType(ins, MIRTypeFromValueType(jitinfo->returnType()));
|
||||
if (replace != ins) {
|
||||
current->pop();
|
||||
|
|
|
@ -1907,8 +1907,8 @@ JS_PUBLIC_API(void)
|
|||
JS_SetGCCallback(JSRuntime *rt, JSGCCallback cb, void *data)
|
||||
{
|
||||
AssertHeapIsIdle(rt);
|
||||
rt->gc.callback = cb;
|
||||
rt->gc.callbackData = data;
|
||||
rt->gc.gcCallback = cb;
|
||||
rt->gc.gcCallbackData = data;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
|
|
|
@ -2255,7 +2255,7 @@ class AutoIdArray : private AutoGCRooter
|
|||
if (idArray)
|
||||
JS_DestroyIdArray(context, idArray);
|
||||
}
|
||||
bool operator!() {
|
||||
bool operator!() const {
|
||||
return !idArray;
|
||||
}
|
||||
jsid operator[](size_t i) const {
|
||||
|
|
1111
js/src/jsgc.cpp
1111
js/src/jsgc.cpp
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -9,6 +9,7 @@
|
|||
#ifndef jsgc_h
|
||||
#define jsgc_h
|
||||
|
||||
#include "mozilla/Atomics.h"
|
||||
#include "mozilla/DebugOnly.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
|
||||
|
@ -89,8 +90,6 @@ class ChunkPool {
|
|||
return emptyCount;
|
||||
}
|
||||
|
||||
inline bool wantBackgroundAllocation(JSRuntime *rt) const;
|
||||
|
||||
/* Must be called with the GC lock taken. */
|
||||
inline Chunk *get(JSRuntime *rt);
|
||||
|
||||
|
@ -561,13 +560,16 @@ class ArenaLists
|
|||
* that case the lock effectively serves as a read barrier to ensure that
|
||||
* the allocation thread sees all the writes done during finalization.
|
||||
*/
|
||||
enum BackgroundFinalizeState {
|
||||
enum BackgroundFinalizeStateEnum {
|
||||
BFS_DONE,
|
||||
BFS_RUN,
|
||||
BFS_JUST_FINISHED
|
||||
};
|
||||
|
||||
volatile uintptr_t backgroundFinalizeState[FINALIZE_LIMIT];
|
||||
typedef mozilla::Atomic<BackgroundFinalizeStateEnum, mozilla::ReleaseAcquire>
|
||||
BackgroundFinalizeState;
|
||||
|
||||
BackgroundFinalizeState backgroundFinalizeState[FINALIZE_LIMIT];
|
||||
|
||||
public:
|
||||
/* For each arena kind, a list of arenas remaining to be swept. */
|
||||
|
|
|
@ -4028,8 +4028,8 @@ LookupPropertyInline(ExclusiveContext *cx,
|
|||
typename MaybeRooted<JSObject*, allowGC>::MutableHandleType objp,
|
||||
typename MaybeRooted<Shape*, allowGC>::MutableHandleType propp)
|
||||
{
|
||||
/* NB: The logic of this procedure is implicitly reflected in IonBuilder.cpp's
|
||||
* |CanEffectlesslyCallLookupGenericOnObject| logic.
|
||||
/* NB: The logic of this procedure is implicitly reflected in
|
||||
* BaselineIC.cpp's |EffectlesslyLookupProperty| logic.
|
||||
* If this changes, please remember to update the logic there as well.
|
||||
*/
|
||||
|
||||
|
@ -4089,9 +4089,8 @@ baseops::LookupProperty<NoGC>(ExclusiveContext *cx, JSObject *obj, jsid id,
|
|||
JSObject::lookupGeneric(JSContext *cx, HandleObject obj, js::HandleId id,
|
||||
MutableHandleObject objp, MutableHandleShape propp)
|
||||
{
|
||||
/*
|
||||
* NB: The logic of lookupGeneric is implicitly reflected in IonBuilder.cpp's
|
||||
* |CanEffectlesslyCallLookupGenericOnObject| logic.
|
||||
/* NB: The logic of lookupGeneric is implicitly reflected in
|
||||
* BaselineIC.cpp's |EffectlesslyLookupProperty| logic.
|
||||
* If this changes, please remember to update the logic there as well.
|
||||
*/
|
||||
LookupGenericOp op = obj->getOps()->lookupGeneric;
|
||||
|
|
|
@ -159,6 +159,7 @@ namespace js {
|
|||
namespace gc {
|
||||
class StoreBuffer;
|
||||
void MarkPersistentRootedChains(JSTracer *);
|
||||
void FinishPersistentRootedChains(JSRuntime *);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -212,7 +213,7 @@ struct Runtime
|
|||
private:
|
||||
template <typename Referent> friend class JS::PersistentRooted;
|
||||
friend void js::gc::MarkPersistentRootedChains(JSTracer *);
|
||||
friend void ::js_FinishGC(JSRuntime *rt);
|
||||
friend void js::gc::FinishPersistentRootedChains(JSRuntime *rt);
|
||||
|
||||
mozilla::LinkedList<PersistentRootedFunction> functionPersistentRooteds;
|
||||
mozilla::LinkedList<PersistentRootedId> idPersistentRooteds;
|
||||
|
|
|
@ -279,10 +279,7 @@ JSRuntime::init(uint32_t maxbytes)
|
|||
if (!threadPool.init())
|
||||
return false;
|
||||
|
||||
if (!js_InitGC(this, maxbytes))
|
||||
return false;
|
||||
|
||||
if (!gc.marker.init(gcMode()))
|
||||
if (!gc.init(maxbytes))
|
||||
return false;
|
||||
|
||||
const char *size = getenv("JSGC_MARK_STACK_LIMIT");
|
||||
|
@ -429,7 +426,7 @@ JSRuntime::~JSRuntime()
|
|||
FinishRuntimeNumberState(this);
|
||||
#endif
|
||||
|
||||
js_FinishGC(this);
|
||||
gc.finish();
|
||||
atomsCompartment_ = nullptr;
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
|
|
|
@ -925,10 +925,10 @@ struct JSRuntime : public JS::shadow::Runtime,
|
|||
gc.marker.setGCMode(mode);
|
||||
}
|
||||
|
||||
bool isHeapBusy() { return gc.heapState != js::Idle; }
|
||||
bool isHeapMajorCollecting() { return gc.heapState == js::MajorCollecting; }
|
||||
bool isHeapMinorCollecting() { return gc.heapState == js::MinorCollecting; }
|
||||
bool isHeapCollecting() { return isHeapMajorCollecting() || isHeapMinorCollecting(); }
|
||||
bool isHeapBusy() { return gc.isHeapBusy(); }
|
||||
bool isHeapMajorCollecting() { return gc.isHeapMajorCollecting(); }
|
||||
bool isHeapMinorCollecting() { return gc.isHeapMinorCollecting(); }
|
||||
bool isHeapCollecting() { return gc.isHeapCollecting(); }
|
||||
|
||||
#ifdef JS_GC_ZEAL
|
||||
int gcZeal() { return gc.zealMode; }
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
<html class="reftest-wait">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
</head>
|
||||
<body onload="start()">
|
||||
<input type="text" style="text-align:right;">
|
||||
<script>
|
||||
function start() {
|
||||
var input = document.querySelector("input");
|
||||
input.focus();
|
||||
document.documentElement.removeAttribute("class");
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,15 @@
|
|||
<html class="reftest-wait">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
</head>
|
||||
<body onload="start()">
|
||||
<input type="text" style="text-align:right; overflow:hidden;">
|
||||
<script>
|
||||
function start() {
|
||||
var input = document.querySelector("input");
|
||||
input.focus();
|
||||
document.documentElement.removeAttribute("class");
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -157,6 +157,8 @@ support-files =
|
|||
bug966992-2-ref.html
|
||||
bug966992-3.html
|
||||
bug966992-3-ref.html
|
||||
bug1007065-1.html
|
||||
bug1007065-1-ref.html
|
||||
[test_bug514127.html]
|
||||
[test_bug518777.html]
|
||||
[test_bug548545.xhtml]
|
||||
|
|
|
@ -136,6 +136,7 @@ var tests = [
|
|||
[ 'bug682712-1.html' , 'bug682712-1-ref.html' ] ,
|
||||
function() {SpecialPowers.clearUserPref("bidi.browser.ui");} ,
|
||||
[ 'bug746993-1.html' , 'bug746993-1-ref.html' ] ,
|
||||
[ 'bug1007065-1.html' , 'bug1007065-1-ref.html' ] ,
|
||||
];
|
||||
|
||||
if (navigator.appVersion.indexOf("Android") == -1 &&
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче