mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-14 22:05:44 +00:00
Merge the last PGO-green inbound changeset to m-c.
This commit is contained in:
commit
ac1756efef
@ -226,7 +226,7 @@ let SocialUI = {
|
||||
return;
|
||||
}
|
||||
}
|
||||
Social.installProvider(targetDoc.location.href, data, function(manifest) {
|
||||
Social.installProvider(targetDoc, data, function(manifest) {
|
||||
this.doActivation(manifest.origin);
|
||||
}.bind(this));
|
||||
},
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0"?>
|
||||
<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist">
|
||||
<emItems>
|
||||
<emItem blockID="s1" id="bad.com@services.mozilla.org"></emItem>
|
||||
<emItem blockID="s1" id="test1.example.com@services.mozilla.org"></emItem>
|
||||
</emItems>
|
||||
</blocklist>
|
||||
|
@ -17,10 +17,10 @@ let manifest = { // normal provider
|
||||
};
|
||||
let manifest2 = { // used for testing install
|
||||
name: "provider 2",
|
||||
origin: "https://example1.com",
|
||||
sidebarURL: "https://example1.com/browser/browser/base/content/test/social/social_sidebar.html",
|
||||
workerURL: "https://example1.com/browser/browser/base/content/test/social/social_worker.js",
|
||||
iconURL: "https://example1.com/browser/browser/base/content/test/moz.png"
|
||||
origin: "https://test1.example.com",
|
||||
sidebarURL: "https://test1.example.com/browser/browser/base/content/test/social/social_sidebar.html",
|
||||
workerURL: "https://test1.example.com/browser/browser/base/content/test/social/social_worker.js",
|
||||
iconURL: "https://test1.example.com/browser/browser/base/content/test/moz.png"
|
||||
};
|
||||
|
||||
function test() {
|
||||
@ -174,62 +174,73 @@ var tests = {
|
||||
|
||||
// we expect the addon install dialog to appear, we need to accept the
|
||||
// install from the dialog.
|
||||
let windowListener = {
|
||||
info("Waiting for install dialog");
|
||||
Services.wm.addListener({
|
||||
onWindowTitleChange: function() {},
|
||||
onCloseWindow: function() {},
|
||||
onOpenWindow: function(window) {
|
||||
var domwindow = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
|
||||
onOpenWindow: function(xulwindow) {
|
||||
Services.wm.removeListener(this);
|
||||
var domwindow = xulwindow.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
|
||||
.getInterface(Components.interfaces.nsIDOMWindow);
|
||||
var self = this;
|
||||
waitForFocus(function() {
|
||||
self.windowReady(domwindow);
|
||||
}, domwindow);
|
||||
},
|
||||
windowReady: function(window) {
|
||||
if (window.document.location.href == XPINSTALL_URL) {
|
||||
info("Saw install dialog");
|
||||
is(domwindow.document.location.href, XPINSTALL_URL, "Should have seen the right window open");
|
||||
// Initially the accept button is disabled on a countdown timer
|
||||
var button = window.document.documentElement.getButton("accept");
|
||||
var button = domwindow.document.documentElement.getButton("accept");
|
||||
button.disabled = false;
|
||||
window.document.documentElement.acceptDialog();
|
||||
Services.wm.removeListener(windowListener);
|
||||
}
|
||||
domwindow.document.documentElement.acceptDialog();
|
||||
}, domwindow);
|
||||
}
|
||||
};
|
||||
Services.wm.addListener(windowListener);
|
||||
});
|
||||
|
||||
let installFrom = "https://example1.com";
|
||||
Services.prefs.setCharPref("social.whitelist", "");
|
||||
is(SocialService.getOriginActivationType(installFrom), "foreign", "testing foriegn install");
|
||||
Social.installProvider(installFrom, manifest2, function(addonManifest) {
|
||||
Services.prefs.clearUserPref("social.whitelist");
|
||||
SocialService.addBuiltinProvider(addonManifest.origin, function(provider) {
|
||||
Social.uninstallProvider(addonManifest.origin);
|
||||
let activationURL = manifest2.origin + "/browser/browser/base/content/test/social/social_activate.html"
|
||||
addTab(activationURL, function(tab) {
|
||||
let doc = tab.linkedBrowser.contentDocument;
|
||||
let installFrom = doc.nodePrincipal.origin;
|
||||
Services.prefs.setCharPref("social.whitelist", "");
|
||||
is(SocialService.getOriginActivationType(installFrom), "foreign", "testing foriegn install");
|
||||
Social.installProvider(doc, manifest2, function(addonManifest) {
|
||||
Services.prefs.clearUserPref("social.whitelist");
|
||||
SocialService.addBuiltinProvider(addonManifest.origin, function(provider) {
|
||||
Social.uninstallProvider(addonManifest.origin);
|
||||
gBrowser.removeTab(tab);
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
testWhitelistInstall: function(next) {
|
||||
AddonManager.addAddonListener(installListener(next));
|
||||
|
||||
let installFrom = "https://example1.com";
|
||||
Services.prefs.setCharPref("social.whitelist", installFrom);
|
||||
is(SocialService.getOriginActivationType(installFrom), "whitelist", "testing whitelist install");
|
||||
Social.installProvider(installFrom, manifest2, function(addonManifest) {
|
||||
Services.prefs.clearUserPref("social.whitelist");
|
||||
SocialService.addBuiltinProvider(addonManifest.origin, function(provider) {
|
||||
Social.uninstallProvider(addonManifest.origin);
|
||||
let activationURL = manifest2.origin + "/browser/browser/base/content/test/social/social_activate.html"
|
||||
addTab(activationURL, function(tab) {
|
||||
let doc = tab.linkedBrowser.contentDocument;
|
||||
let installFrom = doc.nodePrincipal.origin;
|
||||
Services.prefs.setCharPref("social.whitelist", installFrom);
|
||||
is(SocialService.getOriginActivationType(installFrom), "whitelist", "testing whitelist install");
|
||||
Social.installProvider(doc, manifest2, function(addonManifest) {
|
||||
Services.prefs.clearUserPref("social.whitelist");
|
||||
SocialService.addBuiltinProvider(addonManifest.origin, function(provider) {
|
||||
Social.uninstallProvider(addonManifest.origin);
|
||||
gBrowser.removeTab(tab);
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
testDirectoryInstall: function(next) {
|
||||
AddonManager.addAddonListener(installListener(next));
|
||||
|
||||
let installFrom = "https://addons.allizom.org";
|
||||
Services.prefs.setCharPref("social.directories", installFrom);
|
||||
is(SocialService.getOriginActivationType(installFrom), "directory", "testing directory install");
|
||||
Social.installProvider(installFrom, manifest2, function(addonManifest) {
|
||||
Services.prefs.clearUserPref("social.directories");
|
||||
SocialService.addBuiltinProvider(addonManifest.origin, function(provider) {
|
||||
Social.uninstallProvider(addonManifest.origin);
|
||||
let activationURL = manifest2.origin + "/browser/browser/base/content/test/social/social_activate.html"
|
||||
addTab(activationURL, function(tab) {
|
||||
let doc = tab.linkedBrowser.contentDocument;
|
||||
let installFrom = doc.nodePrincipal.origin;
|
||||
Services.prefs.setCharPref("social.directories", installFrom);
|
||||
is(SocialService.getOriginActivationType(installFrom), "directory", "testing directory install");
|
||||
Social.installProvider(doc, manifest2, function(addonManifest) {
|
||||
Services.prefs.clearUserPref("social.directories");
|
||||
SocialService.addBuiltinProvider(addonManifest.origin, function(provider) {
|
||||
Social.uninstallProvider(addonManifest.origin);
|
||||
gBrowser.removeTab(tab);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -11,18 +11,18 @@ let blocklistURL = "http://test:80/browser/browser/base/content/test/social/bloc
|
||||
let blocklistEmpty = "http://test:80/browser/browser/base/content/test/social/blocklistEmpty.xml";
|
||||
|
||||
let manifest = { // normal provider
|
||||
name: "provider 1",
|
||||
name: "provider ok",
|
||||
origin: "https://example.com",
|
||||
sidebarURL: "https://example.com/browser/browser/base/content/test/social/social_sidebar.html",
|
||||
workerURL: "https://example.com/browser/browser/base/content/test/social/social_worker.js",
|
||||
iconURL: "https://example.com/browser/browser/base/content/test/moz.png"
|
||||
};
|
||||
let manifest_bad = { // normal provider
|
||||
name: "provider 1",
|
||||
origin: "https://bad.com",
|
||||
sidebarURL: "https://bad.com/browser/browser/base/content/test/social/social_sidebar.html",
|
||||
workerURL: "https://bad.com/browser/browser/base/content/test/social/social_worker.js",
|
||||
iconURL: "https://bad.com/browser/browser/base/content/test/moz.png"
|
||||
name: "provider blocked",
|
||||
origin: "https://test1.example.com",
|
||||
sidebarURL: "https://test1.example.com/browser/browser/base/content/test/social/social_sidebar.html",
|
||||
workerURL: "https://test1.example.com/browser/browser/base/content/test/social/social_worker.js",
|
||||
iconURL: "https://test1.example.com/browser/browser/base/content/test/moz.png"
|
||||
};
|
||||
|
||||
function test() {
|
||||
@ -40,10 +40,10 @@ var tests = {
|
||||
var blocklist = Components.classes["@mozilla.org/extensions/blocklist;1"]
|
||||
.getService(Components.interfaces.nsIBlocklistService);
|
||||
setAndUpdateBlocklist(blocklistURL, function() {
|
||||
ok(blocklist.isAddonBlocklisted("bad.com@services.mozilla.org", "0", "0", "0"), "blocking 'blocked'");
|
||||
ok(!blocklist.isAddonBlocklisted("good.cpm@services.mozilla.org", "0", "0", "0"), "not blocking 'good'");
|
||||
ok(blocklist.isAddonBlocklisted("test1.example.com@services.mozilla.org", "0", "0", "0"), "blocking 'blocked'");
|
||||
ok(!blocklist.isAddonBlocklisted("example.com@services.mozilla.org", "0", "0", "0"), "not blocking 'good'");
|
||||
setAndUpdateBlocklist(blocklistEmpty, function() {
|
||||
ok(!blocklist.isAddonBlocklisted("bad.com@services.mozilla.org", "0", "0", "0"), "blocklist cleared");
|
||||
ok(!blocklist.isAddonBlocklisted("test1.example.com@services.mozilla.org", "0", "0", "0"), "blocklist cleared");
|
||||
next();
|
||||
});
|
||||
});
|
||||
@ -102,20 +102,26 @@ var tests = {
|
||||
Services.prefs.clearUserPref("social.whitelist");
|
||||
setAndUpdateBlocklist(blocklistEmpty, next);
|
||||
}
|
||||
let installFrom = "https://bad.com";
|
||||
// whitelist to avoid the 3rd party install dialog, we only want to test
|
||||
// the blocklist inside installProvider.
|
||||
Services.prefs.setCharPref("social.whitelist", installFrom);
|
||||
setAndUpdateBlocklist(blocklistURL, function() {
|
||||
try {
|
||||
// expecting an exception when attempting to install a hard blocked
|
||||
// provider
|
||||
Social.installProvider(installFrom, manifest_bad, function(addonManifest) {
|
||||
finish(false);
|
||||
});
|
||||
} catch(e) {
|
||||
finish(true);
|
||||
}
|
||||
let activationURL = manifest_bad.origin + "/browser/browser/base/content/test/social/social_activate.html"
|
||||
addTab(activationURL, function(tab) {
|
||||
let doc = tab.linkedBrowser.contentDocument;
|
||||
let installFrom = doc.nodePrincipal.origin;
|
||||
// whitelist to avoid the 3rd party install dialog, we only want to test
|
||||
// the blocklist inside installProvider.
|
||||
Services.prefs.setCharPref("social.whitelist", installFrom);
|
||||
setAndUpdateBlocklist(blocklistURL, function() {
|
||||
try {
|
||||
// expecting an exception when attempting to install a hard blocked
|
||||
// provider
|
||||
Social.installProvider(doc, manifest_bad, function(addonManifest) {
|
||||
gBrowser.removeTab(tab);
|
||||
finish(false);
|
||||
});
|
||||
} catch(e) {
|
||||
gBrowser.removeTab(tab);
|
||||
finish(true);
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
testBlockingExistingProvider: function(next) {
|
||||
|
@ -251,3 +251,11 @@ function addWindowListener(aURL, aCallback) {
|
||||
onWindowTitleChange: function(aXULWindow, aNewTitle) { }
|
||||
});
|
||||
}
|
||||
|
||||
function addTab(url, callback) {
|
||||
let tab = gBrowser.selectedTab = gBrowser.addTab(url, {skipAnimation: true});
|
||||
tab.linkedBrowser.addEventListener("load", function tabLoad(event) {
|
||||
tab.linkedBrowser.removeEventListener("load", tabLoad, true);
|
||||
executeSoon(function() {callback(tab)});
|
||||
}, true);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
This is the pdf.js project output, https://github.com/mozilla/pdf.js
|
||||
|
||||
Current extension version is: 0.7.337
|
||||
Current extension version is: 0.7.390
|
||||
|
||||
|
155
browser/extensions/pdfjs/components/PdfRedirector.js
Normal file
155
browser/extensions/pdfjs/components/PdfRedirector.js
Normal file
@ -0,0 +1,155 @@
|
||||
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
|
||||
/* Copyright 2012 Mozilla Foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
/* jshint esnext:true */
|
||||
/* globals Components, Services, XPCOMUtils, NetUtil, dump */
|
||||
|
||||
'use strict';
|
||||
|
||||
var EXPORTED_SYMBOLS = ['PdfRedirector'];
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const Cr = Components.results;
|
||||
const Cu = Components.utils;
|
||||
|
||||
const PDF_CONTENT_TYPE = 'application/pdf';
|
||||
const FIREFOX_ID = '{ec8030f7-c20a-464f-9b0e-13a3a9e97384}';
|
||||
|
||||
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
|
||||
Cu.import('resource://gre/modules/Services.jsm');
|
||||
Cu.import('resource://gre/modules/NetUtil.jsm');
|
||||
|
||||
|
||||
function getDOMWindow(aChannel) {
|
||||
var requestor = aChannel.notificationCallbacks ?
|
||||
aChannel.notificationCallbacks :
|
||||
aChannel.loadGroup.notificationCallbacks;
|
||||
var win = requestor.getInterface(Components.interfaces.nsIDOMWindow);
|
||||
return win;
|
||||
}
|
||||
|
||||
function getObjectUrl(window) {
|
||||
var url;
|
||||
var element = window.frameElement;
|
||||
var isOverlay = false;
|
||||
var params = {};
|
||||
if (element) {
|
||||
var tagName = element.nodeName;
|
||||
while (tagName != 'EMBED' && tagName != 'OBJECT') {
|
||||
// plugin overlay skipping until the target plugin is found
|
||||
isOverlay = true;
|
||||
element = element.parentNode;
|
||||
if (!element)
|
||||
throw 'Plugin element is not found';
|
||||
tagName = element.nodeName;
|
||||
}
|
||||
if (tagName == 'EMBED') {
|
||||
for (var i = 0; i < element.attributes.length; ++i) {
|
||||
params[element.attributes[i].localName] = element.attributes[i].value;
|
||||
}
|
||||
url = params.src;
|
||||
} else {
|
||||
for (var i = 0; i < element.childNodes.length; ++i) {
|
||||
var paramElement = element.childNodes[i];
|
||||
if (paramElement.nodeType != Ci.nsIDOMNode.ELEMENT_NODE ||
|
||||
paramElement.nodeName != 'PARAM') {
|
||||
continue;
|
||||
}
|
||||
|
||||
params[paramElement.getAttribute('name')] =
|
||||
paramElement.getAttribute('value');
|
||||
}
|
||||
var dataAttribute = element.getAttribute('data');
|
||||
url = dataAttribute || params.movie || params.src;
|
||||
}
|
||||
}
|
||||
if (!url) {
|
||||
return url; // src is not specified
|
||||
}
|
||||
|
||||
var element = window.frameElement;
|
||||
// XXX base uri?
|
||||
var baseUri = !element ? null :
|
||||
Services.io.newURI(element.ownerDocument.location.href, null, null);
|
||||
|
||||
return Services.io.newURI(url, null, baseUri).spec;
|
||||
}
|
||||
|
||||
function PdfRedirector() {
|
||||
}
|
||||
|
||||
PdfRedirector.prototype = {
|
||||
|
||||
// properties required for XPCOM registration:
|
||||
classID: Components.ID('{8cbfd8d0-2042-4976-b3ef-d9dee1efb975}'),
|
||||
classDescription: 'pdf.js Redirector',
|
||||
contractID:
|
||||
'@mozilla.org/streamconv;1?from=application/x-moz-playpreview-pdfjs&to=*/*',
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([
|
||||
Ci.nsIStreamConverter,
|
||||
Ci.nsIStreamListener,
|
||||
Ci.nsIRequestObserver
|
||||
]),
|
||||
|
||||
// nsIStreamConverter::convert
|
||||
convert: function(aFromStream, aFromType, aToType, aCtxt) {
|
||||
throw Cr.NS_ERROR_NOT_IMPLEMENTED;
|
||||
},
|
||||
|
||||
// nsIStreamConverter::asyncConvertData
|
||||
asyncConvertData: function(aFromType, aToType, aListener, aCtxt) {
|
||||
// Store the listener passed to us
|
||||
this.listener = aListener;
|
||||
},
|
||||
|
||||
// nsIStreamListener::onDataAvailable
|
||||
onDataAvailable: function(aRequest, aContext, aInputStream, aOffset, aCount) {
|
||||
// Do nothing since all the data loading is handled by the viewer.
|
||||
},
|
||||
|
||||
// nsIRequestObserver::onStartRequest
|
||||
onStartRequest: function(aRequest, aContext) {
|
||||
// Setup the request so we can use it below.
|
||||
aRequest.QueryInterface(Ci.nsIChannel);
|
||||
// Cancel the request so the viewer can handle it.
|
||||
aRequest.cancel(Cr.NS_BINDING_ABORTED);
|
||||
|
||||
var domWindow = getDOMWindow(aRequest);
|
||||
var pdfUrl = getObjectUrl(domWindow);
|
||||
if (!pdfUrl) {
|
||||
Services.console.logStringMessage(
|
||||
'PdfRedirector.js: PDF location is not specified for OBJECT/EMBED tag');
|
||||
return;
|
||||
}
|
||||
|
||||
// Create a new channel that is viewer loaded as a resource.
|
||||
var ioService = Services.io;
|
||||
var channel = ioService.newChannel(pdfUrl, null, null);
|
||||
|
||||
channel.loadGroup = aRequest.loadGroup;
|
||||
|
||||
channel.asyncOpen(this.listener, aContext);
|
||||
},
|
||||
|
||||
// nsIRequestObserver::onStopRequest
|
||||
onStopRequest: function(aRequest, aContext, aStatusCode) {
|
||||
// Do nothing
|
||||
}
|
||||
};
|
||||
|
||||
var NSGetFactory = XPCOMUtils.generateNSGetFactory([PdfRedirector]);
|
@ -337,6 +337,7 @@ ChromeActions.prototype = {
|
||||
}, '*');
|
||||
};
|
||||
|
||||
var self = this;
|
||||
this.dataListener.oncomplete =
|
||||
function ChromeActions_dataListenerComplete(data, errorCode) {
|
||||
|
||||
@ -346,7 +347,7 @@ ChromeActions.prototype = {
|
||||
errorCode: errorCode
|
||||
}, '*');
|
||||
|
||||
delete this.dataListener;
|
||||
delete self.dataListener;
|
||||
};
|
||||
|
||||
return true;
|
||||
@ -385,21 +386,19 @@ ChromeActions.prototype = {
|
||||
var message = getLocalizedString(strings, 'unsupported_feature');
|
||||
|
||||
var notificationBox = null;
|
||||
// Multiple browser windows can be opened, finding one for notification box
|
||||
var windowsEnum = Services.wm
|
||||
.getZOrderDOMWindowEnumerator('navigator:browser', true);
|
||||
while (windowsEnum.hasMoreElements()) {
|
||||
var win = windowsEnum.getNext();
|
||||
if (win.closed)
|
||||
continue;
|
||||
var browser = win.gBrowser.getBrowserForDocument(domWindow.top.document);
|
||||
if (browser) {
|
||||
// right window/browser is found, getting the notification box
|
||||
notificationBox = win.gBrowser.getNotificationBox(browser);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!notificationBox) {
|
||||
try {
|
||||
// Based on MDN's "Working with windows in chrome code"
|
||||
var mainWindow = domWindow
|
||||
.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
|
||||
.getInterface(Components.interfaces.nsIWebNavigation)
|
||||
.QueryInterface(Components.interfaces.nsIDocShellTreeItem)
|
||||
.rootTreeItem
|
||||
.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
|
||||
.getInterface(Components.interfaces.nsIDOMWindow);
|
||||
var browser = mainWindow.gBrowser
|
||||
.getBrowserForDocument(domWindow.top.document);
|
||||
notificationBox = mainWindow.gBrowser.getNotificationBox(browser);
|
||||
} catch (e) {
|
||||
log('Unable to get a notification box for the fallback message');
|
||||
return;
|
||||
}
|
||||
|
@ -33,11 +33,15 @@ const PDF_CONTENT_TYPE = 'application/pdf';
|
||||
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
|
||||
Cu.import('resource://gre/modules/Services.jsm');
|
||||
Cu.import('resource://pdf.js.components/PdfStreamConverter.js');
|
||||
Cu.import('resource://pdf.js.components/PdfRedirector.js');
|
||||
|
||||
let Svc = {};
|
||||
XPCOMUtils.defineLazyServiceGetter(Svc, 'mime',
|
||||
'@mozilla.org/mime;1',
|
||||
'nsIMIMEService');
|
||||
XPCOMUtils.defineLazyServiceGetter(Svc, 'pluginHost',
|
||||
'@mozilla.org/plugin/host;1',
|
||||
'nsIPluginHost');
|
||||
|
||||
function getBoolPref(aPref, aDefaultValue) {
|
||||
try {
|
||||
@ -55,8 +59,10 @@ function getIntPref(aPref, aDefaultValue) {
|
||||
}
|
||||
}
|
||||
|
||||
// Register/unregister a constructor as a component.
|
||||
let Factory = {
|
||||
// Factory that registers/unregisters a constructor as a component.
|
||||
function Factory() {}
|
||||
|
||||
Factory.prototype = {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIFactory]),
|
||||
_targetConstructor: null,
|
||||
|
||||
@ -193,7 +199,14 @@ let PdfJs = {
|
||||
if (this._registered)
|
||||
return;
|
||||
|
||||
Factory.register(PdfStreamConverter);
|
||||
this._pdfStreamConverterFactory = new Factory();
|
||||
this._pdfStreamConverterFactory.register(PdfStreamConverter);
|
||||
|
||||
this._pdfRedirectorFactory = new Factory();
|
||||
this._pdfRedirectorFactory.register(PdfRedirector);
|
||||
Svc.pluginHost.registerPlayPreviewMimeType('application/pdf', true,
|
||||
'data:application/x-moz-playpreview-pdfjs;,');
|
||||
|
||||
this._registered = true;
|
||||
},
|
||||
|
||||
@ -201,7 +214,13 @@ let PdfJs = {
|
||||
if (!this._registered)
|
||||
return;
|
||||
|
||||
Factory.unregister();
|
||||
this._pdfStreamConverterFactory.unregister();
|
||||
delete this._pdfStreamConverterFactory;
|
||||
|
||||
this._pdfRedirectorFactory.unregister;
|
||||
delete this._pdfRedirectorFactory;
|
||||
Svc.pluginHost.unregisterPlayPreviewMimeType('application/pdf');
|
||||
|
||||
this._registered = false;
|
||||
}
|
||||
};
|
||||
|
@ -16,8 +16,8 @@
|
||||
*/
|
||||
|
||||
var PDFJS = {};
|
||||
PDFJS.version = '0.7.337';
|
||||
PDFJS.build = 'f58aee1';
|
||||
PDFJS.version = '0.7.390';
|
||||
PDFJS.build = '921f321';
|
||||
|
||||
(function pdfjsWrapper() {
|
||||
// Use strict in our context only - users might not want it
|
||||
@ -832,6 +832,23 @@ var Util = PDFJS.Util = (function UtilClosure() {
|
||||
return [xt, yt];
|
||||
};
|
||||
|
||||
// Applies the transform to the rectangle and finds the minimum axially
|
||||
// aligned bounding box.
|
||||
Util.getAxialAlignedBoundingBox =
|
||||
function Util_getAxialAlignedBoundingBox(r, m) {
|
||||
|
||||
var p1 = Util.applyTransform(r, m);
|
||||
var p2 = Util.applyTransform(r.slice(2, 4), m);
|
||||
var p3 = Util.applyTransform([r[0], r[3]], m);
|
||||
var p4 = Util.applyTransform([r[2], r[1]], m);
|
||||
return [
|
||||
Math.min(p1[0], p2[0], p3[0], p4[0]),
|
||||
Math.min(p1[1], p2[1], p3[1], p4[1]),
|
||||
Math.max(p1[0], p2[0], p3[0], p4[0]),
|
||||
Math.max(p1[1], p2[1], p3[1], p4[1])
|
||||
];
|
||||
};
|
||||
|
||||
Util.inverseTransform = function Util_inverseTransform(m) {
|
||||
var d = m[0] * m[3] - m[1] * m[2];
|
||||
return [m[3] / d, -m[1] / d, -m[2] / d, m[0] / d,
|
||||
@ -2260,6 +2277,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
||||
this.objs = objs;
|
||||
this.textLayer = textLayer;
|
||||
this.imageLayer = imageLayer;
|
||||
this.groupStack = [];
|
||||
if (canvasCtx) {
|
||||
addContextCurrentTransform(canvasCtx);
|
||||
}
|
||||
@ -2392,6 +2410,25 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
||||
return tmpCanvas;
|
||||
}
|
||||
|
||||
function copyCtxState(sourceCtx, destCtx) {
|
||||
var properties = ['strokeStyle', 'fillStyle', 'fillRule', 'globalAlpha',
|
||||
'lineWidth', 'lineCap', 'lineJoin', 'miterLimit',
|
||||
'globalCompositeOperation', 'font'];
|
||||
for (var i = 0, ii = properties.length; i < ii; i++) {
|
||||
var property = properties[i];
|
||||
if (property in sourceCtx) {
|
||||
destCtx[property] = sourceCtx[property];
|
||||
}
|
||||
}
|
||||
if ('setLineDash' in sourceCtx) {
|
||||
destCtx.setLineDash(sourceCtx.getLineDash());
|
||||
destCtx.lineDashOffset = sourceCtx.lineDashOffset;
|
||||
} else if ('mozDash' in sourceCtx) {
|
||||
destCtx.mozDash = sourceCtx.mozDash;
|
||||
destCtx.mozDashOffset = sourceCtx.mozDashOffset;
|
||||
}
|
||||
}
|
||||
|
||||
var LINE_CAP_STYLES = ['butt', 'round', 'square'];
|
||||
var LINE_JOIN_STYLES = ['miter', 'round', 'bevel'];
|
||||
var NORMAL_CLIP = {};
|
||||
@ -2596,6 +2633,22 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
||||
this.current.fillAlpha = state[1];
|
||||
this.ctx.globalAlpha = state[1];
|
||||
break;
|
||||
case 'BM':
|
||||
if (value && value.name && (value.name !== 'Normal')) {
|
||||
var mode = value.name.replace(/([A-Z])/g,
|
||||
function(c) {
|
||||
return '-' + c.toLowerCase();
|
||||
}
|
||||
).substring(1);
|
||||
this.ctx.globalCompositeOperation = mode;
|
||||
if (this.ctx.globalCompositeOperation !== mode) {
|
||||
warn('globalCompositeOperation "' + mode +
|
||||
'" is not supported');
|
||||
}
|
||||
} else {
|
||||
this.ctx.globalCompositeOperation = 'source-over';
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -3008,7 +3061,8 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
||||
var character = glyph.fontChar;
|
||||
var vmetric = glyph.vmetric || defaultVMetrics;
|
||||
if (vertical) {
|
||||
var vx = vmetric[1] * fontSize * current.fontMatrix[0];
|
||||
var vx = glyph.vmetric ? vmetric[1] : glyph.width * 0.5;
|
||||
vx = -vx * fontSize * current.fontMatrix[0];
|
||||
var vy = vmetric[2] * fontSize * current.fontMatrix[0];
|
||||
}
|
||||
var width = vmetric ? -vmetric[0] : glyph.width;
|
||||
@ -3083,7 +3137,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
||||
geom.canvasWidth = canvasWidth;
|
||||
if (vertical) {
|
||||
var vmetric = font.defaultVMetrics;
|
||||
geom.x -= vmetric[1] * fontSize * current.fontMatrix[0] /
|
||||
geom.x += vmetric[1] * fontSize * current.fontMatrix[0] /
|
||||
fontSizeScale * geom.hScale;
|
||||
geom.y += vmetric[2] * fontSize * current.fontMatrix[0] /
|
||||
fontSizeScale * geom.vScale;
|
||||
@ -3144,7 +3198,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
||||
if (vertical) {
|
||||
var fontSizeScale = current.fontSizeScale;
|
||||
var vmetric = font.defaultVMetrics;
|
||||
geom.x -= vmetric[1] * fontSize * current.fontMatrix[0] /
|
||||
geom.x += vmetric[1] * fontSize * current.fontMatrix[0] /
|
||||
fontSizeScale * geom.hScale;
|
||||
geom.y += vmetric[2] * fontSize * current.fontMatrix[0] /
|
||||
fontSizeScale * geom.vScale;
|
||||
@ -3365,6 +3419,89 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
||||
} while (this.current.paintFormXObjectDepth >= depth);
|
||||
},
|
||||
|
||||
beginGroup: function CanvasGraphics_beginGroup(group) {
|
||||
this.save();
|
||||
var currentCtx = this.ctx;
|
||||
// TODO non-isolated groups - according to Rik at adobe non-isolated
|
||||
// group results aren't usually that different and they even have tools
|
||||
// that ignore this setting. Notes from Rik on implmenting:
|
||||
// - When you encounter an transparency group, create a new canvas with
|
||||
// the dimensions of the bbox
|
||||
// - copy the content from the previous canvas to the new canvas
|
||||
// - draw as usual
|
||||
// - remove the backdrop alpha:
|
||||
// alphaNew = 1 - (1 - alpha)/(1 - alphaBackdrop) with 'alpha' the alpha
|
||||
// value of your transparency group and 'alphaBackdrop' the alpha of the
|
||||
// backdrop
|
||||
// - remove background color:
|
||||
// colorNew = color - alphaNew *colorBackdrop /(1 - alphaNew)
|
||||
if (!group.isolated) {
|
||||
TODO('Support non-isolated groups.');
|
||||
}
|
||||
|
||||
// TODO knockout - supposedly possible with the clever use of compositing
|
||||
// modes.
|
||||
if (group.knockout) {
|
||||
TODO('Support knockout groups.');
|
||||
}
|
||||
|
||||
var currentTransform = currentCtx.mozCurrentTransform;
|
||||
if (group.matrix) {
|
||||
currentCtx.transform.apply(currentCtx, group.matrix);
|
||||
}
|
||||
assert(group.bbox, 'Bounding box is required.');
|
||||
|
||||
// Based on the current transform figure out how big the bounding box
|
||||
// will actually be.
|
||||
var bounds = Util.getAxialAlignedBoundingBox(
|
||||
group.bbox,
|
||||
currentCtx.mozCurrentTransform);
|
||||
// Use ceil in case we're between sizes so we don't create canvas that is
|
||||
// too small.
|
||||
var drawnWidth = Math.ceil(bounds[2] - bounds[0]);
|
||||
var drawnHeight = Math.ceil(bounds[3] - bounds[1]);
|
||||
var scratchCanvas = createScratchCanvas(drawnWidth, drawnHeight);
|
||||
var groupCtx = scratchCanvas.getContext('2d');
|
||||
addContextCurrentTransform(groupCtx);
|
||||
// Since we created a new canvas that is just the size of the bounding box
|
||||
// we have to translate the group ctx.
|
||||
var offsetX = bounds[0];
|
||||
var offsetY = bounds[1];
|
||||
groupCtx.translate(-offsetX, -offsetY);
|
||||
groupCtx.transform.apply(groupCtx, currentTransform);
|
||||
|
||||
// Setup the current ctx so when the group is popped we draw it the right
|
||||
// location.
|
||||
currentCtx.setTransform(1, 0, 0, 1, 0, 0);
|
||||
currentCtx.translate(offsetX, offsetY);
|
||||
|
||||
// The transparency group inherits all off the current graphics state
|
||||
// except the blend mode, soft mask, and alpha constants.
|
||||
copyCtxState(currentCtx, groupCtx);
|
||||
this.ctx = groupCtx;
|
||||
this.setGState([
|
||||
['SMask', 'None'],
|
||||
['BM', 'Normal'],
|
||||
['ca', 1],
|
||||
['CA', 1]
|
||||
]);
|
||||
this.groupStack.push(currentCtx);
|
||||
},
|
||||
|
||||
endGroup: function CanvasGraphics_endGroup(group) {
|
||||
var groupCtx = this.ctx;
|
||||
this.ctx = this.groupStack.pop();
|
||||
// Turn off image smoothing to avoid sub pixel interpolation which can
|
||||
// look kind of blurry for some pdfs.
|
||||
if ('imageSmoothingEnabled' in this.ctx) {
|
||||
this.ctx.imageSmoothingEnabled = false;
|
||||
} else {
|
||||
this.ctx.mozImageSmoothingEnabled = false;
|
||||
}
|
||||
this.ctx.drawImage(groupCtx.canvas, 0, 0);
|
||||
this.restore();
|
||||
},
|
||||
|
||||
paintJpegXObject: function CanvasGraphics_paintJpegXObject(objId, w, h) {
|
||||
var domImage = this.objs.get(objId);
|
||||
if (!domImage) {
|
||||
@ -3920,7 +4057,7 @@ var Catalog = (function CatalogClosure() {
|
||||
if (isStream(js)) {
|
||||
js = bytesToString(js.getBytes());
|
||||
}
|
||||
javaScript.push(js);
|
||||
javaScript.push(stringToPDFString(js));
|
||||
}
|
||||
}
|
||||
return shadow(this, 'javaScript', javaScript);
|
||||
@ -4385,6 +4522,9 @@ var NameTree = (function NameTreeClosure() {
|
||||
while (queue.length > 0) {
|
||||
var i, n;
|
||||
var obj = xref.fetchIfRef(queue.shift());
|
||||
if (!isDict(obj)) {
|
||||
continue;
|
||||
}
|
||||
if (obj.has('Kids')) {
|
||||
var kids = obj.get('Kids');
|
||||
for (i = 0, n = kids.length; i < n; i++) {
|
||||
@ -14652,6 +14792,60 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
||||
return loadedName;
|
||||
}
|
||||
|
||||
function buildFormXObject(xobj, smask) {
|
||||
var matrix = xobj.dict.get('Matrix');
|
||||
var bbox = xobj.dict.get('BBox');
|
||||
var group = xobj.dict.get('Group');
|
||||
if (group) {
|
||||
var groupOptions = {
|
||||
matrix: matrix,
|
||||
bbox: bbox,
|
||||
smask: !!smask,
|
||||
isolated: false,
|
||||
knockout: false
|
||||
};
|
||||
|
||||
var groupSubtype = group.get('S');
|
||||
if (isName(groupSubtype) && groupSubtype.name === 'Transparency') {
|
||||
groupOptions.isolated = group.get('I') || false;
|
||||
groupOptions.knockout = group.get('K') || false;
|
||||
// There is also a group colorspace, but since we put everything in
|
||||
// RGB I'm not sure we need it.
|
||||
}
|
||||
fnArray.push('beginGroup');
|
||||
argsArray.push([groupOptions]);
|
||||
}
|
||||
|
||||
fnArray.push('paintFormXObjectBegin');
|
||||
argsArray.push([matrix, bbox]);
|
||||
|
||||
// This adds the operatorList of the xObj to the current queue.
|
||||
var depIdx = dependencyArray.length;
|
||||
|
||||
// Pass in the current `queue` object. That means the `fnArray`
|
||||
// and the `argsArray` in this scope is reused and new commands
|
||||
// are added to them.
|
||||
self.getOperatorList(xobj,
|
||||
xobj.dict.get('Resources') || resources,
|
||||
dependencyArray, queue);
|
||||
|
||||
self.getOperatorList(xobj,
|
||||
xobj.dict.get('Resources') || resources,
|
||||
dependencyArray, queue);
|
||||
|
||||
// Add the dependencies that are required to execute the
|
||||
// operatorList.
|
||||
insertDependency(dependencyArray.slice(depIdx));
|
||||
|
||||
fnArray.push('paintFormXObjectEnd');
|
||||
argsArray.push([]);
|
||||
|
||||
if (group) {
|
||||
fnArray.push('endGroup');
|
||||
argsArray.push([groupOptions]);
|
||||
}
|
||||
}
|
||||
|
||||
function buildPaintImageXObject(image, inline) {
|
||||
var dict = image.dict;
|
||||
var w = dict.get('Width', 'W');
|
||||
@ -14825,28 +15019,9 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
||||
);
|
||||
|
||||
if ('Form' == type.name) {
|
||||
var matrix = xobj.dict.get('Matrix');
|
||||
var bbox = xobj.dict.get('BBox');
|
||||
|
||||
fnArray.push('paintFormXObjectBegin');
|
||||
argsArray.push([matrix, bbox]);
|
||||
|
||||
// This adds the operatorList of the xObj to the current queue.
|
||||
var depIdx = dependencyArray.length;
|
||||
|
||||
// Pass in the current `queue` object. That means the `fnArray`
|
||||
// and the `argsArray` in this scope is reused and new commands
|
||||
// are added to them.
|
||||
this.getOperatorList(xobj,
|
||||
xobj.dict.get('Resources') || resources,
|
||||
dependencyArray, queue);
|
||||
|
||||
// Add the dependencies that are required to execute the
|
||||
// operatorList.
|
||||
insertDependency(dependencyArray.slice(depIdx));
|
||||
|
||||
fn = 'paintFormXObjectEnd';
|
||||
buildFormXObject(xobj);
|
||||
args = [];
|
||||
continue;
|
||||
} else if ('Image' == type.name) {
|
||||
buildPaintImageXObject(xobj, false);
|
||||
} else {
|
||||
@ -14905,6 +15080,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
||||
case 'FL':
|
||||
case 'CA':
|
||||
case 'ca':
|
||||
case 'BM':
|
||||
gsStateObj.push([key, value]);
|
||||
break;
|
||||
case 'Font':
|
||||
@ -14914,11 +15090,6 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
||||
value[1]
|
||||
]);
|
||||
break;
|
||||
case 'BM':
|
||||
// We support the default so don't trigger the TODO.
|
||||
if (!isName(value) || value.name != 'Normal')
|
||||
TODO('graphic state operator ' + key);
|
||||
break;
|
||||
case 'SMask':
|
||||
// We support the default so don't trigger the TODO.
|
||||
if (!isName(value) || value.name != 'None')
|
||||
@ -15459,7 +15630,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
||||
|
||||
if (properties.vertical) {
|
||||
var vmetrics = dict.get('DW2') || [880, -1000];
|
||||
defaultVMetrics = [vmetrics[1], vmetrics[1] / 2, vmetrics[0]];
|
||||
defaultVMetrics = [vmetrics[1], defaultWidth * 0.5, vmetrics[0]];
|
||||
vmetrics = dict.get('W2');
|
||||
if (vmetrics) {
|
||||
for (var i = 0, ii = vmetrics.length; i < ii; i++) {
|
||||
@ -16073,7 +16244,23 @@ var nonStdFontMap = {
|
||||
'LucidaConsole': 'Courier',
|
||||
'LucidaConsole-Bold': 'Courier-Bold',
|
||||
'LucidaConsole-BoldItalic': 'Courier-BoldOblique',
|
||||
'LucidaConsole-Italic': 'Courier-Oblique'
|
||||
'LucidaConsole-Italic': 'Courier-Oblique',
|
||||
'MS-Gothic': 'MS Gothic',
|
||||
'MS-Gothic-Bold': 'MS Gothic-Bold',
|
||||
'MS-Gothic-BoldItalic': 'MS Gothic-BoldItalic',
|
||||
'MS-Gothic-Italic': 'MS Gothic-Italic',
|
||||
'MS-Mincho': 'MS Mincho',
|
||||
'MS-Mincho-Bold': 'MS Mincho-Bold',
|
||||
'MS-Mincho-BoldItalic': 'MS Mincho-BoldItalic',
|
||||
'MS-Mincho-Italic': 'MS Mincho-Italic',
|
||||
'MS-PGothic': 'MS PGothic',
|
||||
'MS-PGothic-Bold': 'MS PGothic-Bold',
|
||||
'MS-PGothic-BoldItalic': 'MS PGothic-BoldItalic',
|
||||
'MS-PGothic-Italic': 'MS PGothic-Italic',
|
||||
'MS-PMincho': 'MS PMincho',
|
||||
'MS-PMincho-Bold': 'MS PMincho-Bold',
|
||||
'MS-PMincho-BoldItalic': 'MS PMincho-BoldItalic',
|
||||
'MS-PMincho-Italic': 'MS PMincho-Italic',
|
||||
};
|
||||
|
||||
var serifFonts = {
|
||||
@ -16139,6 +16326,7 @@ var CMapConverterList = {
|
||||
'90msp-RKSJ-H': sjisToUnicode,
|
||||
'90msp-RKSJ-V': sjisToUnicode,
|
||||
'GBK-EUC-H': gbkToUnicode,
|
||||
'B5pc-H': big5ToUnicode,
|
||||
'ETenms-B5-H': big5ToUnicode,
|
||||
'ETenms-B5-V': big5ToUnicode,
|
||||
};
|
||||
@ -18164,8 +18352,8 @@ var Font = (function FontClosure() {
|
||||
}
|
||||
var bmpLength = i + 1;
|
||||
|
||||
var trailingRangesCount = ranges[bmpLength - 1][1] < 0xFFFF ? 1 : 0;
|
||||
var segCount = bmpLength + trailingRangesCount;
|
||||
if (ranges[i][1] === 0xFFFF) { ranges[i][1] = 0xFFFE; }
|
||||
var segCount = bmpLength + 1;
|
||||
var segCount2 = segCount * 2;
|
||||
var searchRange = getMaxPower2(segCount) * 2;
|
||||
var searchEntry = Math.log(segCount) / Math.log(2);
|
||||
@ -18210,12 +18398,10 @@ var Font = (function FontClosure() {
|
||||
}
|
||||
}
|
||||
|
||||
if (trailingRangesCount > 0) {
|
||||
endCount += '\xFF\xFF';
|
||||
startCount += '\xFF\xFF';
|
||||
idDeltas += '\x00\x01';
|
||||
idRangeOffsets += '\x00\x00';
|
||||
}
|
||||
endCount += '\xFF\xFF';
|
||||
startCount += '\xFF\xFF';
|
||||
idDeltas += '\x00\x01';
|
||||
idRangeOffsets += '\x00\x00';
|
||||
|
||||
var format314 = '\x00\x00' + // language
|
||||
string16(segCount2) +
|
||||
@ -18302,6 +18488,14 @@ var Font = (function FontClosure() {
|
||||
if (firstChar > lastChar) {
|
||||
return false;
|
||||
}
|
||||
stream.getBytes(6); // skipping sTypoAscender/Descender/LineGap
|
||||
var usWinAscent = int16(stream.getBytes(2));
|
||||
if (usWinAscent === 0) { // makes font unreadable by windows
|
||||
return false;
|
||||
}
|
||||
|
||||
// OS/2 appears to be valid, resetting some fields
|
||||
os2.data[8] = os2.data[9] = 0; // IE rejects fonts if fsType != 0
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -19151,16 +19345,6 @@ var Font = (function FontClosure() {
|
||||
return names;
|
||||
}
|
||||
|
||||
function isOS2Valid(os2Table) {
|
||||
var data = os2Table.data;
|
||||
// usWinAscent == 0 makes font unreadable by windows
|
||||
var usWinAscent = (data[74] << 8) | data[75];
|
||||
if (usWinAscent === 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
var TTOpsStackDeltas = [
|
||||
0, 0, 0, 0, 0, 0, 0, 0, -2, -2, -2, -2, 0, 0, -2, -5,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, 0, 0, -1, 0, -1, -1, -1, -1,
|
||||
@ -19355,12 +19539,6 @@ var Font = (function FontClosure() {
|
||||
// of missing tables
|
||||
createOpenTypeHeader(header.version, ttf, numTables);
|
||||
|
||||
// Invalid OS/2 can break the font for the Windows
|
||||
if (os2 && !isOS2Valid(os2)) {
|
||||
tables.splice(tables.indexOf(os2), 1);
|
||||
os2 = null;
|
||||
}
|
||||
|
||||
// Ensure the hmtx table contains the advance width and
|
||||
// sidebearings information for numGlyphs in the maxp table
|
||||
font.pos = (font.start || 0) + maxp.offset;
|
||||
@ -21658,10 +21836,19 @@ var CFFParser = (function CFFParserClosure() {
|
||||
}
|
||||
return { charStrings: charStrings, seacs: seacs };
|
||||
},
|
||||
emptyPrivateDictionary:
|
||||
function CFFParser_emptyPrivateDictionary(parentDict) {
|
||||
var privateDict = this.createDict(CFFPrivateDict, [],
|
||||
parentDict.strings);
|
||||
parentDict.setByKey(18, [0, 0]);
|
||||
parentDict.privateDict = privateDict;
|
||||
},
|
||||
parsePrivateDict: function CFFParser_parsePrivateDict(parentDict) {
|
||||
// no private dict, do nothing
|
||||
if (!parentDict.hasName('Private'))
|
||||
if (!parentDict.hasName('Private')) {
|
||||
this.emptyPrivateDictionary(parentDict);
|
||||
return;
|
||||
}
|
||||
var privateOffset = parentDict.getByName('Private');
|
||||
// make sure the params are formatted correctly
|
||||
if (!isArray(privateOffset) || privateOffset.length !== 2) {
|
||||
@ -21672,7 +21859,7 @@ var CFFParser = (function CFFParserClosure() {
|
||||
var offset = privateOffset[1];
|
||||
// remove empty dicts or ones that refer to invalid location
|
||||
if (size === 0 || offset >= this.bytes.length) {
|
||||
parentDict.removeByName('Private');
|
||||
this.emptyPrivateDictionary(parentDict);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -21690,7 +21877,7 @@ var CFFParser = (function CFFParserClosure() {
|
||||
var relativeOffset = offset + subrsOffset;
|
||||
// Validate the offset.
|
||||
if (subrsOffset === 0 || relativeOffset >= this.bytes.length) {
|
||||
privateDict.removeByName('Subrs');
|
||||
this.emptyPrivateDictionary(parentDict);
|
||||
return;
|
||||
}
|
||||
var subrsIndex = this.parseIndex(relativeOffset);
|
||||
@ -22371,15 +22558,23 @@ var CFFCompiler = (function CFFCompilerClosure() {
|
||||
output) {
|
||||
for (var i = 0, ii = dicts.length; i < ii; ++i) {
|
||||
var fontDict = dicts[i];
|
||||
if (!fontDict.privateDict || !fontDict.hasName('Private'))
|
||||
continue;
|
||||
assert(fontDict.privateDict && fontDict.hasName('Private'),
|
||||
'There must be an private dictionary.');
|
||||
var privateDict = fontDict.privateDict;
|
||||
var privateDictTracker = new CFFOffsetTracker();
|
||||
var privateDictData = this.compileDict(privateDict, privateDictTracker);
|
||||
|
||||
privateDictTracker.offset(output.length);
|
||||
var outputLength = output.length;
|
||||
privateDictTracker.offset(outputLength);
|
||||
if (!privateDictData.length) {
|
||||
// The private dictionary was empty, set the output length to zero to
|
||||
// ensure the offset length isn't out of bounds in the eyes of the
|
||||
// sanitizer.
|
||||
outputLength = 0;
|
||||
}
|
||||
|
||||
trackers[i].setEntryLocation('Private',
|
||||
[privateDictData.length, output.length],
|
||||
[privateDictData.length, outputLength],
|
||||
output);
|
||||
output.add(privateDictData);
|
||||
|
||||
|
@ -826,6 +826,11 @@ html[dir='rtl'] .toolbarButton.pageDown::before {
|
||||
padding-top: 4px;
|
||||
}
|
||||
|
||||
#viewBookmark[href='#'] {
|
||||
opacity: .5;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.toolbarButton.bookmark::before {
|
||||
content: url(images/toolbarButton-bookmark.png);
|
||||
}
|
||||
|
@ -1290,6 +1290,7 @@ var PDFView = {
|
||||
if (PDFView.supportsPrinting) {
|
||||
pdfDocument.getJavaScript().then(function(javaScript) {
|
||||
if (javaScript.length) {
|
||||
console.warn('Warning: JavaScript is not supported');
|
||||
PDFView.fallback();
|
||||
}
|
||||
// Hack to support auto printing.
|
||||
@ -1363,7 +1364,7 @@ var PDFView = {
|
||||
self.setTitle(pdfTitle + ' - ' + document.title);
|
||||
|
||||
if (info.IsAcroFormPresent) {
|
||||
// AcroForm/XFA was found
|
||||
console.warn('Warning: AcroForm/XFA is not supported');
|
||||
PDFView.fallback();
|
||||
}
|
||||
});
|
||||
@ -1565,55 +1566,52 @@ var PDFView = {
|
||||
},
|
||||
|
||||
getVisiblePages: function pdfViewGetVisiblePages() {
|
||||
return this.getVisibleElements(this.container,
|
||||
this.pages, true);
|
||||
if (!this.isFullscreen) {
|
||||
return this.getVisibleElements(this.container, this.pages, true);
|
||||
} else {
|
||||
// The algorithm in getVisibleElements is broken in fullscreen mode.
|
||||
var visible = [], page = this.page;
|
||||
var currentPage = this.pages[page - 1];
|
||||
visible.push({ id: currentPage.id, view: currentPage });
|
||||
|
||||
return { first: currentPage, last: currentPage, views: visible};
|
||||
}
|
||||
},
|
||||
|
||||
getVisibleThumbs: function pdfViewGetVisibleThumbs() {
|
||||
return this.getVisibleElements(this.thumbnailContainer,
|
||||
this.thumbnails);
|
||||
return this.getVisibleElements(this.thumbnailContainer, this.thumbnails);
|
||||
},
|
||||
|
||||
// Generic helper to find out what elements are visible within a scroll pane.
|
||||
getVisibleElements: function pdfViewGetVisibleElements(
|
||||
scrollEl, views, sortByVisibility) {
|
||||
var currentHeight = 0, view;
|
||||
var top = scrollEl.scrollTop;
|
||||
var top = scrollEl.scrollTop, bottom = top + scrollEl.clientHeight;
|
||||
var left = scrollEl.scrollLeft, right = left + scrollEl.clientWidth;
|
||||
|
||||
for (var i = 1, ii = views.length; i <= ii; ++i) {
|
||||
view = views[i - 1];
|
||||
var visible = [], view;
|
||||
var currentHeight, viewHeight, hiddenHeight, percentHeight;
|
||||
var currentWidth, viewWidth;
|
||||
for (var i = 0, ii = views.length; i < ii; ++i) {
|
||||
view = views[i];
|
||||
currentHeight = view.el.offsetTop + view.el.clientTop;
|
||||
if (currentHeight + view.el.clientHeight > top)
|
||||
break;
|
||||
currentHeight += view.el.clientHeight;
|
||||
}
|
||||
|
||||
var visible = [];
|
||||
|
||||
// Algorithm broken in fullscreen mode
|
||||
if (this.isFullscreen) {
|
||||
var currentPage = this.pages[this.page - 1];
|
||||
visible.push({
|
||||
id: currentPage.id,
|
||||
view: currentPage
|
||||
});
|
||||
|
||||
return { first: currentPage, last: currentPage, views: visible};
|
||||
}
|
||||
|
||||
var bottom = top + scrollEl.clientHeight;
|
||||
var nextHeight, hidden, percent, viewHeight;
|
||||
for (; i <= ii && currentHeight < bottom; ++i) {
|
||||
view = views[i - 1];
|
||||
viewHeight = view.el.clientHeight;
|
||||
currentHeight = view.el.offsetTop + view.el.clientTop;
|
||||
nextHeight = currentHeight + viewHeight;
|
||||
hidden = Math.max(0, top - currentHeight) +
|
||||
Math.max(0, nextHeight - bottom);
|
||||
percent = Math.floor((viewHeight - hidden) * 100.0 / viewHeight);
|
||||
if ((currentHeight + viewHeight) < top) {
|
||||
continue;
|
||||
}
|
||||
if (currentHeight > bottom) {
|
||||
break;
|
||||
}
|
||||
currentWidth = view.el.offsetLeft + view.el.clientLeft;
|
||||
viewWidth = view.el.clientWidth;
|
||||
if ((currentWidth + viewWidth) < left || currentWidth > right) {
|
||||
continue;
|
||||
}
|
||||
hiddenHeight = Math.max(0, top - currentHeight) +
|
||||
Math.max(0, currentHeight + viewHeight - bottom);
|
||||
percentHeight = ((viewHeight - hiddenHeight) * 100 / viewHeight) | 0;
|
||||
|
||||
visible.push({ id: view.id, y: currentHeight,
|
||||
view: view, percent: percent });
|
||||
currentHeight = nextHeight;
|
||||
view: view, percent: percentHeight });
|
||||
}
|
||||
|
||||
var first = visible[0];
|
||||
@ -1622,13 +1620,12 @@ var PDFView = {
|
||||
if (sortByVisibility) {
|
||||
visible.sort(function(a, b) {
|
||||
var pc = a.percent - b.percent;
|
||||
if (Math.abs(pc) > 0.001)
|
||||
if (Math.abs(pc) > 0.001) {
|
||||
return -pc;
|
||||
|
||||
}
|
||||
return a.id - b.id; // ensure stability
|
||||
});
|
||||
}
|
||||
|
||||
return {first: first, last: last, views: visible};
|
||||
},
|
||||
|
||||
@ -1704,6 +1701,10 @@ var PDFView = {
|
||||
this.page = this.page;
|
||||
this.clearMouseScrollState();
|
||||
this.hidePresentationControls();
|
||||
|
||||
// Ensure that the thumbnail of the current page is visible
|
||||
// when exiting fullscreen mode.
|
||||
scrollIntoView(document.getElementById('thumbnailContainer' + this.page));
|
||||
},
|
||||
|
||||
showPresentationControls: function pdfViewShowPresentationControls() {
|
||||
@ -2086,7 +2087,6 @@ var PageView = function pageView(container, pdfPage, id, scale,
|
||||
|
||||
var canvas = document.createElement('canvas');
|
||||
canvas.id = 'page' + this.id;
|
||||
canvas.mozOpaque = true;
|
||||
div.appendChild(canvas);
|
||||
this.canvas = canvas;
|
||||
|
||||
@ -2116,13 +2116,10 @@ var PageView = function pageView(container, pdfPage, id, scale,
|
||||
}
|
||||
|
||||
var ctx = canvas.getContext('2d');
|
||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||
// TODO(mack): use data attributes to store these
|
||||
ctx._scaleX = outputScale.sx;
|
||||
ctx._scaleY = outputScale.sy;
|
||||
ctx.save();
|
||||
ctx.fillStyle = 'rgb(255, 255, 255)';
|
||||
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
||||
ctx.restore();
|
||||
if (outputScale.scaled) {
|
||||
ctx.scale(outputScale.sx, outputScale.sy);
|
||||
}
|
||||
@ -2337,7 +2334,6 @@ var ThumbnailView = function thumbnailView(container, pdfPage, id) {
|
||||
function getPageDrawContext() {
|
||||
var canvas = document.createElement('canvas');
|
||||
canvas.id = 'thumbnail' + id;
|
||||
canvas.mozOpaque = true;
|
||||
|
||||
canvas.width = canvasWidth;
|
||||
canvas.height = canvasHeight;
|
||||
@ -2599,7 +2595,7 @@ var TextLayerBuilder = function textLayerBuilder(textLayerDiv, pageIdx) {
|
||||
var textDiv = document.createElement('div');
|
||||
|
||||
// vScale and hScale already contain the scaling to pixel units
|
||||
var fontHeight = geom.fontSize * geom.vScale;
|
||||
var fontHeight = geom.fontSize * Math.abs(geom.vScale);
|
||||
textDiv.dataset.canvasWidth = geom.canvasWidth * geom.hScale;
|
||||
textDiv.dataset.fontName = geom.fontName;
|
||||
|
||||
@ -3250,7 +3246,8 @@ window.addEventListener('keydown', function keydown(evt) {
|
||||
|
||||
// First, handle the key bindings that are independent whether an input
|
||||
// control is selected or not.
|
||||
if (cmd == 1 || cmd == 8) { // either CTRL or META key.
|
||||
if (cmd === 1 || cmd === 8 || cmd === 5 || cmd === 12) {
|
||||
// either CTRL or META key with optional SHIFT.
|
||||
switch (evt.keyCode) {
|
||||
case 70:
|
||||
if (!PDFView.supportsIntegratedFind) {
|
||||
|
@ -1,4 +1,5 @@
|
||||
chrome.manifest
|
||||
components/PdfRedirector.js
|
||||
components/PdfStreamConverter.js
|
||||
content/build/pdf.js
|
||||
content/PdfJs.jsm
|
||||
|
@ -45,7 +45,6 @@ var SelectionHandler = {
|
||||
_contentOffset: { x:0, y:0 },
|
||||
_domWinUtils: null,
|
||||
_selectionMoveActive: false,
|
||||
_lastMarker: "",
|
||||
_debugOptions: { dumpRanges: false, displayRanges: false },
|
||||
_snap: true,
|
||||
|
||||
@ -189,6 +188,14 @@ var SelectionHandler = {
|
||||
// We bail if things get out of sync here implying we missed a message.
|
||||
this._selectionMoveActive = true;
|
||||
|
||||
if (this._targetIsEditable) {
|
||||
// If we're coming out of an out-of-bounds scroll, the node the user is
|
||||
// trying to drag may be hidden (the monocle will be pegged to the edge
|
||||
// of the edit). Make sure the node the user wants to move is visible
|
||||
// and has focus.
|
||||
this._updateInputFocus(aMsg.change);
|
||||
}
|
||||
|
||||
// Update the position of our selection monocles
|
||||
this._updateSelectionUI(true, true);
|
||||
},
|
||||
@ -594,63 +601,16 @@ var SelectionHandler = {
|
||||
}
|
||||
|
||||
// Adjust our y position up such that we are sending coordinates on
|
||||
// the text line vs. below it where the monocle is positioned. This
|
||||
// applies to free floating text areas. For text inputs we'll constrain
|
||||
// coordinates further below.
|
||||
// the text line vs. below it where the monocle is positioned.
|
||||
let halfLineHeight = this._queryHalfLineHeight(aMarker, selection);
|
||||
clientPoint.yPos -= halfLineHeight;
|
||||
|
||||
// Modify selection based on monocle movement
|
||||
if (this._targetIsEditable) {
|
||||
// Check to see if we are beyond the bounds of selection in a input
|
||||
// control. If we are we want to add selection and scroll the added
|
||||
// selection into view.
|
||||
let result = this.updateTextEditSelection(clientPoint);
|
||||
|
||||
// If we're targeting a text input of any kind, make sure clientPoint
|
||||
// is contained within the bounds of the text control. For example, if
|
||||
// a user drags up too close to an upper bounds, selectAtPoint might
|
||||
// select the content above the control. This looks crappy and breaks
|
||||
// our selection rect management.
|
||||
clientPoint =
|
||||
this._constrainPointWithinControl(clientPoint, halfLineHeight);
|
||||
|
||||
// If result.trigger is true, the monocle is outside the bounds of the
|
||||
// control. If it's false, fall through to our additive text selection
|
||||
// below.
|
||||
if (result.trigger) {
|
||||
// _handleSelectionPoint is triggered by input movement, so if we've
|
||||
// tested positive for out-of-bounds scrolling here, we need to set a
|
||||
// recurring timer to keep the expected selection behavior going as
|
||||
// long as the user keeps the monocle out of bounds.
|
||||
if (!this._scrollTimer)
|
||||
this._scrollTimer = new Util.Timeout();
|
||||
this._setTextEditUpdateInterval(result.speed);
|
||||
|
||||
// Smooth the selection
|
||||
this._setContinuousSelection();
|
||||
|
||||
// Update the other monocle's position if we've dragged off to one side
|
||||
this._updateSelectionUI(result.start, result.end);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this._lastMarker = aMarker;
|
||||
|
||||
// If we aren't out-of-bounds, clear the scroll timer if it exists.
|
||||
this._clearTimers();
|
||||
|
||||
// Adjusts the selection based on monocle movement
|
||||
this._adjustSelection(aMarker, clientPoint, aEndOfSelection);
|
||||
|
||||
// Update the other monocle's position. We do this because the dragging
|
||||
// monocle may reset the static monocle to a new position if the dragging
|
||||
// monocle drags ahead or behind the other.
|
||||
if (aMarker == "start") {
|
||||
this._updateSelectionUI(false, true);
|
||||
this._adjustEditableSelection(aMarker, clientPoint,
|
||||
halfLineHeight, aEndOfSelection);
|
||||
} else {
|
||||
this._updateSelectionUI(true, false);
|
||||
this._adjustSelection(aMarker, clientPoint, aEndOfSelection);
|
||||
}
|
||||
},
|
||||
|
||||
@ -659,6 +619,59 @@ var SelectionHandler = {
|
||||
*/
|
||||
|
||||
/*
|
||||
* _adjustEditableSelection
|
||||
*
|
||||
* Based on a monocle marker and position, adds or subtracts from the
|
||||
* existing selection in editable controls. Handles auto-scroll as well.
|
||||
*
|
||||
* @param the marker currently being manipulated
|
||||
* @param aAdjustedClientPoint client point adjusted for line height.
|
||||
* @param aHalfLineHeight half line height in pixels
|
||||
* @param aEndOfSelection indicates if this is the end of a selection
|
||||
* move, in which case we may want to snap to the end of a word or
|
||||
* sentence.
|
||||
*/
|
||||
_adjustEditableSelection: function _adjustEditableSelection(aMarker,
|
||||
aAdjustedClientPoint,
|
||||
aHalfLineHeight,
|
||||
aEndOfSelection) {
|
||||
// Test to see if we need to handle auto-scroll in cases where the
|
||||
// monocle is outside the bounds of the control. This also handles
|
||||
// adjusting selection if out-of-bounds is true.
|
||||
let result = this.updateTextEditSelection(aAdjustedClientPoint);
|
||||
|
||||
// If result.trigger is true, the monocle is outside the bounds of the
|
||||
// control.
|
||||
if (result.trigger) {
|
||||
// _handleSelectionPoint is triggered by input movement, so if we've
|
||||
// tested positive for out-of-bounds scrolling here, we need to set a
|
||||
// recurring timer to keep the expected selection behavior going as
|
||||
// long as the user keeps the monocle out of bounds.
|
||||
this._setTextEditUpdateInterval(result.speed);
|
||||
|
||||
// Smooth the selection
|
||||
this._setContinuousSelection();
|
||||
|
||||
// Update the other monocle's position if we've dragged off to one side
|
||||
this._updateSelectionUI(result.start, result.end);
|
||||
} else {
|
||||
// If we aren't out-of-bounds, clear the scroll timer if it exists.
|
||||
this._clearTimers();
|
||||
|
||||
// Restrict the client point to the interior of the control. Prevents
|
||||
// _adjustSelection from accidentally selecting content outside the
|
||||
// control.
|
||||
let constrainedPoint =
|
||||
this._constrainPointWithinControl(aAdjustedClientPoint, aHalfLineHeight);
|
||||
|
||||
// Add or subtract selection
|
||||
this._adjustSelection(aMarker, constrainedPoint, aEndOfSelection);
|
||||
}
|
||||
},
|
||||
|
||||
/*
|
||||
* _adjustSelection
|
||||
*
|
||||
* Based on a monocle marker and position, adds or subtracts from the
|
||||
* existing selection.
|
||||
*
|
||||
@ -707,6 +720,15 @@ var SelectionHandler = {
|
||||
|
||||
// Smooth over the selection between all existing ranges.
|
||||
this._setContinuousSelection();
|
||||
|
||||
// Update the other monocle's position. We do this because the dragging
|
||||
// monocle may reset the static monocle to a new position if the dragging
|
||||
// monocle drags ahead or behind the other.
|
||||
if (aMarker == "start") {
|
||||
this._updateSelectionUI(false, true);
|
||||
} else {
|
||||
this._updateSelectionUI(true, false);
|
||||
}
|
||||
},
|
||||
|
||||
/*
|
||||
@ -780,9 +802,9 @@ var SelectionHandler = {
|
||||
/*
|
||||
* updateTextEditSelection(aPoint, aClientPoint)
|
||||
*
|
||||
* Checks to see if the monocle point is outside the bounds of the
|
||||
* target edit. If so, use the selection controller to select and
|
||||
* scroll the edit appropriately.
|
||||
* Checks to see if the monocle point is outside the bounds of the target
|
||||
* edit. If so, use the selection controller to select and scroll the edit
|
||||
* appropriately.
|
||||
*
|
||||
* @param aClientPoint raw pointer position
|
||||
* @return { speed: 0.0 -> 1.0,
|
||||
@ -823,6 +845,8 @@ var SelectionHandler = {
|
||||
|
||||
_setTextEditUpdateInterval: function _setTextEditUpdateInterval(aSpeedValue) {
|
||||
let timeout = (75 - (aSpeedValue * 75));
|
||||
if (!this._scrollTimer)
|
||||
this._scrollTimer = new Util.Timeout();
|
||||
this._scrollTimer.interval(timeout, this.scrollTimerCallback);
|
||||
},
|
||||
|
||||
@ -836,7 +860,6 @@ var SelectionHandler = {
|
||||
* _addEditSelection - selection control call wrapper for text inputs.
|
||||
* Adds selection on the anchor or focus side of selection in a text
|
||||
* input. Scrolls the location into view as well.
|
||||
* (TBD: anchor side scrolling is currently broken, see bug 848594)
|
||||
*
|
||||
* @param const selection node identifier
|
||||
*/
|
||||
@ -844,16 +867,32 @@ var SelectionHandler = {
|
||||
let selCtrl = this._getSelectController();
|
||||
try {
|
||||
if (aLocation == kSelectionNodeAnchor) {
|
||||
this._targetElement.selectionStart = this._targetElement.selectionStart - 1;
|
||||
selCtrl.scrollSelectionIntoView(Ci.nsISelectionController.SELECTION_NORMAL,
|
||||
Ci.nsISelectionController.SELECTION_ANCHOR_REGION,
|
||||
Ci.nsISelectionController.SCROLL_SYNCHRONOUS);
|
||||
let start = Math.max(this._targetElement.selectionStart - 1, 0);
|
||||
this._targetElement.setSelectionRange(start, this._targetElement.selectionEnd,
|
||||
"backward");
|
||||
} else {
|
||||
this._targetElement.selectionEnd = this._targetElement.selectionEnd + 1;
|
||||
selCtrl.scrollSelectionIntoView(Ci.nsISelectionController.SELECTION_NORMAL,
|
||||
Ci.nsISelectionController.SELECTION_FOCUS_REGION,
|
||||
Ci.nsISelectionController.SCROLL_SYNCHRONOUS);
|
||||
let end = Math.min(this._targetElement.selectionEnd + 1,
|
||||
this._targetElement.textLength);
|
||||
this._targetElement.setSelectionRange(this._targetElement.selectionStart,
|
||||
end,
|
||||
"forward");
|
||||
}
|
||||
selCtrl.scrollSelectionIntoView(Ci.nsISelectionController.SELECTION_NORMAL,
|
||||
Ci.nsISelectionController.SELECTION_FOCUS_REGION,
|
||||
Ci.nsISelectionController.SCROLL_SYNCHRONOUS);
|
||||
} catch (ex) { Util.dumpLn(ex);}
|
||||
},
|
||||
|
||||
_updateInputFocus: function _updateInputFocus(aMarker) {
|
||||
try {
|
||||
let selCtrl = this._getSelectController();
|
||||
this._targetElement.setSelectionRange(this._targetElement.selectionStart,
|
||||
this._targetElement.selectionEnd,
|
||||
aMarker == "start" ?
|
||||
"backward" : "forward");
|
||||
selCtrl.scrollSelectionIntoView(Ci.nsISelectionController.SELECTION_NORMAL,
|
||||
Ci.nsISelectionController.SELECTION_FOCUS_REGION,
|
||||
Ci.nsISelectionController.SCROLL_SYNCHRONOUS);
|
||||
} catch (ex) {}
|
||||
},
|
||||
|
||||
|
@ -178,8 +178,8 @@ this.Social = {
|
||||
return null;
|
||||
},
|
||||
|
||||
installProvider: function(origin ,sourceURI, data, installCallback) {
|
||||
SocialService.installProvider(origin ,sourceURI, data, installCallback);
|
||||
installProvider: function(doc, data, installCallback) {
|
||||
SocialService.installProvider(doc, data, installCallback);
|
||||
},
|
||||
|
||||
uninstallProvider: function(origin) {
|
||||
|
@ -441,6 +441,12 @@ public class DoCommand {
|
||||
strReturn += GetProcessInfo();
|
||||
strReturn += "\n";
|
||||
strReturn += GetSutUserInfo();
|
||||
strReturn += "\n";
|
||||
strReturn += GetDiskInfo("/data");
|
||||
strReturn += "\n";
|
||||
strReturn += GetDiskInfo("/system");
|
||||
strReturn += "\n";
|
||||
strReturn += GetDiskInfo("/mnt/sdcard");
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -495,6 +501,15 @@ public class DoCommand {
|
||||
strReturn += GetTemperatureInfo();
|
||||
break;
|
||||
|
||||
case DISK:
|
||||
strReturn += "\n";
|
||||
strReturn += GetDiskInfo("/data");
|
||||
strReturn += "\n";
|
||||
strReturn += GetDiskInfo("/system");
|
||||
strReturn += "\n";
|
||||
strReturn += GetDiskInfo("/mnt/sdcard");
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -2670,18 +2685,19 @@ private void CancelNotification()
|
||||
return "Temperature: " + sTempVal;
|
||||
}
|
||||
|
||||
// todo
|
||||
public String GetDiskInfo(String sPath)
|
||||
{
|
||||
String sRet = "";
|
||||
StatFs statFS = new StatFs(sPath);
|
||||
|
||||
int nBlockCount = statFS.getBlockCount();
|
||||
int nBlockSize = statFS.getBlockSize();
|
||||
int nBlocksAvail = statFS.getAvailableBlocks();
|
||||
int nBlocksFree = statFS.getFreeBlocks();
|
||||
long nBlockCount = statFS.getBlockCount();
|
||||
long nBlockSize = statFS.getBlockSize();
|
||||
long nBlocksAvail = statFS.getAvailableBlocks();
|
||||
// Free is often the same as Available, but can include reserved
|
||||
// blocks that are not available to normal applications.
|
||||
// long nBlocksFree = statFS.getFreeBlocks();
|
||||
|
||||
sRet = "total: " + (nBlockCount * nBlockSize) + "\nfree: " + (nBlocksFree * nBlockSize) + "\navailable: " + (nBlocksAvail * nBlockSize);
|
||||
sRet = sPath + ": " + (nBlockCount * nBlockSize) + " total, " + (nBlocksAvail * nBlockSize) + " available";
|
||||
|
||||
return (sRet);
|
||||
}
|
||||
|
@ -70,7 +70,7 @@ GCONF_VERSION=1.2.1
|
||||
GIO_VERSION=2.20
|
||||
STARTUP_NOTIFICATION_VERSION=0.8
|
||||
DBUS_VERSION=0.60
|
||||
SQLITE_VERSION=3.7.15.2
|
||||
SQLITE_VERSION=3.7.16
|
||||
|
||||
MSMANIFEST_TOOL=
|
||||
|
||||
@ -6121,8 +6121,7 @@ dnl If we're on an x86 or x64 system which supports libjpeg-turbo's asm routines
|
||||
dnl and --disable-libjpeg-turbo wasn't passed, check for Yasm, and error out if
|
||||
dnl it doesn't exist or we have too old of a version.
|
||||
if test -n "$LIBJPEG_TURBO_X86_ASM" -o -n "$LIBJPEG_TURBO_X64_ASM" ; then
|
||||
AC_MSG_CHECKING([for Yasm assembler])
|
||||
AC_CHECK_PROGS(LIBJPEG_TURBO_AS, yasm, "")
|
||||
LIBJPEG_TURBO_AS=$YASM
|
||||
|
||||
if test -z "$LIBJPEG_TURBO_AS" ; then
|
||||
AC_MSG_ERROR([Yasm is required to build with libjpeg-turbo's optimized JPEG decoding routines, but you do not appear to have Yasm installed. Either install it or configure with --disable-libjpeg-turbo to use the pure C JPEG decoder. See https://developer.mozilla.org/en/YASM for more details.])
|
||||
|
@ -209,6 +209,15 @@ public:
|
||||
static bool ContentIsDescendantOf(const nsINode* aPossibleDescendant,
|
||||
const nsINode* aPossibleAncestor);
|
||||
|
||||
/**
|
||||
* Similar to ContentIsDescendantOf, except will treat an HTMLTemplateElement
|
||||
* or ShadowRoot as an ancestor of things in the corresponding DocumentFragment.
|
||||
* See the concept of "host-including inclusive ancestor" in the DOM
|
||||
* specification.
|
||||
*/
|
||||
static bool ContentIsHostIncludingDescendantOf(
|
||||
const nsINode* aPossibleDescendant, const nsINode* aPossibleAncestor);
|
||||
|
||||
/**
|
||||
* Similar to ContentIsDescendantOf except it crosses document boundaries.
|
||||
*/
|
||||
|
@ -1630,6 +1630,12 @@ public:
|
||||
mAllowXULXBL = eTriTrue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the template content owner document that owns the content of
|
||||
* HTMLTemplateElement.
|
||||
*/
|
||||
virtual nsIDocument* GetTemplateContentsOwner() = 0;
|
||||
|
||||
/**
|
||||
* true when this document is a static clone of a normal document.
|
||||
* For example print preview and printing use static documents.
|
||||
|
@ -55,7 +55,7 @@ namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
DocumentFragment::DocumentFragment(already_AddRefed<nsINodeInfo> aNodeInfo)
|
||||
: FragmentOrElement(aNodeInfo)
|
||||
: FragmentOrElement(aNodeInfo), mHost(nullptr)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(mNodeInfo->NodeType() ==
|
||||
nsIDOMNode::DOCUMENT_FRAGMENT_NODE &&
|
||||
|
@ -20,6 +20,7 @@ namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class Element;
|
||||
class HTMLTemplateElement;
|
||||
|
||||
class DocumentFragment : public FragmentOrElement,
|
||||
public nsIDOMDocumentFragment
|
||||
@ -101,6 +102,16 @@ public:
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
HTMLTemplateElement* GetHost() const
|
||||
{
|
||||
return mHost;
|
||||
}
|
||||
|
||||
void SetHost(HTMLTemplateElement* aHost)
|
||||
{
|
||||
mHost = aHost;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
virtual void List(FILE* out, int32_t aIndent) const;
|
||||
virtual void DumpContent(FILE* out, int32_t aIndent, bool aDumpAll) const;
|
||||
@ -108,6 +119,7 @@ public:
|
||||
|
||||
protected:
|
||||
nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
|
||||
mozilla::dom::HTMLTemplateElement* mHost; // Weak
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
@ -101,6 +101,7 @@
|
||||
#include "nsRuleProcessorData.h"
|
||||
#include "nsAsyncDOMEvent.h"
|
||||
#include "nsTextNode.h"
|
||||
#include "mozilla/dom/HTMLTemplateElement.h"
|
||||
|
||||
#ifdef MOZ_XUL
|
||||
#include "nsIXULDocument.h"
|
||||
@ -3106,7 +3107,9 @@ IsVoidTag(Element* aElement)
|
||||
static bool
|
||||
Serialize(Element* aRoot, bool aDescendentsOnly, nsAString& aOut)
|
||||
{
|
||||
nsINode* current = aDescendentsOnly ? aRoot->GetFirstChild() : aRoot;
|
||||
nsINode* current = aDescendentsOnly ?
|
||||
nsNodeUtils::GetFirstChildOfTemplateOrNode(aRoot) : aRoot;
|
||||
|
||||
if (!current) {
|
||||
return true;
|
||||
}
|
||||
@ -3120,7 +3123,8 @@ Serialize(Element* aRoot, bool aDescendentsOnly, nsAString& aOut)
|
||||
Element* elem = current->AsElement();
|
||||
StartElement(elem, builder);
|
||||
isVoid = IsVoidTag(elem);
|
||||
if (!isVoid && (next = current->GetFirstChild())) {
|
||||
if (!isVoid &&
|
||||
(next = nsNodeUtils::GetFirstChildOfTemplateOrNode(current))) {
|
||||
current = next;
|
||||
continue;
|
||||
}
|
||||
@ -3186,6 +3190,17 @@ Serialize(Element* aRoot, bool aDescendentsOnly, nsAString& aOut)
|
||||
}
|
||||
|
||||
current = current->GetParentNode();
|
||||
|
||||
// Template case, if we are in a template's content, then the parent
|
||||
// should be the host template element.
|
||||
if (current->NodeType() == nsIDOMNode::DOCUMENT_FRAGMENT_NODE) {
|
||||
DocumentFragment* frag = static_cast<DocumentFragment*>(current);
|
||||
HTMLTemplateElement* fragHost = frag->GetHost();
|
||||
if (fragHost) {
|
||||
current = fragHost;
|
||||
}
|
||||
}
|
||||
|
||||
if (aDescendentsOnly && current == aRoot) {
|
||||
return builder.ToString(aOut);
|
||||
}
|
||||
@ -3292,30 +3307,39 @@ Element::GetInnerHTML(nsAString& aInnerHTML, ErrorResult& aError)
|
||||
void
|
||||
Element::SetInnerHTML(const nsAString& aInnerHTML, ErrorResult& aError)
|
||||
{
|
||||
nsIDocument* doc = OwnerDoc();
|
||||
FragmentOrElement* target = this;
|
||||
// Handle template case.
|
||||
if (nsNodeUtils::IsTemplateElement(target)) {
|
||||
DocumentFragment* frag =
|
||||
static_cast<HTMLTemplateElement*>(target)->Content();
|
||||
MOZ_ASSERT(frag);
|
||||
target = frag;
|
||||
}
|
||||
|
||||
nsIDocument* doc = target->OwnerDoc();
|
||||
|
||||
// Batch possible DOMSubtreeModified events.
|
||||
mozAutoSubtreeModified subtree(doc, nullptr);
|
||||
|
||||
FireNodeRemovedForChildren();
|
||||
target->FireNodeRemovedForChildren();
|
||||
|
||||
// Needed when innerHTML is used in combination with contenteditable
|
||||
mozAutoDocUpdate updateBatch(doc, UPDATE_CONTENT_MODEL, true);
|
||||
|
||||
// Remove childnodes.
|
||||
uint32_t childCount = GetChildCount();
|
||||
nsAutoMutationBatch mb(this, true, false);
|
||||
uint32_t childCount = target->GetChildCount();
|
||||
nsAutoMutationBatch mb(target, true, false);
|
||||
for (uint32_t i = 0; i < childCount; ++i) {
|
||||
RemoveChildAt(0, true);
|
||||
target->RemoveChildAt(0, true);
|
||||
}
|
||||
mb.RemovalDone();
|
||||
|
||||
nsAutoScriptLoaderDisabler sld(doc);
|
||||
|
||||
if (doc->IsHTML()) {
|
||||
int32_t oldChildCount = GetChildCount();
|
||||
int32_t oldChildCount = target->GetChildCount();
|
||||
aError = nsContentUtils::ParseFragmentHTML(aInnerHTML,
|
||||
this,
|
||||
target,
|
||||
Tag(),
|
||||
GetNameSpaceID(),
|
||||
doc->GetCompatibilityMode() ==
|
||||
@ -3323,10 +3347,10 @@ Element::SetInnerHTML(const nsAString& aInnerHTML, ErrorResult& aError)
|
||||
true);
|
||||
mb.NodesAdded();
|
||||
// HTML5 parser has notified, but not fired mutation events.
|
||||
FireMutationEventsForDirectParsing(doc, this, oldChildCount);
|
||||
FireMutationEventsForDirectParsing(doc, target, oldChildCount);
|
||||
} else {
|
||||
nsCOMPtr<nsIDOMDocumentFragment> df;
|
||||
aError = nsContentUtils::CreateContextualFragment(this, aInnerHTML,
|
||||
aError = nsContentUtils::CreateContextualFragment(target, aInnerHTML,
|
||||
true,
|
||||
getter_AddRefs(df));
|
||||
nsCOMPtr<nsINode> fragment = do_QueryInterface(df);
|
||||
@ -3336,7 +3360,7 @@ Element::SetInnerHTML(const nsAString& aInnerHTML, ErrorResult& aError)
|
||||
// listeners on the fragment that comes from the parser.
|
||||
nsAutoScriptBlockerSuppressNodeRemoved scriptBlocker;
|
||||
|
||||
static_cast<nsINode*>(this)->AppendChild(*fragment, aError);
|
||||
static_cast<nsINode*>(target)->AppendChild(*fragment, aError);
|
||||
mb.NodesAdded();
|
||||
}
|
||||
}
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "mozilla/DebugOnly.h"
|
||||
#include "mozilla/dom/DocumentFragment.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/dom/HTMLTemplateElement.h"
|
||||
#include "mozilla/dom/TextDecoderBase.h"
|
||||
#include "mozilla/Likely.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
@ -1854,6 +1855,27 @@ nsContentUtils::ContentIsDescendantOf(const nsINode* aPossibleDescendant,
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
nsContentUtils::ContentIsHostIncludingDescendantOf(
|
||||
const nsINode* aPossibleDescendant, const nsINode* aPossibleAncestor)
|
||||
{
|
||||
NS_PRECONDITION(aPossibleDescendant, "The possible descendant is null!");
|
||||
NS_PRECONDITION(aPossibleAncestor, "The possible ancestor is null!");
|
||||
|
||||
do {
|
||||
if (aPossibleDescendant == aPossibleAncestor)
|
||||
return true;
|
||||
if (aPossibleDescendant->NodeType() == nsIDOMNode::DOCUMENT_FRAGMENT_NODE) {
|
||||
aPossibleDescendant =
|
||||
static_cast<const DocumentFragment*>(aPossibleDescendant)->GetHost();
|
||||
} else {
|
||||
aPossibleDescendant = aPossibleDescendant->GetParentNode();
|
||||
}
|
||||
} while (aPossibleDescendant);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// static
|
||||
bool
|
||||
nsContentUtils::ContentIsCrossDocDescendantOf(nsINode* aPossibleDescendant,
|
||||
|
@ -1708,6 +1708,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsDocument)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCachedEncoder)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mStateObjectCached)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mUndoManager)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTemplateContentsOwner)
|
||||
|
||||
// Traverse all our nsCOMArrays.
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mStyleSheets)
|
||||
@ -1784,6 +1785,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDocument)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mOriginalDocument)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mCachedEncoder)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mUndoManager)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mTemplateContentsOwner)
|
||||
|
||||
tmp->mParentDocument = nullptr;
|
||||
|
||||
@ -8536,6 +8538,37 @@ nsDocument::GetCurrentContentSink()
|
||||
return mParser ? mParser->GetContentSink() : nullptr;
|
||||
}
|
||||
|
||||
nsIDocument*
|
||||
nsDocument::GetTemplateContentsOwner()
|
||||
{
|
||||
if (!mTemplateContentsOwner) {
|
||||
bool hasHadScriptObject = true;
|
||||
nsIScriptGlobalObject* scriptObject =
|
||||
GetScriptHandlingObject(hasHadScriptObject);
|
||||
NS_ENSURE_TRUE(scriptObject || !hasHadScriptObject, nullptr);
|
||||
|
||||
nsCOMPtr<nsIDOMDocument> domDocument;
|
||||
nsresult rv = NS_NewDOMDocument(getter_AddRefs(domDocument),
|
||||
EmptyString(), // aNamespaceURI
|
||||
EmptyString(), // aQualifiedName
|
||||
nullptr, // aDoctype
|
||||
nsIDocument::GetDocumentURI(),
|
||||
nsIDocument::GetDocBaseURI(),
|
||||
NodePrincipal(),
|
||||
true, // aLoadedAsData
|
||||
scriptObject, // aEventObject
|
||||
DocumentFlavorHTML);
|
||||
NS_ENSURE_SUCCESS(rv, nullptr);
|
||||
|
||||
mTemplateContentsOwner = do_QueryInterface(domDocument);
|
||||
NS_ENSURE_TRUE(mTemplateContentsOwner, nullptr);
|
||||
|
||||
mTemplateContentsOwner->SetScriptHandlingObject(scriptObject);
|
||||
}
|
||||
|
||||
return mTemplateContentsOwner;
|
||||
}
|
||||
|
||||
void
|
||||
nsDocument::RegisterHostObjectUri(const nsACString& aUri)
|
||||
{
|
||||
|
@ -864,6 +864,8 @@ public:
|
||||
MaybeRescheduleAnimationFrameNotifications();
|
||||
}
|
||||
|
||||
virtual nsIDocument* GetTemplateContentsOwner();
|
||||
|
||||
NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsDocument,
|
||||
nsIDocument)
|
||||
|
||||
@ -1291,6 +1293,10 @@ protected:
|
||||
nsCOMPtr<nsIChannel> mChannel;
|
||||
nsRefPtr<nsHTMLCSSStyleSheet> mStyleAttrStyleSheet;
|
||||
|
||||
// A document "without a browsing context" that owns the content of
|
||||
// HTMLTemplateElement.
|
||||
nsCOMPtr<nsIDocument> mTemplateContentsOwner;
|
||||
|
||||
// Our update nesting level
|
||||
uint32_t mUpdateNestLevel;
|
||||
|
||||
|
@ -42,6 +42,7 @@
|
||||
#include "nsISelectionPrivate.h"
|
||||
#include "nsITransferable.h" // for kUnicodeMime
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsNodeUtils.h"
|
||||
#include "nsUnicharUtils.h"
|
||||
#include "nsReadableUtils.h"
|
||||
#include "nsTArray.h"
|
||||
@ -495,7 +496,8 @@ nsDocumentEncoder::SerializeToStringRecursive(nsINode* aNode,
|
||||
|
||||
nsINode* node = serializeClonedChildren ? maybeFixedNode : aNode;
|
||||
|
||||
for (nsINode* child = node->GetFirstChild(); child;
|
||||
for (nsINode* child = nsNodeUtils::GetFirstChildOfTemplateOrNode(node);
|
||||
child;
|
||||
child = child->GetNextSibling()) {
|
||||
rv = SerializeToStringRecursive(child, aStr, false);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
@ -1420,8 +1420,10 @@ bool IsAllowedAsChild(nsIContent* aNewChild, nsINode* aParent,
|
||||
// actually equal to each other. Fast-path that case, since aParent
|
||||
// could be pretty deep in the DOM tree.
|
||||
if (aNewChild == aParent ||
|
||||
(aNewChild->GetFirstChild() &&
|
||||
nsContentUtils::ContentIsDescendantOf(aParent, aNewChild))) {
|
||||
((aNewChild->GetFirstChild() ||
|
||||
aNewChild->Tag() == nsGkAtoms::_template) &&
|
||||
nsContentUtils::ContentIsHostIncludingDescendantOf(aParent,
|
||||
aNewChild))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include "nsObjectLoadingContent.h"
|
||||
#include "nsDOMMutationObserver.h"
|
||||
#include "mozilla/dom/BindingUtils.h"
|
||||
#include "mozilla/dom/HTMLTemplateElement.h"
|
||||
|
||||
using namespace mozilla::dom;
|
||||
|
||||
@ -562,6 +563,29 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNode, bool aClone, bool aDeep,
|
||||
}
|
||||
}
|
||||
|
||||
// Cloning template element.
|
||||
if (aDeep && aClone && IsTemplateElement(aNode)) {
|
||||
DocumentFragment* origContent =
|
||||
static_cast<HTMLTemplateElement*>(aNode)->Content();
|
||||
DocumentFragment* cloneContent =
|
||||
static_cast<HTMLTemplateElement*>(clone.get())->Content();
|
||||
|
||||
// Clone the children into the clone's template content owner
|
||||
// document's nodeinfo manager.
|
||||
nsNodeInfoManager* ownerNodeInfoManager =
|
||||
cloneContent->mNodeInfo->NodeInfoManager();
|
||||
|
||||
for (nsIContent* cloneChild = origContent->GetFirstChild();
|
||||
cloneChild;
|
||||
cloneChild = cloneChild->GetNextSibling()) {
|
||||
nsCOMPtr<nsINode> child;
|
||||
rv = CloneAndAdopt(cloneChild, aClone, aDeep, ownerNodeInfoManager,
|
||||
aCx, aNewScope, aNodesWithProperties, cloneContent,
|
||||
getter_AddRefs(child));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
}
|
||||
|
||||
// XXX setting document on some nodes not in a document so XBL will bind
|
||||
// and chrome won't break. Make XBL bind to document-less nodes!
|
||||
// XXXbz Once this is fixed, fix up the asserts in all implementations of
|
||||
@ -609,3 +633,22 @@ nsNodeUtils::UnlinkUserData(nsINode *aNode)
|
||||
document->PropertyTable(DOM_USER_DATA)->DeleteAllPropertiesFor(aNode);
|
||||
document->PropertyTable(DOM_USER_DATA_HANDLER)->DeleteAllPropertiesFor(aNode);
|
||||
}
|
||||
|
||||
bool
|
||||
nsNodeUtils::IsTemplateElement(const nsINode *aNode)
|
||||
{
|
||||
return aNode->IsElement() && aNode->AsElement()->IsHTML(nsGkAtoms::_template);
|
||||
}
|
||||
|
||||
nsIContent*
|
||||
nsNodeUtils::GetFirstChildOfTemplateOrNode(nsINode* aNode)
|
||||
{
|
||||
if (nsNodeUtils::IsTemplateElement(aNode)) {
|
||||
DocumentFragment* frag =
|
||||
static_cast<HTMLTemplateElement*>(aNode)->Content();
|
||||
return frag->GetFirstChild();
|
||||
}
|
||||
|
||||
return aNode->GetFirstChild();
|
||||
}
|
||||
|
||||
|
@ -248,6 +248,22 @@ public:
|
||||
*/
|
||||
static void UnlinkUserData(nsINode *aNode);
|
||||
|
||||
/**
|
||||
* Returns a true if the node is a HTMLTemplate element.
|
||||
*
|
||||
* @param aNode a node to test for HTMLTemplate elementness.
|
||||
*/
|
||||
static bool IsTemplateElement(const nsINode *aNode);
|
||||
|
||||
/**
|
||||
* Returns the first child of a node or the first child of
|
||||
* a template element's content if the provided node is a
|
||||
* template element.
|
||||
*
|
||||
* @param aNode A node from which to retrieve the first child.
|
||||
*/
|
||||
static nsIContent* GetFirstChildOfTemplateOrNode(nsINode* aNode);
|
||||
|
||||
private:
|
||||
/**
|
||||
* Walks aNode, its attributes and, if aDeep is true, its descendant nodes.
|
||||
|
@ -18,8 +18,8 @@ class nsTextControlFrame;
|
||||
|
||||
// IID for the nsITextControl interface
|
||||
#define NS_ITEXTCONTROLELEMENT_IID \
|
||||
{ 0x3558afa1, 0x6136, 0x4421, \
|
||||
{ 0xbd, 0xdc, 0x2c, 0x9d, 0x5f, 0xc1, 0xfb, 0x91 } }
|
||||
{ 0x3dd53b59, 0x9d8f, 0x40a3, \
|
||||
{ 0x81, 0xd7, 0xb3, 0x43, 0xa0, 0x51, 0xfc, 0xb5 } }
|
||||
|
||||
/**
|
||||
* This interface is used for the text control frame to get the editor and
|
||||
@ -76,6 +76,11 @@ public:
|
||||
*/
|
||||
NS_IMETHOD_(int32_t) GetRows() = 0;
|
||||
|
||||
/**
|
||||
* Get the default value of the text control
|
||||
*/
|
||||
NS_IMETHOD_(void) GetDefaultValueFromContent(nsAString& aValue) = 0;
|
||||
|
||||
/**
|
||||
* Return true if the value of the control has been changed.
|
||||
*/
|
||||
|
94
content/html/content/src/HTMLTemplateElement.cpp
Normal file
94
content/html/content/src/HTMLTemplateElement.cpp
Normal file
@ -0,0 +1,94 @@
|
||||
/* -*- 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 "mozilla/dom/HTMLTemplateElement.h"
|
||||
#include "mozilla/dom/HTMLTemplateElementBinding.h"
|
||||
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsStyleConsts.h"
|
||||
#include "nsIAtom.h"
|
||||
#include "nsRuleData.h"
|
||||
|
||||
using namespace mozilla::dom;
|
||||
|
||||
nsGenericHTMLElement*
|
||||
NS_NewHTMLTemplateElement(already_AddRefed<nsINodeInfo> aNodeInfo,
|
||||
FromParser aFromParser)
|
||||
{
|
||||
HTMLTemplateElement* it = new HTMLTemplateElement(aNodeInfo);
|
||||
nsresult rv = it->Init();
|
||||
if (NS_FAILED(rv)) {
|
||||
delete it;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return it;
|
||||
}
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
HTMLTemplateElement::HTMLTemplateElement(already_AddRefed<nsINodeInfo> aNodeInfo)
|
||||
: nsGenericHTMLElement(aNodeInfo)
|
||||
{
|
||||
SetIsDOMBinding();
|
||||
}
|
||||
|
||||
nsresult
|
||||
HTMLTemplateElement::Init()
|
||||
{
|
||||
nsIDocument* doc = OwnerDoc();
|
||||
nsIDocument* contentsOwner = doc;
|
||||
|
||||
// Used to test if the document "has a browsing context".
|
||||
nsCOMPtr<nsISupports> container = doc->GetContainer();
|
||||
if (container) {
|
||||
// GetTemplateContentsOwner lazily creates a document.
|
||||
contentsOwner = doc->GetTemplateContentsOwner();
|
||||
NS_ENSURE_TRUE(contentsOwner, NS_ERROR_UNEXPECTED);
|
||||
}
|
||||
|
||||
ErrorResult rv;
|
||||
mContent = contentsOwner->CreateDocumentFragment(rv);
|
||||
if (rv.Failed()) {
|
||||
return rv.ErrorCode();
|
||||
}
|
||||
mContent->SetHost(this);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
HTMLTemplateElement::~HTMLTemplateElement()
|
||||
{
|
||||
if (mContent) {
|
||||
mContent->SetHost(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(HTMLTemplateElement, Element)
|
||||
NS_IMPL_RELEASE_INHERITED(HTMLTemplateElement, Element)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_INHERITED_1(HTMLTemplateElement,
|
||||
nsGenericHTMLElement,
|
||||
mContent)
|
||||
|
||||
// QueryInterface implementation for HTMLTemplateElement
|
||||
NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(HTMLTemplateElement)
|
||||
NS_HTML_CONTENT_INTERFACE_TABLE0(HTMLTemplateElement)
|
||||
NS_HTML_CONTENT_INTERFACE_TABLE_TO_MAP_SEGUE(HTMLTemplateElement,
|
||||
nsGenericHTMLElement)
|
||||
NS_HTML_CONTENT_INTERFACE_MAP_END
|
||||
|
||||
NS_IMPL_ELEMENT_CLONE_WITH_INIT(HTMLTemplateElement)
|
||||
|
||||
JSObject*
|
||||
HTMLTemplateElement::WrapNode(JSContext *aCx, JSObject *aScope)
|
||||
{
|
||||
return HTMLTemplateElementBinding::Wrap(aCx, aScope, this);
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
59
content/html/content/src/HTMLTemplateElement.h
Normal file
59
content/html/content/src/HTMLTemplateElement.h
Normal file
@ -0,0 +1,59 @@
|
||||
/* -*- 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 mozilla_dom_HTMLTemplateElement_h
|
||||
#define mozilla_dom_HTMLTemplateElement_h
|
||||
|
||||
#include "nsIDOMHTMLElement.h"
|
||||
#include "nsGenericHTMLElement.h"
|
||||
#include "mozilla/dom/DocumentFragment.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class HTMLTemplateElement : public nsGenericHTMLElement,
|
||||
public nsIDOMHTMLElement
|
||||
{
|
||||
public:
|
||||
HTMLTemplateElement(already_AddRefed<nsINodeInfo> aNodeInfo);
|
||||
virtual ~HTMLTemplateElement();
|
||||
|
||||
// nsISupports
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
// nsIDOMNode
|
||||
NS_FORWARD_NSIDOMNODE_TO_NSINODE
|
||||
|
||||
// nsIDOMElement
|
||||
NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
|
||||
|
||||
// nsIDOMHTMLElement
|
||||
NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
|
||||
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(HTMLTemplateElement,
|
||||
nsGenericHTMLElement)
|
||||
|
||||
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
|
||||
|
||||
virtual nsIDOMNode* AsDOMNode() { return this; }
|
||||
|
||||
nsresult Init();
|
||||
|
||||
DocumentFragment* Content()
|
||||
{
|
||||
return mContent;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual JSObject* WrapNode(JSContext *aCx, JSObject *aScope) MOZ_OVERRIDE;
|
||||
|
||||
nsRefPtr<DocumentFragment> mContent;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_HTMLTemplateElement_h
|
||||
|
@ -353,6 +353,9 @@ HTMLTextAreaElement::SetValueChanged(bool aValueChanged)
|
||||
bool previousValue = mValueChanged;
|
||||
|
||||
mValueChanged = aValueChanged;
|
||||
if (!aValueChanged && !mState.IsEmpty()) {
|
||||
mState.EmptyValue();
|
||||
}
|
||||
|
||||
if (mValueChanged != previousValue) {
|
||||
UpdateState(true);
|
||||
@ -1379,6 +1382,12 @@ HTMLTextAreaElement::GetRows()
|
||||
return DEFAULT_ROWS_TEXTAREA;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(void)
|
||||
HTMLTextAreaElement::GetDefaultValueFromContent(nsAString& aValue)
|
||||
{
|
||||
GetDefaultValue(aValue);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(bool)
|
||||
HTMLTextAreaElement::ValueChanged() const
|
||||
{
|
||||
|
@ -87,6 +87,7 @@ public:
|
||||
NS_IMETHOD_(int32_t) GetCols();
|
||||
NS_IMETHOD_(int32_t) GetWrapCols();
|
||||
NS_IMETHOD_(int32_t) GetRows();
|
||||
NS_IMETHOD_(void) GetDefaultValueFromContent(nsAString& aValue);
|
||||
NS_IMETHOD_(bool) ValueChanged() const;
|
||||
NS_IMETHOD_(void) GetTextEditorValue(nsAString& aValue, bool aIgnoreWrap) const;
|
||||
NS_IMETHOD_(nsIEditor*) GetTextEditor();
|
||||
|
@ -73,6 +73,7 @@ EXPORTS_mozilla/dom = \
|
||||
HTMLTableElement.h \
|
||||
HTMLTableRowElement.h \
|
||||
HTMLTableSectionElement.h \
|
||||
HTMLTemplateElement.h \
|
||||
HTMLTextAreaElement.h \
|
||||
HTMLTimeElement.h \
|
||||
HTMLTitleElement.h \
|
||||
@ -141,6 +142,7 @@ CPPSRCS = \
|
||||
HTMLTableColElement.cpp \
|
||||
HTMLTableRowElement.cpp \
|
||||
HTMLTableSectionElement.cpp \
|
||||
HTMLTemplateElement.cpp \
|
||||
HTMLTextAreaElement.cpp \
|
||||
HTMLTimeElement.cpp \
|
||||
HTMLTitleElement.cpp \
|
||||
|
@ -1954,6 +1954,7 @@ NS_DECLARE_NS_NEW_HTML_ELEMENT(Table)
|
||||
NS_DECLARE_NS_NEW_HTML_ELEMENT(TableRow)
|
||||
NS_DECLARE_NS_NEW_HTML_ELEMENT(TableSection)
|
||||
NS_DECLARE_NS_NEW_HTML_ELEMENT(Tbody)
|
||||
NS_DECLARE_NS_NEW_HTML_ELEMENT(Template)
|
||||
NS_DECLARE_NS_NEW_HTML_ELEMENT(TextArea)
|
||||
NS_DECLARE_NS_NEW_HTML_ELEMENT(Tfoot)
|
||||
NS_DECLARE_NS_NEW_HTML_ELEMENT(Thead)
|
||||
|
@ -5557,6 +5557,20 @@ nsHTMLInputElement::GetRows()
|
||||
return DEFAULT_ROWS;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(void)
|
||||
nsHTMLInputElement::GetDefaultValueFromContent(nsAString& aValue)
|
||||
{
|
||||
nsTextEditorState *state = GetEditorState();
|
||||
if (state) {
|
||||
GetDefaultValue(aValue);
|
||||
// This is called by the frame to show the value.
|
||||
// We have to sanitize it when needed.
|
||||
if (!mParserCreating) {
|
||||
SanitizeValue(aValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(bool)
|
||||
nsHTMLInputElement::ValueChanged() const
|
||||
{
|
||||
|
@ -147,6 +147,7 @@ public:
|
||||
NS_IMETHOD_(int32_t) GetCols();
|
||||
NS_IMETHOD_(int32_t) GetWrapCols();
|
||||
NS_IMETHOD_(int32_t) GetRows();
|
||||
NS_IMETHOD_(void) GetDefaultValueFromContent(nsAString& aValue);
|
||||
NS_IMETHOD_(bool) ValueChanged() const;
|
||||
NS_IMETHOD_(void) GetTextEditorValue(nsAString& aValue, bool aIgnoreWrap) const;
|
||||
NS_IMETHOD_(nsIEditor*) GetTextEditor();
|
||||
|
@ -1747,7 +1747,9 @@ nsTextEditorState::GetValue(nsAString& aValue, bool aIgnoreWrap) const
|
||||
mCachedValue.Truncate();
|
||||
}
|
||||
} else {
|
||||
if (mValue) {
|
||||
if (!mTextCtrlElement->ValueChanged() || !mValue) {
|
||||
mTextCtrlElement->GetDefaultValueFromContent(aValue);
|
||||
} else {
|
||||
aValue = NS_ConvertUTF8toUTF16(*mValue);
|
||||
}
|
||||
}
|
||||
|
@ -137,6 +137,8 @@ public:
|
||||
void SetValue(const nsAString& aValue, bool aUserInput,
|
||||
bool aSetValueAsChanged);
|
||||
void GetValue(nsAString& aValue, bool aIgnoreWrap) const;
|
||||
void EmptyValue() { if (mValue) mValue->Truncate(); }
|
||||
bool IsEmpty() const { return mValue ? mValue->IsEmpty() : true; }
|
||||
|
||||
nsresult CreatePlaceholderNode();
|
||||
|
||||
|
@ -214,6 +214,7 @@ HTML_TAG("textarea", "TextArea", [], [ "nsIDOMNSEditableElement" ]);
|
||||
HTML_TAG("tfoot", "TableSection");
|
||||
HTML_TAG("th", "TableCell");
|
||||
HTML_TAG("thead", "TableSection");
|
||||
HTML_TAG("template", "Template");
|
||||
HTML_TAG("time", "Time");
|
||||
HTML_TAG("title", "Title");
|
||||
HTML_TAG("tr", "TableRow");
|
||||
|
@ -2282,96 +2282,81 @@ nsHTMLDocument::Plugins()
|
||||
return Embeds();
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLDocument::ResolveName(const nsAString& aName,
|
||||
nsIContent *aForm,
|
||||
nsISupports **aResult,
|
||||
nsWrapperCache **aCache)
|
||||
nsISupports*
|
||||
nsHTMLDocument::ResolveName(const nsAString& aName, nsWrapperCache **aCache)
|
||||
{
|
||||
*aResult = nullptr;
|
||||
*aCache = nullptr;
|
||||
|
||||
nsIdentifierMapEntry *entry = mIdentifierMap.GetEntry(aName);
|
||||
if (!entry) {
|
||||
return NS_OK;
|
||||
*aCache = nullptr;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
uint32_t length = 0;
|
||||
nsBaseContentList *list = entry->GetNameContentList();
|
||||
if (list) {
|
||||
list->GetLength(&length);
|
||||
}
|
||||
uint32_t length = list ? list->Length() : 0;
|
||||
|
||||
if (length > 0) {
|
||||
if (length == 1) {
|
||||
// Only one element in the list, return the element instead of
|
||||
// returning the list
|
||||
|
||||
// Only one element in the list, return the element instead of returning
|
||||
// the list.
|
||||
nsIContent *node = list->Item(0);
|
||||
if (!aForm || nsContentUtils::BelongsInForm(aForm, node)) {
|
||||
NS_ADDREF(*aResult = node);
|
||||
*aCache = node;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
*aCache = node;
|
||||
return node;
|
||||
}
|
||||
|
||||
// The list contains more than one element, return the whole
|
||||
// list, unless...
|
||||
|
||||
if (aForm) {
|
||||
// ... we're called from a form, in that case we create a
|
||||
// nsFormContentList which will filter out the elements in the
|
||||
// list that don't belong to aForm
|
||||
|
||||
nsFormContentList *fc_list = new nsFormContentList(aForm, *list);
|
||||
NS_ENSURE_TRUE(fc_list, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
uint32_t len;
|
||||
fc_list->GetLength(&len);
|
||||
|
||||
if (len < 2) {
|
||||
// After the nsFormContentList is done filtering there's either
|
||||
// nothing or one element in the list. Return that element, or null
|
||||
// if there's no element in the list.
|
||||
|
||||
nsIContent *node = fc_list->Item(0);
|
||||
|
||||
NS_IF_ADDREF(*aResult = node);
|
||||
*aCache = node;
|
||||
|
||||
delete fc_list;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
list = fc_list;
|
||||
}
|
||||
|
||||
return CallQueryInterface(list, aResult);
|
||||
// The list contains more than one element, return the whole list.
|
||||
*aCache = list;
|
||||
return list;
|
||||
}
|
||||
|
||||
// No named items were found, see if there's one registerd by id for
|
||||
// aName. If we get this far, FindNamedItems() will have been called
|
||||
// for aName, so we're guaranteed that if there is an element with
|
||||
// the id aName, it'll be entry's IdContent.
|
||||
|
||||
// No named items were found, see if there's one registerd by id for aName.
|
||||
Element *e = entry->GetIdElement();
|
||||
|
||||
if (e && e->IsHTML()) {
|
||||
nsIAtom *tag = e->Tag();
|
||||
|
||||
if ((tag == nsGkAtoms::embed ||
|
||||
tag == nsGkAtoms::img ||
|
||||
tag == nsGkAtoms::object ||
|
||||
tag == nsGkAtoms::applet) &&
|
||||
(!aForm || nsContentUtils::BelongsInForm(aForm, e))) {
|
||||
NS_ADDREF(*aResult = e);
|
||||
if (tag == nsGkAtoms::embed ||
|
||||
tag == nsGkAtoms::img ||
|
||||
tag == nsGkAtoms::object ||
|
||||
tag == nsGkAtoms::applet) {
|
||||
*aCache = e;
|
||||
return e;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
*aCache = nullptr;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
already_AddRefed<nsISupports>
|
||||
nsHTMLDocument::ResolveName(const nsAString& aName,
|
||||
nsIContent *aForm,
|
||||
nsWrapperCache **aCache)
|
||||
{
|
||||
nsISupports* result = ResolveName(aName, aCache);
|
||||
if (!result) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIContent> node = do_QueryInterface(result);
|
||||
if (!node) {
|
||||
// We create a nsFormContentList which will filter out the elements in the
|
||||
// list that don't belong to aForm.
|
||||
nsRefPtr<nsBaseContentList> list =
|
||||
new nsFormContentList(aForm, *static_cast<nsBaseContentList*>(result));
|
||||
if (list->Length() > 1) {
|
||||
*aCache = list;
|
||||
return list.forget();
|
||||
}
|
||||
|
||||
// After the nsFormContentList is done filtering there's either nothing or
|
||||
// one element in the list. Return that element, or null if there's no
|
||||
// element in the list.
|
||||
node = list->Item(0);
|
||||
} else if (!nsContentUtils::BelongsInForm(aForm, node)) {
|
||||
node = nullptr;
|
||||
}
|
||||
|
||||
*aCache = node;
|
||||
return node.forget();
|
||||
}
|
||||
|
||||
//----------------------------
|
||||
|
@ -114,10 +114,10 @@ public:
|
||||
nsWrapperCache **aCache,
|
||||
nsresult *aResult);
|
||||
|
||||
virtual nsresult ResolveName(const nsAString& aName,
|
||||
nsIContent *aForm,
|
||||
nsISupports **aResult,
|
||||
nsWrapperCache **aCache);
|
||||
nsISupports* ResolveName(const nsAString& aName, nsWrapperCache **aCache);
|
||||
virtual already_AddRefed<nsISupports> ResolveName(const nsAString& aName,
|
||||
nsIContent *aForm,
|
||||
nsWrapperCache **aCache);
|
||||
|
||||
virtual void AddedForm();
|
||||
virtual void RemovedForm();
|
||||
|
@ -33,10 +33,9 @@ public:
|
||||
*/
|
||||
virtual void SetCompatibilityMode(nsCompatibility aMode) = 0;
|
||||
|
||||
virtual nsresult ResolveName(const nsAString& aName,
|
||||
nsIContent *aForm,
|
||||
nsISupports **aResult,
|
||||
nsWrapperCache **aCache) = 0;
|
||||
virtual already_AddRefed<nsISupports> ResolveName(const nsAString& aName,
|
||||
nsIContent *aForm,
|
||||
nsWrapperCache **aCache) = 0;
|
||||
|
||||
/**
|
||||
* Called when form->BindToTree() is called so that document knows
|
||||
|
@ -108,7 +108,7 @@ AudioContext::CreateGain()
|
||||
already_AddRefed<DelayNode>
|
||||
AudioContext::CreateDelay(double aMaxDelayTime, ErrorResult& aRv)
|
||||
{
|
||||
if (aMaxDelayTime > 0. && aMaxDelayTime < 3.) {
|
||||
if (aMaxDelayTime > 0. && aMaxDelayTime < 180.) {
|
||||
nsRefPtr<DelayNode> delayNode = new DelayNode(this, aMaxDelayTime);
|
||||
return delayNode.forget();
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ addLoadEvent(function() {
|
||||
context.createDelay(0);
|
||||
}, DOMException.NOT_SUPPORTED_ERR);
|
||||
expectException(function() {
|
||||
context.createDelay(3);
|
||||
context.createDelay(180);
|
||||
}, DOMException.NOT_SUPPORTED_ERR);
|
||||
expectTypeError(function() {
|
||||
context.createDelay(NaN);
|
||||
|
@ -1,6 +1,6 @@
|
||||
This is sqlite 3.7.15.2
|
||||
This is sqlite 3.7.16
|
||||
|
||||
-- Ryan VanderMeulen <ryanvm@gmail.com>, 01/2013
|
||||
-- Ryan VanderMeulen <ryanvm@gmail.com>, 03/2013
|
||||
|
||||
See http://www.sqlite.org/ for more info.
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -107,9 +107,9 @@ extern "C" {
|
||||
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
|
||||
** [sqlite_version()] and [sqlite_source_id()].
|
||||
*/
|
||||
#define SQLITE_VERSION "3.7.15.2"
|
||||
#define SQLITE_VERSION_NUMBER 3007015
|
||||
#define SQLITE_SOURCE_ID "2013-01-09 11:53:05 c0e09560d26f0a6456be9dd3447f5311eb4f238f"
|
||||
#define SQLITE_VERSION "3.7.16"
|
||||
#define SQLITE_VERSION_NUMBER 3007016
|
||||
#define SQLITE_SOURCE_ID "2013-03-18 11:39:23 66d5f2b76750f3520eb7a495f6247206758f5b90"
|
||||
|
||||
/*
|
||||
** CAPI3REF: Run-Time Library Version Numbers
|
||||
@ -288,7 +288,7 @@ typedef sqlite_uint64 sqlite3_uint64;
|
||||
** [sqlite3_blob_close | close] all [BLOB handles], and
|
||||
** [sqlite3_backup_finish | finish] all [sqlite3_backup] objects associated
|
||||
** with the [sqlite3] object prior to attempting to close the object. ^If
|
||||
** sqlite3_close() is called on a [database connection] that still has
|
||||
** sqlite3_close_v2() is called on a [database connection] that still has
|
||||
** outstanding [prepared statements], [BLOB handles], and/or
|
||||
** [sqlite3_backup] objects then it returns SQLITE_OK but the deallocation
|
||||
** of resources is deferred until all [prepared statements], [BLOB handles],
|
||||
@ -483,7 +483,17 @@ SQLITE_API int sqlite3_exec(
|
||||
#define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8))
|
||||
#define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8))
|
||||
#define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8))
|
||||
#define SQLITE_READONLY_ROLLBACK (SQLITE_READONLY | (3<<8))
|
||||
#define SQLITE_ABORT_ROLLBACK (SQLITE_ABORT | (2<<8))
|
||||
#define SQLITE_CONSTRAINT_CHECK (SQLITE_CONSTRAINT | (1<<8))
|
||||
#define SQLITE_CONSTRAINT_COMMITHOOK (SQLITE_CONSTRAINT | (2<<8))
|
||||
#define SQLITE_CONSTRAINT_FOREIGNKEY (SQLITE_CONSTRAINT | (3<<8))
|
||||
#define SQLITE_CONSTRAINT_FUNCTION (SQLITE_CONSTRAINT | (4<<8))
|
||||
#define SQLITE_CONSTRAINT_NOTNULL (SQLITE_CONSTRAINT | (5<<8))
|
||||
#define SQLITE_CONSTRAINT_PRIMARYKEY (SQLITE_CONSTRAINT | (6<<8))
|
||||
#define SQLITE_CONSTRAINT_TRIGGER (SQLITE_CONSTRAINT | (7<<8))
|
||||
#define SQLITE_CONSTRAINT_UNIQUE (SQLITE_CONSTRAINT | (8<<8))
|
||||
#define SQLITE_CONSTRAINT_VTAB (SQLITE_CONSTRAINT | (9<<8))
|
||||
|
||||
/*
|
||||
** CAPI3REF: Flags For File Open Operations
|
||||
|
@ -14,21 +14,24 @@
|
||||
"use strict";
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
SpecialPowers.pushPrefEnv({"set": [["dom.mozAlarms.enabled", true]]}, function() {
|
||||
if (SpecialPowers.hasPermission("alarms", document)) {
|
||||
SpecialPowers.removePermission("alarms", document);
|
||||
window.location.reload();
|
||||
} else {
|
||||
SpecialPowers.pushPrefEnv({"set": [["dom.mozAlarms.enabled", true]]}, function() {
|
||||
SpecialPowers.removePermission("alarms", document);
|
||||
|
||||
// mozAlarms is intalled on all platforms except Android for the moment.
|
||||
if (navigator.appVersion.indexOf("Android") != -1) {
|
||||
ok(!('mozAlarms' in navigator), "navigator.mozAlarms should not exist");
|
||||
} else {
|
||||
ok('mozAlarms' in navigator, "navigator.mozAlarms should exist");
|
||||
is(navigator.mozAlarms, null, "navigator.mozAlarms should return null");
|
||||
}
|
||||
|
||||
SimpleTest.finish();
|
||||
});
|
||||
|
||||
// mozAlarms is intalled on all platforms except Android for the moment.
|
||||
if (navigator.appVersion.indexOf("Android") != -1) {
|
||||
ok(!('mozAlarms' in navigator), "navigator.mozAlarms should not exist");
|
||||
} else {
|
||||
ok('mozAlarms' in navigator, "navigator.mozAlarms should exist");
|
||||
is(navigator.mozAlarms, null, "navigator.mozAlarms should return null");
|
||||
}
|
||||
SpecialPowers.addPermission("alarms", true, document);
|
||||
SimpleTest.finish();
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
|
@ -28,7 +28,6 @@ SpecialPowers.pushPrefEnv({"set": [["dom.mozAlarms.enabled", true]]}, function()
|
||||
"navigator.mozAlarms should be an nsIDOMMozAlarmsManager object");
|
||||
}
|
||||
|
||||
SpecialPowers.removePermission("alarms", document);
|
||||
SimpleTest.finish();
|
||||
});
|
||||
|
||||
|
@ -9,6 +9,7 @@ const Ci = Components.interfaces;
|
||||
const Cu = Components.utils;
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/FileUtils.jsm");
|
||||
|
||||
this.EXPORTED_SYMBOLS = ["FreeSpaceWatcher"];
|
||||
|
||||
@ -42,15 +43,7 @@ this.FreeSpaceWatcher = {
|
||||
currentStatus: null,
|
||||
notify: function(aTimer) {
|
||||
try {
|
||||
let deviceStorage = Services.wm.getMostRecentWindow("navigator:browser")
|
||||
.navigator.getDeviceStorage("apps");
|
||||
let req = deviceStorage.freeSpace();
|
||||
req.onsuccess = req.onerror = function statResult(e) {
|
||||
if (!e.target.result) {
|
||||
return;
|
||||
}
|
||||
|
||||
let freeBytes = e.target.result;
|
||||
let checkFreeSpace = function (freeBytes) {
|
||||
debug("Free bytes: " + freeBytes);
|
||||
let newStatus = freeBytes > aThreshold;
|
||||
if (newStatus != callback.currentStatus) {
|
||||
@ -58,8 +51,44 @@ this.FreeSpaceWatcher = {
|
||||
aOnStatusChange(newStatus ? "free" : "full");
|
||||
callback.currentStatus = newStatus;
|
||||
}
|
||||
};
|
||||
|
||||
let deviceStorage = Services.wm.getMostRecentWindow("navigator:browser")
|
||||
.navigator.getDeviceStorage("apps");
|
||||
if (deviceStorage) {
|
||||
let req = deviceStorage.freeSpace();
|
||||
req.onsuccess = req.onerror = function statResult(e) {
|
||||
if (!e.target.result) {
|
||||
return;
|
||||
}
|
||||
|
||||
let freeBytes = e.target.result;
|
||||
checkFreeSpace(freeBytes);
|
||||
}
|
||||
} else {
|
||||
// deviceStorage isn't available, so use the webappsDir instead.
|
||||
// This needs to be moved from a hardcoded string to DIRECTORY_NAME
|
||||
// in AppsUtils. See bug 852685.
|
||||
let dir = FileUtils.getDir("webappsDir", ["webapps"], true, true);
|
||||
let freeBytes;
|
||||
try {
|
||||
freeBytes = dir.diskSpaceAvailable;
|
||||
} catch(e) {
|
||||
// If disk space information isn't available, we should assume
|
||||
// that there is enough free space, and that we'll fail when
|
||||
// we actually run out of disk space.
|
||||
callback.currentStatus = true;
|
||||
}
|
||||
if (freeBytes) {
|
||||
// We have disk space information. Call this here so that
|
||||
// any exceptions are caught in the outer catch block.
|
||||
checkFreeSpace(freeBytes);
|
||||
}
|
||||
}
|
||||
} catch(e) { debug(e); }
|
||||
} catch(e) {
|
||||
// If the aOnStatusChange callback has errored we'll end up here.
|
||||
debug(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -267,6 +267,8 @@ WebappsRegistry.prototype = {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.mozIDOMApplicationRegistry,
|
||||
#ifdef MOZ_B2G
|
||||
Ci.mozIDOMApplicationRegistry2,
|
||||
#elifdef MOZ_WIDGET_ANDROID
|
||||
Ci.mozIDOMApplicationRegistry2,
|
||||
#endif
|
||||
Ci.nsIDOMGlobalPropertyInitializer]),
|
||||
|
||||
@ -275,6 +277,8 @@ WebappsRegistry.prototype = {
|
||||
interfaces: [Ci.mozIDOMApplicationRegistry,
|
||||
#ifdef MOZ_B2G
|
||||
Ci.mozIDOMApplicationRegistry2,
|
||||
#elifdef MOZ_WIDGET_ANDROID
|
||||
Ci.mozIDOMApplicationRegistry2,
|
||||
#endif
|
||||
],
|
||||
flags: Ci.nsIClassInfo.DOM_OBJECT,
|
||||
|
@ -1799,7 +1799,9 @@ this.DOMApplicationRegistry = {
|
||||
delete this.queuedDownload[aManifestURL];
|
||||
},
|
||||
|
||||
confirmInstall: function(aData, aFromSync, aProfileDir, aOfflineCacheObserver) {
|
||||
confirmInstall: function(aData, aFromSync, aProfileDir,
|
||||
aOfflineCacheObserver,
|
||||
aZipDownloadSuccessCallback) {
|
||||
let isReinstall = false;
|
||||
let app = aData.app;
|
||||
app.removable = true;
|
||||
@ -1956,6 +1958,9 @@ this.DOMApplicationRegistry = {
|
||||
manifestURL: appObject.manifestURL,
|
||||
app: app,
|
||||
manifest: aManifest });
|
||||
if (aZipDownloadSuccessCallback) {
|
||||
aZipDownloadSuccessCallback(aManifest);
|
||||
}
|
||||
}).bind(this));
|
||||
}).bind(this));
|
||||
}
|
||||
@ -2401,28 +2406,45 @@ this.DOMApplicationRegistry = {
|
||||
sendProgressEvent();
|
||||
};
|
||||
|
||||
let checkDownloadSize = function (freeBytes) {
|
||||
if (freeBytes) {
|
||||
debug("Free storage: " + freeBytes + ". Download size: " +
|
||||
aApp.downloadSize);
|
||||
if (freeBytes <=
|
||||
aApp.downloadSize + AppDownloadManager.MIN_REMAINING_FREESPACE) {
|
||||
cleanup("INSUFFICIENT_STORAGE");
|
||||
return;
|
||||
}
|
||||
}
|
||||
download();
|
||||
};
|
||||
|
||||
let deviceStorage = Services.wm.getMostRecentWindow("navigator:browser")
|
||||
.navigator.getDeviceStorage("apps");
|
||||
let req = deviceStorage.freeSpace();
|
||||
req.onsuccess = req.onerror = function statResult(e) {
|
||||
// Even if we could not retrieve the device storage free space, we try
|
||||
// to download the package.
|
||||
if (!e.target.result) {
|
||||
download();
|
||||
return;
|
||||
}
|
||||
|
||||
let freeBytes = e.target.result;
|
||||
if (freeBytes) {
|
||||
debug("Free storage: " + freeBytes + ". Download size: " +
|
||||
aApp.downloadSize);
|
||||
if (freeBytes <=
|
||||
aApp.downloadSize + AppDownloadManager.MIN_REMAINING_FREESPACE) {
|
||||
cleanup("INSUFFICIENT_STORAGE");
|
||||
if (deviceStorage) {
|
||||
let req = deviceStorage.freeSpace();
|
||||
req.onsuccess = req.onerror = function statResult(e) {
|
||||
// Even if we could not retrieve the device storage free space, we try
|
||||
// to download the package.
|
||||
if (!e.target.result) {
|
||||
download();
|
||||
return;
|
||||
}
|
||||
|
||||
let freeBytes = e.target.result;
|
||||
checkDownloadSize(freeBytes);
|
||||
}
|
||||
} else {
|
||||
// deviceStorage isn't available, so use FileUtils to find the size of available storage.
|
||||
let dir = FileUtils.getDir(DIRECTORY_NAME, ["webapps"], true, true);
|
||||
try {
|
||||
checkDownloadSize(dir.diskSpaceAvailable);
|
||||
} catch(ex) {
|
||||
// If disk space information isn't available, we'll end up here.
|
||||
// We should either proceed anyway, otherwise devices that support neither
|
||||
// deviceStorage nor diskSpaceAvailable will never be able to install packaged apps.
|
||||
download();
|
||||
}
|
||||
download();
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -3637,7 +3637,7 @@ nsWindowSH::GlobalScopePolluterNewResolve(JSContext *cx, JSHandleObject obj,
|
||||
}
|
||||
|
||||
if (!result) {
|
||||
document->ResolveName(str, nullptr, getter_AddRefs(result), &cache);
|
||||
result = document->ResolveName(str, &cache);
|
||||
}
|
||||
|
||||
if (result) {
|
||||
@ -6612,7 +6612,8 @@ ResolveImpl(JSContext *cx, nsIXPConnectWrappedNative *wrapper, jsid id,
|
||||
nsDependentJSString depStr;
|
||||
NS_ENSURE_TRUE(depStr.init(cx, str), NS_ERROR_UNEXPECTED);
|
||||
|
||||
return doc->ResolveName(depStr, nullptr, result, aCache);
|
||||
NS_IF_ADDREF(*result = doc->ResolveName(depStr, aCache));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
@ -7218,7 +7219,7 @@ nsHTMLFormElementSH::FindNamedItem(nsIForm *aForm, jsid id,
|
||||
do_QueryInterface(content->GetDocument());
|
||||
|
||||
if (html_doc && content) {
|
||||
html_doc->ResolveName(name, content, aResult, aCache);
|
||||
*aResult = html_doc->ResolveName(name, content, aCache).get();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -456,6 +456,12 @@ DOMInterfaces = {
|
||||
]
|
||||
},
|
||||
|
||||
'HTMLTemplateElement': {
|
||||
'resultNotAddRefed': [
|
||||
'content'
|
||||
]
|
||||
},
|
||||
|
||||
'HTMLTextAreaElement': {
|
||||
'resultNotAddRefed': [
|
||||
'form', 'controllers', 'editor'
|
||||
|
@ -467,6 +467,7 @@ BluetoothOppManager::AfterOppDisconnected()
|
||||
mConnected = false;
|
||||
mLastCommand = 0;
|
||||
mBlob = nullptr;
|
||||
mPacketLeftLength = 0;
|
||||
|
||||
// We can't reset mSuccessFlag here since this function may be called
|
||||
// before we send system message of transfer complete
|
||||
|
@ -266,10 +266,10 @@ public:
|
||||
NS_ENSURE_TRUE(bs, NS_ERROR_FAILURE);
|
||||
sAdapterPath = mPath;
|
||||
|
||||
// Due to the fact that we need to queue the dbus call to the command thread
|
||||
// inside the bluetoothservice, we have to route the call down to the main
|
||||
// thread and then back out to the command thread. There has to be a better
|
||||
// way to do this.
|
||||
// Due to the fact that we need to queue the dbus call to the command
|
||||
// thread inside the bluetoothservice, we have to route the call down
|
||||
// to the main thread and then back out to the command thread. There has
|
||||
// to be a better way to do this.
|
||||
if (NS_FAILED(bs->PrepareAdapterInternal())) {
|
||||
NS_WARNING("Prepare adapter failed");
|
||||
return NS_ERROR_FAILURE;
|
||||
@ -406,7 +406,8 @@ static DBusHandlerResult
|
||||
AgentEventFilter(DBusConnection *conn, DBusMessage *msg, void *data)
|
||||
{
|
||||
if (dbus_message_get_type(msg) != DBUS_MESSAGE_TYPE_METHOD_CALL) {
|
||||
BT_WARNING("%s: agent handler not interested (not a method call).\n", __FUNCTION__);
|
||||
BT_WARNING("%s: agent handler not interested (not a method call).\n",
|
||||
__FUNCTION__);
|
||||
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
||||
}
|
||||
|
||||
@ -484,9 +485,8 @@ AgentEventFilter(DBusConnection *conn, DBusMessage *msg, void *data)
|
||||
DBUS_TYPE_OBJECT_PATH, &objectPath,
|
||||
DBUS_TYPE_UINT32, &passkey,
|
||||
DBUS_TYPE_INVALID)) {
|
||||
BT_WARNING("%s: Invalid arguments for RequestConfirmation() method",
|
||||
__FUNCTION__);
|
||||
errorStr.AssignLiteral("Invalid arguments for RequestConfirmation() method");
|
||||
BT_WARNING("%s: Invalid arguments: RequestConfirmation()", __FUNCTION__);
|
||||
errorStr.AssignLiteral("Invalid arguments: RequestConfirmation()");
|
||||
} else {
|
||||
parameters.AppendElement(BluetoothNamedValue(
|
||||
NS_LITERAL_STRING("path"),
|
||||
@ -899,7 +899,14 @@ RunDBusCallback(DBusMessage* aMsg, void* aBluetoothReplyRunnable,
|
||||
// being gtk based, sometimes we'll get signals/reply coming in on the main
|
||||
// thread. There's not a lot we can do about that for the time being and it
|
||||
// (technically) shouldn't hurt anything. However, on gonk, die.
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
|
||||
// Due to the fact introducing workaround in Bug 827888, the callback for a
|
||||
// message gets executed immediately. The proper fix is in bug 830290, but
|
||||
// it's a intrusive change, it is better to remove assertion here since it
|
||||
// would not hurt anything.
|
||||
// Tracking bug 830290 for intrusive solution.
|
||||
|
||||
// MOZ_ASSERT(!NS_IsMainThread());
|
||||
#endif
|
||||
nsRefPtr<BluetoothReplyRunnable> replyRunnable =
|
||||
dont_AddRef(static_cast< BluetoothReplyRunnable* >(aBluetoothReplyRunnable));
|
||||
@ -1132,13 +1139,13 @@ ParseProperties(DBusMessageIter* aIter,
|
||||
int prop_index = -1;
|
||||
|
||||
NS_ASSERTION(dbus_message_iter_get_arg_type(aIter) == DBUS_TYPE_ARRAY,
|
||||
"Trying to parse a property from something that's not an array!");
|
||||
"Trying to parse a property from sth. that's not an array");
|
||||
|
||||
dbus_message_iter_recurse(aIter, &dict);
|
||||
InfallibleTArray<BluetoothNamedValue> props;
|
||||
do {
|
||||
NS_ASSERTION(dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY,
|
||||
"Trying to parse a property from something that's not an dict!");
|
||||
"Trying to parse a property from sth. that's not an dict!");
|
||||
dbus_message_iter_recurse(&dict, &dict_entry);
|
||||
|
||||
if (!GetProperty(dict_entry, aPropertyTypes, aPropertyTypeLen, &prop_index,
|
||||
@ -1448,7 +1455,7 @@ EventFilter(DBusConnection* aConn, DBusMessage* aMsg, void* aData)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
errorStr.AssignLiteral("DBus device found message structure not as expected!");
|
||||
errorStr.AssignLiteral("Unexpected message struct in msg DeviceFound");
|
||||
}
|
||||
} else if (dbus_message_is_signal(aMsg, DBUS_ADAPTER_IFACE,
|
||||
"DeviceDisappeared")) {
|
||||
@ -1877,7 +1884,8 @@ public:
|
||||
|
||||
const InfallibleTArray<BluetoothNamedValue>& arr =
|
||||
v.get_ArrayOfBluetoothNamedValue();
|
||||
NS_ASSERTION(arr[0].name().EqualsLiteral("path"), "failed to get object path");
|
||||
NS_ASSERTION(arr[0].name().EqualsLiteral("path"),
|
||||
"failed to get object path");
|
||||
NS_ASSERTION(arr[0].value().type() == BluetoothValue::TnsString,
|
||||
"failed to get_nsString");
|
||||
nsString devicePath = arr[0].value().get_nsString();
|
||||
@ -1891,7 +1899,8 @@ public:
|
||||
prop.get_ArrayOfBluetoothNamedValue();
|
||||
|
||||
// Return original dbus message parameters and also device name
|
||||
// for agent events "RequestConfirmation", "RequestPinCode", and "RequestPasskey"
|
||||
// for agent events "RequestConfirmation", "RequestPinCode",
|
||||
// and "RequestPasskey"
|
||||
InfallibleTArray<BluetoothNamedValue>& parameters =
|
||||
v.get_ArrayOfBluetoothNamedValue();
|
||||
|
||||
@ -2056,10 +2065,10 @@ BluetoothDBusService::SetProperty(BluetoothObjectType aType,
|
||||
|
||||
/* Compose the command */
|
||||
DBusMessage* msg = dbus_message_new_method_call(
|
||||
"org.bluez",
|
||||
NS_ConvertUTF16toUTF8(sAdapterPath).get(),
|
||||
interface,
|
||||
"SetProperty");
|
||||
"org.bluez",
|
||||
NS_ConvertUTF16toUTF8(sAdapterPath).get(),
|
||||
interface,
|
||||
"SetProperty");
|
||||
|
||||
if (!msg) {
|
||||
NS_WARNING("Could not allocate D-Bus message object!");
|
||||
@ -2100,7 +2109,8 @@ BluetoothDBusService::SetProperty(BluetoothObjectType aType,
|
||||
DBusMessageIter value_iter, iter;
|
||||
dbus_message_iter_init_append(msg, &iter);
|
||||
char var_type[2] = {(char)type, '\0'};
|
||||
if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT, var_type, &value_iter) ||
|
||||
if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
|
||||
var_type, &value_iter) ||
|
||||
!dbus_message_iter_append_basic(&value_iter, type, val) ||
|
||||
!dbus_message_iter_close_container(&iter, &value_iter)) {
|
||||
NS_WARNING("Could not append argument to method call!");
|
||||
|
@ -1097,20 +1097,21 @@ MmsService.prototype = {
|
||||
// For RETRIEVAL_MODE_AUTOMATIC, proceed to retrieve MMS.
|
||||
this.retrieveMessage(url, (function responseNotify(mmsStatus,
|
||||
retrievedMessage) {
|
||||
debug("retrievedMessage = " + JSON.stringify(retrievedMessage));
|
||||
|
||||
// The absence of the field does not indicate any default
|
||||
// value. So we go check the same field in the retrieved
|
||||
// message instead.
|
||||
if ((wish == null) && retrievedMessage) {
|
||||
if (wish == null && retrievedMessage) {
|
||||
wish = retrievedMessage.headers["x-mms-delivery-report"];
|
||||
}
|
||||
let reportAllowed = this.getReportAllowed(this.confSendDeliveryReport,
|
||||
wish);
|
||||
|
||||
// Should update the retrievedStatus in database.
|
||||
debug("retrievedMessage = " + JSON.stringify(retrievedMessage));
|
||||
|
||||
// If the mmsStatus is still MMS_PDU_STATUS_DEFERRED after retry,
|
||||
// we should not store it into database.
|
||||
// If the mmsStatus isn't MMS_PDU_STATUS_RETRIEVED after retrieving,
|
||||
// something must be wrong with MMSC, so stop updating the DB record.
|
||||
// We could send a message to content to notify the user the MMS
|
||||
// retrieving failed. The end user has to retrieve the MMS again.
|
||||
if (MMS.MMS_PDU_STATUS_RETRIEVED !== mmsStatus) {
|
||||
let transaction =
|
||||
new NotifyResponseTransaction(transactionId,
|
||||
@ -1126,18 +1127,20 @@ MmsService.prototype = {
|
||||
gMobileMessageDatabaseService.saveReceivedMessage(savableMessage,
|
||||
(function (rv, domMessage) {
|
||||
let success = Components.isSuccessCode(rv);
|
||||
let transaction =
|
||||
new NotifyResponseTransaction(transactionId,
|
||||
success ? MMS.MMS_PDU_STATUS_RETRIEVED
|
||||
: MMS.MMS_PDU_STATUS_DEFERRED,
|
||||
reportAllowed);
|
||||
transaction.run();
|
||||
|
||||
if (!success) {
|
||||
// At this point we could send a message to content to
|
||||
// notify the user that storing an incoming MMS failed, most
|
||||
// likely due to a full disk.
|
||||
// notify the user that storing an incoming MMS failed,
|
||||
// most likely due to a full disk. The end user has to
|
||||
// retrieve the MMS again.
|
||||
debug("Could not store MMS " + domMessage.id +
|
||||
", error code " + rv);
|
||||
|
||||
let transaction =
|
||||
new NotifyResponseTransaction(transactionId,
|
||||
MMS.MMS_PDU_STATUS_DEFERRED,
|
||||
reportAllowed);
|
||||
transaction.run();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,8 @@
|
||||
# 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/.
|
||||
|
||||
TEST_DIRS += ['test']
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
|
||||
TEST_DIRS += ['test']
|
||||
|
||||
XPIDL_SOURCES += [
|
||||
'nsIDOMPowerManager.idl',
|
||||
|
@ -19,24 +19,24 @@ SimpleTest.waitForExplicitFinish();
|
||||
function startTest() {
|
||||
window.frames[0].frameElement.setAttribute('onload', 'doTest2()');
|
||||
power = window.frames[0].navigator.mozPower;
|
||||
ok(!power, "Shouldn't be able to access power manager without permission.");
|
||||
|
||||
SpecialPowers.addPermission("power", true, window.frames[0].document);
|
||||
window.frames[0].location.reload();
|
||||
}
|
||||
|
||||
function doTest2() {
|
||||
window.frames[0].frameElement.setAttribute('onload', 'doTest3()');
|
||||
power = window.frames[0].navigator.mozPower;
|
||||
ok(power, "Should be able to access power manager with permission.");
|
||||
|
||||
SpecialPowers.removePermission("power", window.frames[0].document);
|
||||
window.frames[0].location.reload();
|
||||
}
|
||||
|
||||
function doTest2() {
|
||||
window.frames[0].frameElement.setAttribute('onload', 'doTest3()');
|
||||
power = window.frames[0].navigator.mozPower;
|
||||
ok(!power, "Shouldn't be able to access power manager with permission.");
|
||||
|
||||
SpecialPowers.addPermission("power",true, window.frames[0].document);
|
||||
window.frames[0].location.reload();
|
||||
}
|
||||
|
||||
function doTest3() {
|
||||
power = window.frames[0].navigator.mozPower;
|
||||
ok(!power, "Shouldn't be able to access power manager without permission.");
|
||||
ok(power, "Should be able to access power manager with permission.");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
</script>
|
||||
|
@ -111,6 +111,7 @@ function test() {
|
||||
HTML_TAG("tfoot", "TableSection")
|
||||
HTML_TAG("th", "TableCell")
|
||||
HTML_TAG("thead", "TableSection")
|
||||
HTML_TAG("template", "Template")
|
||||
HTML_TAG("title", "Title")
|
||||
HTML_TAG("tr", "TableRow")
|
||||
HTML_TAG("tt", "Span")
|
||||
|
@ -129,6 +129,7 @@ HTML_TAG("textarea", "TextArea")
|
||||
HTML_TAG("tfoot", "TableSection")
|
||||
HTML_TAG("th", "TableCell")
|
||||
HTML_TAG("thead", "TableSection")
|
||||
HTML_TAG("template", "Template")
|
||||
HTML_TAG("title", "Title")
|
||||
HTML_TAG("tr", "TableRow")
|
||||
HTML_TAG("tt", "Span")
|
||||
|
@ -13,6 +13,7 @@ include $(DEPTH)/config/autoconf.mk
|
||||
MOCHITEST_FILES = \
|
||||
test_document_register.html \
|
||||
test_document_register_lifecycle.html \
|
||||
test_template.html \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
145
dom/tests/mochitest/webcomponents/test_template.html
Normal file
145
dom/tests/mochitest/webcomponents/test_template.html
Normal file
@ -0,0 +1,145 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=818976
|
||||
-->
|
||||
<head>
|
||||
<title>Test for template element</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
<script>
|
||||
function shouldNotCall() {
|
||||
ok(false, "Template contents should be inert.");
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<script>
|
||||
shouldNotCall();
|
||||
</script>
|
||||
</template>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=818976">Bug 818976</a>
|
||||
<template id="grabme"><div id="insidetemplate"></div></template>
|
||||
<template id="justtemplate"></template>
|
||||
<template id="first">Hi<template>Bye</template></template>
|
||||
<div><template id="second"><span></span></template></div>
|
||||
<template id="cloneme"><span>I want a clone</span><span>me too</span></template>
|
||||
<template id="cycleone"></template>
|
||||
<template id="cycletwo"><template></template></template>
|
||||
<template id="cyclethree"></template>
|
||||
<template id="cyclefour"><template></template></template>
|
||||
<template id="appendtome"></template>
|
||||
<template id="insertinme"></template>
|
||||
<template>
|
||||
<script>
|
||||
shouldNotCall();
|
||||
</script>
|
||||
</template>
|
||||
<div id="fillme"></div>
|
||||
<script>
|
||||
var templateEl = document.getElementById("grabme");
|
||||
ok(templateEl, "template element should be in document.");
|
||||
is(window.getComputedStyle(templateEl).display, "none", "Template element should not be visible.");
|
||||
ok(!document.getElementById("insidetemplate"), "Template content should not be in document.");
|
||||
is(templateEl.childNodes.length, 0, "Template element should have no children.");
|
||||
is(templateEl.content.childNodes.length, 1, "Template content should have 1 child <div>.");
|
||||
|
||||
// Make sure that template is owned by different document.
|
||||
ok(templateEl.content.ownerDocument != templateEl.ownerDocument, "Template should be in a different document because the current document has a browsing context.");
|
||||
var otherTemplateEl = document.getElementById("first");
|
||||
is(templateEl.content.ownerDocument, otherTemplateEl.content.ownerDocument, "Template contents within the same document should be owned by the same template contents owner.");
|
||||
|
||||
// Tests for XMLSerializer
|
||||
templateEl = document.getElementById("justtemplate");
|
||||
var serializer = new XMLSerializer();
|
||||
is(serializer.serializeToString(templateEl), '<template xmlns="http://www.w3.org/1999/xhtml" id="justtemplate"></template>', "XMLSerializer should serialize template element.");
|
||||
|
||||
templateEl = document.getElementById("first");
|
||||
is(serializer.serializeToString(templateEl), '<template xmlns="http://www.w3.org/1999/xhtml" id="first">Hi<template>Bye</template></template>', "XMLSerializer should serialize template content.");
|
||||
|
||||
// Tests for innerHTML.
|
||||
is(templateEl.innerHTML, 'Hi<template>Bye</template>', "innerHTML should serialize content.");
|
||||
// Tests for outerHTML, not specified but should do something reasonable.
|
||||
is(templateEl.outerHTML, '<template id="first">Hi<template>Bye</template></template>', "outerHTML should serialize content.");
|
||||
|
||||
templateEl.innerHTML = "Hello";
|
||||
is(templateEl.innerHTML, "Hello", "innerHTML of template should be set to 'Hello'");
|
||||
is(templateEl.childNodes.length, 0, "Template element should have no children.");
|
||||
is(templateEl.content.childNodes.length, 1, "Template content should have 'Hello' as child.");
|
||||
|
||||
// Test for innerHTML on parent of template element.
|
||||
var templateParent = document.getElementById("second").parentNode;
|
||||
is(templateParent.innerHTML, '<template id="second"><span></span></template>', "InnerHTML on parent of template element should serialize template and template content.");
|
||||
|
||||
templateEl.innerHTML = '<template id="inner">Hello</template>';
|
||||
ok(templateEl.content.childNodes[0] instanceof HTMLTemplateElement, "Template content should have <template> as child.");
|
||||
is(templateEl.content.childNodes[0].childNodes.length, 0, "Parsed temlate element should have no children.");
|
||||
is(templateEl.content.childNodes[0].content.childNodes.length, 1, "Parsed temlate element should have 'Hello' in content.");
|
||||
|
||||
// Test cloning.
|
||||
templateEl = document.getElementById("cloneme");
|
||||
var nonDeepClone = templateEl.cloneNode(false);
|
||||
is(nonDeepClone.childNodes.length, 0, "There should be no children on the clone.");
|
||||
is(nonDeepClone.content.childNodes.length, 0, "Content should not be cloned.");
|
||||
var deepClone = templateEl.cloneNode(true);
|
||||
is(deepClone.childNodes.length, 0, "There should be no children on the clone.");
|
||||
is(deepClone.content.childNodes.length, 2, "The content should be cloned.");
|
||||
|
||||
// Append content into a node.
|
||||
var parentEl = document.getElementById("fillme");
|
||||
parentEl.appendChild(templateEl.content);
|
||||
is(parentEl.childNodes.length, 2, "Parent should be appended with cloned content.");
|
||||
|
||||
// Test exceptions thrown for cycles.
|
||||
templateEl = document.getElementById("cycleone");
|
||||
try {
|
||||
templateEl.content.appendChild(templateEl);
|
||||
ok(false, "Exception should be thrown when creating cycles in template content.");
|
||||
} catch (ex) {
|
||||
ok(true, "Exception should be thrown when creating cycles in template content.");
|
||||
}
|
||||
|
||||
templateEl = document.getElementById("cycletwo");
|
||||
try {
|
||||
// Append template to template content within the template content.
|
||||
templateEl.content.childNodes[0].content.appendChild(templateEl);
|
||||
ok(false, "Exception should be thrown when creating cycles in template content.");
|
||||
} catch (ex) {
|
||||
ok(true, "Exception should be thrown when creating cycles in template content.");
|
||||
}
|
||||
|
||||
templateEl = document.getElementById("cyclethree");
|
||||
try {
|
||||
templateEl.appendChild(templateEl);
|
||||
ok(false, "Exception should be thrown when creating cycles in hierarchy.");
|
||||
} catch (ex) {
|
||||
ok(true, "Exception should be thrown when creating cycles in hierarchy.");
|
||||
}
|
||||
|
||||
templateEl = document.getElementById("cyclefour");
|
||||
try {
|
||||
templateEl.content.childNodes[0].appendChild(templateEl);
|
||||
ok(false, "Exception should be thrown when creating cycles in hierarchy.");
|
||||
} catch (ex) {
|
||||
ok(true, "Exception should be thrown when creating cycles in hierarchy.");
|
||||
}
|
||||
|
||||
templateEl = document.getElementById("insertinme");
|
||||
var sentinel = document.createElement("div");
|
||||
try {
|
||||
templateEl.content.appendChild(sentinel);
|
||||
templateEl.content.insertBefore(templateEl, sentinel);
|
||||
ok(false, "Exception should be thrown when creating cycles in hierarchy.");
|
||||
} catch (ex) {
|
||||
ok(true, "Exception should be thrown when creating cycles in hierarchy.");
|
||||
}
|
||||
|
||||
// Appending normal stuff into content should work.
|
||||
templateEl = document.getElementById("appendtome");
|
||||
templateEl.content.appendChild(document.createElement("div"));
|
||||
is(templateEl.content.childNodes.length, 1, "Template should have div element appended as child");
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
15
dom/webidl/HTMLTemplateElement.webidl
Normal file
15
dom/webidl/HTMLTemplateElement.webidl
Normal file
@ -0,0 +1,15 @@
|
||||
/* 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/.
|
||||
*
|
||||
* The origin of this IDL file is
|
||||
* https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/templates/index.html
|
||||
*
|
||||
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
|
||||
* liability, trademark and document use rules apply.
|
||||
*/
|
||||
|
||||
interface HTMLTemplateElement : HTMLElement {
|
||||
readonly attribute DocumentFragment content;
|
||||
};
|
||||
|
@ -125,6 +125,7 @@ webidl_files = \
|
||||
HTMLTableElement.webidl \
|
||||
HTMLTableRowElement.webidl \
|
||||
HTMLTableSectionElement.webidl \
|
||||
HTMLTemplateElement.webidl \
|
||||
HTMLTextAreaElement.webidl \
|
||||
HTMLTimeElement.webidl \
|
||||
HTMLTitleElement.webidl \
|
||||
|
@ -751,6 +751,7 @@ static const nsElementInfo kElements[eHTMLTag_userdefined] = {
|
||||
ELEM(tfoot, true, false, GROUP_NONE, GROUP_TBODY_CONTENT),
|
||||
ELEM(th, true, false, GROUP_TR_CONTENT, GROUP_FLOW_ELEMENT),
|
||||
ELEM(thead, true, false, GROUP_NONE, GROUP_TBODY_CONTENT),
|
||||
ELEM(template, false, false, GROUP_NONE, GROUP_NONE),
|
||||
ELEM(time, true, false, GROUP_PHRASE, GROUP_INLINE_ELEMENT),
|
||||
ELEM(title, true, false, GROUP_HEAD_CONTENT, GROUP_LEAF),
|
||||
ELEM(tr, true, false, GROUP_TBODY_CONTENT, GROUP_TR_CONTENT),
|
||||
|
@ -204,6 +204,8 @@ win32-gdi-font-cache-no-HFONT.patch: Bug 717178, don't cache GDI font faces when
|
||||
|
||||
fix-win32-font-assertion.patch: Bug 838617, fix assertion from bug 717178 that was in the wrong place
|
||||
|
||||
xlib-flush-glyphs.patch: bug 839745, flush glyphs when necessary
|
||||
|
||||
==== pixman patches ====
|
||||
|
||||
pixman-android-cpu-detect.patch: Add CPU detection support for Android, where we can't reliably access /proc/self/auxv.
|
||||
|
@ -55,8 +55,10 @@
|
||||
#include "cairo-surface-snapshot-private.h"
|
||||
#include "cairo-surface-subsurface-private.h"
|
||||
#include "cairo-region-private.h"
|
||||
#include "cairo-xlib-xrender-private.h"
|
||||
|
||||
#include <X11/Xutil.h> /* for XDestroyImage */
|
||||
#include <X11/Xlibint.h> /* for access to XDisplay's innards */
|
||||
|
||||
#define XLIB_COORD_MAX 32767
|
||||
|
||||
@ -73,7 +75,6 @@
|
||||
#endif
|
||||
|
||||
#if DEBUG
|
||||
#include <X11/Xlibint.h>
|
||||
static void CAIRO_PRINTF_FORMAT (2, 3)
|
||||
_x_bread_crumb (Display *dpy,
|
||||
const char *fmt,
|
||||
@ -4318,6 +4319,13 @@ _cairo_xlib_surface_add_glyph (cairo_xlib_display_t *display,
|
||||
}
|
||||
/* XXX assume X server wants pixman padding. Xft assumes this as well */
|
||||
|
||||
struct _XDisplay *dpy = (struct _XDisplay *) display->display;
|
||||
int req_length = sz_xRenderAddGlyphsReq + 4;
|
||||
if (req_length & 3)
|
||||
req_length += 4 - (req_length & 3);
|
||||
if (dpy->bufptr + req_length > dpy->bufmax)
|
||||
XFlush (display->display);
|
||||
|
||||
XRenderAddGlyphs (display->display, glyphset_info->glyphset,
|
||||
&glyph_index, &glyph_info, 1,
|
||||
(char *) data,
|
||||
|
66
gfx/cairo/xlib-flush-glyphs.patch
Normal file
66
gfx/cairo/xlib-flush-glyphs.patch
Normal file
@ -0,0 +1,66 @@
|
||||
diff --git a/gfx/cairo/cairo/src/cairo-xlib-surface.c b/gfx/cairo/cairo/src/cairo-xlib-surface.c
|
||||
index f0de3c7..e24c962 100644
|
||||
--- a/gfx/cairo/cairo/src/cairo-xlib-surface.c
|
||||
+++ b/gfx/cairo/cairo/src/cairo-xlib-surface.c
|
||||
@@ -50,35 +50,36 @@
|
||||
#include "cairo-xlib-private.h"
|
||||
#include "cairo-xlib-surface-private.h"
|
||||
#include "cairo-clip-private.h"
|
||||
#include "cairo-error-private.h"
|
||||
#include "cairo-scaled-font-private.h"
|
||||
#include "cairo-surface-snapshot-private.h"
|
||||
#include "cairo-surface-subsurface-private.h"
|
||||
#include "cairo-region-private.h"
|
||||
+#include "cairo-xlib-xrender-private.h"
|
||||
|
||||
#include <X11/Xutil.h> /* for XDestroyImage */
|
||||
+#include <X11/Xlibint.h> /* for access to XDisplay's innards */
|
||||
|
||||
#define XLIB_COORD_MAX 32767
|
||||
|
||||
#define DEBUG 0
|
||||
|
||||
#if DEBUG
|
||||
#define UNSUPPORTED(reason) \
|
||||
fprintf (stderr, \
|
||||
"cairo-xlib: hit unsupported operation %s(), line %d: %s\n", \
|
||||
__FUNCTION__, __LINE__, reason), \
|
||||
CAIRO_INT_STATUS_UNSUPPORTED
|
||||
#else
|
||||
#define UNSUPPORTED(reason) CAIRO_INT_STATUS_UNSUPPORTED
|
||||
#endif
|
||||
|
||||
#if DEBUG
|
||||
-#include <X11/Xlibint.h>
|
||||
static void CAIRO_PRINTF_FORMAT (2, 3)
|
||||
_x_bread_crumb (Display *dpy,
|
||||
const char *fmt,
|
||||
...)
|
||||
{
|
||||
xReq *req;
|
||||
char buf[2048];
|
||||
unsigned int len, len_dwords;
|
||||
@@ -4313,16 +4314,23 @@ _cairo_xlib_surface_add_glyph (cairo_xlib_display_t *display,
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ASSERT_NOT_REACHED;
|
||||
break;
|
||||
}
|
||||
/* XXX assume X server wants pixman padding. Xft assumes this as well */
|
||||
|
||||
+ struct _XDisplay *dpy = (struct _XDisplay *) display->display;
|
||||
+ int req_length = sz_xRenderAddGlyphsReq + 4;
|
||||
+ if (req_length & 3)
|
||||
+ req_length += 4 - (req_length & 3);
|
||||
+ if (dpy->bufptr + req_length > dpy->bufmax)
|
||||
+ XFlush (display->display);
|
||||
+
|
||||
XRenderAddGlyphs (display->display, glyphset_info->glyphset,
|
||||
&glyph_index, &glyph_info, 1,
|
||||
(char *) data,
|
||||
glyph_surface->stride * glyph_surface->height);
|
||||
|
||||
if (data != glyph_surface->data)
|
||||
free (data);
|
||||
|
@ -379,7 +379,17 @@ gfxPlatform::Init()
|
||||
= do_CreateInstance("@mozilla.org/gfx/init;1");
|
||||
|
||||
if (Preferences::GetBool("gfx.2d.recording", false)) {
|
||||
gPlatform->mRecorder = Factory::CreateEventRecorderForFile("browserrecording.aer");
|
||||
|
||||
nsAutoCString fileName;
|
||||
nsAdoptingString prefFileName = Preferences::GetString("gfx.2d.recordingfile");
|
||||
|
||||
if (prefFileName) {
|
||||
fileName.Append(NS_ConvertUTF16toUTF8(prefFileName));
|
||||
} else {
|
||||
fileName.AssignLiteral("browserrecording.aer");
|
||||
}
|
||||
|
||||
gPlatform->mRecorder = Factory::CreateEventRecorderForFile(fileName.BeginReading());
|
||||
Factory::SetGlobalEventRecorder(gPlatform->mRecorder);
|
||||
}
|
||||
|
||||
|
@ -53,4 +53,5 @@ Includes = (
|
||||
'nsTArray.h',
|
||||
'nsIFile.h',
|
||||
'mozilla/ipc/ProtocolUtils.h',
|
||||
'GeckoProfiler.h'
|
||||
)
|
||||
|
@ -4932,6 +4932,7 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
|
||||
args=[ ExprLiteral.String(md.prettyMsgName(self.protocol.name
|
||||
+'::')) ])),
|
||||
self.logMessage(md, md.msgCast(msgexpr), 'Received '),
|
||||
self.profilerLabel('Recv', md.decl.progname),
|
||||
Whitespace.NL
|
||||
])
|
||||
|
||||
@ -4986,13 +4987,13 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
|
||||
|
||||
return stmts
|
||||
|
||||
|
||||
def sendAsync(self, md, msgexpr, actor=None):
|
||||
sendok = ExprVar('__sendok')
|
||||
return (
|
||||
sendok,
|
||||
([ Whitespace.NL,
|
||||
self.logMessage(md, msgexpr, 'Sending ') ]
|
||||
self.logMessage(md, msgexpr, 'Sending '),
|
||||
self.profilerLabel('AsyncSend', md.decl.progname) ]
|
||||
+ self.transition(md, 'out', actor)
|
||||
+ [ Whitespace.NL,
|
||||
StmtDecl(Decl(Type.BOOL, sendok.name),
|
||||
@ -5008,7 +5009,8 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
|
||||
return (
|
||||
sendok,
|
||||
([ Whitespace.NL,
|
||||
self.logMessage(md, msgexpr, 'Sending ') ]
|
||||
self.logMessage(md, msgexpr, 'Sending '),
|
||||
self.profilerLabel('Send', md.decl.progname) ]
|
||||
+ self.transition(md, 'out', actor)
|
||||
+ [ Whitespace.NL,
|
||||
StmtDecl(
|
||||
@ -5084,6 +5086,11 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
|
||||
args=[ ExprLiteral.String('['+ actorname +'] '+ pfx),
|
||||
ExprVar('stderr') ])) ])
|
||||
|
||||
def profilerLabel(self, tag, msgname):
|
||||
return StmtExpr(ExprCall(ExprVar('PROFILER_LABEL'),
|
||||
[ ExprLiteral.String('IPDL::' + self.protocol.name),
|
||||
ExprLiteral.String(tag + msgname) ]))
|
||||
|
||||
def saveActorId(self, md):
|
||||
idvar = ExprVar('__id')
|
||||
if md.decl.type.hasReply():
|
||||
|
@ -40,7 +40,9 @@ namespace JS {
|
||||
struct ObjectsExtraSizes
|
||||
{
|
||||
size_t slots;
|
||||
size_t elements;
|
||||
size_t elementsNonAsmJS;
|
||||
size_t elementsAsmJSHeap;
|
||||
size_t elementsAsmJSNonHeap;
|
||||
size_t argumentsData;
|
||||
size_t regExpStatics;
|
||||
size_t propertyIteratorData;
|
||||
@ -52,7 +54,9 @@ struct ObjectsExtraSizes
|
||||
|
||||
void add(ObjectsExtraSizes &sizes) {
|
||||
this->slots += sizes.slots;
|
||||
this->elements += sizes.elements;
|
||||
this->elementsNonAsmJS += sizes.elementsNonAsmJS;
|
||||
this->elementsAsmJSHeap += sizes.elementsAsmJSHeap;
|
||||
this->elementsAsmJSNonHeap += sizes.elementsAsmJSNonHeap;
|
||||
this->argumentsData += sizes.argumentsData;
|
||||
this->regExpStatics += sizes.regExpStatics;
|
||||
this->propertyIteratorData += sizes.propertyIteratorData;
|
||||
|
@ -414,10 +414,7 @@ CPPSRCS += ExecutableAllocatorOS2.cpp \
|
||||
$(NONE)
|
||||
endif
|
||||
|
||||
ifneq (,$(filter arm% sparc %86 x86_64 mips%,$(TARGET_CPU)))
|
||||
ENABLE_YARR_JIT = 1
|
||||
DEFINES += -DENABLE_YARR_JIT=1
|
||||
|
||||
ifneq (,$(ENABLE_METHODJIT)$(ENABLE_ION)$(ENABLE_YARR_JIT))
|
||||
VPATH += $(srcdir)/assembler/assembler \
|
||||
$(srcdir)/methodjit \
|
||||
$(NONE)
|
||||
@ -425,9 +422,12 @@ VPATH += $(srcdir)/assembler/assembler \
|
||||
CPPSRCS += ARMAssembler.cpp \
|
||||
MacroAssemblerARM.cpp \
|
||||
MacroAssemblerX86Common.cpp \
|
||||
YarrJIT.cpp \
|
||||
$(NONE)
|
||||
|
||||
ifdef ENABLE_YARR_JIT
|
||||
CPPSRCS += YarrJIT.cpp
|
||||
endif
|
||||
|
||||
ifeq (86, $(findstring 86,$(TARGET_CPU)))
|
||||
ifeq (x86_64, $(TARGET_CPU))
|
||||
#CPPSRCS += only_on_x86_64.cpp
|
||||
|
@ -79,13 +79,13 @@ ParallelArrayObject::initProps(JSContext *cx, HandleObject obj)
|
||||
RootedValue undef(cx, UndefinedValue());
|
||||
RootedValue zero(cx, Int32Value(0));
|
||||
|
||||
if (!JSObject::setProperty(cx, obj, obj, cx->names().buffer, &undef, true))
|
||||
if (!JSObject::defineProperty(cx, obj, cx->names().buffer, undef))
|
||||
return false;
|
||||
if (!JSObject::setProperty(cx, obj, obj, cx->names().offset, &zero, true))
|
||||
if (!JSObject::defineProperty(cx, obj, cx->names().offset, zero))
|
||||
return false;
|
||||
if (!JSObject::setProperty(cx, obj, obj, cx->names().shape, &undef, true))
|
||||
if (!JSObject::defineProperty(cx, obj, cx->names().shape, undef))
|
||||
return false;
|
||||
if (!JSObject::setProperty(cx, obj, obj, cx->names().get, &undef, true))
|
||||
if (!JSObject::defineProperty(cx, obj, cx->names().get, undef))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
@ -2079,6 +2079,7 @@ i?86-*)
|
||||
ENABLE_MONOIC=1
|
||||
ENABLE_POLYIC=1
|
||||
ENABLE_METHODJIT_TYPED_ARRAY=1
|
||||
ENABLE_YARR_JIT=1
|
||||
AC_DEFINE(JS_CPU_X86)
|
||||
AC_DEFINE(JS_NUNBOX32)
|
||||
;;
|
||||
@ -2088,6 +2089,7 @@ x86_64*-*)
|
||||
ENABLE_MONOIC=1
|
||||
ENABLE_POLYIC=1
|
||||
ENABLE_METHODJIT_TYPED_ARRAY=1
|
||||
ENABLE_YARR_JIT=1
|
||||
AC_DEFINE(JS_CPU_X64)
|
||||
AC_DEFINE(JS_PUNBOX64)
|
||||
;;
|
||||
@ -2097,6 +2099,7 @@ arm*-*)
|
||||
ENABLE_MONOIC=1
|
||||
ENABLE_POLYIC=1
|
||||
ENABLE_METHODJIT_TYPED_ARRAY=1
|
||||
ENABLE_YARR_JIT=1
|
||||
AC_DEFINE(JS_CPU_ARM)
|
||||
AC_DEFINE(JS_NUNBOX32)
|
||||
;;
|
||||
@ -2106,6 +2109,7 @@ sparc*-*)
|
||||
ENABLE_MONOIC=1
|
||||
ENABLE_POLYIC=1
|
||||
ENABLE_METHODJIT_TYPED_ARRAY=1
|
||||
ENABLE_YARR_JIT=1
|
||||
dnl ENABLE_ION=0
|
||||
AC_DEFINE(JS_CPU_SPARC)
|
||||
AC_DEFINE(JS_NUNBOX32)
|
||||
@ -2116,6 +2120,7 @@ mips*-*)
|
||||
ENABLE_MONOIC=1
|
||||
ENABLE_POLYIC=1
|
||||
ENABLE_METHODJIT_TYPED_ARRAY=1
|
||||
ENABLE_YARR_JIT=1
|
||||
AC_DEFINE(JS_CPU_MIPS)
|
||||
AC_DEFINE(JS_NUNBOX32)
|
||||
;;
|
||||
@ -2142,6 +2147,10 @@ MOZ_ARG_ENABLE_BOOL(methodjit-spew,
|
||||
ENABLE_METHODJIT_SPEW=1,
|
||||
ENABLE_METHODJIT_SPEW= )
|
||||
|
||||
MOZ_ARG_DISABLE_BOOL(yarr-jit,
|
||||
[ --disable-yarr-jit Disable YARR JIT support],
|
||||
ENABLE_YARR_JIT= )
|
||||
|
||||
AC_SUBST(ENABLE_METHODJIT)
|
||||
AC_SUBST(ENABLE_METHODJIT_SPEW)
|
||||
|
||||
@ -2169,6 +2178,12 @@ if test "$ENABLE_ION"; then
|
||||
AC_DEFINE(JS_ION)
|
||||
fi
|
||||
|
||||
AC_SUBST(ENABLE_YARR_JIT)
|
||||
|
||||
if test "$ENABLE_YARR_JIT"; then
|
||||
AC_DEFINE(ENABLE_YARR_JIT)
|
||||
fi
|
||||
|
||||
MOZ_COMPILER_OPTS
|
||||
if test -z "$SKIP_COMPILER_CHECKS"; then
|
||||
dnl Checks for typedefs, structures, and compiler characteristics.
|
||||
|
@ -46,7 +46,7 @@ ParseContext<ParseHandler>::ParseContext(Parser<ParseHandler> *prs, SharedContex
|
||||
decls_(prs->context),
|
||||
args_(prs->context),
|
||||
vars_(prs->context),
|
||||
yieldNode(ParseHandler::null()),
|
||||
yieldOffset(0),
|
||||
parserPC(&prs->pc),
|
||||
lexdeps(prs->context),
|
||||
parent(prs->pc),
|
||||
|
@ -332,12 +332,9 @@ ParseContext<ParseHandler>::generateFunctionBindings(JSContext *cx, InternalHand
|
||||
|
||||
template <typename ParseHandler>
|
||||
bool
|
||||
Parser<ParseHandler>::report(ParseReportKind kind, bool strict, Node pn, unsigned errorNumber, ...)
|
||||
Parser<ParseHandler>::reportHelper(ParseReportKind kind, bool strict, uint32_t offset,
|
||||
unsigned errorNumber, va_list args)
|
||||
{
|
||||
uint32_t offset = (pn ? handler.getPosition(pn) : tokenStream.currentToken().pos).begin;
|
||||
|
||||
va_list args;
|
||||
va_start(args, errorNumber);
|
||||
bool result = false;
|
||||
switch (kind) {
|
||||
case ParseError:
|
||||
@ -354,6 +351,30 @@ Parser<ParseHandler>::report(ParseReportKind kind, bool strict, Node pn, unsigne
|
||||
result = tokenStream.reportStrictModeErrorNumberVA(offset, strict, errorNumber, args);
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
bool
|
||||
Parser<ParseHandler>::report(ParseReportKind kind, bool strict, Node pn, unsigned errorNumber, ...)
|
||||
{
|
||||
uint32_t offset = (pn ? handler.getPosition(pn) : tokenStream.currentToken().pos).begin;
|
||||
|
||||
va_list args;
|
||||
va_start(args, errorNumber);
|
||||
bool result = reportHelper(kind, strict, offset, errorNumber, args);
|
||||
va_end(args);
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
bool
|
||||
Parser<ParseHandler>::reportWithOffset(ParseReportKind kind, bool strict, uint32_t offset,
|
||||
unsigned errorNumber, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, errorNumber);
|
||||
bool result = reportHelper(kind, strict, offset, errorNumber, args);
|
||||
va_end(args);
|
||||
return result;
|
||||
}
|
||||
@ -2882,7 +2903,7 @@ Parser<ParseHandler>::returnOrYield(bool useAssignExpr)
|
||||
pc->sc->asFunctionBox()->setIsGenerator();
|
||||
} else {
|
||||
pc->yieldCount++;
|
||||
pc->yieldNode = pn;
|
||||
pc->yieldOffset = handler.getPosition(pn).begin;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -5215,7 +5236,7 @@ class GenexpGuard
|
||||
ParseContext<ParseHandler> *pc = parser->pc;
|
||||
if (pc->parenDepth == 0) {
|
||||
pc->yieldCount = 0;
|
||||
pc->yieldNode = ParseHandler::null();
|
||||
pc->yieldOffset = 0;
|
||||
}
|
||||
startYieldCount = pc->yieldCount;
|
||||
pc->parenDepth++;
|
||||
@ -5246,10 +5267,12 @@ GenexpGuard<ParseHandler>::checkValidBody(Node pn, unsigned err)
|
||||
{
|
||||
ParseContext<ParseHandler> *pc = parser->pc;
|
||||
if (pc->yieldCount > startYieldCount) {
|
||||
Node errorNode = pc->yieldNode;
|
||||
if (!errorNode)
|
||||
errorNode = pn;
|
||||
parser->report(ParseError, false, errorNode, err, js_yield_str);
|
||||
uint32_t offset = pc->yieldOffset
|
||||
? pc->yieldOffset
|
||||
: (pn ? parser->handler.getPosition(pn)
|
||||
: parser->tokenStream.currentToken().pos).begin;
|
||||
|
||||
parser->reportWithOffset(ParseError, false, offset, err, js_yield_str);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -155,10 +155,10 @@ struct ParseContext /* tree context for semantic checks */
|
||||
bool generateFunctionBindings(JSContext *cx, InternalHandle<Bindings*> bindings) const;
|
||||
|
||||
public:
|
||||
Node yieldNode; /* parse node for a yield expression that might
|
||||
be an error if we turn out to be inside a
|
||||
generator expression */
|
||||
|
||||
uint32_t yieldOffset; /* offset of a yield expression that might
|
||||
be an error if we turn out to be inside
|
||||
a generator expression. Zero means
|
||||
there isn't one. */
|
||||
private:
|
||||
ParseContext **parserPC; /* this points to the Parser's active pc
|
||||
and holds either |this| or one of
|
||||
@ -296,7 +296,13 @@ struct Parser : private AutoGCRooter, public StrictModeGetter
|
||||
/* State specific to the kind of parse being performed. */
|
||||
ParseHandler handler;
|
||||
|
||||
private:
|
||||
bool reportHelper(ParseReportKind kind, bool strict, uint32_t offset,
|
||||
unsigned errorNumber, va_list args);
|
||||
public:
|
||||
bool report(ParseReportKind kind, bool strict, Node pn, unsigned errorNumber, ...);
|
||||
bool reportWithOffset(ParseReportKind kind, bool strict, uint32_t offset, unsigned errorNumber,
|
||||
...);
|
||||
|
||||
Parser(JSContext *cx, const CompileOptions &options,
|
||||
const jschar *chars, size_t length, bool foldConstants);
|
||||
|
@ -395,6 +395,46 @@ class StrictModeGetter {
|
||||
virtual bool strictMode() = 0;
|
||||
};
|
||||
|
||||
// TokenStream is the lexical scanner for Javascript source text.
|
||||
//
|
||||
// It takes a buffer of jschars and linearly scans it into |Token|s.
|
||||
// Internally the class uses a four element circular buffer |tokens| of
|
||||
// |Token|s. As an index for |tokens|, the member |cursor| points to the
|
||||
// current token.
|
||||
// Calls to getToken() increase |cursor| by one and return the new current
|
||||
// token. If a TokenStream was just created, the current token is initialized
|
||||
// with random data (i.e. not initialized). It is therefore important that
|
||||
// either of the first four member functions listed below is called first.
|
||||
// The circular buffer lets us go back up to two tokens from the last
|
||||
// scanned token. Internally, the relative number of backward steps that were
|
||||
// taken (via ungetToken()) after the last token was scanned is stored in
|
||||
// |lookahead|.
|
||||
//
|
||||
// The following table lists in which situations it is safe to call each listed
|
||||
// function. No checks are made by the functions in non-debug builds.
|
||||
//
|
||||
// Function Name | Precondition; changes to |lookahead|
|
||||
// ------------------+---------------------------------------------------------
|
||||
// getToken | none; if |lookahead > 0| then |lookahead--|
|
||||
// peekToken | none; none
|
||||
// peekTokenSameLine | none; none
|
||||
// matchToken | none; if |lookahead > 0| and the match succeeds then
|
||||
// | |lookahead--|
|
||||
// consumeKnownToken | none; if |lookahead > 0| then |lookahead--|
|
||||
// ungetToken | 0 <= |lookahead| <= |maxLookahead - 1|; |lookahead++|
|
||||
//
|
||||
// The behavior of the token scanning process (see getTokenInternal()) can be
|
||||
// modified by calling one of the first four above listed member functions with
|
||||
// an optional argument of type TokenStreamFlags. The two flags that do
|
||||
// influence the scanning process are TSF_OPERAND and TSF_KEYWORD_IS_NAME.
|
||||
// However, they will be ignored unless |lookahead == 0| holds.
|
||||
// Due to constraints of the grammar, this turns out not to be a problem in
|
||||
// practice. See the mozilla.dev.tech.js-engine.internals thread entitled 'Bug
|
||||
// in the scanner?' for more details (https://groups.google.com/forum/?
|
||||
// fromgroups=#!topic/mozilla.dev.tech.js-engine.internals/2JLH5jRcr7E).
|
||||
//
|
||||
// The methods seek() and tell() allow to rescan from a previous visited
|
||||
// location of the buffer.
|
||||
class TokenStream
|
||||
{
|
||||
/* Unicode separators that are treated as line terminators, in addition to \n, \r */
|
||||
@ -535,7 +575,7 @@ class TokenStream
|
||||
* Push the last scanned token back into the stream.
|
||||
*/
|
||||
void ungetToken() {
|
||||
JS_ASSERT(lookahead < ntokensMask);
|
||||
JS_ASSERT(lookahead < maxLookahead);
|
||||
lookahead++;
|
||||
cursor = (cursor - 1) & ntokensMask;
|
||||
}
|
||||
|
@ -255,7 +255,7 @@ class RelocatablePtr : public EncapsulatedPtr<T>
|
||||
if (v)
|
||||
post();
|
||||
}
|
||||
explicit RelocatablePtr(const RelocatablePtr<T> &v) : EncapsulatedPtr<T>(v) {
|
||||
RelocatablePtr(const RelocatablePtr<T> &v) : EncapsulatedPtr<T>(v) {
|
||||
if (this->value)
|
||||
post();
|
||||
}
|
||||
|
@ -99,3 +99,35 @@ function assertTypeFailInEval(str)
|
||||
assertTypeFailInEval('function f({}) { "use asm"; function g() {} return g }');
|
||||
assertTypeFailInEval('function f({global}) { "use asm"; function g() {} return g }');
|
||||
assertTypeFailInEval('function f(global, {imports}) { "use asm"; function g() {} return g }');
|
||||
|
||||
function assertLinkFailInEval(str)
|
||||
{
|
||||
if (!isAsmJSCompilationAvailable())
|
||||
return;
|
||||
|
||||
var caught = false;
|
||||
var oldOpts = options("werror");
|
||||
assertEq(oldOpts.indexOf("werror"), -1);
|
||||
try {
|
||||
eval(str);
|
||||
} catch (e) {
|
||||
assertEq((''+e).indexOf(ASM_OK_STRING) == -1, false);
|
||||
caught = true;
|
||||
}
|
||||
assertEq(caught, true);
|
||||
options("werror");
|
||||
|
||||
var code = eval(str);
|
||||
|
||||
var caught = false;
|
||||
var oldOpts = options("werror");
|
||||
assertEq(oldOpts.indexOf("werror"), -1);
|
||||
try {
|
||||
code.apply(null, Array.slice(arguments, 1));
|
||||
} catch (e) {
|
||||
caught = true;
|
||||
}
|
||||
assertEq(caught, true);
|
||||
options("werror");
|
||||
}
|
||||
assertLinkFailInEval('(function(global) { "use asm"; var im=global.Math.imul; function g() {} return g })');
|
||||
|
@ -1,4 +1,4 @@
|
||||
// |jit-test| error:InternalError
|
||||
// |jit-test| slow; error:InternalError
|
||||
|
||||
// Binary: cache/js-dbg-64-a2bbe9c999b4-linux
|
||||
// Flags: -m -n
|
||||
|
6
js/src/jit-test/tests/basic/bug854137.js
Normal file
6
js/src/jit-test/tests/basic/bug854137.js
Normal file
@ -0,0 +1,6 @@
|
||||
// Don't assert.
|
||||
try {
|
||||
eval("function x(y = {\
|
||||
x: (7) ? 0 : yield(0)\
|
||||
}");
|
||||
} catch (e) {}
|
@ -165,7 +165,7 @@ class JSFunction : public JSObject
|
||||
}
|
||||
|
||||
JSAtom *atom() const { return hasGuessedAtom() ? NULL : atom_.get(); }
|
||||
js::PropertyName *name() const { return hasGuessedAtom() ? NULL : atom_->asPropertyName(); }
|
||||
js::PropertyName *name() const { return hasGuessedAtom() || !atom_ ? NULL : atom_->asPropertyName(); }
|
||||
inline void initAtom(JSAtom *atom);
|
||||
JSAtom *displayAtom() const { return atom_; }
|
||||
|
||||
|
@ -5040,3 +5040,40 @@ js_DumpBacktrace(JSContext *cx)
|
||||
fprintf(stdout, "%s", sprinter.string());
|
||||
}
|
||||
|
||||
void
|
||||
JSObject::sizeOfExcludingThis(JSMallocSizeOfFun mallocSizeOf, JS::ObjectsExtraSizes *sizes)
|
||||
{
|
||||
if (hasDynamicSlots())
|
||||
sizes->slots = mallocSizeOf(slots);
|
||||
|
||||
if (hasDynamicElements()) {
|
||||
js::ObjectElements *elements = getElementsHeader();
|
||||
if (JS_UNLIKELY(elements->isAsmJSArrayBuffer())) {
|
||||
#if defined (JS_CPU_X64)
|
||||
// On x64, ArrayBufferObject::prepareForAsmJS switches the
|
||||
// ArrayBufferObject to use mmap'd storage.
|
||||
sizes->elementsAsmJSNonHeap = asArrayBuffer().byteLength();
|
||||
#else
|
||||
sizes->elementsAsmJSHeap = mallocSizeOf(elements);
|
||||
#endif
|
||||
} else {
|
||||
sizes->elementsNonAsmJS = mallocSizeOf(elements);
|
||||
}
|
||||
}
|
||||
|
||||
// Other things may be measured in the future if DMD indicates it is worthwhile.
|
||||
// Note that sizes->private_ is measured elsewhere.
|
||||
if (isArguments()) {
|
||||
sizes->argumentsData = asArguments().sizeOfMisc(mallocSizeOf);
|
||||
} else if (isRegExpStatics()) {
|
||||
sizes->regExpStatics = js::SizeOfRegExpStaticsData(this, mallocSizeOf);
|
||||
} else if (isPropertyIterator()) {
|
||||
sizes->propertyIteratorData = asPropertyIterator().sizeOfMisc(mallocSizeOf);
|
||||
#ifdef JS_HAS_CTYPES
|
||||
} else {
|
||||
// This must be the last case.
|
||||
sizes->ctypesData = js::SizeOfDataIfCDataObject(mallocSizeOf, const_cast<JSObject *>(this));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -370,7 +370,7 @@ class JSObject : public js::ObjectImpl
|
||||
|
||||
inline bool hasShapeTable() const;
|
||||
|
||||
inline void sizeOfExcludingThis(JSMallocSizeOfFun mallocSizeOf, JS::ObjectsExtraSizes *sizes);
|
||||
void sizeOfExcludingThis(JSMallocSizeOfFun mallocSizeOf, JS::ObjectsExtraSizes *sizes);
|
||||
|
||||
bool hasIdempotentProtoChain() const;
|
||||
|
||||
|
@ -235,6 +235,7 @@ JSObject::finalize(js::FreeOp *fop)
|
||||
js::Probes::finalizeObject(this);
|
||||
|
||||
#ifdef DEBUG
|
||||
JS_ASSERT(isTenured());
|
||||
if (!IsBackgroundFinalized(tenuredGetAllocKind())) {
|
||||
/* Assert we're on the main thread. */
|
||||
fop->runtime()->assertValidThread();
|
||||
@ -1076,42 +1077,6 @@ JSObject::hasShapeTable() const
|
||||
return lastProperty()->hasTable();
|
||||
}
|
||||
|
||||
inline void
|
||||
JSObject::sizeOfExcludingThis(JSMallocSizeOfFun mallocSizeOf, JS::ObjectsExtraSizes *sizes)
|
||||
{
|
||||
if (hasDynamicSlots())
|
||||
sizes->slots = mallocSizeOf(slots);
|
||||
|
||||
if (hasDynamicElements()) {
|
||||
js::ObjectElements *elements = getElementsHeader();
|
||||
#if defined (JS_CPU_X64)
|
||||
// On x64, ArrayBufferObject::prepareForAsmJS switches the
|
||||
// ArrayBufferObject to use mmap'd storage. This is not included in the
|
||||
// total 'explicit' figure and thus we must not include it here.
|
||||
// TODO: include it somewhere else.
|
||||
if (JS_LIKELY(!elements->isAsmJSArrayBuffer()))
|
||||
sizes->elements = mallocSizeOf(elements);
|
||||
#else
|
||||
sizes->elements = mallocSizeOf(elements);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Other things may be measured in the future if DMD indicates it is worthwhile.
|
||||
// Note that sizes->private_ is measured elsewhere.
|
||||
if (isArguments()) {
|
||||
sizes->argumentsData = asArguments().sizeOfMisc(mallocSizeOf);
|
||||
} else if (isRegExpStatics()) {
|
||||
sizes->regExpStatics = js::SizeOfRegExpStaticsData(this, mallocSizeOf);
|
||||
} else if (isPropertyIterator()) {
|
||||
sizes->propertyIteratorData = asPropertyIterator().sizeOfMisc(mallocSizeOf);
|
||||
#ifdef JS_HAS_CTYPES
|
||||
} else {
|
||||
// This must be the last case.
|
||||
sizes->ctypesData = js::SizeOfDataIfCDataObject(mallocSizeOf, const_cast<JSObject *>(this));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ inline JSBool
|
||||
JSObject::lookupGeneric(JSContext *cx, js::HandleObject obj, js::HandleId id,
|
||||
js::MutableHandleObject objp, js::MutableHandleShape propp)
|
||||
|
@ -2593,7 +2593,6 @@ template<typename T>
|
||||
JSBool
|
||||
ArrayBufferObject::createTypedArrayFromBuffer(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
typedef TypedArrayTemplate<T> ArrayType;
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
return CallNonGenericMethod<IsArrayBuffer, createTypedArrayFromBufferImpl<T> >(cx, args);
|
||||
}
|
||||
|
@ -1763,11 +1763,29 @@ ReportCompartmentStats(const JS::CompartmentStats &cStats,
|
||||
"stored on the JavaScript heap; those slots "
|
||||
"are not counted here, but in 'gc-heap/objects' instead.");
|
||||
|
||||
ZCREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("objects-extra/elements"),
|
||||
cStats.objectsExtra.elements,
|
||||
"Memory allocated for object element "
|
||||
"arrays, which are used to represent indexed object "
|
||||
"properties.");
|
||||
ZCREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("objects-extra/elements/non-asm.js"),
|
||||
cStats.objectsExtra.elementsNonAsmJS,
|
||||
"Memory allocated for non-asm.js object element arrays, "
|
||||
"which are used to represent indexed object properties.");
|
||||
|
||||
// asm.js arrays are heap-allocated on some platforms and
|
||||
// non-heap-allocated on others. We never put them under sundries,
|
||||
// because (a) in practice they're almost always larger than the sundries
|
||||
// threshold, and (b) we'd need a third category of non-heap, non-GC
|
||||
// sundries, which would be a pain.
|
||||
#define ASM_JS_DESC "Memory allocated for object element " \
|
||||
"arrays used as asm.js array buffers."
|
||||
size_t asmJSHeap = cStats.objectsExtra.elementsAsmJSHeap;
|
||||
size_t asmJSNonHeap = cStats.objectsExtra.elementsAsmJSNonHeap;
|
||||
JS_ASSERT(asmJSHeap == 0 || asmJSNonHeap == 0);
|
||||
if (asmJSHeap > 0) {
|
||||
REPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("objects-extra/elements/asm.js"),
|
||||
nsIMemoryReporter::KIND_HEAP, asmJSHeap, ASM_JS_DESC);
|
||||
}
|
||||
if (asmJSNonHeap > 0) {
|
||||
REPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("objects-extra/elements/asm.js"),
|
||||
nsIMemoryReporter::KIND_NONHEAP, asmJSNonHeap, ASM_JS_DESC);
|
||||
}
|
||||
|
||||
ZCREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("objects-extra/arguments-data"),
|
||||
cStats.objectsExtra.argumentsData,
|
||||
|
0
layout/base/crashtests/317934-1-inner.html
Executable file → Normal file
0
layout/base/crashtests/317934-1-inner.html
Executable file → Normal file
0
layout/forms/crashtests/317502-1.xhtml
Executable file → Normal file
0
layout/forms/crashtests/317502-1.xhtml
Executable file → Normal file
0
layout/generic/crashtests/289864-1.html
Executable file → Normal file
0
layout/generic/crashtests/289864-1.html
Executable file → Normal file
0
layout/generic/crashtests/289864-1.jpg
Executable file → Normal file
0
layout/generic/crashtests/289864-1.jpg
Executable file → Normal file
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 41 KiB |
0
layout/generic/crashtests/592118.html
Executable file → Normal file
0
layout/generic/crashtests/592118.html
Executable file → Normal file
@ -1105,8 +1105,23 @@ nsContainerFrame::ReflowOverflowContainerChildren(nsPresContext* aPres
|
||||
}
|
||||
}
|
||||
|
||||
if (!overflowContainers)
|
||||
// Our own excess overflow containers from a previous reflow can still be
|
||||
// present if our next-in-flow hasn't been reflown yet.
|
||||
nsFrameList* selfExcessOCFrames =
|
||||
RemovePropTableFrames(aPresContext, ExcessOverflowContainersProperty());
|
||||
if (selfExcessOCFrames) {
|
||||
if (overflowContainers) {
|
||||
overflowContainers->AppendFrames(nullptr, *selfExcessOCFrames);
|
||||
delete selfExcessOCFrames;
|
||||
} else {
|
||||
overflowContainers = selfExcessOCFrames;
|
||||
SetPropTableFrames(aPresContext, overflowContainers,
|
||||
OverflowContainersProperty());
|
||||
}
|
||||
}
|
||||
if (!overflowContainers) {
|
||||
return NS_OK; // nothing to reflow
|
||||
}
|
||||
|
||||
nsOverflowContinuationTracker tracker(aPresContext, this, false, false);
|
||||
bool shouldReflowAllKids = aReflowState.ShouldReflowAllKids();
|
||||
@ -1655,7 +1670,17 @@ nsOverflowContinuationTracker::Insert(nsIFrame* aOverflowCont,
|
||||
nsresult rv = NS_OK;
|
||||
bool reparented = false;
|
||||
nsPresContext* presContext = aOverflowCont->PresContext();
|
||||
const bool addToList = !mSentry || aOverflowCont != mSentry->GetNextInFlow();
|
||||
bool addToList = !mSentry || aOverflowCont != mSentry->GetNextInFlow();
|
||||
|
||||
// If we have a list and aOverflowCont is already in it then don't try to
|
||||
// add it again.
|
||||
if (addToList && aOverflowCont->GetParent() == mParent &&
|
||||
(aOverflowCont->GetStateBits() & NS_FRAME_IS_OVERFLOW_CONTAINER) &&
|
||||
mOverflowContList && mOverflowContList->ContainsFrame(aOverflowCont)) {
|
||||
addToList = false;
|
||||
mPrevOverflowCont = aOverflowCont->GetPrevSibling();
|
||||
}
|
||||
|
||||
if (addToList) {
|
||||
if (aOverflowCont->GetStateBits() & NS_FRAME_IS_OVERFLOW_CONTAINER) {
|
||||
// aOverflowCont is in some other overflow container list,
|
||||
@ -1682,6 +1707,27 @@ nsOverflowContinuationTracker::Insert(nsIFrame* aOverflowCont,
|
||||
mParent);
|
||||
reparented = true;
|
||||
}
|
||||
|
||||
// If aOverflowCont has a prev/next-in-flow that might be in
|
||||
// mOverflowContList we need to find it and insert after/before it to
|
||||
// maintain the order amongst next-in-flows in this list.
|
||||
nsIFrame* pif = aOverflowCont->GetPrevInFlow();
|
||||
nsIFrame* nif = aOverflowCont->GetNextInFlow();
|
||||
if ((pif && pif->GetParent() == mParent && pif != mPrevOverflowCont) ||
|
||||
(nif && nif->GetParent() == mParent && mPrevOverflowCont)) {
|
||||
for (nsFrameList::Enumerator e(*mOverflowContList); !e.AtEnd(); e.Next()) {
|
||||
nsIFrame* f = e.get();
|
||||
if (f == pif) {
|
||||
mPrevOverflowCont = pif;
|
||||
break;
|
||||
}
|
||||
if (f == nif) {
|
||||
mPrevOverflowCont = f->GetPrevSibling();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mOverflowContList->InsertFrame(mParent, mPrevOverflowCont, aOverflowCont);
|
||||
aReflowStatus |= NS_FRAME_REFLOW_NEXTINFLOW;
|
||||
}
|
||||
|
0
layout/generic/test/file_bug514732_window.xul
Executable file → Normal file
0
layout/generic/test/file_bug514732_window.xul
Executable file → Normal file
@ -16,6 +16,7 @@ PARALLEL_DIRS += [
|
||||
'mathml',
|
||||
'inspector/public',
|
||||
'inspector/src',
|
||||
'tools/recording',
|
||||
]
|
||||
|
||||
if CONFIG['NS_PRINTING']:
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user