Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(115)

Side by Side Diff: chrome/browser/resources/print_preview/margin_settings.js

Issue 8233030: Print Preview: Making margin lines draggable. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixing mouse events outside the plugin area, adding documentations Created 9 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 cr.define('print_preview', function() { 5 cr.define('print_preview', function() {
6 'use strict'; 6 'use strict';
7 7
8 /** 8 /**
9 * Creates a Margins object that holds four margin values. The units in which 9 * Creates a Margins object that holds four margin values. The units in which
10 * the values are expressed can be any numeric value. 10 * the values are expressed can be any numeric value.
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
53 * @param {Margins} rhs The Margins object values to be used. 53 * @param {Margins} rhs The Margins object values to be used.
54 */ 54 */
55 copy: function(rhs) { 55 copy: function(rhs) {
56 this[MarginSettings.TOP_GROUP] = rhs[MarginSettings.TOP_GROUP]; 56 this[MarginSettings.TOP_GROUP] = rhs[MarginSettings.TOP_GROUP];
57 this[MarginSettings.LEFT_GROUP] = rhs[MarginSettings.LEFT_GROUP]; 57 this[MarginSettings.LEFT_GROUP] = rhs[MarginSettings.LEFT_GROUP];
58 this[MarginSettings.RIGHT_GROUP] = rhs[MarginSettings.RIGHT_GROUP]; 58 this[MarginSettings.RIGHT_GROUP] = rhs[MarginSettings.RIGHT_GROUP];
59 this[MarginSettings.BOTTOM_GROUP] = rhs[MarginSettings.BOTTOM_GROUP]; 59 this[MarginSettings.BOTTOM_GROUP] = rhs[MarginSettings.BOTTOM_GROUP];
60 }, 60 },
61 61
62 /** 62 /**
63 * Helper method returning an array of the string indices used for accessing
64 * all margins.
65 * @return {array} An array of string indices.
66 * @private
67 */
68 indicesAsArray_: function() {
69 return [MarginSettings.LEFT_GROUP, MarginSettings.TOP_GROUP,
70 MarginSettings.RIGHT_GROUP, MarginSettings.BOTTOM_GROUP];
71 },
72
73 /**
74 * Rounds |this| based on the precision used when displaying the margins in
75 * inches. This is done by converting from points to inches and back to
76 * points.
77 */
78 roundToInches: function() {
79 var indicesAsArray = this.indicesAsArray_();
80 for (var i = 0; i < indicesAsArray.length; i++) {
81 this[indicesAsArray[i]] =
82 print_preview.convertPointsToInchesTextAndBack(
83 this[indicesAsArray[i]]);
84 }
85 },
86
87 /**
63 * Converts |this| to inches and returns the result in a new Margins object. 88 * Converts |this| to inches and returns the result in a new Margins object.
64 * |this| is not affected. It assumes that |this| is currently expressed in 89 * |this| is not affected. It assumes that |this| is currently expressed in
65 * points. 90 * points.
66 * @param {number} The number of decimal points to keep. 91 * @param {number} The number of decimal points to keep.
67 * @return {Margins} The equivalent of |this| in inches. 92 * @return {Margins} The equivalent of |this| in inches.
68 */ 93 */
69 toInches: function(precision) { 94 toInches: function(precision) {
70 return new Margins( 95 return new Margins(
71 Margins.roundToPrecision(convertPointsToInches( 96 Margins.roundToPrecision(convertPointsToInches(
72 this[MarginSettings.LEFT_GROUP]), precision), 97 this[MarginSettings.LEFT_GROUP]), precision),
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
128 this.lastSelectedOption_ = MarginSettings.MARGINS_VALUE_DEFAULT; 153 this.lastSelectedOption_ = MarginSettings.MARGINS_VALUE_DEFAULT;
129 154
130 // Holds the currently updated default page layout values. 155 // Holds the currently updated default page layout values.
131 this.currentDefaultPageLayout = null; 156 this.currentDefaultPageLayout = null;
132 // Holds the default page layout values when the custom margins was last 157 // Holds the default page layout values when the custom margins was last
133 // selected. 158 // selected.
134 this.previousDefaultPageLayout_ = null; 159 this.previousDefaultPageLayout_ = null;
135 160
136 // True if the margins UI should be shown regardless of mouse position. 161 // True if the margins UI should be shown regardless of mouse position.
137 this.forceDisplayingMarginLines_ = true; 162 this.forceDisplayingMarginLines_ = true;
163
164 // @type {EventTracker} Used to keep track of certain event listeners.
165 this.eventTracker = new EventTracker();
138 } 166 }
139 167
140 // Number of points per inch. 168 // Number of points per inch.
141 MarginSettings.POINTS_PER_INCH = 72; 169 MarginSettings.POINTS_PER_INCH = 72;
170 // Minimum allowed distance in points between top-bottom, left-right margins.
171 MarginSettings.MINIMUM_MARGINS_DISTANCE = 36;
142 // Margin list values. 172 // Margin list values.
143 MarginSettings.MARGINS_VALUE_DEFAULT = 0; 173 MarginSettings.MARGINS_VALUE_DEFAULT = 0;
144 MarginSettings.MARGINS_VALUE_NO_MARGINS = 1; 174 MarginSettings.MARGINS_VALUE_NO_MARGINS = 1;
145 MarginSettings.MARGINS_VALUE_CUSTOM = 2; 175 MarginSettings.MARGINS_VALUE_CUSTOM = 2;
146 // Default Margins option index. 176 // Default Margins option index.
147 MarginSettings.DEFAULT_MARGINS_OPTION_INDEX = 0; 177 MarginSettings.DEFAULT_MARGINS_OPTION_INDEX = 0;
148 // Group name corresponding to the top margin. 178 // Group name corresponding to the top margin.
149 MarginSettings.TOP_GROUP = 'top'; 179 MarginSettings.TOP_GROUP = 'top';
150 // Group name corresponding to the left margin. 180 // Group name corresponding to the left margin.
151 MarginSettings.LEFT_GROUP = 'left'; 181 MarginSettings.LEFT_GROUP = 'left';
(...skipping 20 matching lines...) Expand all
172 202
173 /** 203 /**
174 * @return {number} The value of the selected margin option. 204 * @return {number} The value of the selected margin option.
175 */ 205 */
176 get selectedMarginsValue() { 206 get selectedMarginsValue() {
177 var val = this.marginList_.options[this.marginList_.selectedIndex].value; 207 var val = this.marginList_.options[this.marginList_.selectedIndex].value;
178 return parseInt(val, 10); 208 return parseInt(val, 10);
179 }, 209 },
180 210
181 /** 211 /**
212 * @return {number} The total width of the plugin in points.
213 */
214 get totalWidthInPoints() {
215 var pageInformation = previewArea.getPageLocationNormalized();
216 return this.pageWidth_ / pageInformation.width;
217 },
218
219 /**
220 * @return {number} The total height of the plugin in points.
221 */
222 get totalHeightInPoints() {
223 var pageInformation = previewArea.getPageLocationNormalized();
224 return this.pageHeight_ / pageInformation.height;
225 },
226
227 /**
182 * @return {boolean} True if default margins are selected. 228 * @return {boolean} True if default margins are selected.
183 */ 229 */
184 isDefaultMarginsSelected: function() { 230 isDefaultMarginsSelected: function() {
185 return this.selectedMarginsValue == MarginSettings.MARGINS_VALUE_DEFAULT; 231 return this.selectedMarginsValue == MarginSettings.MARGINS_VALUE_DEFAULT;
186 }, 232 },
187 233
188 /** 234 /**
189 * @return {boolean} True if no margins are selected. 235 * @return {boolean} True if no margins are selected.
190 */ 236 */
191 isNoMarginsSelected: function() { 237 isNoMarginsSelected: function() {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
238 284
239 /** 285 /**
240 * Adds listeners to all margin related controls. 286 * Adds listeners to all margin related controls.
241 */ 287 */
242 addEventListeners: function() { 288 addEventListeners: function() {
243 this.marginList_.onchange = this.onMarginsChanged_.bind(this); 289 this.marginList_.onchange = this.onMarginsChanged_.bind(this);
244 document.addEventListener('PDFLoaded', this.onPDFLoaded_.bind(this)); 290 document.addEventListener('PDFLoaded', this.onPDFLoaded_.bind(this));
245 }, 291 },
246 292
247 /** 293 /**
294 * Executes whenever a "DragEvent" occurs.
295 * @param {cr.Event} e The event that triggered this listener.
296 */
297 onDragEvent_: function(e) {
298 var dragDeltaInPoints = this.convertDragDeltaToPoints_(e.dragDelta);
299 this.marginsUI.lastClickedMarginsUIPair.updateWhileDragging(
300 dragDeltaInPoints, e.destinationPoint);
301 },
302
303 /**
304 * @param {number} dragDelta The difference in pixels between the original
305 * and current postion of the last clicked margin line.
306 * @return {number} The difference in points.
307 * @private
308 */
309 convertDragDeltaToPoints_: function(dragDelta) {
310 if (this.marginsUI.lastClickedMarginsUIPair.isTop_() ||
311 this.marginsUI.lastClickedMarginsUIPair.isBottom_()) {
312 return dragDelta * this.totalHeightInPoints;
313 } else {
314 return dragDelta * this.totalWidthInPoints;
315 }
316 },
317
318 /**
248 * @return {boolean} True if the margin settings are valid. 319 * @return {boolean} True if the margin settings are valid.
249 */ 320 */
250 areMarginSettingsValid: function() { 321 areMarginSettingsValid: function() {
251 if (this.marginsUI_ == null) 322 if (this.marginsUI_ == null)
252 return true; 323 return true;
253 324
254 var pairs = this.marginsUI.pairsAsList; 325 var pairs = this.marginsUI.pairsAsList;
255 return pairs.every(function(pair) { return pair.box_.isValid; }); 326 return pairs.every(function(pair) { return pair.box_.isValid; });
256 }, 327 },
257 328
258 /** 329 /**
259 * Calculates the maximum allowable value of the selected margin text for 330 * Calculates the maximum allowable value of the selected margin text for
260 * every margin. 331 * every margin.
261 * @return {array} The maximum allowable value in order top, left, right, 332 * @return {array} The maximum allowable value in points in order top, left,
262 * bottom. 333 * right, bottom.
263 * @private 334 * @private
264 */ 335 */
265 getMarginValueLimits_: function() { 336 getMarginValueLimits_: function() {
266 var marginValueLimits = []; 337 var marginValueLimits = [];
267 marginValueLimits[0] = this.pageHeight_ - this.customMargins_.bottom; 338 marginValueLimits[0] = this.pageHeight_ - this.customMargins_.bottom -
268 marginValueLimits[1] = this.pageWidth_ - this.customMargins_.right; 339 MarginSettings.MINIMUM_MARGINS_DISTANCE;
269 marginValueLimits[2] = this.pageWidth_ - this.customMargins_.left; 340 marginValueLimits[1] = this.pageWidth_ - this.customMargins_.right -
270 marginValueLimits[3] = this.pageHeight_ - this.customMargins_.top; 341 MarginSettings.MINIMUM_MARGINS_DISTANCE;
342 marginValueLimits[2] = this.pageWidth_ - this.customMargins_.left -
343 MarginSettings.MINIMUM_MARGINS_DISTANCE;
344 marginValueLimits[3] = this.pageHeight_ - this.customMargins_.top -
345 MarginSettings.MINIMUM_MARGINS_DISTANCE;
346
347 for (var i = 0; i < marginValueLimits.length; i++) {
348 marginValueLimits[i] = print_preview.convertPointsToInchesTextAndBack(
349 marginValueLimits[i]);
350 }
271 return marginValueLimits; 351 return marginValueLimits;
272 }, 352 },
273 353
274 /** 354 /**
355 * @return {array} The margin value limits positions normalized to the total
356 * width and height of the plugin and with respect to the top left
357 * corner of the plugin.
358 */
359 getMarginValueLimitsInPercent_: function() {
360 var pageInformation = previewArea.getPageLocationNormalized();
361 var totalWidthInPoints = this.pageWidth_ / pageInformation.width;
362 var totalHeightInPoints = this.pageHeight_ / pageInformation.height;
363 var marginValueLimits = this.getMarginValueLimits_();
364 var marginValueLimitsInPercent = [];
365 marginValueLimitsInPercent[0] = pageInformation.y + marginValueLimits[0] /
366 totalHeightInPoints;
367 marginValueLimitsInPercent[1] = pageInformation.x + marginValueLimits[1] /
368 totalWidthInPoints;
369 marginValueLimitsInPercent[2] = pageInformation.x +
370 pageInformation.width - marginValueLimits[2] / totalWidthInPoints;
371 marginValueLimitsInPercent[3] = pageInformation.y +
372 pageInformation.height - marginValueLimits[3] / totalHeightInPoints;
373 return marginValueLimitsInPercent;
374 },
375
376 /**
275 * When the user stops typing in the margin text box a new print preview is 377 * When the user stops typing in the margin text box a new print preview is
276 * requested, only if 378 * requested, only if
277 * 1) The input is compeletely valid (it can be parsed in its entirety). 379 * 1) The input is compeletely valid (it can be parsed in its entirety).
278 * 2) The newly selected margins differ from the previously selected. 380 * 2) The newly selected margins differ from the previously selected.
279 * @param {cr.Event} event The change event holding information about what 381 * @param {cr.Event} event The change event holding information about what
280 * changed. 382 * changed.
281 * @private 383 * @private
282 */ 384 */
283 onMarginTextValueMayHaveChanged_: function(event) { 385 onMarginTextValueMayHaveChanged_: function(event) {
284 var marginBox = event.target; 386 var marginBox = event.target;
285 var marginBoxValue = convertInchesToPoints(marginBox.margin); 387 var marginBoxValue = convertInchesToPoints(marginBox.margin);
286 this.customMargins_[marginBox.marginGroup] = marginBoxValue; 388 this.customMargins_[marginBox.marginGroup] = marginBoxValue;
287 this.requestPreviewIfNeeded_(); 389 this.requestPreviewIfNeeded_();
288 }, 390 },
289 391
290 /** 392 /**
291 * @type {print_preview.MarginsUI} The object holding the UI for specifying 393 * @type {print_preview.MarginsUI} The object holding the UI for specifying
292 * custom margins. 394 * custom margins.
293 */ 395 */
294 get marginsUI() { 396 get marginsUI() {
295 if (!this.marginsUI_) { 397 if (!this.marginsUI_) {
296 this.marginsUI_ = new print_preview.MarginsUI($('mainview')); 398 this.marginsUI_ = new print_preview.MarginsUI();
399 $('mainview').appendChild(this.marginsUI_);
297 this.marginsUI_.addObserver( 400 this.marginsUI_.addObserver(
298 this.onMarginTextValueMayHaveChanged_.bind(this)); 401 this.onMarginTextValueMayHaveChanged_.bind(this));
299 } 402 }
300 return this.marginsUI_; 403 return this.marginsUI_;
301 }, 404 },
302 405
303 /** 406 /**
304 * Adds listeners when the custom margins option is selected. 407 * Adds listeners when the custom margins option is selected.
305 * @private 408 * @private
306 */ 409 */
307 addCustomMarginEventListeners_: function() { 410 addCustomMarginEventListeners_: function() {
308 $('mainview').onmouseover = this.onMainviewMouseOver_.bind(this); 411 $('mainview').onmouseover = this.onMainviewMouseOver_.bind(this);
309 $('sidebar').onmouseover = this.onSidebarMouseOver_.bind(this); 412 $('sidebar').onmouseover = this.onSidebarMouseOver_.bind(this);
413 this.eventTracker.add(
414 this.marginsUI, 'DragEvent', this.onDragEvent_.bind(this), false);
310 }, 415 },
311 416
312 /** 417 /**
313 * Removes the event listeners associated with the custom margins option. 418 * Removes the event listeners associated with the custom margins option.
314 * @private 419 * @private
315 */ 420 */
316 removeCustomMarginEventListeners_: function() { 421 removeCustomMarginEventListeners_: function() {
317 $('mainview').onmouseover = null; 422 $('mainview').onmouseover = null;
318 $('sidebar').onmouseover = null; 423 $('sidebar').onmouseover = null;
424 this.eventTracker.remove(this.marginsUI, 'DragEvent');
319 this.marginsUI.hide(); 425 this.marginsUI.hide();
320 }, 426 },
321 427
322 /** 428 /**
323 * Updates |this.marginsUI| depending on the specified margins and the 429 * Updates |this.marginsUI| depending on the specified margins and the
324 * position of the page within the plugin. 430 * position of the page within the plugin.
325 * @private 431 * @private
326 */ 432 */
327 drawCustomMarginsUI_: function() { 433 drawCustomMarginsUI_: function() {
328 // TODO(dpapad): find out why passing |!this.areMarginsSettingsValid()| 434 // TODO(dpapad): find out why passing |!this.areMarginsSettingsValid()|
329 // directly produces the opposite value even though 435 // directly produces the opposite value even though
330 // |this.getMarginsRectangleInPercent_()| and 436 // |this.getMarginsRectangleInPercent_()| and
331 // |this.getMarginValueLimits_()| have no side effects. 437 // |this.getMarginValueLimits_()| have no side effects.
332 var keepDisplayedValue = !this.areMarginSettingsValid(); 438 var keepDisplayedValue = !this.areMarginSettingsValid();
333 this.marginsUI.update(this.getMarginsRectangleInPercent_(), 439 this.marginsUI.update(this.getMarginsRectangleInPercent_(),
334 this.customMargins_, 440 this.customMargins_,
335 this.getMarginValueLimits_(), 441 this.getMarginValueLimits_(),
336 keepDisplayedValue); 442 keepDisplayedValue,
443 this.getMarginValueLimitsInPercent_());
337 this.marginsUI.draw(); 444 this.marginsUI.draw();
338 }, 445 },
339 446
340 /** 447 /**
341 * Called when there is change in the preview position or size. 448 * Called when there is change in the preview position or size.
342 */ 449 */
343 onPreviewPositionChanged: function() { 450 onPreviewPositionChanged: function() {
344 if (this.isCustomMarginsSelected() && previewArea.pdfLoaded && 451 if (this.isCustomMarginsSelected() && previewArea.pdfLoaded &&
345 pageSettings.totalPageCount != undefined) { 452 pageSettings.totalPageCount != undefined) {
346 this.drawCustomMarginsUI_(); 453 this.drawCustomMarginsUI_();
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
384 setDefaultValuesAndRegeneratePreview(false); 491 setDefaultValuesAndRegeneratePreview(false);
385 }, 492 },
386 493
387 /** 494 /**
388 * Executes when the custom margins option is selected. 495 * Executes when the custom margins option is selected.
389 * @private 496 * @private
390 */ 497 */
391 onCustomMarginsSelected_: function() { 498 onCustomMarginsSelected_: function() {
392 this.addCustomMarginEventListeners_(); 499 this.addCustomMarginEventListeners_();
393 500
394 if (this.lastSelectedOption_ == MarginSettings.MARGINS_VALUE_DEFAULT) 501 if (this.lastSelectedOption_ == MarginSettings.MARGINS_VALUE_DEFAULT) {
395 this.customMargins_ = this.currentDefaultPageLayout.margins_; 502 this.customMargins_ = this.currentDefaultPageLayout.margins_;
503 this.customMargins_.roundToInches();
504 }
396 this.previousCustomMargins_.copy(this.customMargins_); 505 this.previousCustomMargins_.copy(this.customMargins_);
397 506
398 if (this.previousDefaultPageLayout_ != this.currentDefaultPageLayout) { 507 if (this.previousDefaultPageLayout_ != this.currentDefaultPageLayout) {
399 this.pageWidth_ = this.currentDefaultPageLayout.pageWidth; 508 this.pageWidth_ = this.currentDefaultPageLayout.pageWidth;
400 this.pageHeight_ = this.currentDefaultPageLayout.pageHeight; 509 this.pageHeight_ = this.currentDefaultPageLayout.pageHeight;
401 } 510 }
402 511
403 this.previousDefaultPageLayout_ = this.currentDefaultPageLayout; 512 this.previousDefaultPageLayout_ = this.currentDefaultPageLayout;
404 this.drawCustomMarginsUI_(); 513 this.drawCustomMarginsUI_();
405 this.marginsUI.show(); 514 this.marginsUI.show();
(...skipping 20 matching lines...) Expand all
426 return new print_preview.Rect( 535 return new print_preview.Rect(
427 leftX, topY, contentWidth, contentHeight); 536 leftX, topY, contentWidth, contentHeight);
428 }, 537 },
429 538
430 /** 539 /**
431 * @return {print_preview.Margins} The currently selected margin values 540 * @return {print_preview.Margins} The currently selected margin values
432 * normalized to the total width and height of the plugin. 541 * normalized to the total width and height of the plugin.
433 * @private 542 * @private
434 */ 543 */
435 getMarginsInPercent_: function() { 544 getMarginsInPercent_: function() {
545 return this.convertMarginsInPointsToPercent(this.customMargins_);
546 },
547
548 /**
549 * Converts |marginsToConvert| to points and normalizes it to the height and
550 * width of the plugin.
551 * @return {print_preview.Margins} The margins in percent.
552 * @private
553 */
554 convertMarginsInPointsToPercent: function(marginsToConvert) {
436 var pageInformation = previewArea.getPageLocationNormalized(); 555 var pageInformation = previewArea.getPageLocationNormalized();
437 var totalWidthInPoints = this.pageWidth_ / pageInformation.width; 556 var totalWidthInPoints = this.pageWidth_ / pageInformation.width;
438 var totalHeightInPoints = this.pageHeight_ / pageInformation.height; 557 var totalHeightInPoints = this.pageHeight_ / pageInformation.height;
439 var marginsInPercent = new Margins( 558 var marginsInPercent = new Margins(
440 this.customMargins_.left / totalWidthInPoints, 559 marginsToConvert.left / totalWidthInPoints,
441 this.customMargins_.top / totalHeightInPoints, 560 marginsToConvert.top / totalHeightInPoints,
442 this.customMargins_.right / totalWidthInPoints, 561 marginsToConvert.right / totalWidthInPoints,
443 this.customMargins_.bottom / totalHeightInPoints); 562 marginsToConvert.bottom / totalHeightInPoints);
444 return marginsInPercent; 563 return marginsInPercent;
445 }, 564 },
446 565
447 /** 566 /**
448 * If custom margins is the currently selected option then change to the 567 * If custom margins is the currently selected option then change to the
449 * default margins option. 568 * default margins option.
450 * @private 569 * @private
451 */ 570 */
452 resetMarginsIfNeeded: function() { 571 resetMarginsIfNeeded: function() {
453 if (this.isCustomMarginsSelected()) { 572 if (this.isCustomMarginsSelected()) {
454 this.marginList_.options[ 573 this.marginList_.options[
455 MarginSettings.DEFAULT_MARGINS_OPTION_INDEX].selected = true; 574 MarginSettings.DEFAULT_MARGINS_OPTION_INDEX].selected = true;
456 this.removeCustomMarginEventListeners_(); 575 this.removeCustomMarginEventListeners_();
576 this.forceDisplayingMarginLines_ = true;
457 this.lastSelectedOption_ = MarginSettings.MARGINS_VALUE_DEFAULT; 577 this.lastSelectedOption_ = MarginSettings.MARGINS_VALUE_DEFAULT;
458 } 578 }
459 }, 579 },
460 580
461 /** 581 /**
462 * Executes when a PDFLoaded event occurs. 582 * Executes when a PDFLoaded event occurs.
463 * @private 583 * @private
464 */ 584 */
465 onPDFLoaded_: function() { 585 onPDFLoaded_: function() {
466 if (!previewModifiable) 586 if (!previewModifiable)
467 fadeOutElement(this.marginsOption_); 587 fadeOutElement(this.marginsOption_);
468 } 588 }
469 }; 589 };
470 590
471 return { 591 return {
472 MarginSettings: MarginSettings, 592 MarginSettings: MarginSettings,
473 PageLayout: PageLayout, 593 PageLayout: PageLayout,
474 }; 594 };
475 }); 595 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698