Merge the last PGO-green inbound changeset to m-c.

This commit is contained in:
Ryan VanderMeulen 2013-03-26 10:07:44 -04:00
commit ac1756efef
199 changed files with 7043 additions and 4672 deletions

View File

@ -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));
},

View File

@ -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>

View File

@ -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);
});
});
});
}

View File

@ -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) {

View File

@ -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);
}

View File

@ -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

View 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]);

View File

@ -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;
}

View File

@ -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;
}
};

View File

@ -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);

View File

@ -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);
}

View File

@ -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) {

View File

@ -1,4 +1,5 @@
chrome.manifest
components/PdfRedirector.js
components/PdfStreamConverter.js
content/build/pdf.js
content/PdfJs.jsm

View File

@ -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) {}
},

View File

@ -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) {

View File

@ -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);
}

View File

@ -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.])

View File

@ -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.
*/

View File

@ -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.

View File

@ -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 &&

View File

@ -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

View File

@ -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();
}
}

View File

@ -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,

View File

@ -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)
{

View File

@ -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;

View File

@ -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);

View File

@ -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;
}

View File

@ -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();
}

View File

@ -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.

View File

@ -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.
*/

View 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

View 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

View File

@ -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
{

View File

@ -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();

View File

@ -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 \

View File

@ -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)

View File

@ -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
{

View File

@ -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();

View File

@ -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);
}
}

View File

@ -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();

View File

@ -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");

View File

@ -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();
}
//----------------------------

View File

@ -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();

View File

@ -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

View File

@ -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();
}

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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>

View File

@ -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();
});

View File

@ -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);
}
}
}

View File

@ -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,

View File

@ -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();
}
},

View File

@ -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();
}
}

View File

@ -456,6 +456,12 @@ DOMInterfaces = {
]
},
'HTMLTemplateElement': {
'resultNotAddRefed': [
'content'
]
},
'HTMLTextAreaElement': {
'resultNotAddRefed': [
'form', 'controllers', 'editor'

View File

@ -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

View File

@ -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!");

View File

@ -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;
}

View File

@ -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',

View File

@ -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>

View File

@ -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")

View File

@ -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")

View File

@ -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

View 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>

View 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;
};

View File

@ -125,6 +125,7 @@ webidl_files = \
HTMLTableElement.webidl \
HTMLTableRowElement.webidl \
HTMLTableSectionElement.webidl \
HTMLTemplateElement.webidl \
HTMLTextAreaElement.webidl \
HTMLTimeElement.webidl \
HTMLTitleElement.webidl \

View File

@ -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),

View File

@ -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.

View File

@ -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,

View 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);

View File

@ -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);
}

View File

@ -53,4 +53,5 @@ Includes = (
'nsTArray.h',
'nsIFile.h',
'mozilla/ipc/ProtocolUtils.h',
'GeckoProfiler.h'
)

View File

@ -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():

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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.

View File

@ -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),

View File

@ -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;
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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();
}

View File

@ -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 })');

View File

@ -1,4 +1,4 @@
// |jit-test| error:InternalError
// |jit-test| slow; error:InternalError
// Binary: cache/js-dbg-64-a2bbe9c999b4-linux
// Flags: -m -n

View File

@ -0,0 +1,6 @@
// Don't assert.
try {
eval("function x(y = {\
x: (7) ? 0 : yield(0)\
}");
} catch (e) {}

View File

@ -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_; }

View File

@ -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
}
}

View File

@ -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;

View File

@ -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)

View File

@ -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);
}

View File

@ -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
View File

0
layout/forms/crashtests/317502-1.xhtml Executable file → Normal file
View File

0
layout/generic/crashtests/289864-1.html Executable file → Normal file
View File

0
layout/generic/crashtests/289864-1.jpg Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 41 KiB

0
layout/generic/crashtests/592118.html Executable file → Normal file
View File

View 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
View File

View 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