This commit is contained in:
Ryan VanderMeulen 2014-05-12 16:33:27 -04:00
Родитель cf5b79cfb2 df91ea951b
Коммит a95d50a6d2
146 изменённых файлов: 4154 добавлений и 4053 удалений

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

@ -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(() => {

1
browser/devtools/webconsole/test/browser.ini Normal file → Executable file
Просмотреть файл

@ -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 {

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

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

@ -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 &&

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше