Merge f-t to m-c

This commit is contained in:
Phil Ringnalda 2013-10-27 10:22:27 -07:00
commit 1a9ee616c1
17 changed files with 298 additions and 124 deletions

View File

@ -571,7 +571,7 @@
onclick="gPopupBlockerObserver.onReportButtonClick(event);"/>
<image id="star-button"
class="urlbar-icon"
onclick="BookmarkingUI.onCommand(event);"/>
onclick="if (event.button === 0) BookmarkingUI.onCommand(event);"/>
<image id="go-button"
class="urlbar-icon"
tooltiptext="&goEndCap.tooltip;"

View File

@ -64,7 +64,7 @@ function test() {
MockFilePicker.returnFiles = [aFile];
MockFilePicker.displayDirectory = null;
aWin.getTargetFile(params, function() {
aWin.promiseTargetFile(params).then(function() {
// File picker should start with expected display dir.
is(MockFilePicker.displayDirectory.path, aDisplayDir.path,
"File picker should start with browser.download.lastDir");
@ -78,7 +78,7 @@ function test() {
gDownloadLastDir.cleanupPrivateFile();
aWin.close();
aCallback();
});
}).then(null, function() { ok(false); });
}
testOnWindow(false, function(win, downloadDir) {

View File

@ -1,4 +1,4 @@
This is the pdf.js project output, https://github.com/mozilla/pdf.js
Current extension version is: 0.8.629
Current extension version is: 0.8.641

View File

@ -20,8 +20,8 @@ if (typeof PDFJS === 'undefined') {
(typeof window !== 'undefined' ? window : this).PDFJS = {};
}
PDFJS.version = '0.8.629';
PDFJS.build = 'b16b3be';
PDFJS.version = '0.8.641';
PDFJS.build = '19485c3';
(function pdfjsWrapper() {
// Use strict in our context only - users might not want it
@ -6575,6 +6575,11 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
var bounds = Util.getAxialAlignedBoundingBox(
group.bbox,
currentCtx.mozCurrentTransform);
// Clip the bounding box to the current canvas.
bounds = Util.intersect(bounds, [0,
0,
currentCtx.canvas.width,
currentCtx.canvas.height]);
// Use ceil in case we're between sizes so we don't create canvas that is
// too small and make the canvas at least 1x1 pixels.
var drawnWidth = Math.max(Math.ceil(bounds[2] - bounds[0]), 1);

View File

@ -20,8 +20,8 @@ if (typeof PDFJS === 'undefined') {
(typeof window !== 'undefined' ? window : this).PDFJS = {};
}
PDFJS.version = '0.8.629';
PDFJS.build = 'b16b3be';
PDFJS.version = '0.8.641';
PDFJS.build = '19485c3';
(function pdfjsWrapper() {
// Use strict in our context only - users might not want it

View File

@ -223,7 +223,7 @@ limitations under the License.
data-l10n-id="page_rotate_ccw"></menuitem>
</menu>
<div id="viewerContainer">
<div id="viewerContainer" tabindex="0">
<div id="viewer"></div>
</div>

View File

@ -1299,11 +1299,12 @@ var SecondaryToolbar = {
initialize: function secondaryToolbarInitialize(options) {
this.toolbar = options.toolbar;
this.presentationMode = options.presentationMode;
this.buttonContainer = this.toolbar.firstElementChild;
// Define the toolbar buttons.
this.toggleButton = options.toggleButton;
this.presentationMode = options.presentationMode;
this.presentationModeButton = options.presentationModeButton;
this.openFile = options.openFile;
this.print = options.print;
this.download = options.download;
@ -1315,7 +1316,8 @@ var SecondaryToolbar = {
// Attach the event listeners.
var elements = [
{ element: this.toggleButton, handler: this.toggle },
{ element: this.presentationMode, handler: this.presentationModeClick },
{ element: this.presentationModeButton,
handler: this.presentationModeClick },
{ element: this.openFile, handler: this.openFileClick },
{ element: this.print, handler: this.printClick },
{ element: this.download, handler: this.downloadClick },
@ -1335,7 +1337,7 @@ var SecondaryToolbar = {
// Event handling functions.
presentationModeClick: function secondaryToolbarPresentationModeClick(evt) {
PresentationMode.request();
this.presentationMode.request();
this.close();
},
@ -1372,7 +1374,7 @@ var SecondaryToolbar = {
// Misc. functions for interacting with the toolbar.
setMaxHeight: function secondaryToolbarSetMaxHeight(container) {
if (!container) {
if (!container || !this.buttonContainer) {
return;
}
this.newContainerHeight = container.clientHeight;
@ -1410,10 +1412,6 @@ var SecondaryToolbar = {
} else {
this.open();
}
},
get isOpen() {
return this.opened;
}
};
@ -1506,6 +1504,8 @@ var PresentationMode = {
this.container = options.container;
this.secondaryToolbar = options.secondaryToolbar;
this.viewer = this.container.firstElementChild;
this.firstPage = options.firstPage;
this.lastPage = options.lastPage;
this.pageRotateCw = options.pageRotateCw;
@ -1538,7 +1538,8 @@ var PresentationMode = {
},
request: function presentationModeRequest() {
if (!PDFView.supportsFullscreen || this.isFullscreen) {
if (!PDFView.supportsFullscreen || this.isFullscreen ||
!this.viewer.hasChildNodes()) {
return false;
}
@ -1720,8 +1721,10 @@ var PDFView = {
SecondaryToolbar.initialize({
toolbar: document.getElementById('secondaryToolbar'),
presentationMode: PresentationMode,
toggleButton: document.getElementById('secondaryToolbarToggle'),
presentationMode: document.getElementById('secondaryPresentationMode'),
presentationModeButton:
document.getElementById('secondaryPresentationMode'),
openFile: document.getElementById('secondaryOpenFile'),
print: document.getElementById('secondaryPrint'),
download: document.getElementById('secondaryDownload'),
@ -1968,8 +1971,8 @@ var PDFView = {
},
get isHorizontalScrollbarEnabled() {
var div = document.getElementById('viewerContainer');
return div.scrollWidth > div.clientWidth;
return (PresentationMode.active ? false :
(this.container.scrollWidth > this.container.clientWidth));
},
initPassiveLoading: function pdfViewInitPassiveLoading() {
@ -3230,6 +3233,7 @@ var PageView = function pageView(container, id, scale,
this.scrollIntoView = function pageViewScrollIntoView(dest) {
if (PresentationMode.active) { // Avoid breaking presentation mode.
dest = null;
PDFView.setScale(PDFView.currentScaleValue, true, true);
}
if (!dest) {
scrollIntoView(div);
@ -4554,7 +4558,7 @@ window.addEventListener('DOMMouseScroll', function(evt) {
window.addEventListener('click', function click(evt) {
if (!PresentationMode.active) {
if (SecondaryToolbar.isOpen && PDFView.container.contains(evt.target)) {
if (SecondaryToolbar.opened && PDFView.container.contains(evt.target)) {
SecondaryToolbar.close();
}
} else if (evt.button === 0) {
@ -4649,6 +4653,9 @@ window.addEventListener('keydown', function keydown(evt) {
return; // ignoring if the 'toolbar' element is focused
curElement = curElement.parentNode;
}
// Workaround for issue in Firefox, that prevents scroll keys from working
// when elements with 'tabindex' are focused.
PDFView.container.blur();
if (cmd === 0) { // no control key pressed at all.
switch (evt.keyCode) {
@ -4673,7 +4680,7 @@ window.addEventListener('keydown', function keydown(evt) {
handled = true;
break;
case 27: // esc key
if (SecondaryToolbar.isOpen) {
if (SecondaryToolbar.opened) {
SecondaryToolbar.close();
handled = true;
}

View File

@ -1,11 +1,11 @@
chrome.manifest
components/PdfRedirector.js
components/PdfStreamConverter.js
content/PdfJs.jsm
content/PdfJsTelemetry.jsm
content/build/pdf.js
content/build/pdf.worker.js
content/network.js
content/PdfJs.jsm
content/PdfJsTelemetry.jsm
content/web/debugger.js
content/web/images/annotation-check.svg
content/web/images/annotation-comment.svg

View File

@ -49,8 +49,12 @@ public:
bool Headphones() const
{
MOZ_ASSERT(mState != hal::SWITCH_STATE_UNKNOWN);
return mState != hal::SWITCH_STATE_OFF;
// Bug 929139 - Remove the assert check for SWITCH_STATE_UNKNOWN.
// If any devices (ex: emulator) didn't have the corresponding sys node for
// headset switch state then GonkSwitch will report the unknown state.
// So it is possible to get unknown state here.
return mState != hal::SWITCH_STATE_OFF &&
mState != hal::SWITCH_STATE_UNKNOWN;
}
bool SetVolumeControlChannel(const nsAString& aChannel);

View File

@ -304,29 +304,33 @@ AbstractFile.normalizeOpenMode = function normalizeOpenMode(mode) {
write: false,
trunc: false,
create: false,
existing: false
existing: false,
append: true
};
for (let key in mode) {
if (!mode[key]) continue; // Only interpret true-ish keys
let val = !!mode[key]; // bool cast.
switch (key) {
case "read":
result.read = true;
result.read = val;
break;
case "write":
result.write = true;
result.write = val;
break;
case "truncate": // fallthrough
case "trunc":
result.trunc = true;
result.write = true;
result.trunc = val;
result.write |= val;
break;
case "create":
result.create = true;
result.write = true;
result.create = val;
result.write |= val;
break;
case "existing": // fallthrough
case "exist":
result.existing = true;
result.existing = val;
break;
case "append":
result.append = val;
break;
default:
throw new TypeError("Mode " + key + " not understood");

View File

@ -203,8 +203,11 @@
* on the other fields of |mode|.
* - {bool} write If |true|, the file will be opened for
* writing. The file may also be opened for reading, depending
* on the other fields of |mode|. If neither |truncate| nor
* |create| is specified, the file is opened for appending.
* on the other fields of |mode|.
* - {bool} append If |true|, the file will be opened for appending,
* meaning the equivalent of |.setPosition(0, POS_END)| is executed
* before each write. The default is |true|, i.e. opening a file for
* appending. Specify |append: false| to open the file in regular mode.
*
* If neither |truncate|, |create| or |write| is specified, the file
* is opened for reading.
@ -251,12 +254,11 @@
flags |= Const.O_CREAT | Const.O_EXCL;
} else if (mode.read && !mode.write) {
// flags are sufficient
} else /*append*/ {
if (mode.existing) {
flags |= Const.O_APPEND;
} else {
flags |= Const.O_APPEND | Const.O_CREAT;
}
} else if (!mode.existing) {
flags |= Const.O_CREAT;
}
if (mode.append) {
flags |= Const.O_APPEND;
}
}
return error_or_file(UnixFile.open(path, flags, omode));
@ -548,10 +550,12 @@
let result;
try {
source = File.open(sourcePath);
// Need to open the output file with |append:false|, or else |splice|
// won't work.
if (options.noOverwrite) {
dest = File.open(destPath, {create:true});
dest = File.open(destPath, {create:true, append:false});
} else {
dest = File.open(destPath, {trunc:true});
dest = File.open(destPath, {trunc:true, append:false});
}
if (options.unixUserland) {
result = pump_userland(source, dest, options);

View File

@ -134,6 +134,11 @@
* @throws {OS.File.Error} In case of I/O error.
*/
File.prototype._write = function _write(buffer, nbytes, options) {
if (this._appendMode) {
// Need to manually seek on Windows, as O_APPEND is not supported.
// This is, of course, a race, but there is no real way around this.
this.setPosition(0, File.POS_END);
}
// |gBytesWrittenPtr| is a pointer to |gBytesWritten|.
throw_on_zero("write",
WinFile.WriteFile(this.fd, buffer, nbytes, gBytesWrittenPtr, null)
@ -225,8 +230,11 @@
* on the other fields of |mode|.
* - {bool} write If |true|, the file will be opened for
* writing. The file may also be opened for reading, depending
* on the other fields of |mode|. If neither |truncate| nor
* |create| is specified, the file is opened for appending.
* on the other fields of |mode|.
* - {bool} append If |true|, the file will be opened for appending,
* meaning the equivalent of |.setPosition(0, POS_END)| is executed
* before each write. The default is |true|, i.e. opening a file for
* appending. Specify |append: false| to open the file in regular mode.
*
* If neither |truncate|, |create| or |write| is specified, the file
* is opened for reading.
@ -264,6 +272,9 @@
let template = options.winTemplate ? options.winTemplate._fd : null;
let access;
let disposition;
mode = OS.Shared.AbstractFile.normalizeOpenMode(mode);
if ("winAccess" in options && "winDisposition" in options) {
access = options.winAccess;
disposition = options.winDisposition;
@ -272,7 +283,6 @@
throw new TypeError("OS.File.open requires either both options " +
"winAccess and winDisposition or neither");
} else {
mode = OS.Shared.AbstractFile.normalizeOpenMode(mode);
if (mode.read) {
access |= Const.GENERIC_READ;
}
@ -293,16 +303,18 @@
disposition = Const.CREATE_NEW;
} else if (mode.read && !mode.write) {
disposition = Const.OPEN_EXISTING;
} else /*append*/ {
if (mode.existing) {
disposition = Const.OPEN_EXISTING;
} else {
disposition = Const.OPEN_ALWAYS;
}
} else if (mode.existing) {
disposition = Const.OPEN_EXISTING;
} else {
disposition = Const.OPEN_ALWAYS;
}
}
let file = error_or_file(WinFile.CreateFile(path,
access, share, security, disposition, flags, template));
file._appendMode = !!mode.append;
if (!(mode.trunc && mode.existing)) {
return file;
}

View File

@ -0,0 +1,122 @@
"use strict";
do_print("starting tests");
Components.utils.import("resource://gre/modules/osfile.jsm");
Components.utils.import("resource://gre/modules/Task.jsm");
/**
* A test to check that the |append| mode flag is correctly implemented.
* (see bug 925865)
*/
function setup_mode(mode) {
// Complete mode.
let realMode = {
read: true,
write: true
};
for (let k in mode) {
realMode[k] = mode[k];
}
return realMode;
}
// Test append mode.
function test_append(mode) {
let path = OS.Path.join(OS.Constants.Path.tmpDir,
"test_osfile_async_append.tmp");
// Clear any left-over files from previous runs.
try {
yield OS.File.remove(path);
} catch (ex if ex.becauseNoSuchFile) {
// ignore
}
try {
mode = setup_mode(mode);
mode.append = true;
if (mode.trunc) {
// Pre-fill file with some data to see if |trunc| actually works.
yield OS.File.writeAtomic(path, new Uint8Array(500));
}
let file = yield OS.File.open(path, mode);
try {
yield file.write(new Uint8Array(1000));
yield file.setPosition(0, OS.File.POS_START);
yield file.read(100);
// Should be at offset 100, length 1000 now.
yield file.write(new Uint8Array(100));
// Should be at offset 1100, length 1100 now.
let stat = yield file.stat();
do_check_eq(1100, stat.size);
} finally {
yield file.close();
}
} catch(ex) {
try {
yield OS.File.remove(path);
} catch (ex if ex.becauseNoSuchFile) {
// ignore.
}
}
}
// Test no-append mode.
function test_no_append(mode) {
let path = OS.Path.join(OS.Constants.Path.tmpDir,
"test_osfile_async_noappend.tmp");
// Clear any left-over files from previous runs.
try {
yield OS.File.remove(path);
} catch (ex if ex.becauseNoSuchFile) {
// ignore
}
try {
mode = setup_mode(mode);
mode.append = false;
if (mode.trunc) {
// Pre-fill file with some data to see if |trunc| actually works.
yield OS.File.writeAtomic(path, new Uint8Array(500));
}
let file = yield OS.File.open(path, mode);
try {
yield file.write(new Uint8Array(1000));
yield file.setPosition(0, OS.File.POS_START);
yield file.read(100);
// Should be at offset 100, length 1000 now.
yield file.write(new Uint8Array(100));
// Should be at offset 200, length 1000 now.
let stat = yield file.stat();
do_check_eq(1000, stat.size);
} finally {
yield file.close();
}
} finally {
try {
yield OS.File.remove(path);
} catch (ex if ex.becauseNoSuchFile) {
// ignore.
}
}
}
let test_flags = [
{},
{create:true},
{trunc:true}
];
function run_test() {
do_test_pending();
for (let t of test_flags) {
add_task(test_append.bind(null, t));
add_task(test_no_append.bind(null, t));
}
add_task(do_test_finished);
run_next_test();
}

View File

@ -5,6 +5,7 @@ tail =
[test_osfile_closed.js]
[test_path.js]
[test_osfile_async.js]
[test_osfile_async_append.js]
[test_osfile_async_bytes.js]
[test_osfile_async_copy.js]
[test_profiledir.js]

View File

@ -3,9 +3,24 @@
# 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/.
Components.utils.import("resource://gre/modules/Services.jsm");
Components.utils.import("resource://gre/modules/PrivateBrowsingUtils.jsm");
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Downloads",
"resource://gre/modules/Downloads.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "DownloadLastDir",
"resource://gre/modules/DownloadLastDir.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "FileUtils",
"resource://gre/modules/FileUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "OS",
"resource://gre/modules/osfile.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils",
"resource://gre/modules/PrivateBrowsingUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Promise",
"resource://gre/modules/commonjs/sdk/core/promise.js");
XPCOMUtils.defineLazyModuleGetter(this, "Services",
"resource://gre/modules/Services.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Task",
"resource://gre/modules/Task.jsm");
var ContentAreaUtils = {
// this is for backwards compatibility.
@ -311,15 +326,15 @@ function internalSave(aURL, aDocument, aDefaultFileName, aContentDisposition,
// Find a URI to use for determining last-downloaded-to directory
let relatedURI = aReferrer || sourceURI;
getTargetFile(fpParams, function(aDialogCancelled) {
if (aDialogCancelled)
promiseTargetFile(fpParams, aSkipPrompt, relatedURI).then(aDialogAccepted => {
if (!aDialogAccepted)
return;
saveAsType = fpParams.saveAsType;
file = fpParams.file;
continueSave();
}, aSkipPrompt, relatedURI);
}).then(null, Components.utils.reportError);
}
function continueSave() {
@ -527,10 +542,6 @@ function initFileInfo(aFI, aURL, aURLCharset, aDocument,
* @param aFpP
* A structure (see definition in internalSave(...) method)
* containing all the data used within this method.
* @param aCallback
* A callback function that will be called once the function finishes.
* The first argument passed to the function will be a boolean that,
* when true, indicated that the user dismissed the file picker.
* @param aSkipPrompt
* If true, attempt to save the file automatically to the user's default
* download directory, thus skipping the explicit prompt for a file name,
@ -542,58 +553,59 @@ function initFileInfo(aFI, aURL, aURLCharset, aDocument,
* An nsIURI associated with the download. The last used
* directory of the picker is retrieved from/stored in the
* Content Pref Service using this URI.
* @return Promise
* @resolve a boolean. When true, it indicates that the file picker dialog
* is accepted.
*/
function getTargetFile(aFpP, aCallback, /* optional */ aSkipPrompt, /* optional */ aRelatedURI)
function promiseTargetFile(aFpP, /* optional */ aSkipPrompt, /* optional */ aRelatedURI)
{
if (!getTargetFile.DownloadLastDir)
Components.utils.import("resource://gre/modules/DownloadLastDir.jsm", getTargetFile);
var gDownloadLastDir = new getTargetFile.DownloadLastDir(window);
return Task.spawn(function() {
let downloadLastDir = new DownloadLastDir(window);
let prefBranch = Services.prefs.getBranch("browser.download.");
let useDownloadDir = prefBranch.getBoolPref("useDownloadDir");
var prefs = Services.prefs.getBranch("browser.download.");
var useDownloadDir = prefs.getBoolPref("useDownloadDir");
const nsIFile = Components.interfaces.nsIFile;
if (!aSkipPrompt)
useDownloadDir = false;
if (!aSkipPrompt)
useDownloadDir = false;
// Default to the user's default downloads directory configured
// through download prefs.
let dirPath = yield Downloads.getPreferredDownloadsDirectory();
let dirExists = yield OS.File.exists(dirPath);
let dir = new FileUtils.File(dirPath);
// Default to the user's default downloads directory configured
// through download prefs.
var dir = Services.downloads.userDownloadsDirectory;
var dirExists = dir && dir.exists();
if (useDownloadDir && dirExists) {
dir.append(getNormalizedLeafName(aFpP.fileInfo.fileName,
aFpP.fileInfo.fileExt));
aFpP.file = uniqueFile(dir);
aCallback(false);
return;
}
// We must prompt for the file name explicitly.
// If we must prompt because we were asked to...
if (useDownloadDir) {
// Keep async behavior in both branches
Services.tm.mainThread.dispatch(function() {
displayPicker();
}, Components.interfaces.nsIThread.DISPATCH_NORMAL);
} else {
gDownloadLastDir.getFileAsync(aRelatedURI, function getFileAsyncCB(aFile) {
if (aFile && aFile.exists()) {
dir = aFile;
dirExists = true;
}
displayPicker();
});
}
function displayPicker() {
if (!dirExists) {
// Default to desktop.
dir = Services.dirsvc.get("Desk", nsIFile);
if (useDownloadDir && dirExists) {
dir.append(getNormalizedLeafName(aFpP.fileInfo.fileName,
aFpP.fileInfo.fileExt));
aFpP.file = uniqueFile(dir);
throw new Task.Result(true);
}
var fp = makeFilePicker();
var titleKey = aFpP.fpTitleKey || "SaveLinkTitle";
// We must prompt for the file name explicitly.
// If we must prompt because we were asked to...
let deferred = Promise.defer();
if (useDownloadDir) {
// Keep async behavior in both branches
Services.tm.mainThread.dispatch(function() {
deferred.resolve(null);
}, Components.interfaces.nsIThread.DISPATCH_NORMAL);
} else {
downloadLastDir.getFileAsync(aRelatedURI, function getFileAsyncCB(aFile) {
deferred.resolve(aFile);
});
}
let file = yield deferred.promise;
if (file && (yield OS.File.exists(file.path))) {
dir = file;
dirExists = true;
}
if (!dirExists) {
// Default to desktop.
dir = Services.dirsvc.get("Desk", Components.interfaces.nsIFile);
}
let fp = makeFilePicker();
let titleKey = aFpP.fpTitleKey || "SaveLinkTitle";
fp.init(window, ContentAreaUtils.stringBundle.GetStringFromName(titleKey),
Components.interfaces.nsIFilePicker.modeSave);
@ -608,31 +620,35 @@ function getTargetFile(aFpP, aCallback, /* optional */ aSkipPrompt, /* optional
// more than one filter in addition to "All Files".
if (aFpP.saveMode != SAVEMODE_FILEONLY) {
try {
fp.filterIndex = prefs.getIntPref("save_converter_index");
fp.filterIndex = prefBranch.getIntPref("save_converter_index");
}
catch (e) {
}
}
if (fp.show() == Components.interfaces.nsIFilePicker.returnCancel || !fp.file) {
aCallback(true);
return;
let deferComplete = Promise.defer();
fp.open(function(aResult) {
deferComplete.resolve(aResult);
});
let result = yield deferComplete.promise;
if (result == Components.interfaces.nsIFilePicker.returnCancel || !fp.file) {
throw new Task.Result(false);
}
if (aFpP.saveMode != SAVEMODE_FILEONLY)
prefs.setIntPref("save_converter_index", fp.filterIndex);
prefBranch.setIntPref("save_converter_index", fp.filterIndex);
// Do not store the last save directory as a pref inside the private browsing mode
var directory = fp.file.parent.QueryInterface(nsIFile);
gDownloadLastDir.setFile(aRelatedURI, directory);
downloadLastDir.setFile(aRelatedURI, fp.file.parent);
fp.file.leafName = validateFileName(fp.file.leafName);
aFpP.saveAsType = fp.filterIndex;
aFpP.file = fp.file;
aFpP.fileURL = fp.fileURL;
aCallback(false);
}
throw new Task.Result(true);
});
}
// Since we're automatically downloading, we don't get the file picker's

View File

@ -807,8 +807,7 @@
this.yearField = document.getAnonymousElementByAttribute(this, "anonid", yfield);
if (!twoDigitYear)
this.yearField.parentNode.className =
"datetimepicker-input-subbox datetimepicker-year";
this.yearField.parentNode.classList.add("datetimepicker-input-subbox", "datetimepicker-year");
this.monthField = document.getAnonymousElementByAttribute(this, "anonid", mfield);
this.dateField = document.getAnonymousElementByAttribute(this, "anonid", dfield);
@ -1178,7 +1177,7 @@
return;
var target = event.originalTarget;
if (target.className == "datepicker-gridlabel" &&
if (target.classList.contains("datepicker-gridlabel") &&
target != this.selectedItem) {
this.selectedItem = target;
this._dateValue = new Date(this._displayedDate);

View File

@ -220,11 +220,11 @@ Services.obs.addObserver(function observe(aSubject, aTopic, aValue) {
return;
}
if (stack) {
message += " at " + stack;
message += "\nFull Stack: " + stack;
}
error.init(
/*message*/"A promise chain failed to handle a rejection: on " +
date + ", " + message,
/*message*/"A promise chain failed to handle a rejection.\n\n" +
"Date: " + date + "\nFull Message: " + message,
/*sourceName*/ fileName,
/*sourceLine*/ lineNumber?("" + lineNumber):0,
/*lineNumber*/ lineNumber || 0,