pdf: Warn about form changes entering annotation
This is a contingency for the event that the annotation feature is enabled but form saving is not. * A new field hasUnsavedChanges is added to the save result, this is set when there are edits but form saving is not enabled. * When this field is true, a dialog is shown to the user allowing a choice whether to continue to enter annotation mode or not. * The annotation toggle event is made custom to avoid re-entrancy when entering anntation mode is aborted. Bug: 902646 Change-Id: I885aa9ee76afb500a086097aed08422ececdf052 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1502255 Reviewed-by: Lei Zhang <thestig@chromium.org> Reviewed-by: dsinclair <dsinclair@chromium.org> Commit-Queue: dstockwell <dstockwell@chromium.org> Cr-Commit-Position: refs/heads/master@{#637893}
This commit is contained in:
chrome/browser
extensions
api
resources_private
resources
component_extension_resources.grd
pdf
ui
webui
print_preview
pdf
@ -118,6 +118,12 @@ void AddStringsForPdf(base::DictionaryValue* dict) {
|
||||
SetL10nString(dict, "annotationSize12", IDS_PDF_ANNOTATION_SIZE12);
|
||||
SetL10nString(dict, "annotationSize16", IDS_PDF_ANNOTATION_SIZE16);
|
||||
SetL10nString(dict, "annotationSize20", IDS_PDF_ANNOTATION_SIZE20);
|
||||
SetL10nString(dict, "annotationFormWarningTitle",
|
||||
IDS_PDF_DISCARD_FORM_CHANGES);
|
||||
SetL10nString(dict, "annotationFormWarningDetail",
|
||||
IDS_PDF_DISCARD_FORM_CHANGES_DETAIL);
|
||||
SetL10nString(dict, "annotationFormWarningKeepEditing", IDS_PDF_KEEP_EDITING);
|
||||
SetL10nString(dict, "annotationFormWarningDiscard", IDS_PDF_DISCARD);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -131,6 +131,8 @@
|
||||
<include name="IDR_PDF_VIEWER_INK_HOST_JS" file="pdf/elements/viewer-ink-host/viewer-ink-host.js" type="BINDATA" />
|
||||
<include name="IDR_PDF_VIEWER_PEN_OPTIONS_HTML" file="pdf/elements/viewer-pen-options/viewer-pen-options.html" type="BINDATA" />
|
||||
<include name="IDR_PDF_VIEWER_PEN_OPTIONS_JS" file="pdf/elements/viewer-pen-options/viewer-pen-options.js" type="BINDATA" />
|
||||
<include name="IDR_PDF_VIEWER_FORM_WARNING_HTML" file="pdf/elements/viewer-form-warning/viewer-form-warning.html" type="BINDATA" />
|
||||
<include name="IDR_PDF_VIEWER_FORM_WARNING_JS" file="pdf/elements/viewer-form-warning/viewer-form-warning.js" type="BINDATA" />
|
||||
</if>
|
||||
<include name="IDR_PDF_VIEWER_PAGE_INDICATOR_HTML" file="pdf/elements/viewer-page-indicator/viewer-page-indicator.html" type="BINDATA" />
|
||||
<include name="IDR_PDF_VIEWER_PAGE_INDICATOR_JS" file="pdf/elements/viewer-page-indicator/viewer-page-indicator.js" type="BINDATA" flattenhtml="true" />
|
||||
|
@ -10,6 +10,7 @@ group("closure_compile") {
|
||||
":pdf_resources",
|
||||
"elements/viewer-bookmark:closure_compile",
|
||||
"elements/viewer-error-screen:closure_compile",
|
||||
"elements/viewer-form-warning:closure_compile",
|
||||
"elements/viewer-page-indicator:closure_compile",
|
||||
"elements/viewer-page-selector:closure_compile",
|
||||
"elements/viewer-password-screen:closure_compile",
|
||||
|
@ -0,0 +1,18 @@
|
||||
# Copyright 2019 The Chromium Authors. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
import("//third_party/closure_compiler/compile_js.gni")
|
||||
|
||||
js_type_check("closure_compile") {
|
||||
deps = [
|
||||
":viewer-form-warning",
|
||||
]
|
||||
}
|
||||
|
||||
js_library("viewer-form-warning") {
|
||||
deps = [
|
||||
"//ui/webui/resources/cr_elements/cr_dialog:cr_dialog",
|
||||
"//ui/webui/resources/js:promise_resolver",
|
||||
]
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
<link rel="import" href="chrome://resources/html/polymer.html">
|
||||
|
||||
<link rel="import" href="chrome://resources/cr_elements/cr_dialog/cr_dialog.html">
|
||||
<link rel="import" href="chrome://resources/cr_elements/hidden_style_css.html">
|
||||
<link rel="import" href="chrome://resources/cr_elements/paper_button_style_css.html">
|
||||
<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html">
|
||||
|
||||
<dom-module id="viewer-form-warning">
|
||||
<template>
|
||||
<style include="paper-button-style cr-hidden-style"></style>
|
||||
<cr-dialog id="dialog" no-cancel>
|
||||
<div slot="title">[[strings.annotationFormWarningTitle]]</div>
|
||||
<div slot="body">[[strings.annotationFormWarningDetail]]</div>
|
||||
<div slot="button-container">
|
||||
<paper-button class="cancel-button" on-click="onCancel">
|
||||
[[strings.annotationFormWarningKeepEditing]]
|
||||
</paper-button>
|
||||
<paper-button class="action-button" on-click="onAction">
|
||||
[[strings.annotationFormWarningDiscard]]
|
||||
</paper-button>
|
||||
</div>
|
||||
</cr-dialog>
|
||||
</template>
|
||||
<script src="viewer-form-warning.js"></script>
|
||||
</dom-module>
|
@ -0,0 +1,29 @@
|
||||
// Copyright 2019 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
Polymer({
|
||||
is: 'viewer-form-warning',
|
||||
properties: {
|
||||
strings: Object,
|
||||
},
|
||||
|
||||
/** @private {PromiseResolver} */
|
||||
resolver_: null,
|
||||
|
||||
show: function() {
|
||||
this.resolver_ = new PromiseResolver();
|
||||
/** @type {!CrDialogElement} */ (this.$.dialog).showModal();
|
||||
return this.resolver_.promise;
|
||||
},
|
||||
|
||||
onCancel: function() {
|
||||
this.resolver_.reject();
|
||||
this.$.dialog.cancel();
|
||||
},
|
||||
|
||||
onAction: function() {
|
||||
this.resolver_.resolve();
|
||||
this.$.dialog.close();
|
||||
},
|
||||
});
|
@ -190,6 +190,11 @@ Polymer({
|
||||
// Select pen tool when entering annotation mode.
|
||||
this.updateAnnotationTool_(this.$.pen);
|
||||
}
|
||||
this.dispatchEvent(new CustomEvent('annotation-mode-toggled', {
|
||||
detail: {
|
||||
value: this.annotationMode,
|
||||
},
|
||||
}));
|
||||
},
|
||||
|
||||
/** @param {Event} e */
|
||||
|
@ -9,9 +9,11 @@
|
||||
<link rel="import" href="elements/viewer-pdf-toolbar/viewer-pdf-toolbar.html">
|
||||
<link rel="import" href="elements/viewer-zoom-toolbar/viewer-zoom-toolbar.html">
|
||||
<link rel="import" href="elements/shared-vars.html">
|
||||
<link rel="import" href="chrome://resources/cr_elements/cr_dialog/cr_dialog.html">
|
||||
|
||||
<if expr="chromeos">
|
||||
<link rel="import" href="elements/viewer-ink-host/viewer-ink-host.html">
|
||||
<link rel="import" href="elements/viewer-form-warning/viewer-form-warning.html">
|
||||
</if>
|
||||
|
||||
<link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css">
|
||||
@ -30,6 +32,10 @@
|
||||
|
||||
<viewer-error-screen id="error-screen"></viewer-error-screen>
|
||||
|
||||
<if expr="chromeos">
|
||||
<viewer-form-warning id="form-warning"></viewer-form-warning>
|
||||
</if>
|
||||
|
||||
<div id="content"></div>
|
||||
|
||||
</body>
|
||||
|
@ -256,7 +256,7 @@ function PDFViewer(browserApi) {
|
||||
this.toolbar_.addEventListener(
|
||||
'rotate-right', () => this.rotateClockwise());
|
||||
this.toolbar_.addEventListener(
|
||||
'annotation-mode-changed', e => this.annotationModeChanged_(e));
|
||||
'annotation-mode-toggled', e => this.annotationModeToggled_(e));
|
||||
this.toolbar_.addEventListener(
|
||||
'annotation-tool-changed',
|
||||
e => this.inkController_.setAnnotationTool(e.detail.value));
|
||||
@ -500,17 +500,28 @@ PDFViewer.prototype = {
|
||||
* @param {!CustomEvent<{value: boolean}>} e
|
||||
* @private
|
||||
*/
|
||||
annotationModeChanged_: async function(e) {
|
||||
annotationModeToggled_: async function(e) {
|
||||
const annotationMode = e.detail.value;
|
||||
if (annotationMode) {
|
||||
// Enter annotation mode.
|
||||
PDFMetrics.record(PDFMetrics.UserAction.ENTER_ANNOTATION_MODE);
|
||||
this.hasEnteredAnnotationMode_ = true;
|
||||
assert(this.currentController_ == this.pluginController_);
|
||||
// TODO(dstockwell): set plugin read-only, begin transition
|
||||
this.updateProgress(0);
|
||||
// TODO(dstockwell): handle save failure
|
||||
const result = await this.pluginController_.save(true);
|
||||
if (result.hasUnsavedChanges) {
|
||||
assert(!loadTimeData.getBoolean('pdfFormSaveEnabled'));
|
||||
try {
|
||||
await $('form-warning').show();
|
||||
} catch (e) {
|
||||
// The user aborted entering annotation mode. Revert to the plugin.
|
||||
this.toolbar_.annotationMode = false;
|
||||
this.updateProgress(100);
|
||||
return;
|
||||
}
|
||||
}
|
||||
PDFMetrics.record(PDFMetrics.UserAction.ENTER_ANNOTATION_MODE);
|
||||
this.hasEnteredAnnotationMode_ = true;
|
||||
// TODO(dstockwell): feed real progress data from the Ink component
|
||||
this.updateProgress(50);
|
||||
await this.inkController_.load(result.fileName, result.dataToSave);
|
||||
@ -737,6 +748,9 @@ PDFViewer.prototype = {
|
||||
$('zoom-toolbar').strings = strings;
|
||||
$('password-screen').strings = strings;
|
||||
$('error-screen').strings = strings;
|
||||
if ($('form-warning')) {
|
||||
$('form-warning').strings = strings;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -364,6 +364,10 @@ std::vector<std::string> SetupPrintPreviewPlugin(
|
||||
{"pdf/elements/viewer-pdf-toolbar/viewer-pdf-toolbar.js",
|
||||
IDR_PDF_VIEWER_PDF_TOOLBAR_JS},
|
||||
#if defined(OS_CHROMEOS)
|
||||
{"pdf/elements/viewer-form-warning/viewer-form-warning.html",
|
||||
IDR_PDF_VIEWER_FORM_WARNING_HTML},
|
||||
{"pdf/elements/viewer-form-warning/viewer-form-warning.js",
|
||||
IDR_PDF_VIEWER_FORM_WARNING_JS},
|
||||
{"pdf/elements/viewer-pen-options/viewer-pen-options.html",
|
||||
IDR_PDF_VIEWER_PEN_OPTIONS_HTML},
|
||||
{"pdf/elements/viewer-pen-options/viewer-pen-options.js",
|
||||
|
@ -106,6 +106,7 @@ constexpr char kJSForce[] = "force";
|
||||
constexpr char kJSSaveDataType[] = "saveData";
|
||||
constexpr char kJSFileName[] = "fileName";
|
||||
constexpr char kJSDataToSave[] = "dataToSave";
|
||||
constexpr char kJSHasUnsavedChanges[] = "hasUnsavedChanges";
|
||||
// Consume save token (Plugin -> Page)
|
||||
constexpr char kJSConsumeSaveTokenType[] = "consumeSaveToken";
|
||||
// Go to page (Plugin -> Page)
|
||||
@ -1453,6 +1454,9 @@ void OutOfProcessInstance::SaveToBuffer(const std::string& token) {
|
||||
message.Set(kJSFileName, pp::Var(file_name));
|
||||
// This will be overwritten if the save is successful.
|
||||
message.Set(kJSDataToSave, pp::Var(pp::Var::Null()));
|
||||
const bool hasUnsavedChanges =
|
||||
edit_mode_ && !base::FeatureList::IsEnabled(features::kSaveEditedPDFForm);
|
||||
message.Set(kJSHasUnsavedChanges, pp::Var(hasUnsavedChanges));
|
||||
|
||||
if (ShouldSaveEdits()) {
|
||||
std::vector<uint8_t> data = engine_->GetSaveData();
|
||||
|
Reference in New Issue
Block a user