mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-27 04:38:02 +00:00
Bug 1682162 - Use the paperSizeUnit to display and handle mm/inch custom margin values. r=emalysz,fluent-reviewers,flod
Differential Revision: https://phabricator.services.mozilla.com/D104291
This commit is contained in:
parent
2dd2d5d19d
commit
72d4c476b1
@ -75,7 +75,7 @@
|
||||
<option value="default" data-l10n-id="printui-margins-default"></option>
|
||||
<option value="minimum" data-l10n-id="printui-margins-min"></option>
|
||||
<option value="none" data-l10n-id="printui-margins-none"></option>
|
||||
<option value="custom" data-l10n-id="printui-margins-custom-inches"></option>
|
||||
<option value="custom" data-unit-prefix-l10n-id="printui-margins-custom-"></option>
|
||||
</select>
|
||||
<div id="custom-margins" class="margin-group" role="group" hidden>
|
||||
<div class="vertical-margins">
|
||||
@ -85,7 +85,7 @@
|
||||
aria-describedby="margins-custom-margin-top-desc"
|
||||
min="0" step="0.01" required>
|
||||
<label for="custom-margin-top" class="margin-descriptor" data-l10n-id="printui-margins-custom-top"></label>
|
||||
<label hidden id="margins-custom-margin-top-desc" data-l10n-id="printui-margins-custom-top-inches"></label>
|
||||
<label hidden id="margins-custom-margin-top-desc" data-unit-prefix-l10n-id="printui-margins-custom-top-"></label>
|
||||
</div>
|
||||
<div class="margin-pair">
|
||||
<input is="setting-number"
|
||||
@ -93,7 +93,7 @@
|
||||
aria-describedby="margins-custom-margin-bottom-desc"
|
||||
min="0" step="0.01" required>
|
||||
<label for="custom-margin-bottom" class="margin-descriptor" data-l10n-id="printui-margins-custom-bottom"></label>
|
||||
<label hidden id="margins-custom-margin-bottom-desc" data-l10n-id="printui-margins-custom-bottom-inches"></label>
|
||||
<label hidden id="margins-custom-margin-bottom-desc" data-unit-prefix-l10n-id="printui-margins-custom-bottom-"></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="horizontal-margins">
|
||||
@ -103,7 +103,7 @@
|
||||
aria-describedby="margins-custom-margin-left-desc"
|
||||
min="0" step="0.01" required>
|
||||
<label for="custom-margin-left" class="margin-descriptor" data-l10n-id="printui-margins-custom-left"></label>
|
||||
<label hidden id="margins-custom-margin-left-desc" data-l10n-id="printui-margins-custom-left-inches"></label>
|
||||
<label hidden id="margins-custom-margin-left-desc" data-unit-prefix-l10n-id="printui-margins-custom-left-"></label>
|
||||
</div>
|
||||
<div class="margin-pair">
|
||||
<input is="setting-number"
|
||||
@ -111,7 +111,7 @@
|
||||
aria-describedby="margins-custom-margin-right-desc"
|
||||
min="0" step="0.01" required>
|
||||
<label for="custom-margin-right" class="margin-descriptor" data-l10n-id="printui-margins-custom-right"></label>
|
||||
<label hidden id="margins-custom-margin-right-desc" data-l10n-id="printui-margins-custom-right-inches"></label>
|
||||
<label hidden id="margins-custom-margin-right-desc" data-unit-prefix-l10n-id="printui-margins-custom-right-"></label>
|
||||
</div>
|
||||
</div>
|
||||
<p id="error-invalid-margin" hidden data-l10n-id="printui-error-invalid-margin" class="error-message" role="alert"></p>
|
||||
|
@ -24,6 +24,7 @@ const PDF_JS_URI = "resource://pdf.js/web/viewer.html";
|
||||
const INPUT_DELAY_MS = Cu.isInAutomation ? 100 : 500;
|
||||
const MM_PER_POINT = 25.4 / 72;
|
||||
const INCHES_PER_POINT = 1 / 72;
|
||||
const INCHES_PER_MM = 1 / 25.4;
|
||||
const ourBrowser = window.docShell.chromeEventHandler;
|
||||
const PSSVC = Cc["@mozilla.org/gfx/printsettings-service;1"].getService(
|
||||
Ci.nsIPrintSettingsService
|
||||
@ -499,6 +500,10 @@ var PrintEventHandler = {
|
||||
paperSizeUnit = PrintEventHandler.settings.kPaperSizeMillimeters;
|
||||
} else {
|
||||
paperId = this.viewSettings.paperId;
|
||||
logger.debug(
|
||||
"No paperId or matchedPaper, get a new default from viewSettings:",
|
||||
paperId
|
||||
);
|
||||
paperWidth = this.viewSettings.paperWidth;
|
||||
paperHeight = this.viewSettings.paperHeight;
|
||||
paperSizeUnit = this.viewSettings.paperSizeUnit;
|
||||
@ -2276,6 +2281,8 @@ class MarginsPicker extends PrintUIControlMixin(HTMLElement) {
|
||||
this._customLeftMargin = this.querySelector("#custom-margin-left");
|
||||
this._customRightMargin = this.querySelector("#custom-margin-right");
|
||||
this._marginError = this.querySelector("#error-invalid-margin");
|
||||
this._sizeUnit = null;
|
||||
this._toInchesMultiplier = 1;
|
||||
}
|
||||
|
||||
get templateId() {
|
||||
@ -2284,10 +2291,10 @@ class MarginsPicker extends PrintUIControlMixin(HTMLElement) {
|
||||
|
||||
updateCustomMargins() {
|
||||
let newMargins = {
|
||||
marginTop: this._customTopMargin.value,
|
||||
marginBottom: this._customBottomMargin.value,
|
||||
marginLeft: this._customLeftMargin.value,
|
||||
marginRight: this._customRightMargin.value,
|
||||
marginTop: this.toInchValue(this._customTopMargin.value),
|
||||
marginBottom: this.toInchValue(this._customBottomMargin.value),
|
||||
marginLeft: this.toInchValue(this._customLeftMargin.value),
|
||||
marginRight: this.toInchValue(this._customRightMargin.value),
|
||||
};
|
||||
|
||||
this.dispatchSettingsChange({
|
||||
@ -2298,12 +2305,12 @@ class MarginsPicker extends PrintUIControlMixin(HTMLElement) {
|
||||
}
|
||||
|
||||
updateMaxValues() {
|
||||
this._customTopMargin.max =
|
||||
this._maxHeight - this._customBottomMargin.value;
|
||||
this._customBottomMargin.max =
|
||||
this._maxHeight - this._customTopMargin.value;
|
||||
this._customLeftMargin.max = this._maxWidth - this._customRightMargin.value;
|
||||
this._customRightMargin.max = this._maxWidth - this._customLeftMargin.value;
|
||||
let maxWidth = this.toCurrentUnitValue(this._maxWidth);
|
||||
let maxHeight = this.toCurrentUnitValue(this._maxHeight);
|
||||
this._customTopMargin.max = maxHeight - this._customBottomMargin.value;
|
||||
this._customBottomMargin.max = maxHeight - this._customTopMargin.value;
|
||||
this._customLeftMargin.max = maxWidth - this._customRightMargin.value;
|
||||
this._customRightMargin.max = maxWidth - this._customLeftMargin.value;
|
||||
}
|
||||
|
||||
formatMargin(target) {
|
||||
@ -2315,23 +2322,41 @@ class MarginsPicker extends PrintUIControlMixin(HTMLElement) {
|
||||
}
|
||||
}
|
||||
|
||||
toCurrentUnitValue(val) {
|
||||
if (typeof val == "string") {
|
||||
val = parseFloat(val);
|
||||
}
|
||||
return val / this._toInchesMultiplier;
|
||||
}
|
||||
|
||||
toInchValue(val) {
|
||||
if (typeof val == "string") {
|
||||
val = parseFloat(val);
|
||||
}
|
||||
return val * this._toInchesMultiplier;
|
||||
}
|
||||
|
||||
setAllMarginValues(settings) {
|
||||
this._customTopMargin.value = parseFloat(
|
||||
this._customTopMargin.value = this.toCurrentUnitValue(
|
||||
settings.customMargins.marginTop
|
||||
).toFixed(2);
|
||||
this._customBottomMargin.value = parseFloat(
|
||||
this._customBottomMargin.value = this.toCurrentUnitValue(
|
||||
settings.customMargins.marginBottom
|
||||
).toFixed(2);
|
||||
this._customLeftMargin.value = parseFloat(
|
||||
this._customLeftMargin.value = this.toCurrentUnitValue(
|
||||
settings.customMargins.marginLeft
|
||||
).toFixed(2);
|
||||
this._customRightMargin.value = parseFloat(
|
||||
this._customRightMargin.value = this.toCurrentUnitValue(
|
||||
settings.customMargins.marginRight
|
||||
).toFixed(2);
|
||||
}
|
||||
|
||||
update(settings) {
|
||||
// Re-evaluate which margin options should be enabled whenever the printer or paper changes
|
||||
this._toInchesMultiplier =
|
||||
settings.paperSizeUnit == settings.kPaperSizeMillimeters
|
||||
? INCHES_PER_MM
|
||||
: 1;
|
||||
if (
|
||||
settings.paperId !== this._paperId ||
|
||||
settings.printerName !== this._printerName ||
|
||||
@ -2345,17 +2370,23 @@ class MarginsPicker extends PrintUIControlMixin(HTMLElement) {
|
||||
this._printerName = settings.printerName;
|
||||
this._orientation = settings.orientation;
|
||||
|
||||
// Paper dimensions are in the paperSizeUnit. As the margin values are in inches
|
||||
// we'll normalize to that when storing max dimensions
|
||||
let height =
|
||||
this._orientation == 0 ? settings.paperHeight : settings.paperWidth;
|
||||
let width =
|
||||
this._orientation == 0 ? settings.paperWidth : settings.paperHeight;
|
||||
let heightInches =
|
||||
Math.round(this._toInchesMultiplier * height * 100) / 100;
|
||||
let widthInches =
|
||||
Math.round(this._toInchesMultiplier * width * 100) / 100;
|
||||
|
||||
this._maxHeight =
|
||||
height -
|
||||
heightInches -
|
||||
settings.unwriteableMarginTop -
|
||||
settings.unwriteableMarginBottom;
|
||||
this._maxWidth =
|
||||
width -
|
||||
widthInches -
|
||||
settings.unwriteableMarginLeft -
|
||||
settings.unwriteableMarginRight;
|
||||
|
||||
@ -2368,6 +2399,16 @@ class MarginsPicker extends PrintUIControlMixin(HTMLElement) {
|
||||
this._marginError.hidden = true;
|
||||
}
|
||||
|
||||
if (settings.paperSizeUnit !== this._sizeUnit) {
|
||||
this._sizeUnit = settings.paperSizeUnit;
|
||||
let unitStr =
|
||||
this._sizeUnit == settings.kPaperSizeMillimeters ? "mm" : "inches";
|
||||
for (let elem of this.querySelectorAll("[data-unit-prefix-l10n-id]")) {
|
||||
let l10nId = elem.getAttribute("data-unit-prefix-l10n-id") + unitStr;
|
||||
elem.setAttribute("data-l10n-id", l10nId);
|
||||
}
|
||||
}
|
||||
|
||||
// We need to ensure we don't override the value if the value should be custom.
|
||||
if (this._marginPicker.value != "custom") {
|
||||
// Reset the custom margin values if they are not valid and revalidate the form
|
||||
|
@ -21,7 +21,7 @@ add_task(async function testSanityCheckPaperList() {
|
||||
helper.addMockPrinter({ name: mockPrinterName, paperList });
|
||||
await helper.startPrint();
|
||||
await helper.dispatchSettingsChange({ printerName: mockPrinterName });
|
||||
await helper.awaitAnimationFrame();
|
||||
await helper.waitForSettingsEvent();
|
||||
|
||||
is(
|
||||
helper.settings.printerName,
|
||||
@ -62,7 +62,7 @@ add_task(async function testEmptyPaperListGetsFallbackPaperSizes() {
|
||||
);
|
||||
|
||||
await helper.dispatchSettingsChange({ printerName: mockPrinterName });
|
||||
await helper.awaitAnimationFrame();
|
||||
await helper.waitForSettingsEvent();
|
||||
|
||||
is(
|
||||
helper.settings.printerName,
|
||||
|
@ -800,3 +800,172 @@ add_task(async function testResetMarginPersists() {
|
||||
await helper.closeDialog();
|
||||
});
|
||||
});
|
||||
|
||||
add_task(async function testCustomMarginUnits() {
|
||||
const mockPrinterName = "MetricPrinter";
|
||||
await PrintHelper.withTestPage(async helper => {
|
||||
// Add a metric-unit printer we can test with
|
||||
helper.addMockPrinter({
|
||||
name: mockPrinterName,
|
||||
paperSizeUnit: Ci.nsIPrintSettings.kPaperSizeMillimeters,
|
||||
paperList: [],
|
||||
});
|
||||
|
||||
// settings are saved in inches
|
||||
const persistedMargins = {
|
||||
top: 0.5,
|
||||
right: 5,
|
||||
bottom: 0.5,
|
||||
left: 1,
|
||||
};
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
[
|
||||
"print.printer_Mozilla_Save_to_PDF.print_margin_right",
|
||||
persistedMargins.right.toString(),
|
||||
],
|
||||
[
|
||||
"print.printer_Mozilla_Save_to_PDF.print_margin_left",
|
||||
persistedMargins.left.toString(),
|
||||
],
|
||||
[
|
||||
"print.printer_Mozilla_Save_to_PDF.print_margin_top",
|
||||
persistedMargins.top.toString(),
|
||||
],
|
||||
[
|
||||
"print.printer_Mozilla_Save_to_PDF.print_margin_bottom",
|
||||
persistedMargins.bottom.toString(),
|
||||
],
|
||||
],
|
||||
});
|
||||
await helper.startPrint();
|
||||
await helper.openMoreSettings();
|
||||
|
||||
helper.assertSettingsMatch({
|
||||
paperId: "na_letter",
|
||||
marginTop: persistedMargins.top,
|
||||
marginRight: persistedMargins.right,
|
||||
marginBottom: persistedMargins.bottom,
|
||||
marginLeft: persistedMargins.left,
|
||||
});
|
||||
|
||||
is(
|
||||
helper.settings.printerName,
|
||||
DEFAULT_PRINTER_NAME,
|
||||
"The PDF (inch-unit) printer is current"
|
||||
);
|
||||
|
||||
is(
|
||||
helper.get("margins-picker").value,
|
||||
"custom",
|
||||
"The margins picker has the expected value"
|
||||
);
|
||||
is(
|
||||
helper.get("margins-picker").selectedOptions[0].dataset.l10nId,
|
||||
"printui-margins-custom-inches",
|
||||
"The custom margins option has correct unit string id"
|
||||
);
|
||||
// the unit value should be correct for inches
|
||||
for (let edgeName of Object.keys(persistedMargins)) {
|
||||
is(
|
||||
helper.get(`custom-margin-${edgeName}`).value,
|
||||
persistedMargins[edgeName].toFixed(2),
|
||||
`Has the expected unit-converted ${edgeName}-margin value`
|
||||
);
|
||||
}
|
||||
|
||||
await helper.assertSettingsChanged(
|
||||
{ marginTop: persistedMargins.top },
|
||||
{ marginTop: 1 },
|
||||
async () => {
|
||||
// update the top margin to 1"
|
||||
await helper.text(helper.get("custom-margin-top"), "1");
|
||||
assertPendingMarginsUpdate(helper);
|
||||
|
||||
// Wait for the preview to update, the margin options delay updates by
|
||||
// INPUT_DELAY_MS, which is 500ms.
|
||||
await helper.waitForSettingsEvent();
|
||||
// ensure any round-trip correctly re-converts the setting value back to the displayed mm value
|
||||
is(
|
||||
helper.get("custom-margin-top").value,
|
||||
"1",
|
||||
"Converted custom margin value is expected value"
|
||||
);
|
||||
}
|
||||
);
|
||||
// put it back to how it was
|
||||
await helper.text(
|
||||
helper.get("custom-margin-top"),
|
||||
persistedMargins.top.toString()
|
||||
);
|
||||
await helper.waitForSettingsEvent();
|
||||
|
||||
// Now switch to the metric printer
|
||||
await helper.dispatchSettingsChange({ printerName: mockPrinterName });
|
||||
await helper.waitForSettingsEvent();
|
||||
|
||||
is(
|
||||
helper.settings.printerName,
|
||||
mockPrinterName,
|
||||
"The metric printer is current"
|
||||
);
|
||||
is(
|
||||
helper.get("margins-picker").value,
|
||||
"custom",
|
||||
"The margins picker has the expected value"
|
||||
);
|
||||
is(
|
||||
helper.get("margins-picker").selectedOptions[0].dataset.l10nId,
|
||||
"printui-margins-custom-mm",
|
||||
"The custom margins option has correct unit string id"
|
||||
);
|
||||
// the unit value should be correct for mm
|
||||
for (let edgeName of Object.keys(persistedMargins)) {
|
||||
is(
|
||||
helper.get(`custom-margin-${edgeName}`).value,
|
||||
(persistedMargins[edgeName] * 25.4).toFixed(2),
|
||||
`Has the expected unit-converted ${edgeName}-margin value`
|
||||
);
|
||||
}
|
||||
|
||||
await helper.assertSettingsChanged(
|
||||
{ marginTop: persistedMargins.top },
|
||||
{ marginTop: 1 },
|
||||
async () => {
|
||||
let marginError = helper.get("error-invalid-margin");
|
||||
ok(marginError.hidden, "Margin error is hidden");
|
||||
|
||||
// update the top margin to 1" in mm
|
||||
await helper.text(helper.get("custom-margin-top"), "25.4");
|
||||
// Check the constraints validation is using the right max
|
||||
// as 25" top margin would be an error, but 25mm is ok
|
||||
ok(marginError.hidden, "Margin error is hidden");
|
||||
|
||||
assertPendingMarginsUpdate(helper);
|
||||
// Wait for the preview to update, the margin options delay updates by INPUT_DELAY_MS
|
||||
await helper.waitForSettingsEvent();
|
||||
// ensure any round-trip correctly re-converts the setting value back to the displayed mm value
|
||||
is(
|
||||
helper.get("custom-margin-top").value,
|
||||
"25.4",
|
||||
"Converted custom margin value is expected value"
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
// check margin validation is actually working with unit-appropriate max
|
||||
await helper.assertSettingsNotChanged({ marginTop: 1 }, async () => {
|
||||
let marginError = helper.get("error-invalid-margin");
|
||||
ok(marginError.hidden, "Margin error is hidden");
|
||||
|
||||
await helper.text(helper.get("custom-margin-top"), "300");
|
||||
await BrowserTestUtils.waitForAttributeRemoval("hidden", marginError);
|
||||
|
||||
ok(!marginError.hidden, "Margin error is showing");
|
||||
assertNoPendingMarginsUpdate(helper);
|
||||
});
|
||||
|
||||
await SpecialPowers.popPrefEnv();
|
||||
await helper.closeDialog();
|
||||
});
|
||||
});
|
||||
|
@ -1,4 +1,5 @@
|
||||
const PRINT_DOCUMENT_URI = "chrome://global/content/print.html";
|
||||
const DEFAULT_PRINTER_NAME = "Mozilla Save to PDF";
|
||||
const { MockFilePicker } = SpecialPowers;
|
||||
|
||||
let pickerMocked = false;
|
||||
@ -78,13 +79,18 @@ class PrintHelper {
|
||||
name: "Regular Size",
|
||||
width: 612,
|
||||
height: 792,
|
||||
unwriteableMargin: {
|
||||
marginTop: 0.1,
|
||||
marginBottom: 0.1,
|
||||
marginLeft: 0.1,
|
||||
marginRight: 0.1,
|
||||
QueryInterface: ChromeUtils.generateQI([Ci.nsIPaperMargin]),
|
||||
},
|
||||
unwriteableMargin: Promise.resolve(
|
||||
Object.assign(
|
||||
{
|
||||
top: 0.1,
|
||||
bottom: 0.1,
|
||||
left: 0.1,
|
||||
right: 0.1,
|
||||
QueryInterface: ChromeUtils.generateQI([Ci.nsIPaperMargin]),
|
||||
},
|
||||
paperProperties.unwriteableMargin
|
||||
)
|
||||
),
|
||||
QueryInterface: ChromeUtils.generateQI([Ci.nsIPaper]),
|
||||
},
|
||||
paperProperties
|
||||
@ -237,18 +243,45 @@ class PrintHelper {
|
||||
}
|
||||
let {
|
||||
name = "Mock Printer",
|
||||
paperList = [],
|
||||
paperList,
|
||||
printerInfoPromise = Promise.resolve(),
|
||||
paperSizeUnit = Ci.nsIPrintSettings.kPaperSizeInches,
|
||||
paperId,
|
||||
} = opts;
|
||||
let PSSVC = Cc["@mozilla.org/gfx/printsettings-service;1"].getService(
|
||||
Ci.nsIPrintSettingsService
|
||||
);
|
||||
// Use the fallbackPaperList as the default for mock printers
|
||||
if (!paperList) {
|
||||
info("addMockPrinter, using the fallbackPaperList");
|
||||
paperList = Cc["@mozilla.org/gfx/printerlist;1"].createInstance(
|
||||
Ci.nsIPrinterList
|
||||
).fallbackPaperList;
|
||||
}
|
||||
|
||||
let defaultSettings = PSSVC.newPrintSettings;
|
||||
defaultSettings.printerName = name;
|
||||
defaultSettings.toFileName = "";
|
||||
defaultSettings.outputFormat = Ci.nsIPrintSettings.kOutputFormatNative;
|
||||
defaultSettings.printToFile = false;
|
||||
defaultSettings.paperSizeUnit = paperSizeUnit;
|
||||
if (paperId) {
|
||||
defaultSettings.paperId = paperId;
|
||||
}
|
||||
|
||||
if (
|
||||
defaultSettings.paperId &&
|
||||
Array.from(paperList).find(p => p.id == defaultSettings.paperId)
|
||||
) {
|
||||
info(
|
||||
`addMockPrinter, using paperId: ${defaultSettings.paperId} from the paperList`
|
||||
);
|
||||
} else if (paperList.length) {
|
||||
defaultSettings.paperId = paperList[0].id;
|
||||
info(
|
||||
`addMockPrinter, corrected default paperId setting value: ${defaultSettings.paperId}`
|
||||
);
|
||||
}
|
||||
|
||||
let printer = {
|
||||
name,
|
||||
|
@ -68,14 +68,19 @@ printui-margins-default = Default
|
||||
printui-margins-min = Minimum
|
||||
printui-margins-none = None
|
||||
printui-margins-custom-inches = Custom (inches)
|
||||
printui-margins-custom-mm = Custom (mm)
|
||||
printui-margins-custom-top = Top
|
||||
printui-margins-custom-top-inches = Top (inches)
|
||||
printui-margins-custom-top-mm = Top (mm)
|
||||
printui-margins-custom-bottom = Bottom
|
||||
printui-margins-custom-bottom-inches = Bottom (inches)
|
||||
printui-margins-custom-bottom-mm = Bottom (mm)
|
||||
printui-margins-custom-left = Left
|
||||
printui-margins-custom-left-inches = Left (inches)
|
||||
printui-margins-custom-left-mm = Left (mm)
|
||||
printui-margins-custom-right = Right
|
||||
printui-margins-custom-right-inches = Right (inches)
|
||||
printui-margins-custom-right-mm = Right (mm)
|
||||
|
||||
printui-system-dialog-link = Print using the system dialog…
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user