mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-08 12:37:37 +00:00
Merge m-c to b2g-inbound.
This commit is contained in:
commit
135bcf29f9
1
.hgtags
1
.hgtags
@ -105,3 +105,4 @@ ba2cc1eda988a1614d8986ae145d28e1268409b9 FIREFOX_AURORA_29_BASE-m
|
||||
0000000000000000000000000000000000000000 FIREFOX_AURORA_29_BASE-m
|
||||
ba2cc1eda988a1614d8986ae145d28e1268409b9 FIREFOX_AURORA_29_BASE
|
||||
9f12a9fab080f2d363d7424e25b9ffe85ebc3414 FIREFOX_AURORA_28_BASE
|
||||
83c9853e136451474dfa6d1aaa60a7fca7d2d83a FIREFOX_AURORA_30_BASE
|
||||
|
@ -44,9 +44,10 @@ let developerHUD = {
|
||||
|
||||
/**
|
||||
* This method registers a metric watcher that will watch one or more metrics
|
||||
* of apps that are being tracked. A watcher must implement the trackApp(app)
|
||||
* and untrackApp(app) methods, add entries to the app.metrics map, keep them
|
||||
* up-to-date, and call app.display() when values were changed.
|
||||
* on app frames that are being tracked. A watcher must implement the
|
||||
* `trackTarget(target)` and `untrackTarget(target)` methods, register
|
||||
* observed metrics with `target.register(metric)`, and keep them up-to-date
|
||||
* with `target.update(metric, value, message)` when necessary.
|
||||
*/
|
||||
registerWatcher: function dwp_registerWatcher(watcher) {
|
||||
this._watchers.unshift(watcher);
|
||||
@ -87,7 +88,7 @@ let developerHUD = {
|
||||
});
|
||||
});
|
||||
|
||||
SettingsListener.observe('hud.logging', enabled => {
|
||||
SettingsListener.observe('hud.logging', this._logging, enabled => {
|
||||
this._logging = enabled;
|
||||
});
|
||||
},
|
||||
@ -194,9 +195,9 @@ let developerHUD = {
|
||||
|
||||
|
||||
/**
|
||||
* An App object represents all there is to know about a Firefox OS app that is
|
||||
* being tracked, e.g. its manifest information, current values of watched
|
||||
* metrics, and how to update these values on the front-end.
|
||||
* A Target object represents all there is to know about a Firefox OS app frame
|
||||
* that is being tracked, e.g. a pointer to the frame, current values of watched
|
||||
* metrics, and how to notify the front-end when metrics have changed.
|
||||
*/
|
||||
function Target(frame, actor) {
|
||||
this.frame = frame;
|
||||
@ -276,17 +277,27 @@ Target.prototype = {
|
||||
|
||||
/**
|
||||
* The Console Watcher tracks the following metrics in apps: reflows, warnings,
|
||||
* and errors.
|
||||
* and errors, with security errors reported separately.
|
||||
*/
|
||||
let consoleWatcher = {
|
||||
|
||||
_client: null,
|
||||
_targets: new Map(),
|
||||
_watching: {
|
||||
reflows: false,
|
||||
warnings: false,
|
||||
errors: false
|
||||
errors: false,
|
||||
security: false
|
||||
},
|
||||
_client: null,
|
||||
_security: [
|
||||
'Mixed Content Blocker',
|
||||
'Mixed Content Message',
|
||||
'CSP',
|
||||
'Invalid HSTS Headers',
|
||||
'Insecure Password Field',
|
||||
'SSL',
|
||||
'CORS'
|
||||
],
|
||||
|
||||
init: function cw_init(client) {
|
||||
this._client = client;
|
||||
@ -296,7 +307,7 @@ let consoleWatcher = {
|
||||
|
||||
for (let key in watching) {
|
||||
let metric = key;
|
||||
SettingsListener.observe('hud.' + metric, false, watch => {
|
||||
SettingsListener.observe('hud.' + metric, watching[metric], watch => {
|
||||
// Watch or unwatch the metric.
|
||||
if (watching[metric] = watch) {
|
||||
return;
|
||||
@ -319,6 +330,7 @@ let consoleWatcher = {
|
||||
target.register('reflows');
|
||||
target.register('warnings');
|
||||
target.register('errors');
|
||||
target.register('security');
|
||||
|
||||
this._client.request({
|
||||
to: target.actor.consoleActor,
|
||||
@ -357,13 +369,17 @@ let consoleWatcher = {
|
||||
output += 'error (';
|
||||
}
|
||||
|
||||
if (this._security.indexOf(pageError.category) > -1) {
|
||||
metric = 'security';
|
||||
}
|
||||
|
||||
let {errorMessage, sourceName, category, lineNumber, columnNumber} = pageError;
|
||||
output += category + '): "' + (errorMessage.initial || errorMessage) +
|
||||
'" in ' + sourceName + ':' + lineNumber + ':' + columnNumber;
|
||||
break;
|
||||
|
||||
case 'consoleAPICall':
|
||||
switch (packet.output.level) {
|
||||
switch (packet.message.level) {
|
||||
|
||||
case 'error':
|
||||
metric = 'errors';
|
||||
|
@ -5,7 +5,7 @@
|
||||
MOZ_APP_BASENAME=B2G
|
||||
MOZ_APP_VENDOR=Mozilla
|
||||
|
||||
MOZ_APP_VERSION=30.0a1
|
||||
MOZ_APP_VERSION=31.0a1
|
||||
MOZ_APP_UA_NAME=Firefox
|
||||
|
||||
MOZ_UA_OS_AGNOSTIC=1
|
||||
|
@ -1 +1 @@
|
||||
30.0a1
|
||||
31.0a1
|
||||
|
@ -7,8 +7,9 @@
|
||||
"use strict";
|
||||
|
||||
// Used to detect minification for automatic pretty printing
|
||||
const SAMPLE_SIZE = 30; // no of lines
|
||||
const INDENT_COUNT_THRESHOLD = 20; // percentage
|
||||
const SAMPLE_SIZE = 50; // no of lines
|
||||
const INDENT_COUNT_THRESHOLD = 5; // percentage
|
||||
const CHARACTER_LIMIT = 250; // line character limit
|
||||
|
||||
/**
|
||||
* Functions handling the sources UI.
|
||||
@ -1500,6 +1501,7 @@ let SourceUtils = {
|
||||
let lineStartIndex = 0;
|
||||
let lines = 0;
|
||||
let indentCount = 0;
|
||||
let overCharLimit = false;
|
||||
|
||||
// Strip comments.
|
||||
aText = aText.replace(/\/\*[\S\s]*?\*\/|\/\/(.+|\n)/g, "");
|
||||
@ -1512,9 +1514,15 @@ let SourceUtils = {
|
||||
if (/^\s+/.test(aText.slice(lineStartIndex, lineEndIndex))) {
|
||||
indentCount++;
|
||||
}
|
||||
// For files with no indents but are not minified.
|
||||
if ((lineEndIndex - lineStartIndex) > CHARACTER_LIMIT) {
|
||||
overCharLimit = true;
|
||||
break;
|
||||
}
|
||||
lineStartIndex = lineEndIndex + 1;
|
||||
}
|
||||
isMinified = ((indentCount / lines ) * 100) < INDENT_COUNT_THRESHOLD;
|
||||
isMinified = ((indentCount / lines ) * 100) < INDENT_COUNT_THRESHOLD ||
|
||||
overCharLimit;
|
||||
|
||||
this._minifiedCache.set(sourceClient, isMinified);
|
||||
return isMinified;
|
||||
|
@ -1,4 +1,4 @@
|
||||
This is the pdf.js project output, https://github.com/mozilla/pdf.js
|
||||
|
||||
Current extension version is: 0.8.1114
|
||||
Current extension version is: 0.8.1181
|
||||
|
||||
|
@ -61,6 +61,27 @@ function getIntPref(aPref, aDefaultValue) {
|
||||
}
|
||||
}
|
||||
|
||||
function initializeDefaultPreferences() {
|
||||
Cu.import('resource://pdf.js/default_preferences.js');
|
||||
|
||||
var defaultBranch = Services.prefs.getDefaultBranch(PREF_PREFIX + '.');
|
||||
var defaultValue;
|
||||
for (var key in DEFAULT_PREFERENCES) {
|
||||
defaultValue = DEFAULT_PREFERENCES[key];
|
||||
switch (typeof defaultValue) {
|
||||
case 'boolean':
|
||||
defaultBranch.setBoolPref(key, defaultValue);
|
||||
break;
|
||||
case 'number':
|
||||
defaultBranch.setIntPref(key, defaultValue);
|
||||
break;
|
||||
case 'string':
|
||||
defaultBranch.setCharPref(key, defaultValue);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Register/unregister a constructor as a factory.
|
||||
function Factory() {}
|
||||
Factory.prototype = {
|
||||
@ -104,6 +125,8 @@ let PdfJs = {
|
||||
Services.obs.addObserver(this, TOPIC_PDFJS_HANDLER_CHANGED, false);
|
||||
Services.obs.addObserver(this, TOPIC_PLUGINS_LIST_UPDATED, false);
|
||||
Services.obs.addObserver(this, TOPIC_PLUGIN_INFO_UPDATED, false);
|
||||
|
||||
initializeDefaultPreferences();
|
||||
},
|
||||
|
||||
_migrate: function migrate() {
|
||||
|
@ -16,7 +16,7 @@
|
||||
*/
|
||||
/* jshint esnext:true */
|
||||
/* globals Components, Services, XPCOMUtils, NetUtil, PrivateBrowsingUtils,
|
||||
dump, NetworkManager, PdfJsTelemetry, DEFAULT_PREFERENCES */
|
||||
dump, NetworkManager, PdfJsTelemetry */
|
||||
|
||||
'use strict';
|
||||
|
||||
@ -33,16 +33,14 @@ const PDF_CONTENT_TYPE = 'application/pdf';
|
||||
const PREF_PREFIX = 'pdfjs';
|
||||
const PDF_VIEWER_WEB_PAGE = 'resource://pdf.js/web/viewer.html';
|
||||
const MAX_DATABASE_LENGTH = 4096;
|
||||
const MAX_STRING_PREF_LENGTH = 4096;
|
||||
const MAX_NUMBER_OF_PREFS = 50;
|
||||
const MAX_STRING_PREF_LENGTH = 128;
|
||||
|
||||
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
|
||||
Cu.import('resource://gre/modules/Services.jsm');
|
||||
Cu.import('resource://gre/modules/NetUtil.jsm');
|
||||
Cu.import('resource://pdf.js/network.js');
|
||||
|
||||
// Load the default preferences.
|
||||
Cu.import('resource://pdf.js/default_preferences.js');
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, 'PrivateBrowsingUtils',
|
||||
'resource://gre/modules/PrivateBrowsingUtils.jsm');
|
||||
|
||||
@ -453,56 +451,60 @@ ChromeActions.prototype = {
|
||||
.updateControlState(result, findPrevious);
|
||||
},
|
||||
setPreferences: function(prefs) {
|
||||
var prefValue, defaultValue, prefName, prefType, defaultType;
|
||||
|
||||
for (var key in DEFAULT_PREFERENCES) {
|
||||
var defaultBranch = Services.prefs.getDefaultBranch(PREF_PREFIX + '.');
|
||||
var numberOfPrefs = 0;
|
||||
var prefValue, prefName;
|
||||
for (var key in prefs) {
|
||||
if (++numberOfPrefs > MAX_NUMBER_OF_PREFS) {
|
||||
log('setPreferences - Exceeded the maximum number of preferences ' +
|
||||
'that is allowed to be set at once.');
|
||||
break;
|
||||
} else if (!defaultBranch.getPrefType(key)) {
|
||||
continue;
|
||||
}
|
||||
prefValue = prefs[key];
|
||||
defaultValue = DEFAULT_PREFERENCES[key];
|
||||
prefName = (PREF_PREFIX + '.' + key);
|
||||
|
||||
if (prefValue === undefined || prefValue === defaultValue) {
|
||||
Services.prefs.clearUserPref(prefName);
|
||||
} else {
|
||||
prefType = typeof prefValue;
|
||||
defaultType = typeof defaultValue;
|
||||
|
||||
if (prefType !== defaultType) {
|
||||
continue;
|
||||
}
|
||||
switch (defaultType) {
|
||||
case 'boolean':
|
||||
setBoolPref(prefName, prefValue);
|
||||
break;
|
||||
case 'number':
|
||||
setIntPref(prefName, prefValue);
|
||||
break;
|
||||
case 'string':
|
||||
// Protect against adding arbitrarily long strings in about:config.
|
||||
if (prefValue.length <= MAX_STRING_PREF_LENGTH) {
|
||||
setStringPref(prefName, prefValue);
|
||||
}
|
||||
break;
|
||||
}
|
||||
switch (typeof prefValue) {
|
||||
case 'boolean':
|
||||
setBoolPref(prefName, prefValue);
|
||||
break;
|
||||
case 'number':
|
||||
setIntPref(prefName, prefValue);
|
||||
break;
|
||||
case 'string':
|
||||
if (prefValue.length > MAX_STRING_PREF_LENGTH) {
|
||||
log('setPreferences - Exceeded the maximum allowed length ' +
|
||||
'for a string preference.');
|
||||
} else {
|
||||
setStringPref(prefName, prefValue);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
getPreferences: function() {
|
||||
var currentPrefs = {};
|
||||
var defaultValue, prefName;
|
||||
|
||||
for (var key in DEFAULT_PREFERENCES) {
|
||||
defaultValue = DEFAULT_PREFERENCES[key];
|
||||
getPreferences: function(prefs) {
|
||||
var defaultBranch = Services.prefs.getDefaultBranch(PREF_PREFIX + '.');
|
||||
var currentPrefs = {}, numberOfPrefs = 0;
|
||||
var prefValue, prefName;
|
||||
for (var key in prefs) {
|
||||
if (++numberOfPrefs > MAX_NUMBER_OF_PREFS) {
|
||||
log('getPreferences - Exceeded the maximum number of preferences ' +
|
||||
'that is allowed to be fetched at once.');
|
||||
break;
|
||||
} else if (!defaultBranch.getPrefType(key)) {
|
||||
continue;
|
||||
}
|
||||
prefValue = prefs[key];
|
||||
prefName = (PREF_PREFIX + '.' + key);
|
||||
|
||||
switch (typeof defaultValue) {
|
||||
switch (typeof prefValue) {
|
||||
case 'boolean':
|
||||
currentPrefs[key] = getBoolPref(prefName, defaultValue);
|
||||
currentPrefs[key] = getBoolPref(prefName, prefValue);
|
||||
break;
|
||||
case 'number':
|
||||
currentPrefs[key] = getIntPref(prefName, defaultValue);
|
||||
currentPrefs[key] = getIntPref(prefName, prefValue);
|
||||
break;
|
||||
case 'string':
|
||||
currentPrefs[key] = getStringPref(prefName, defaultValue);
|
||||
currentPrefs[key] = getStringPref(prefName, prefValue);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
1824
browser/extensions/pdfjs/content/build/pdf.worker.js
vendored
1824
browser/extensions/pdfjs/content/build/pdf.worker.js
vendored
File diff suppressed because it is too large
Load Diff
@ -46,13 +46,17 @@ var FontInspector = (function FontInspectorClosure() {
|
||||
}
|
||||
}
|
||||
function textLayerClick(e) {
|
||||
if (!e.target.dataset.fontName || e.target.tagName.toUpperCase() !== 'DIV')
|
||||
if (!e.target.dataset.fontName ||
|
||||
e.target.tagName.toUpperCase() !== 'DIV') {
|
||||
return;
|
||||
}
|
||||
var fontName = e.target.dataset.fontName;
|
||||
var selects = document.getElementsByTagName('input');
|
||||
for (var i = 0; i < selects.length; ++i) {
|
||||
var select = selects[i];
|
||||
if (select.dataset.fontName != fontName) continue;
|
||||
if (select.dataset.fontName != fontName) {
|
||||
continue;
|
||||
}
|
||||
select.checked = !select.checked;
|
||||
selectFont(fontName, select.checked);
|
||||
select.scrollIntoView();
|
||||
@ -140,8 +144,9 @@ var FontInspector = (function FontInspectorClosure() {
|
||||
// Somewhat of a hack, should probably add a hook for when the text layer
|
||||
// is done rendering.
|
||||
setTimeout(function() {
|
||||
if (this.active)
|
||||
if (this.active) {
|
||||
resetSelection();
|
||||
}
|
||||
}.bind(this), 2000);
|
||||
}
|
||||
};
|
||||
@ -172,8 +177,9 @@ var StepperManager = (function StepperManagerClosure() {
|
||||
stepperDiv = document.createElement('div');
|
||||
this.panel.appendChild(stepperControls);
|
||||
this.panel.appendChild(stepperDiv);
|
||||
if (sessionStorage.getItem('pdfjsBreakPoints'))
|
||||
if (sessionStorage.getItem('pdfjsBreakPoints')) {
|
||||
breakPoints = JSON.parse(sessionStorage.getItem('pdfjsBreakPoints'));
|
||||
}
|
||||
},
|
||||
enabled: false,
|
||||
active: false,
|
||||
@ -191,19 +197,22 @@ var StepperManager = (function StepperManagerClosure() {
|
||||
var initBreakPoints = breakPoints[pageIndex] || [];
|
||||
var stepper = new Stepper(debug, pageIndex, initBreakPoints);
|
||||
steppers.push(stepper);
|
||||
if (steppers.length === 1)
|
||||
if (steppers.length === 1) {
|
||||
this.selectStepper(pageIndex, false);
|
||||
}
|
||||
return stepper;
|
||||
},
|
||||
selectStepper: function selectStepper(pageIndex, selectPanel) {
|
||||
if (selectPanel)
|
||||
if (selectPanel) {
|
||||
this.manager.selectPanel(1);
|
||||
}
|
||||
for (var i = 0; i < steppers.length; ++i) {
|
||||
var stepper = steppers[i];
|
||||
if (stepper.pageIndex == pageIndex)
|
||||
if (stepper.pageIndex == pageIndex) {
|
||||
stepper.panel.removeAttribute('hidden');
|
||||
else
|
||||
} else {
|
||||
stepper.panel.setAttribute('hidden', true);
|
||||
}
|
||||
}
|
||||
var options = stepperChooser.options;
|
||||
for (var i = 0; i < options.length; ++i) {
|
||||
@ -223,8 +232,9 @@ var Stepper = (function StepperClosure() {
|
||||
// Shorter way to create element and optionally set textContent.
|
||||
function c(tag, textContent) {
|
||||
var d = document.createElement(tag);
|
||||
if (textContent)
|
||||
if (textContent) {
|
||||
d.textContent = textContent;
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
@ -297,10 +307,11 @@ var Stepper = (function StepperClosure() {
|
||||
cbox.checked = checked;
|
||||
cbox.onclick = (function(x) {
|
||||
return function() {
|
||||
if (this.checked)
|
||||
if (this.checked) {
|
||||
self.breakPoints.push(x);
|
||||
else
|
||||
} else {
|
||||
self.breakPoints.splice(self.breakPoints.indexOf(x), 1);
|
||||
}
|
||||
StepperManager.saveBreakPoints(self.pageIndex, self.breakPoints);
|
||||
};
|
||||
})(i);
|
||||
@ -336,8 +347,9 @@ var Stepper = (function StepperClosure() {
|
||||
getNextBreakPoint: function getNextBreakPoint() {
|
||||
this.breakPoints.sort(function(a, b) { return a - b; });
|
||||
for (var i = 0; i < this.breakPoints.length; i++) {
|
||||
if (this.breakPoints[i] > this.currentIdx)
|
||||
if (this.breakPoints[i] > this.currentIdx) {
|
||||
return this.breakPoints[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
@ -385,13 +397,16 @@ var Stepper = (function StepperClosure() {
|
||||
var Stats = (function Stats() {
|
||||
var stats = [];
|
||||
function clear(node) {
|
||||
while (node.hasChildNodes())
|
||||
while (node.hasChildNodes()) {
|
||||
node.removeChild(node.lastChild);
|
||||
}
|
||||
}
|
||||
function getStatIndex(pageNumber) {
|
||||
for (var i = 0, ii = stats.length; i < ii; ++i)
|
||||
if (stats[i].pageNumber === pageNumber)
|
||||
for (var i = 0, ii = stats.length; i < ii; ++i) {
|
||||
if (stats[i].pageNumber === pageNumber) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return {
|
||||
@ -408,8 +423,9 @@ var Stats = (function Stats() {
|
||||
active: false,
|
||||
// Stats specific functions.
|
||||
add: function(pageNumber, stat) {
|
||||
if (!stat)
|
||||
if (!stat) {
|
||||
return;
|
||||
}
|
||||
var statsIndex = getStatIndex(pageNumber);
|
||||
if (statsIndex !== false) {
|
||||
var b = stats[statsIndex];
|
||||
@ -428,8 +444,9 @@ var Stats = (function Stats() {
|
||||
stats.push({ pageNumber: pageNumber, div: wrapper });
|
||||
stats.sort(function(a, b) { return a.pageNumber - b.pageNumber; });
|
||||
clear(this.panel);
|
||||
for (var i = 0, ii = stats.length; i < ii; ++i)
|
||||
for (var i = 0, ii = stats.length; i < ii; ++i) {
|
||||
this.panel.appendChild(stats[i].div);
|
||||
}
|
||||
}
|
||||
};
|
||||
})();
|
||||
@ -448,12 +465,14 @@ var PDFBug = (function PDFBugClosure() {
|
||||
],
|
||||
enable: function(ids) {
|
||||
var all = false, tools = this.tools;
|
||||
if (ids.length === 1 && ids[0] === 'all')
|
||||
if (ids.length === 1 && ids[0] === 'all') {
|
||||
all = true;
|
||||
}
|
||||
for (var i = 0; i < tools.length; ++i) {
|
||||
var tool = tools[i];
|
||||
if (all || ids.indexOf(tool.id) !== -1)
|
||||
if (all || ids.indexOf(tool.id) !== -1) {
|
||||
tool.enabled = true;
|
||||
}
|
||||
}
|
||||
if (!all) {
|
||||
// Sort the tools by the order they are enabled.
|
||||
@ -509,19 +528,21 @@ var PDFBug = (function PDFBugClosure() {
|
||||
panels.appendChild(panel);
|
||||
tool.panel = panel;
|
||||
tool.manager = this;
|
||||
if (tool.enabled)
|
||||
if (tool.enabled) {
|
||||
tool.init();
|
||||
else
|
||||
} else {
|
||||
panel.textContent = tool.name + ' is disabled. To enable add ' +
|
||||
' "' + tool.id + '" to the pdfBug parameter ' +
|
||||
'and refresh (seperate multiple by commas).';
|
||||
}
|
||||
buttons.push(panelButton);
|
||||
}
|
||||
this.selectPanel(0);
|
||||
},
|
||||
selectPanel: function selectPanel(index) {
|
||||
if (index === activePanel)
|
||||
if (index === activePanel) {
|
||||
return;
|
||||
}
|
||||
activePanel = index;
|
||||
var tools = this.tools;
|
||||
for (var j = 0; j < tools.length; ++j) {
|
||||
|
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="40"
|
||||
height="40"
|
||||
viewBox="0 0 40 40">
|
||||
</svg>
|
After Width: | Height: | Size: 158 B |
@ -1157,14 +1157,7 @@ canvas {
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.page > a,
|
||||
.annotationLayer > a {
|
||||
display: block;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.page > a:hover,
|
||||
.annotationLayer > a:hover {
|
||||
.annotLink > a:hover {
|
||||
opacity: 0.2;
|
||||
background: #ff0;
|
||||
box-shadow: 0px 2px 10px #ff0;
|
||||
@ -1229,29 +1222,49 @@ canvas {
|
||||
::selection { background:rgba(0,0,255,0.3); }
|
||||
::-moz-selection { background:rgba(0,0,255,0.3); }
|
||||
|
||||
.annotText > div {
|
||||
z-index: 200;
|
||||
.annotationHighlight {
|
||||
position: absolute;
|
||||
padding: 0.6em;
|
||||
max-width: 20em;
|
||||
background-color: #FFFF99;
|
||||
box-shadow: 0px 2px 10px #333;
|
||||
border-radius: 7px;
|
||||
border: 2px #FFFF99 solid;
|
||||
}
|
||||
|
||||
.annotText > img {
|
||||
position: absolute;
|
||||
opacity: 0.6;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.annotText > img:hover {
|
||||
opacity: 1;
|
||||
.annotTextContentWrapper {
|
||||
position: absolute;
|
||||
width: 20em;
|
||||
}
|
||||
|
||||
.annotText > div > h1 {
|
||||
font-size: 1.2em;
|
||||
.annotTextContent {
|
||||
z-index: 200;
|
||||
float: left;
|
||||
max-width: 20em;
|
||||
background-color: #FFFF99;
|
||||
box-shadow: 0px 2px 5px #333;
|
||||
border-radius: 2px;
|
||||
padding: 0.6em;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.annotTextContent > h1 {
|
||||
font-size: 1em;
|
||||
border-bottom: 1px solid #000000;
|
||||
margin: 0px;
|
||||
padding-bottom: 0.2em;
|
||||
}
|
||||
|
||||
.annotTextContent > p {
|
||||
padding-top: 0.2em;
|
||||
}
|
||||
|
||||
.annotLink > a {
|
||||
position: absolute;
|
||||
font-size: 1em;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#errorWrapper {
|
||||
|
@ -68,10 +68,9 @@ var CustomStyle = (function CustomStyleClosure() {
|
||||
// in some versions of IE9 it is critical that ms appear in this list
|
||||
// before Moz
|
||||
var prefixes = ['ms', 'Moz', 'Webkit', 'O'];
|
||||
var _cache = { };
|
||||
var _cache = {};
|
||||
|
||||
function CustomStyle() {
|
||||
}
|
||||
function CustomStyle() {}
|
||||
|
||||
CustomStyle.getProp = function get(propName, element) {
|
||||
// check cache only when no element is given
|
||||
@ -104,8 +103,9 @@ var CustomStyle = (function CustomStyleClosure() {
|
||||
|
||||
CustomStyle.setProp = function set(propName, element, str) {
|
||||
var prop = this.getProp(propName);
|
||||
if (prop != 'undefined')
|
||||
if (prop != 'undefined') {
|
||||
element.style[prop] = str;
|
||||
}
|
||||
};
|
||||
|
||||
return CustomStyle;
|
||||
@ -291,11 +291,13 @@ var Cache = function cacheCache(size) {
|
||||
var data = [];
|
||||
this.push = function cachePush(view) {
|
||||
var i = data.indexOf(view);
|
||||
if (i >= 0)
|
||||
if (i >= 0) {
|
||||
data.splice(i);
|
||||
}
|
||||
data.push(view);
|
||||
if (data.length > size)
|
||||
if (data.length > size) {
|
||||
data.shift().destroy();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
@ -315,12 +317,13 @@ var Preferences = (function PreferencesClosure() {
|
||||
function Preferences() {
|
||||
this.prefs = {};
|
||||
this.isInitializedPromiseResolved = false;
|
||||
this.initializedPromise = this.readFromStorage().then(function(prefObj) {
|
||||
this.isInitializedPromiseResolved = true;
|
||||
if (prefObj) {
|
||||
this.prefs = prefObj;
|
||||
}
|
||||
}.bind(this));
|
||||
this.initializedPromise = this.readFromStorage(DEFAULT_PREFERENCES).then(
|
||||
function(prefObj) {
|
||||
this.isInitializedPromiseResolved = true;
|
||||
if (prefObj) {
|
||||
this.prefs = prefObj;
|
||||
}
|
||||
}.bind(this));
|
||||
}
|
||||
|
||||
Preferences.prototype = {
|
||||
@ -328,7 +331,7 @@ var Preferences = (function PreferencesClosure() {
|
||||
return;
|
||||
},
|
||||
|
||||
readFromStorage: function Preferences_readFromStorage() {
|
||||
readFromStorage: function Preferences_readFromStorage(prefObj) {
|
||||
var readFromStoragePromise = Promise.resolve();
|
||||
return readFromStoragePromise;
|
||||
},
|
||||
@ -336,7 +339,7 @@ var Preferences = (function PreferencesClosure() {
|
||||
reset: function Preferences_reset() {
|
||||
if (this.isInitializedPromiseResolved) {
|
||||
this.prefs = {};
|
||||
this.writeToStorage(this.prefs);
|
||||
this.writeToStorage(DEFAULT_PREFERENCES);
|
||||
}
|
||||
},
|
||||
|
||||
@ -361,6 +364,12 @@ var Preferences = (function PreferencesClosure() {
|
||||
valueType + '\", expected a \"' + defaultType + '\".');
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (valueType === 'number' && (value | 0) !== value) {
|
||||
console.error('Preferences_set: \'' + value +
|
||||
'\' must be an \"integer\".');
|
||||
return;
|
||||
}
|
||||
}
|
||||
this.prefs[name] = value;
|
||||
this.writeToStorage(this.prefs);
|
||||
@ -427,8 +436,8 @@ var FirefoxCom = (function FirefoxComClosure() {
|
||||
var request = document.createTextNode('');
|
||||
if (callback) {
|
||||
document.addEventListener('pdf.js.response', function listener(event) {
|
||||
var node = event.target,
|
||||
response = event.detail.response;
|
||||
var node = event.target;
|
||||
var response = event.detail.response;
|
||||
|
||||
document.documentElement.removeChild(node);
|
||||
|
||||
@ -483,9 +492,10 @@ Preferences.prototype.writeToStorage = function(prefObj) {
|
||||
FirefoxCom.requestSync('setPreferences', prefObj);
|
||||
};
|
||||
|
||||
Preferences.prototype.readFromStorage = function() {
|
||||
Preferences.prototype.readFromStorage = function(prefObj) {
|
||||
var readFromStoragePromise = new Promise(function (resolve) {
|
||||
var readPrefs = JSON.parse(FirefoxCom.requestSync('getPreferences'));
|
||||
var readPrefs = JSON.parse(FirefoxCom.requestSync('getPreferences',
|
||||
prefObj));
|
||||
resolve(readPrefs);
|
||||
});
|
||||
return readFromStoragePromise;
|
||||
@ -576,8 +586,6 @@ var ViewHistory = (function ViewHistoryClosure() {
|
||||
})();
|
||||
|
||||
|
||||
/* globals PDFFindController, FindStates, mozL10n */
|
||||
|
||||
/**
|
||||
* Creates a "search bar" given set of DOM elements
|
||||
* that act as controls for searching, or for setting
|
||||
@ -586,7 +594,6 @@ var ViewHistory = (function ViewHistoryClosure() {
|
||||
* searching is done by PDFFindController
|
||||
*/
|
||||
var PDFFindBar = {
|
||||
|
||||
opened: false,
|
||||
bar: null,
|
||||
toggleButton: null,
|
||||
@ -600,7 +607,7 @@ var PDFFindBar = {
|
||||
|
||||
initialize: function(options) {
|
||||
if(typeof PDFFindController === 'undefined' || PDFFindController === null) {
|
||||
throw 'PDFFindBar cannot be initialized ' +
|
||||
throw 'PDFFindBar cannot be initialized ' +
|
||||
'without a PDFFindController instance.';
|
||||
}
|
||||
|
||||
@ -715,8 +722,9 @@ var PDFFindBar = {
|
||||
},
|
||||
|
||||
close: function() {
|
||||
if (!this.opened) return;
|
||||
|
||||
if (!this.opened) {
|
||||
return;
|
||||
}
|
||||
this.opened = false;
|
||||
this.toggleButton.classList.remove('toggled');
|
||||
this.bar.classList.add('hidden');
|
||||
@ -735,8 +743,6 @@ var PDFFindBar = {
|
||||
|
||||
|
||||
|
||||
/* globals PDFFindBar, PDFJS, FindStates, FirefoxCom, Promise */
|
||||
|
||||
/**
|
||||
* Provides a "search" or "find" functionality for the PDF.
|
||||
* This object actually performs the search for a given string.
|
||||
@ -876,8 +882,9 @@ var PDFFindController = {
|
||||
self.pageContents.push(str);
|
||||
|
||||
extractTextPromisesResolves[pageIndex](pageIndex);
|
||||
if ((pageIndex + 1) < self.pdfPageSource.pages.length)
|
||||
if ((pageIndex + 1) < self.pdfPageSource.pages.length) {
|
||||
extractPageText(pageIndex + 1);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
@ -2432,10 +2439,11 @@ var PDFView = {
|
||||
viewAreaElement.addEventListener('scroll', function webViewerScroll(evt) {
|
||||
var currentY = viewAreaElement.scrollTop;
|
||||
var lastY = state.lastY;
|
||||
if (currentY > lastY)
|
||||
if (currentY > lastY) {
|
||||
state.down = true;
|
||||
else if (currentY < lastY)
|
||||
} else if (currentY < lastY) {
|
||||
state.down = false;
|
||||
}
|
||||
// else do nothing and use previous value
|
||||
state.lastY = currentY;
|
||||
callback();
|
||||
@ -2688,8 +2696,9 @@ var PDFView = {
|
||||
}
|
||||
var args = e.data;
|
||||
|
||||
if (typeof args !== 'object' || !('pdfjsLoadAction' in args))
|
||||
if (typeof args !== 'object' || !('pdfjsLoadAction' in args)) {
|
||||
return;
|
||||
}
|
||||
switch (args.pdfjsLoadAction) {
|
||||
case 'supportsRangedLoading':
|
||||
PDFView.open(args.pdfUrl, 0, undefined, pdfDataRangeTransport, {
|
||||
@ -2884,8 +2893,9 @@ var PDFView = {
|
||||
},
|
||||
|
||||
getDestinationHash: function pdfViewGetDestinationHash(dest) {
|
||||
if (typeof dest === 'string')
|
||||
if (typeof dest === 'string') {
|
||||
return PDFView.getAnchorUrl('#' + escape(dest));
|
||||
}
|
||||
if (dest instanceof Array) {
|
||||
var destRef = dest[0]; // see navigateTo method for dest format
|
||||
var pageNumber = destRef instanceof Object ?
|
||||
@ -3003,15 +3013,18 @@ var PDFView = {
|
||||
var thumbsView = document.getElementById('thumbnailView');
|
||||
thumbsView.parentNode.scrollTop = 0;
|
||||
|
||||
while (thumbsView.hasChildNodes())
|
||||
while (thumbsView.hasChildNodes()) {
|
||||
thumbsView.removeChild(thumbsView.lastChild);
|
||||
}
|
||||
|
||||
if ('_loadingInterval' in thumbsView)
|
||||
if ('_loadingInterval' in thumbsView) {
|
||||
clearInterval(thumbsView._loadingInterval);
|
||||
}
|
||||
|
||||
var container = document.getElementById('viewer');
|
||||
while (container.hasChildNodes())
|
||||
while (container.hasChildNodes()) {
|
||||
container.removeChild(container.lastChild);
|
||||
}
|
||||
|
||||
var pagesCount = pdfDocument.numPages;
|
||||
|
||||
@ -3178,16 +3191,17 @@ var PDFView = {
|
||||
(PDFJS.version ? ' (PDF.js: ' + PDFJS.version + ')' : ''));
|
||||
|
||||
var pdfTitle;
|
||||
if (metadata) {
|
||||
if (metadata.has('dc:title'))
|
||||
pdfTitle = metadata.get('dc:title');
|
||||
if (metadata && metadata.has('dc:title')) {
|
||||
pdfTitle = metadata.get('dc:title');
|
||||
}
|
||||
|
||||
if (!pdfTitle && info && info['Title'])
|
||||
if (!pdfTitle && info && info['Title']) {
|
||||
pdfTitle = info['Title'];
|
||||
}
|
||||
|
||||
if (pdfTitle)
|
||||
if (pdfTitle) {
|
||||
self.setTitle(pdfTitle + ' - ' + document.title);
|
||||
}
|
||||
|
||||
if (info.IsAcroFormPresent) {
|
||||
console.warn('Warning: AcroForm/XFA is not supported');
|
||||
@ -3313,21 +3327,24 @@ var PDFView = {
|
||||
}
|
||||
for (var i = 0; i < numVisible; ++i) {
|
||||
var view = visibleViews[i].view;
|
||||
if (!this.isViewFinished(view))
|
||||
if (!this.isViewFinished(view)) {
|
||||
return view;
|
||||
}
|
||||
}
|
||||
|
||||
// All the visible views have rendered, try to render next/previous pages.
|
||||
if (scrolledDown) {
|
||||
var nextPageIndex = visible.last.id;
|
||||
// ID's start at 1 so no need to add 1.
|
||||
if (views[nextPageIndex] && !this.isViewFinished(views[nextPageIndex]))
|
||||
if (views[nextPageIndex] && !this.isViewFinished(views[nextPageIndex])) {
|
||||
return views[nextPageIndex];
|
||||
}
|
||||
} else {
|
||||
var previousPageIndex = visible.first.id - 2;
|
||||
if (views[previousPageIndex] &&
|
||||
!this.isViewFinished(views[previousPageIndex]))
|
||||
!this.isViewFinished(views[previousPageIndex])) {
|
||||
return views[previousPageIndex];
|
||||
}
|
||||
}
|
||||
// Everything that needs to be rendered has been.
|
||||
return false;
|
||||
@ -3360,8 +3377,9 @@ var PDFView = {
|
||||
},
|
||||
|
||||
setHash: function pdfViewSetHash(hash) {
|
||||
if (!hash)
|
||||
if (!hash) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (hash.indexOf('=') >= 0) {
|
||||
var params = PDFView.parseQueryString(hash);
|
||||
@ -3449,8 +3467,9 @@ var PDFView = {
|
||||
thumbsView.classList.add('hidden');
|
||||
outlineView.classList.remove('hidden');
|
||||
|
||||
if (outlineButton.getAttribute('disabled'))
|
||||
if (outlineButton.getAttribute('disabled')) {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
},
|
||||
@ -3567,8 +3586,9 @@ var PDFView = {
|
||||
|
||||
afterPrint: function pdfViewSetupAfterPrint() {
|
||||
var div = document.getElementById('printContainer');
|
||||
while (div.hasChildNodes())
|
||||
while (div.hasChildNodes()) {
|
||||
div.removeChild(div.lastChild);
|
||||
}
|
||||
},
|
||||
|
||||
rotatePages: function pdfViewRotatePages(delta) {
|
||||
@ -3610,14 +3630,16 @@ var PDFView = {
|
||||
// In case one page has already been flipped there is a cooldown time
|
||||
// which has to expire before next page can be scrolled on to.
|
||||
if (currentTime > storedTime &&
|
||||
currentTime - storedTime < MOUSE_SCROLL_COOLDOWN_TIME)
|
||||
currentTime - storedTime < MOUSE_SCROLL_COOLDOWN_TIME) {
|
||||
return;
|
||||
}
|
||||
|
||||
// In case the user decides to scroll to the opposite direction than before
|
||||
// clear the accumulated delta.
|
||||
if ((this.mouseScrollDelta > 0 && mouseScrollDelta < 0) ||
|
||||
(this.mouseScrollDelta < 0 && mouseScrollDelta > 0))
|
||||
(this.mouseScrollDelta < 0 && mouseScrollDelta > 0)) {
|
||||
this.clearMouseScrollState();
|
||||
}
|
||||
|
||||
this.mouseScrollDelta += mouseScrollDelta;
|
||||
|
||||
@ -3640,8 +3662,9 @@ var PDFView = {
|
||||
// to do anything.
|
||||
if ((currentPage == 1 && pageFlipDirection == PageFlipDirection.UP) ||
|
||||
(currentPage == this.pages.length &&
|
||||
pageFlipDirection == PageFlipDirection.DOWN))
|
||||
pageFlipDirection == PageFlipDirection.DOWN)) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.page += pageFlipDirection;
|
||||
this.mouseScrollTimeStamp = currentTime;
|
||||
@ -3946,10 +3969,13 @@ var PageView = function pageView(container, id, scale,
|
||||
CustomStyle.setProp('transformOrigin', element, transformOriginStr);
|
||||
|
||||
if (data.subtype === 'Link' && !data.url) {
|
||||
if (data.action) {
|
||||
bindNamedAction(element, data.action);
|
||||
} else {
|
||||
bindLink(element, ('dest' in data) ? data.dest : null);
|
||||
var link = element.getElementsByTagName('a')[0];
|
||||
if (link) {
|
||||
if (data.action) {
|
||||
bindNamedAction(link, data.action);
|
||||
} else {
|
||||
bindLink(link, ('dest' in data) ? data.dest : null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -4215,6 +4241,7 @@ var PageView = function pageView(container, id, scale,
|
||||
canvasContext: ctx,
|
||||
viewport: this.viewport,
|
||||
textLayer: textLayer,
|
||||
// intent: 'default', // === 'display'
|
||||
continueCallback: function pdfViewcContinueCallback(cont) {
|
||||
if (PDFView.highestPriorityPage !== 'page' + self.id) {
|
||||
self.renderingState = RenderingStates.PAUSED;
|
||||
@ -4286,13 +4313,13 @@ var PageView = function pageView(container, id, scale,
|
||||
|
||||
var renderContext = {
|
||||
canvasContext: ctx,
|
||||
viewport: viewport
|
||||
viewport: viewport,
|
||||
intent: 'print'
|
||||
};
|
||||
|
||||
pdfPage.render(renderContext).promise.then(function() {
|
||||
// Tell the printEngine that rendering this canvas/page has finished.
|
||||
obj.done();
|
||||
self.pdfPage.destroy();
|
||||
}, function(error) {
|
||||
console.error(error);
|
||||
// Tell the printEngine that rendering this canvas/page has failed.
|
||||
@ -4302,7 +4329,6 @@ var PageView = function pageView(container, id, scale,
|
||||
} else {
|
||||
obj.done();
|
||||
}
|
||||
self.pdfPage.destroy();
|
||||
});
|
||||
};
|
||||
};
|
||||
@ -4522,12 +4548,12 @@ var TextLayerBuilder = function textLayerBuilder(options) {
|
||||
this.viewport = options.viewport;
|
||||
this.isViewerInPresentationMode = options.isViewerInPresentationMode;
|
||||
|
||||
if(typeof PDFFindController === 'undefined') {
|
||||
window.PDFFindController = null;
|
||||
if (typeof PDFFindController === 'undefined') {
|
||||
window.PDFFindController = null;
|
||||
}
|
||||
|
||||
if(typeof this.lastScrollSource === 'undefined') {
|
||||
this.lastScrollSource = null;
|
||||
if (typeof this.lastScrollSource === 'undefined') {
|
||||
this.lastScrollSource = null;
|
||||
}
|
||||
|
||||
this.beginLayout = function textLayerBuilderBeginLayout() {
|
||||
@ -4548,8 +4574,9 @@ var TextLayerBuilder = function textLayerBuilder(options) {
|
||||
// No point in rendering so many divs as it'd make the browser unusable
|
||||
// even after the divs are rendered
|
||||
var MAX_TEXT_DIVS_TO_RENDER = 100000;
|
||||
if (textDivs.length > MAX_TEXT_DIVS_TO_RENDER)
|
||||
if (textDivs.length > MAX_TEXT_DIVS_TO_RENDER) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (var i = 0, ii = textDivs.length; i < ii; i++) {
|
||||
var textDiv = textDivs[i];
|
||||
@ -4581,16 +4608,17 @@ var TextLayerBuilder = function textLayerBuilder(options) {
|
||||
// run it right away
|
||||
var RENDER_DELAY = 200; // in ms
|
||||
var self = this;
|
||||
var lastScroll = this.lastScrollSource === null ?
|
||||
0 : this.lastScrollSource.lastScroll;
|
||||
var lastScroll = (this.lastScrollSource === null ?
|
||||
0 : this.lastScrollSource.lastScroll);
|
||||
|
||||
if (Date.now() - lastScroll > RENDER_DELAY) {
|
||||
// Render right away
|
||||
this.renderLayer();
|
||||
} else {
|
||||
// Schedule
|
||||
if (this.renderTimer)
|
||||
if (this.renderTimer) {
|
||||
clearTimeout(this.renderTimer);
|
||||
}
|
||||
this.renderTimer = setTimeout(function() {
|
||||
self.setupRenderLayoutTimer();
|
||||
}, RENDER_DELAY);
|
||||
@ -4608,8 +4636,8 @@ var TextLayerBuilder = function textLayerBuilder(options) {
|
||||
|
||||
textDiv.style.fontSize = fontHeight + 'px';
|
||||
textDiv.style.fontFamily = geom.fontFamily;
|
||||
var fontAscent = geom.ascent ? geom.ascent * fontHeight :
|
||||
geom.descent ? (1 + geom.descent) * fontHeight : fontHeight;
|
||||
var fontAscent = (geom.ascent ? geom.ascent * fontHeight :
|
||||
(geom.descent ? (1 + geom.descent) * fontHeight : fontHeight));
|
||||
textDiv.style.left = (geom.x + (fontAscent * Math.sin(geom.angle))) + 'px';
|
||||
textDiv.style.top = (geom.y - (fontAscent * Math.cos(geom.angle))) + 'px';
|
||||
|
||||
@ -4621,8 +4649,9 @@ var TextLayerBuilder = function textLayerBuilder(options) {
|
||||
this.insertDivContent = function textLayerUpdateTextContent() {
|
||||
// Only set the content of the divs once layout has finished, the content
|
||||
// for the divs is available and content is not yet set on the divs.
|
||||
if (!this.layoutDone || this.divContentDone || !this.textContent)
|
||||
if (!this.layoutDone || this.divContentDone || !this.textContent) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.divContentDone = true;
|
||||
|
||||
@ -4661,8 +4690,8 @@ var TextLayerBuilder = function textLayerBuilder(options) {
|
||||
var iIndex = 0;
|
||||
var bidiTexts = this.textContent;
|
||||
var end = bidiTexts.length - 1;
|
||||
var queryLen = PDFFindController === null ?
|
||||
0 : PDFFindController.state.query.length;
|
||||
var queryLen = (PDFFindController === null ?
|
||||
0 : PDFFindController.state.query.length);
|
||||
|
||||
var lastDivIdx = -1;
|
||||
var pos;
|
||||
@ -4721,14 +4750,14 @@ var TextLayerBuilder = function textLayerBuilder(options) {
|
||||
var bidiTexts = this.textContent;
|
||||
var textDivs = this.textDivs;
|
||||
var prevEnd = null;
|
||||
var isSelectedPage = PDFFindController === null ?
|
||||
false : (this.pageIdx === PDFFindController.selected.pageIdx);
|
||||
var isSelectedPage = (PDFFindController === null ?
|
||||
false : (this.pageIdx === PDFFindController.selected.pageIdx));
|
||||
|
||||
var selectedMatchIdx = PDFFindController === null ?
|
||||
-1 : PDFFindController.selected.matchIdx;
|
||||
var selectedMatchIdx = (PDFFindController === null ?
|
||||
-1 : PDFFindController.selected.matchIdx);
|
||||
|
||||
var highlightAll = PDFFindController === null ?
|
||||
false : PDFFindController.state.highlightAll;
|
||||
var highlightAll = (PDFFindController === null ?
|
||||
false : PDFFindController.state.highlightAll);
|
||||
|
||||
var infty = {
|
||||
divIdx: -1,
|
||||
@ -4827,8 +4856,9 @@ var TextLayerBuilder = function textLayerBuilder(options) {
|
||||
|
||||
this.updateMatches = function textLayerUpdateMatches() {
|
||||
// Only show matches, once all rendering is done.
|
||||
if (!this.renderingDone)
|
||||
if (!this.renderingDone) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Clear out all matches.
|
||||
var matches = this.matches;
|
||||
@ -4848,14 +4878,14 @@ var TextLayerBuilder = function textLayerBuilder(options) {
|
||||
clearedUntilDivIdx = match.end.divIdx + 1;
|
||||
}
|
||||
|
||||
if (PDFFindController === null || !PDFFindController.active)
|
||||
if (PDFFindController === null || !PDFFindController.active) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Convert the matches on the page controller into the match format used
|
||||
// for the textLayer.
|
||||
this.matches = matches =
|
||||
this.convertMatches(PDFFindController === null ?
|
||||
[] : (PDFFindController.pageMatches[this.pageIdx] || []));
|
||||
this.matches = matches = (this.convertMatches(PDFFindController === null ?
|
||||
[] : (PDFFindController.pageMatches[this.pageIdx] || [])));
|
||||
|
||||
this.renderMatches(this.matches);
|
||||
};
|
||||
@ -4866,13 +4896,14 @@ var TextLayerBuilder = function textLayerBuilder(options) {
|
||||
var DocumentOutlineView = function documentOutlineView(outline) {
|
||||
var outlineView = document.getElementById('outlineView');
|
||||
var outlineButton = document.getElementById('viewOutline');
|
||||
while (outlineView.firstChild)
|
||||
while (outlineView.firstChild) {
|
||||
outlineView.removeChild(outlineView.firstChild);
|
||||
}
|
||||
|
||||
if (!outline) {
|
||||
if (!outlineView.classList.contains('hidden'))
|
||||
if (!outlineView.classList.contains('hidden')) {
|
||||
PDFView.switchSidebarView('thumbs');
|
||||
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -5101,8 +5132,9 @@ document.addEventListener('DOMContentLoaded', webViewerLoad, true);
|
||||
|
||||
function updateViewarea() {
|
||||
|
||||
if (!PDFView.initialized)
|
||||
if (!PDFView.initialized) {
|
||||
return;
|
||||
}
|
||||
var visible = PDFView.getVisiblePages();
|
||||
var visiblePages = visible.views;
|
||||
if (visiblePages.length === 0) {
|
||||
@ -5118,9 +5150,9 @@ function updateViewarea() {
|
||||
i < ii; ++i) {
|
||||
var page = visiblePages[i];
|
||||
|
||||
if (page.percent < 100)
|
||||
if (page.percent < 100) {
|
||||
break;
|
||||
|
||||
}
|
||||
if (page.id === PDFView.page) {
|
||||
stillFullyVisible = true;
|
||||
break;
|
||||
@ -5473,23 +5505,6 @@ window.addEventListener('keydown', function keydown(evt) {
|
||||
PDFView.rotatePages(90);
|
||||
break;
|
||||
}
|
||||
if (!handled && !PresentationMode.active) {
|
||||
// 33=Page Up 34=Page Down 35=End 36=Home
|
||||
// 37=Left 38=Up 39=Right 40=Down
|
||||
if (evt.keyCode >= 33 && evt.keyCode <= 40 &&
|
||||
!PDFView.container.contains(curElement)) {
|
||||
// The page container is not focused, but a page navigation key has been
|
||||
// pressed. Change the focus to the viewer container to make sure that
|
||||
// navigation by keyboard works as expected.
|
||||
PDFView.container.focus();
|
||||
}
|
||||
// 32=Spacebar
|
||||
if (evt.keyCode === 32 && curElementTagName !== 'BUTTON') {
|
||||
// Workaround for issue in Firefox, that prevents scroll keys from working
|
||||
// when elements with 'tabindex' are focused. (#3499)
|
||||
PDFView.container.blur();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cmd === 4) { // shift-key
|
||||
@ -5509,6 +5524,24 @@ window.addEventListener('keydown', function keydown(evt) {
|
||||
}
|
||||
}
|
||||
|
||||
if (!handled && !PresentationMode.active) {
|
||||
// 33=Page Up 34=Page Down 35=End 36=Home
|
||||
// 37=Left 38=Up 39=Right 40=Down
|
||||
if (evt.keyCode >= 33 && evt.keyCode <= 40 &&
|
||||
!PDFView.container.contains(curElement)) {
|
||||
// The page container is not focused, but a page navigation key has been
|
||||
// pressed. Change the focus to the viewer container to make sure that
|
||||
// navigation by keyboard works as expected.
|
||||
PDFView.container.focus();
|
||||
}
|
||||
// 32=Spacebar
|
||||
if (evt.keyCode === 32 && curElementTagName !== 'BUTTON') {
|
||||
// Workaround for issue in Firefox, that prevents scroll keys from
|
||||
// working when elements with 'tabindex' are focused. (#3498)
|
||||
PDFView.container.blur();
|
||||
}
|
||||
}
|
||||
|
||||
if (cmd === 2) { // alt-key
|
||||
switch (evt.keyCode) {
|
||||
case 37: // left arrow
|
||||
|
@ -44,8 +44,12 @@ endif
|
||||
# by GDB when we debug executables there.
|
||||
# NOTE: Keep .gdbinit in the topsrcdir for people who run gdb from the topsrcdir.
|
||||
GDBINIT_FILES := $(topsrcdir)/.gdbinit
|
||||
GDBINIT_OBJDIR_FILES = $(topsrcdir)/.gdbinit
|
||||
GDBINIT_DEST = $(FINAL_TARGET)
|
||||
INSTALL_TARGETS += GDBINIT
|
||||
|
||||
# needs to be absolute to be distinct from $(topsrcdir)/.gdbinit
|
||||
GDBINIT_OBJDIR_DEST = $(abspath $(DEPTH))
|
||||
INSTALL_TARGETS += GDBINIT GDBINIT_OBJDIR
|
||||
|
||||
# Put a .lldbinit in the bin directory and the objdir, to be picked up
|
||||
# automatically by LLDB when we debug executables using either of those two
|
||||
|
@ -10,4 +10,4 @@
|
||||
# hardcoded milestones in the tree from these two files.
|
||||
#--------------------------------------------------------
|
||||
|
||||
30.0a1
|
||||
31.0a1
|
||||
|
11
configure.in
11
configure.in
@ -7888,7 +7888,13 @@ dnl ========================================================
|
||||
dnl Check for pixman and cairo
|
||||
dnl ========================================================
|
||||
|
||||
MOZ_TREE_CAIRO=1
|
||||
if test "$MOZ_WIDGET_TOOLKIT" = "gtk3" ; then
|
||||
# cairo-gtk3 can be build with system-cairo only
|
||||
MOZ_TREE_CAIRO=
|
||||
else
|
||||
MOZ_TREE_CAIRO=1
|
||||
fi
|
||||
|
||||
MOZ_ARG_ENABLE_BOOL(system-cairo,
|
||||
[ --enable-system-cairo Use system cairo (located with pkgconfig)],
|
||||
MOZ_TREE_CAIRO=,
|
||||
@ -7978,6 +7984,9 @@ if test "$MOZ_TREE_CAIRO"; then
|
||||
MOZ_CHECK_HEADER(d3d10.h, MOZ_ENABLE_D3D10_LAYER=1)
|
||||
fi
|
||||
;;
|
||||
gtk3)
|
||||
AC_MSG_ERROR([cairo-gtk3 toolkit is incompatible with in-tree cairo. Please add --enable-system-cairo to your build config.])
|
||||
;;
|
||||
esac
|
||||
if test "$USE_FC_FREETYPE"; then
|
||||
FC_FONT_FEATURE="#define CAIRO_HAS_FC_FONT 1"
|
||||
|
@ -4,9 +4,11 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "WebGLBuffer.h"
|
||||
#include "WebGLContext.h"
|
||||
|
||||
#include "GLContext.h"
|
||||
#include "mozilla/dom/WebGLRenderingContextBinding.h"
|
||||
#include "WebGLContext.h"
|
||||
#include "WebGLElementArrayCache.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
@ -55,6 +57,22 @@ WebGLBuffer::ElementArrayCacheBufferSubData(size_t pos, const void* ptr, size_t
|
||||
mCache->BufferSubData(pos, ptr, update_size_in_bytes);
|
||||
}
|
||||
|
||||
size_t
|
||||
WebGLBuffer::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
|
||||
{
|
||||
size_t sizeOfCache = mCache ? mCache->SizeOfIncludingThis(aMallocSizeOf) : 0;
|
||||
return aMallocSizeOf(this) + sizeOfCache;
|
||||
}
|
||||
|
||||
bool
|
||||
WebGLBuffer::Validate(GLenum type, uint32_t max_allowed,
|
||||
size_t first, size_t count,
|
||||
uint32_t* out_upperBound)
|
||||
{
|
||||
return mCache->Validate(type, max_allowed, first, count, out_upperBound);
|
||||
}
|
||||
|
||||
|
||||
JSObject*
|
||||
WebGLBuffer::WrapObject(JSContext *cx, JS::Handle<JSObject*> scope) {
|
||||
return dom::WebGLBufferBinding::Wrap(cx, scope, this);
|
||||
|
@ -6,14 +6,12 @@
|
||||
#ifndef WEBGLBUFFER_H_
|
||||
#define WEBGLBUFFER_H_
|
||||
|
||||
#include "WebGLObjectModel.h"
|
||||
#include "WebGLElementArrayCache.h"
|
||||
#include "GLDefs.h"
|
||||
|
||||
#include "nsWrapperCache.h"
|
||||
|
||||
#include "mozilla/LinkedList.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "nsWrapperCache.h"
|
||||
#include "WebGLObjectModel.h"
|
||||
#include "WebGLTypes.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
@ -32,10 +30,7 @@ public:
|
||||
|
||||
void Delete();
|
||||
|
||||
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const {
|
||||
size_t sizeOfCache = mCache ? mCache->SizeOfIncludingThis(aMallocSizeOf) : 0;
|
||||
return aMallocSizeOf(this) + sizeOfCache;
|
||||
}
|
||||
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
|
||||
|
||||
bool HasEverBeenBound() { return mHasEverBeenBound; }
|
||||
void SetHasEverBeenBound(bool x) { mHasEverBeenBound = x; }
|
||||
@ -51,9 +46,8 @@ public:
|
||||
|
||||
void ElementArrayCacheBufferSubData(size_t pos, const void* ptr, size_t update_size_in_bytes);
|
||||
|
||||
bool Validate(GLenum type, uint32_t max_allowed, size_t first, size_t count) {
|
||||
return mCache->Validate(type, max_allowed, first, count);
|
||||
}
|
||||
bool Validate(GLenum type, uint32_t max_allowed, size_t first, size_t count,
|
||||
uint32_t* out_upperBound);
|
||||
|
||||
WebGLContext *GetParentObject() const {
|
||||
return Context();
|
||||
|
@ -787,7 +787,8 @@ private:
|
||||
|
||||
bool DrawArrays_check(GLint first, GLsizei count, GLsizei primcount, const char* info);
|
||||
bool DrawElements_check(GLsizei count, GLenum type, WebGLintptr byteOffset,
|
||||
GLsizei primcount, const char* info);
|
||||
GLsizei primcount, const char* info,
|
||||
GLuint* out_upperBound = nullptr);
|
||||
bool DrawInstanced_check(const char* info);
|
||||
void Draw_cleanup();
|
||||
|
||||
|
@ -4,16 +4,18 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "WebGLContext.h"
|
||||
#include "WebGLBuffer.h"
|
||||
#include "WebGLVertexAttribData.h"
|
||||
#include "WebGLVertexArray.h"
|
||||
#include "WebGLTexture.h"
|
||||
#include "WebGLRenderbuffer.h"
|
||||
#include "WebGLFramebuffer.h"
|
||||
#include "WebGLUniformInfo.h"
|
||||
#include "WebGLShader.h"
|
||||
#include "WebGLProgram.h"
|
||||
|
||||
#include "GLContext.h"
|
||||
#include "mozilla/CheckedInt.h"
|
||||
#include "WebGLBuffer.h"
|
||||
#include "WebGLFramebuffer.h"
|
||||
#include "WebGLProgram.h"
|
||||
#include "WebGLRenderbuffer.h"
|
||||
#include "WebGLShader.h"
|
||||
#include "WebGLTexture.h"
|
||||
#include "WebGLUniformInfo.h"
|
||||
#include "WebGLVertexArray.h"
|
||||
#include "WebGLVertexAttribData.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace dom;
|
||||
@ -554,7 +556,9 @@ WebGLContext::DrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsiz
|
||||
}
|
||||
|
||||
bool
|
||||
WebGLContext::DrawElements_check(GLsizei count, GLenum type, WebGLintptr byteOffset, GLsizei primcount, const char* info)
|
||||
WebGLContext::DrawElements_check(GLsizei count, GLenum type,
|
||||
WebGLintptr byteOffset, GLsizei primcount,
|
||||
const char* info, GLuint* out_upperBound)
|
||||
{
|
||||
if (count < 0 || byteOffset < 0) {
|
||||
ErrorInvalidValue("%s: negative count or offset", info);
|
||||
@ -620,7 +624,9 @@ WebGLContext::DrawElements_check(GLsizei count, GLenum type, WebGLintptr byteOff
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mBoundVertexArray->mBoundElementArrayBuffer->ByteLength()) {
|
||||
WebGLBuffer& elemArrayBuffer = *mBoundVertexArray->mBoundElementArrayBuffer;
|
||||
|
||||
if (!elemArrayBuffer.ByteLength()) {
|
||||
ErrorInvalidOperation("%s: bound element array buffer doesn't have any data", info);
|
||||
return false;
|
||||
}
|
||||
@ -632,7 +638,7 @@ WebGLContext::DrawElements_check(GLsizei count, GLenum type, WebGLintptr byteOff
|
||||
return false;
|
||||
}
|
||||
|
||||
if (uint32_t(checked_neededByteCount.value()) > mBoundVertexArray->mBoundElementArrayBuffer->ByteLength()) {
|
||||
if (uint32_t(checked_neededByteCount.value()) > elemArrayBuffer.ByteLength()) {
|
||||
ErrorInvalidOperation("%s: bound element array buffer is too small for given count and offset", info);
|
||||
return false;
|
||||
}
|
||||
@ -641,7 +647,7 @@ WebGLContext::DrawElements_check(GLsizei count, GLenum type, WebGLintptr byteOff
|
||||
return false;
|
||||
|
||||
if (!mMaxFetchedVertices ||
|
||||
!mBoundVertexArray->mBoundElementArrayBuffer->Validate(type, mMaxFetchedVertices - 1, first, count))
|
||||
!elemArrayBuffer.Validate(type, mMaxFetchedVertices - 1, first, count, out_upperBound))
|
||||
{
|
||||
ErrorInvalidOperation(
|
||||
"%s: bound vertex attribute buffers do not have sufficient "
|
||||
@ -673,7 +679,7 @@ WebGLContext::DrawElements_check(GLsizei count, GLenum type, WebGLintptr byteOff
|
||||
|
||||
void
|
||||
WebGLContext::DrawElements(GLenum mode, GLsizei count, GLenum type,
|
||||
WebGLintptr byteOffset)
|
||||
WebGLintptr byteOffset)
|
||||
{
|
||||
if (IsContextLost())
|
||||
return;
|
||||
@ -681,18 +687,28 @@ WebGLContext::DrawElements(GLenum mode, GLsizei count, GLenum type,
|
||||
if (!ValidateDrawModeEnum(mode, "drawElements: mode"))
|
||||
return;
|
||||
|
||||
if (!DrawElements_check(count, type, byteOffset, 1, "drawElements"))
|
||||
GLuint upperBound = UINT_MAX;
|
||||
if (!DrawElements_check(count, type, byteOffset, 1, "drawElements",
|
||||
&upperBound))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SetupContextLossTimer();
|
||||
gl->fDrawElements(mode, count, type, reinterpret_cast<GLvoid*>(byteOffset));
|
||||
|
||||
if (gl->IsSupported(gl::GLFeature::draw_range_elements)) {
|
||||
gl->fDrawRangeElements(mode, 0, upperBound,
|
||||
count, type, reinterpret_cast<GLvoid*>(byteOffset));
|
||||
} else {
|
||||
gl->fDrawElements(mode, count, type, reinterpret_cast<GLvoid*>(byteOffset));
|
||||
}
|
||||
|
||||
Draw_cleanup();
|
||||
}
|
||||
|
||||
void
|
||||
WebGLContext::DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type,
|
||||
WebGLintptr byteOffset, GLsizei primcount)
|
||||
WebGLintptr byteOffset, GLsizei primcount)
|
||||
{
|
||||
if (IsContextLost())
|
||||
return;
|
||||
|
@ -16,6 +16,24 @@
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
static void
|
||||
SetUpperBound(uint32_t* out_upperBound, uint32_t newBound)
|
||||
{
|
||||
if (!out_upperBound)
|
||||
return;
|
||||
|
||||
*out_upperBound = newBound;
|
||||
}
|
||||
|
||||
static void
|
||||
UpdateUpperBound(uint32_t* out_upperBound, uint32_t newBound)
|
||||
{
|
||||
if (!out_upperBound)
|
||||
return;
|
||||
|
||||
*out_upperBound = std::max(*out_upperBound, newBound);
|
||||
}
|
||||
|
||||
/*
|
||||
* WebGLElementArrayCacheTree contains most of the implementation of WebGLElementArrayCache,
|
||||
* which performs WebGL element array buffer validation for drawElements.
|
||||
@ -227,7 +245,9 @@ public:
|
||||
return ((numElements - 1) | sElementsPerLeafMask) + 1;
|
||||
}
|
||||
|
||||
bool Validate(T maxAllowed, size_t firstLeaf, size_t lastLeaf) {
|
||||
bool Validate(T maxAllowed, size_t firstLeaf, size_t lastLeaf,
|
||||
uint32_t* out_upperBound)
|
||||
{
|
||||
MOZ_ASSERT(!mInvalidated);
|
||||
|
||||
size_t firstTreeIndex = TreeIndexForLeaf(firstLeaf);
|
||||
@ -240,13 +260,17 @@ public:
|
||||
|
||||
// final case where there is only 1 node to validate at the current tree level
|
||||
if (lastTreeIndex == firstTreeIndex) {
|
||||
return mTreeData[firstTreeIndex] <= maxAllowed;
|
||||
const T& curData = mTreeData[firstTreeIndex];
|
||||
UpdateUpperBound(out_upperBound, curData);
|
||||
return curData <= maxAllowed;
|
||||
}
|
||||
|
||||
// if the first node at current tree level is a right node, handle it individually
|
||||
// and replace it with its right neighbor, which is a left node
|
||||
if (IsRightNode(firstTreeIndex)) {
|
||||
if (mTreeData[firstTreeIndex] > maxAllowed)
|
||||
const T& curData = mTreeData[firstTreeIndex];
|
||||
UpdateUpperBound(out_upperBound, curData);
|
||||
if (curData > maxAllowed)
|
||||
return false;
|
||||
firstTreeIndex = RightNeighborNode(firstTreeIndex);
|
||||
}
|
||||
@ -254,7 +278,9 @@ public:
|
||||
// if the last node at current tree level is a left node, handle it individually
|
||||
// and replace it with its left neighbor, which is a right node
|
||||
if (IsLeftNode(lastTreeIndex)) {
|
||||
if (mTreeData[lastTreeIndex] > maxAllowed)
|
||||
const T& curData = mTreeData[lastTreeIndex];
|
||||
UpdateUpperBound(out_upperBound, curData);
|
||||
if (curData > maxAllowed)
|
||||
return false;
|
||||
lastTreeIndex = LeftNeighborNode(lastTreeIndex);
|
||||
}
|
||||
@ -490,10 +516,18 @@ void WebGLElementArrayCache::InvalidateTrees(size_t firstByte, size_t lastByte)
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool WebGLElementArrayCache::Validate(uint32_t maxAllowed, size_t firstElement, size_t countElements) {
|
||||
bool
|
||||
WebGLElementArrayCache::Validate(uint32_t maxAllowed, size_t firstElement,
|
||||
size_t countElements, uint32_t* out_upperBound)
|
||||
{
|
||||
SetUpperBound(out_upperBound, 0);
|
||||
|
||||
// if maxAllowed is >= the max T value, then there is no way that a T index could be invalid
|
||||
if (maxAllowed >= std::numeric_limits<T>::max())
|
||||
uint32_t maxTSize = std::numeric_limits<T>::max();
|
||||
if (maxAllowed >= maxTSize) {
|
||||
SetUpperBound(out_upperBound, maxTSize);
|
||||
return true;
|
||||
}
|
||||
|
||||
T maxAllowedT(maxAllowed);
|
||||
|
||||
@ -515,8 +549,10 @@ bool WebGLElementArrayCache::Validate(uint32_t maxAllowed, size_t firstElement,
|
||||
|
||||
// fast exit path when the global maximum for the whole element array buffer
|
||||
// falls in the allowed range
|
||||
if (tree->GlobalMaximum() <= maxAllowedT)
|
||||
T globalMax = tree->GlobalMaximum();
|
||||
if (globalMax <= maxAllowedT)
|
||||
{
|
||||
SetUpperBound(out_upperBound, globalMax);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -527,14 +563,18 @@ bool WebGLElementArrayCache::Validate(uint32_t maxAllowed, size_t firstElement,
|
||||
size_t firstElementAdjustmentEnd = std::min(lastElement,
|
||||
tree->LastElementUnderSameLeaf(firstElement));
|
||||
while (firstElement <= firstElementAdjustmentEnd) {
|
||||
if (elements[firstElement] > maxAllowedT)
|
||||
const T& curData = elements[firstElement];
|
||||
UpdateUpperBound(out_upperBound, curData);
|
||||
if (curData > maxAllowedT)
|
||||
return false;
|
||||
firstElement++;
|
||||
}
|
||||
size_t lastElementAdjustmentEnd = std::max(firstElement,
|
||||
tree->FirstElementUnderSameLeaf(lastElement));
|
||||
while (lastElement >= lastElementAdjustmentEnd) {
|
||||
if (elements[lastElement] > maxAllowedT)
|
||||
const T& curData = elements[lastElement];
|
||||
UpdateUpperBound(out_upperBound, curData);
|
||||
if (curData > maxAllowedT)
|
||||
return false;
|
||||
lastElement--;
|
||||
}
|
||||
@ -546,20 +586,29 @@ bool WebGLElementArrayCache::Validate(uint32_t maxAllowed, size_t firstElement,
|
||||
// general case
|
||||
return tree->Validate(maxAllowedT,
|
||||
tree->LeafForElement(firstElement),
|
||||
tree->LeafForElement(lastElement));
|
||||
tree->LeafForElement(lastElement),
|
||||
out_upperBound);
|
||||
}
|
||||
|
||||
bool WebGLElementArrayCache::Validate(GLenum type, uint32_t maxAllowed, size_t firstElement, size_t countElements) {
|
||||
bool
|
||||
WebGLElementArrayCache::Validate(GLenum type, uint32_t maxAllowed,
|
||||
size_t firstElement, size_t countElements,
|
||||
uint32_t* out_upperBound)
|
||||
{
|
||||
if (type == LOCAL_GL_UNSIGNED_BYTE)
|
||||
return Validate<uint8_t>(maxAllowed, firstElement, countElements);
|
||||
return Validate<uint8_t>(maxAllowed, firstElement, countElements, out_upperBound);
|
||||
if (type == LOCAL_GL_UNSIGNED_SHORT)
|
||||
return Validate<uint16_t>(maxAllowed, firstElement, countElements);
|
||||
return Validate<uint16_t>(maxAllowed, firstElement, countElements, out_upperBound);
|
||||
if (type == LOCAL_GL_UNSIGNED_INT)
|
||||
return Validate<uint32_t>(maxAllowed, firstElement, countElements);
|
||||
return Validate<uint32_t>(maxAllowed, firstElement, countElements, out_upperBound);
|
||||
|
||||
MOZ_ASSERT(false, "Invalid type.");
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t WebGLElementArrayCache::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const {
|
||||
size_t
|
||||
WebGLElementArrayCache::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
|
||||
{
|
||||
size_t uint8TreeSize = mUint8Tree ? mUint8Tree->SizeOfIncludingThis(aMallocSizeOf) : 0;
|
||||
size_t uint16TreeSize = mUint16Tree ? mUint16Tree->SizeOfIncludingThis(aMallocSizeOf) : 0;
|
||||
size_t uint32TreeSize = mUint32Tree ? mUint32Tree->SizeOfIncludingThis(aMallocSizeOf) : 0;
|
||||
|
@ -33,7 +33,8 @@ public:
|
||||
bool BufferData(const void* ptr, size_t byteSize);
|
||||
void BufferSubData(size_t pos, const void* ptr, size_t updateByteSize);
|
||||
|
||||
bool Validate(GLenum type, uint32_t maxAllowed, size_t first, size_t count);
|
||||
bool Validate(GLenum type, uint32_t maxAllowed, size_t first, size_t count,
|
||||
uint32_t* out_upperBound = nullptr);
|
||||
|
||||
template<typename T>
|
||||
T Element(size_t i) const { return Elements<T>()[i]; }
|
||||
@ -53,7 +54,8 @@ public:
|
||||
private:
|
||||
|
||||
template<typename T>
|
||||
bool Validate(uint32_t maxAllowed, size_t first, size_t count);
|
||||
bool Validate(uint32_t maxAllowed, size_t first, size_t count,
|
||||
uint32_t* out_upperBound);
|
||||
|
||||
size_t ByteSize() const {
|
||||
return mByteSize;
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "nsWrapperCache.h"
|
||||
#include "mozilla/ErrorResult.h"
|
||||
#include "mozilla/dom/TextTrack.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
@ -28,6 +29,12 @@ public:
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(TextTrackRegion)
|
||||
|
||||
static bool RegionsEnabled(JSContext* cx, JSObject* obj)
|
||||
{
|
||||
return Preferences::GetBool("media.webvtt.enabled") &&
|
||||
Preferences::GetBool("media.webvtt.regions.enabled");
|
||||
}
|
||||
|
||||
virtual JSObject* WrapObject(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
|
||||
|
||||
|
@ -17,7 +17,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=833386
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SpecialPowers.pushPrefEnv({"set": [["media.webvtt.enabled", true]]},
|
||||
SpecialPowers.pushPrefEnv({"set": [["media.webvtt.enabled", true],
|
||||
["media.webvtt.regions.enabled", true]]},
|
||||
function() {
|
||||
var video = document.createElement("video");
|
||||
video.src = "seek.webm";
|
||||
|
@ -17,7 +17,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=917945
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SpecialPowers.pushPrefEnv({"set": [["media.webvtt.enabled", true]]},
|
||||
SpecialPowers.pushPrefEnv({"set": [["media.webvtt.enabled", true],
|
||||
["media.webvtt.regions.enabled", true]]},
|
||||
function() {
|
||||
var video = document.createElement("video");
|
||||
video.src = "seek.webm";
|
||||
|
@ -1118,7 +1118,7 @@ var interfaceNamesInGlobalScope =
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"VTTCue",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"VTTRegion",
|
||||
{name: "VTTRegion", pref: "media.webvtt.regions.enabled"},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"WaveShaperNode",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
|
@ -32,6 +32,7 @@ interface VTTCue : EventTarget {
|
||||
attribute double startTime;
|
||||
attribute double endTime;
|
||||
attribute boolean pauseOnExit;
|
||||
[Pref="media.webvtt.regions.enabled"]
|
||||
attribute VTTRegion? region;
|
||||
attribute DirectionSetting vertical;
|
||||
attribute boolean snapToLines;
|
||||
|
@ -7,7 +7,7 @@
|
||||
* http://dev.w3.org/html5/webvtt/#extension-of-the-texttrack-interface-for-region-support
|
||||
*/
|
||||
|
||||
[Constructor, Pref="media.webvtt.enabled"]
|
||||
[Constructor, Func="TextTrackRegion::RegionsEnabled"]
|
||||
interface VTTRegion {
|
||||
[SetterThrows]
|
||||
attribute double width;
|
||||
|
@ -138,6 +138,7 @@ static const char *sExtensionNames[] = {
|
||||
"GL_ARB_half_float_pixel",
|
||||
"GL_EXT_frag_depth",
|
||||
"GL_OES_compressed_ETC1_RGB8_texture",
|
||||
"GL_EXT_draw_range_elements",
|
||||
nullptr
|
||||
};
|
||||
|
||||
@ -1073,6 +1074,20 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl)
|
||||
}
|
||||
}
|
||||
|
||||
if (IsSupported(GLFeature::draw_range_elements)) {
|
||||
SymLoadStruct imageSymbols[] = {
|
||||
{ (PRFuncPtr*) &mSymbols.fDrawRangeElements, { "DrawRangeElementsEXT", "DrawRangeElements", nullptr } },
|
||||
{ nullptr, { nullptr } },
|
||||
};
|
||||
|
||||
if (!LoadSymbols(&imageSymbols[0], trygl, prefix)) {
|
||||
NS_ERROR("GL supports draw_range_elements without supplying its functions.");
|
||||
|
||||
MarkUnsupported(GLFeature::draw_range_elements);
|
||||
mSymbols.fDrawRangeElements = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// Load developer symbols, don't fail if we can't find them.
|
||||
SymLoadStruct auxSymbols[] = {
|
||||
{ (PRFuncPtr*) &mSymbols.fGetTexImage, { "GetTexImage", nullptr } },
|
||||
|
@ -87,6 +87,7 @@ MOZ_BEGIN_ENUM_CLASS(GLFeature)
|
||||
depth_texture,
|
||||
draw_buffers,
|
||||
draw_instanced,
|
||||
draw_range_elements,
|
||||
element_index_uint,
|
||||
ES2_compatibility,
|
||||
ES3_compatibility,
|
||||
@ -419,6 +420,7 @@ public:
|
||||
ARB_half_float_pixel,
|
||||
EXT_frag_depth,
|
||||
OES_compressed_ETC1_RGB8_texture,
|
||||
EXT_draw_range_elements,
|
||||
Extensions_Max,
|
||||
Extensions_End
|
||||
};
|
||||
@ -2228,6 +2230,17 @@ public:
|
||||
AfterGLDrawCall();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Feature draw_range_elements
|
||||
public:
|
||||
void fDrawRangeElements(GLenum mode, GLuint start, GLuint end,
|
||||
GLsizei count, GLenum type, const GLvoid* indices)
|
||||
{
|
||||
BEFORE_GL_CALL;
|
||||
ASSERT_SYMBOL_PRESENT(fDrawRangeElements);
|
||||
mSymbols.fDrawRangeElements(mode, start, end, count, type, indices);
|
||||
AFTER_GL_CALL;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Package XXX_framebuffer_blit
|
||||
@ -2698,7 +2711,7 @@ protected:
|
||||
// storage to support DebugMode on an arbitrary thread.
|
||||
static unsigned sCurrentGLContextTLS;
|
||||
#endif
|
||||
|
||||
|
||||
ScopedDeletePtr<GLBlitHelper> mBlitHelper;
|
||||
ScopedDeletePtr<GLBlitTextureImageHelper> mBlitTextureImageHelper;
|
||||
ScopedDeletePtr<GLReadTexImageHelper> mReadTexImageHelper;
|
||||
|
@ -84,6 +84,15 @@ static const FeatureInfo sFeatureInfoArr[] = {
|
||||
GLContext::Extensions_End
|
||||
}
|
||||
},
|
||||
{
|
||||
"draw_range_elements",
|
||||
120, // OpenGL version
|
||||
300, // OpenGL ES version
|
||||
{
|
||||
GLContext::EXT_draw_range_elements,
|
||||
GLContext::Extensions_End
|
||||
}
|
||||
},
|
||||
{
|
||||
"element_index_uint",
|
||||
200, // OpenGL version
|
||||
|
@ -493,6 +493,10 @@ struct GLContextSymbols
|
||||
PFNGLOBJECTPTRLABEL fObjectPtrLabel;
|
||||
typedef void (GLAPIENTRY * PFNGLGETOBJECTPTRLABEL) (const GLvoid* ptr, GLsizei bufSize, GLsizei* length, GLchar* label);
|
||||
PFNGLGETOBJECTPTRLABEL fGetObjectPtrLabel;
|
||||
|
||||
// draw_range_elements
|
||||
typedef void (GLAPIENTRY * PFNGLDRAWRANGEELEMENTS) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid* indices);
|
||||
PFNGLDRAWRANGEELEMENTS fDrawRangeElements;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -286,19 +286,15 @@ CopyableCanvasLayer::PaintWithOpacity(gfx::DrawTarget* aTarget,
|
||||
|
||||
DrawOptions options = DrawOptions(aOpacity, CompositionOp::OP_SOURCE);
|
||||
|
||||
// If content opaque, then save off current operator and set to source.
|
||||
// This ensures that alpha is not applied even if the source surface
|
||||
// has an alpha channel
|
||||
if (GetContentFlags() & CONTENT_OPAQUE) {
|
||||
options.mCompositionOp = CompositionOp::OP_SOURCE;
|
||||
}
|
||||
|
||||
if (aOperator != CompositionOp::OP_OVER) {
|
||||
options.mCompositionOp = aOperator;
|
||||
}
|
||||
|
||||
// XXX: This needs rewriting for acceptable performance using CoreGraphics.
|
||||
// Therefore - this ::PaintWithOpacity is currently not used
|
||||
Rect rect = Rect(0, 0, mBounds.width, mBounds.height);
|
||||
aTarget->FillRect(rect, pat, options);
|
||||
|
||||
if (aMaskSurface) {
|
||||
aTarget->MaskSurface(pat, aMaskSurface, Point(0, 0), options);
|
||||
}
|
||||
|
@ -79,10 +79,10 @@ CanvasClient2D::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
|
||||
bool updated = false;
|
||||
{
|
||||
// Restrict drawTarget to a scope so that terminates before Unlock.
|
||||
RefPtr<DrawTarget> drawTarget =
|
||||
mBuffer->AsTextureClientDrawTarget()->GetAsDrawTarget();
|
||||
if (drawTarget) {
|
||||
aLayer->UpdateTarget(drawTarget);
|
||||
nsRefPtr<gfxASurface> surface =
|
||||
mBuffer->AsTextureClientSurface()->GetAsSurface();
|
||||
if (surface) {
|
||||
aLayer->DeprecatedUpdateSurface(surface);
|
||||
updated = true;
|
||||
}
|
||||
}
|
||||
|
@ -76,11 +76,12 @@ public:
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!child->GetInvalidRegion().IsEmpty()) {
|
||||
ToClientLayer(child)->RenderLayer();
|
||||
|
||||
if (!ClientManager()->GetRepeatTransaction() &&
|
||||
!child->GetInvalidRegion().IsEmpty()) {
|
||||
child->Mutated();
|
||||
}
|
||||
|
||||
ToClientLayer(child)->RenderLayer();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -194,10 +194,10 @@ ClientLayerManager::EndTransactionInternal(DrawThebesLayerCallback aCallback,
|
||||
|
||||
GetRoot()->ComputeEffectiveTransforms(Matrix4x4());
|
||||
|
||||
if (!GetRoot()->GetInvalidRegion().IsEmpty()) {
|
||||
root->RenderLayer();
|
||||
if (!mRepeatTransaction && !GetRoot()->GetInvalidRegion().IsEmpty()) {
|
||||
GetRoot()->Mutated();
|
||||
}
|
||||
root->RenderLayer();
|
||||
|
||||
mThebesLayerCallback = nullptr;
|
||||
mThebesLayerCallbackData = nullptr;
|
||||
|
@ -30,8 +30,8 @@ class nsIWidget;
|
||||
// IID for the nsITheme interface
|
||||
// {b0f3efe9-0bd4-4f6b-8daa-0ec7f6006822}
|
||||
#define NS_ITHEME_IID \
|
||||
{ 0x2e49c679, 0x2130, 0x432c, \
|
||||
{ 0x92, 0xcb, 0xd4, 0x8e, 0x9a, 0xe2, 0x34, 0x75 } }
|
||||
{ 0x4440b5c7, 0xd8bd, 0x4d9c, \
|
||||
{ 0x9c, 0x3e, 0xa5, 0xe6, 0x26, 0x81, 0x10, 0xa0 } }
|
||||
// {D930E29B-6909-44e5-AB4B-AF10D6923705}
|
||||
#define NS_THEMERENDERER_CID \
|
||||
{ 0x9020805b, 0x14a3, 0x4125, \
|
||||
@ -63,8 +63,7 @@ public:
|
||||
nsIFrame* aFrame,
|
||||
uint8_t aWidgetType,
|
||||
const nsRect& aRect,
|
||||
const nsRect& aDirtyRect,
|
||||
nsIntRegion* aRegionToClear = nullptr) = 0;
|
||||
const nsRect& aDirtyRect) = 0;
|
||||
|
||||
/**
|
||||
* Get the computed CSS border for the widget, in pixels.
|
||||
|
@ -906,6 +906,11 @@ namespace JSC {
|
||||
return m_buffer.uncheckedSize();
|
||||
}
|
||||
|
||||
size_t allocSize() const
|
||||
{
|
||||
return m_buffer.allocSize();
|
||||
}
|
||||
|
||||
void ensureSpace(int insnSpace, int constSpace)
|
||||
{
|
||||
m_buffer.ensureSpace(insnSpace, constSpace);
|
||||
|
@ -42,6 +42,7 @@
|
||||
#include <stdarg.h>
|
||||
#include "jsfriendapi.h"
|
||||
#include "jsopcode.h"
|
||||
#include "jsutil.h"
|
||||
|
||||
#include "jit/IonSpewer.h"
|
||||
#include "js/RootingAPI.h"
|
||||
@ -63,6 +64,7 @@ namespace JSC {
|
||||
: m_buffer(m_inlineBuffer)
|
||||
, m_capacity(inlineCapacity)
|
||||
, m_size(0)
|
||||
, m_allocSize(0)
|
||||
, m_oom(false)
|
||||
{
|
||||
}
|
||||
@ -143,6 +145,11 @@ namespace JSC {
|
||||
return m_size;
|
||||
}
|
||||
|
||||
size_t allocSize() const
|
||||
{
|
||||
return m_allocSize;
|
||||
}
|
||||
|
||||
bool oom() const
|
||||
{
|
||||
return m_oom;
|
||||
@ -159,7 +166,9 @@ namespace JSC {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void* result = allocator->alloc(m_size, poolp, kind);
|
||||
m_allocSize = js::AlignBytes(m_size, sizeof(void *));
|
||||
|
||||
void* result = allocator->alloc(m_allocSize, poolp, kind);
|
||||
if (!result) {
|
||||
*poolp = NULL;
|
||||
return 0;
|
||||
@ -255,6 +264,7 @@ namespace JSC {
|
||||
char* m_buffer;
|
||||
size_t m_capacity;
|
||||
size_t m_size;
|
||||
size_t m_allocSize;
|
||||
bool m_oom;
|
||||
};
|
||||
|
||||
|
@ -66,38 +66,19 @@ public:
|
||||
LinkBuffer(MacroAssembler* masm, ExecutableAllocator* executableAllocator,
|
||||
ExecutablePool** poolp, bool* ok, CodeKind codeKind)
|
||||
{
|
||||
// LinkBuffer is only used by Yarr. MacroAssemblerCodeRef::release relies on this.
|
||||
MOZ_ASSERT(codeKind == REGEXP_CODE);
|
||||
m_codeKind = codeKind;
|
||||
m_code = executableAllocAndCopy(*masm, executableAllocator, poolp);
|
||||
m_executablePool = *poolp;
|
||||
m_size = masm->m_assembler.size(); // must come after call to executableAllocAndCopy()!
|
||||
m_allocSize = masm->m_assembler.allocSize();
|
||||
#ifndef NDEBUG
|
||||
m_completed = false;
|
||||
#endif
|
||||
*ok = !!m_code;
|
||||
}
|
||||
|
||||
LinkBuffer(CodeKind kind)
|
||||
: m_executablePool(NULL)
|
||||
, m_code(NULL)
|
||||
, m_size(0)
|
||||
, m_codeKind(kind)
|
||||
#ifndef NDEBUG
|
||||
, m_completed(false)
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
LinkBuffer(uint8_t* ncode, size_t size, CodeKind kind)
|
||||
: m_executablePool(NULL)
|
||||
, m_code(ncode)
|
||||
, m_size(size)
|
||||
, m_codeKind(kind)
|
||||
#ifndef NDEBUG
|
||||
, m_completed(false)
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
~LinkBuffer()
|
||||
{
|
||||
ASSERT(!m_executablePool || m_completed);
|
||||
@ -183,7 +164,8 @@ public:
|
||||
{
|
||||
performFinalization();
|
||||
|
||||
return CodeRef(m_code, m_executablePool, m_size);
|
||||
MOZ_ASSERT(m_allocSize >= m_size);
|
||||
return CodeRef(m_code, m_executablePool, m_allocSize);
|
||||
}
|
||||
CodeLocationLabel finalizeCodeAddendum()
|
||||
{
|
||||
@ -225,6 +207,7 @@ protected:
|
||||
ExecutablePool* m_executablePool;
|
||||
void* m_code;
|
||||
size_t m_size;
|
||||
size_t m_allocSize;
|
||||
CodeKind m_codeKind;
|
||||
#ifndef NDEBUG
|
||||
bool m_completed;
|
||||
|
@ -182,14 +182,14 @@ class MacroAssemblerCodeRef {
|
||||
public:
|
||||
MacroAssemblerCodeRef()
|
||||
: m_executablePool(NULL),
|
||||
m_size(0)
|
||||
m_allocSize(0)
|
||||
{
|
||||
}
|
||||
|
||||
MacroAssemblerCodeRef(void* code, ExecutablePool* executablePool, size_t size)
|
||||
MacroAssemblerCodeRef(void* code, ExecutablePool* executablePool, size_t allocSize)
|
||||
: m_code(code)
|
||||
, m_executablePool(executablePool)
|
||||
, m_size(size)
|
||||
, m_allocSize(allocSize)
|
||||
{
|
||||
}
|
||||
|
||||
@ -201,22 +201,23 @@ public:
|
||||
|
||||
#if defined DEBUG && (defined WTF_CPU_X86 || defined WTF_CPU_X86_64)
|
||||
void *addr = m_code.executableAddress();
|
||||
memset(addr, 0xcc, m_size);
|
||||
memset(addr, 0xcc, m_allocSize);
|
||||
#endif
|
||||
m_executablePool->release();
|
||||
// MacroAssemblerCodeRef is only used by Yarr.
|
||||
m_executablePool->release(m_allocSize, REGEXP_CODE);
|
||||
m_executablePool = NULL;
|
||||
}
|
||||
|
||||
MacroAssemblerCodePtr code() const {
|
||||
return m_code;
|
||||
}
|
||||
size_t size() const {
|
||||
return m_size;
|
||||
size_t allocSize() const {
|
||||
return m_allocSize;
|
||||
}
|
||||
|
||||
MacroAssemblerCodePtr m_code;
|
||||
ExecutablePool* m_executablePool;
|
||||
size_t m_size;
|
||||
size_t m_allocSize;
|
||||
};
|
||||
|
||||
} // namespace JSC
|
||||
|
@ -440,6 +440,7 @@ public:
|
||||
};
|
||||
|
||||
size_t size() const { return m_formatter.size(); }
|
||||
size_t allocSize() const { return m_formatter.allocSize(); }
|
||||
unsigned char *buffer() const { return m_formatter.buffer(); }
|
||||
bool oom() const { return m_formatter.oom(); }
|
||||
|
||||
@ -3867,6 +3868,7 @@ private:
|
||||
// Administrative methods:
|
||||
|
||||
size_t size() const { return m_buffer.size(); }
|
||||
size_t allocSize() const { return m_buffer.allocSize(); }
|
||||
unsigned char *buffer() const { return m_buffer.buffer(); }
|
||||
bool oom() const { return m_buffer.oom(); }
|
||||
bool isAligned(int alignment) const { return m_buffer.isAligned(alignment); }
|
||||
|
@ -38,6 +38,11 @@ size_t ExecutableAllocator::largeAllocSize = 0;
|
||||
|
||||
ExecutablePool::~ExecutablePool()
|
||||
{
|
||||
MOZ_ASSERT(m_ionCodeBytes == 0);
|
||||
MOZ_ASSERT(m_baselineCodeBytes == 0);
|
||||
MOZ_ASSERT(m_regexpCodeBytes == 0);
|
||||
MOZ_ASSERT(m_otherCodeBytes == 0);
|
||||
|
||||
m_allocator->releasePoolPages(this);
|
||||
}
|
||||
|
||||
|
@ -85,7 +85,7 @@ namespace JSC {
|
||||
|
||||
class ExecutableAllocator;
|
||||
|
||||
enum CodeKind { ION_CODE, BASELINE_CODE, REGEXP_CODE, OTHER_CODE };
|
||||
enum CodeKind { ION_CODE = 0, BASELINE_CODE, REGEXP_CODE, OTHER_CODE };
|
||||
|
||||
// These are reference-counted. A new one starts with a count of 1.
|
||||
class ExecutablePool {
|
||||
@ -130,6 +130,31 @@ public:
|
||||
if (--m_refCount == 0)
|
||||
js_delete(this);
|
||||
}
|
||||
void release(size_t n, CodeKind kind)
|
||||
{
|
||||
switch (kind) {
|
||||
case ION_CODE:
|
||||
m_ionCodeBytes -= n;
|
||||
MOZ_ASSERT(m_ionCodeBytes < m_allocation.size); // Shouldn't underflow.
|
||||
break;
|
||||
case BASELINE_CODE:
|
||||
m_baselineCodeBytes -= n;
|
||||
MOZ_ASSERT(m_baselineCodeBytes < m_allocation.size);
|
||||
break;
|
||||
case REGEXP_CODE:
|
||||
m_regexpCodeBytes -= n;
|
||||
MOZ_ASSERT(m_regexpCodeBytes < m_allocation.size);
|
||||
break;
|
||||
case OTHER_CODE:
|
||||
m_otherCodeBytes -= n;
|
||||
MOZ_ASSERT(m_otherCodeBytes < m_allocation.size);
|
||||
break;
|
||||
default:
|
||||
MOZ_ASSUME_UNREACHABLE("bad code kind");
|
||||
}
|
||||
|
||||
release();
|
||||
}
|
||||
|
||||
ExecutablePool(ExecutableAllocator* allocator, Allocation a)
|
||||
: m_allocator(allocator), m_freePtr(a.pages), m_end(m_freePtr + a.size), m_allocation(a),
|
||||
@ -223,10 +248,11 @@ public:
|
||||
// pool; i.e. alloc() increments the count before returning the object.
|
||||
void* alloc(size_t n, ExecutablePool** poolp, CodeKind type)
|
||||
{
|
||||
// Round 'n' up to a multiple of word size; if all allocations are of
|
||||
// word sized quantities, then all subsequent allocations will be
|
||||
// Caller must ensure 'n' is word-size aligned. If all allocations are
|
||||
// of word sized quantities, then all subsequent allocations will be
|
||||
// aligned.
|
||||
n = roundUpAllocationSize(n, sizeof(void*));
|
||||
JS_ASSERT(roundUpAllocationSize(n, sizeof(void*)) == n);
|
||||
|
||||
if (n == OVERSIZE_ALLOCATION) {
|
||||
*poolp = NULL;
|
||||
return NULL;
|
||||
@ -347,7 +373,7 @@ public:
|
||||
ExecutablePool* pool = createPool(largeAllocSize);
|
||||
if (!pool)
|
||||
return NULL;
|
||||
// At this point, local |pool| is the owner.
|
||||
// At this point, local |pool| is the owner.
|
||||
|
||||
if (m_smallPools.length() < maxSmallPools) {
|
||||
// We haven't hit the maximum number of live pools; add the new pool.
|
||||
@ -373,7 +399,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
// Pass ownership to the caller.
|
||||
// Pass ownership to the caller.
|
||||
return pool;
|
||||
}
|
||||
|
||||
|
@ -615,25 +615,28 @@ JitRuntime::getVMWrapper(const VMFunction &f) const
|
||||
|
||||
template <AllowGC allowGC>
|
||||
JitCode *
|
||||
JitCode::New(JSContext *cx, uint8_t *code, uint32_t bufferSize, JSC::ExecutablePool *pool)
|
||||
JitCode::New(JSContext *cx, uint8_t *code, uint32_t bufferSize, uint32_t headerSize,
|
||||
JSC::ExecutablePool *pool, JSC::CodeKind kind)
|
||||
{
|
||||
JitCode *codeObj = js::NewJitCode<allowGC>(cx);
|
||||
if (!codeObj) {
|
||||
pool->release();
|
||||
pool->release(headerSize + bufferSize, kind);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
new (codeObj) JitCode(code, bufferSize, pool);
|
||||
new (codeObj) JitCode(code, bufferSize, headerSize, pool, kind);
|
||||
return codeObj;
|
||||
}
|
||||
|
||||
template
|
||||
JitCode *
|
||||
JitCode::New<CanGC>(JSContext *cx, uint8_t *code, uint32_t bufferSize, JSC::ExecutablePool *pool);
|
||||
JitCode::New<CanGC>(JSContext *cx, uint8_t *code, uint32_t bufferSize, uint32_t headerSize,
|
||||
JSC::ExecutablePool *pool, JSC::CodeKind kind);
|
||||
|
||||
template
|
||||
JitCode *
|
||||
JitCode::New<NoGC>(JSContext *cx, uint8_t *code, uint32_t bufferSize, JSC::ExecutablePool *pool);
|
||||
JitCode::New<NoGC>(JSContext *cx, uint8_t *code, uint32_t bufferSize, uint32_t headerSize,
|
||||
JSC::ExecutablePool *pool, JSC::CodeKind kind);
|
||||
|
||||
void
|
||||
JitCode::copyFrom(MacroAssembler &masm)
|
||||
@ -696,7 +699,7 @@ JitCode::finalize(FreeOp *fop)
|
||||
// Horrible hack: if we are using perf integration, we don't
|
||||
// want to reuse code addresses, so we just leak the memory instead.
|
||||
if (!PerfEnabled())
|
||||
pool_->release();
|
||||
pool_->release(headerSize_ + bufferSize_, JSC::CodeKind(kind_));
|
||||
pool_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "jsinfer.h"
|
||||
#include "jstypes.h"
|
||||
|
||||
#include "assembler/jit/ExecutableAllocator.h"
|
||||
#include "gc/Heap.h"
|
||||
#include "jit/IonOptimizationLevels.h"
|
||||
#include "jit/IonTypes.h"
|
||||
@ -37,13 +38,15 @@ class JitCode : public gc::BarrieredCell<JitCode>
|
||||
protected:
|
||||
uint8_t *code_;
|
||||
JSC::ExecutablePool *pool_;
|
||||
uint32_t bufferSize_; // Total buffer size.
|
||||
uint32_t bufferSize_; // Total buffer size. Does not include headerSize_.
|
||||
uint32_t insnSize_; // Instruction stream size.
|
||||
uint32_t dataSize_; // Size of the read-only data area.
|
||||
uint32_t jumpRelocTableBytes_; // Size of the jump relocation table.
|
||||
uint32_t dataRelocTableBytes_; // Size of the data relocation table.
|
||||
uint32_t preBarrierTableBytes_; // Size of the prebarrier table.
|
||||
bool invalidated_; // Whether the code object has been invalidated.
|
||||
uint8_t headerSize_ : 5; // Number of bytes allocated before codeStart.
|
||||
uint8_t kind_ : 3; // JSC::CodeKind, for the memory reporters.
|
||||
bool invalidated_ : 1; // Whether the code object has been invalidated.
|
||||
// This is necessary to prevent GC tracing.
|
||||
|
||||
#if JS_BITS_PER_WORD == 32
|
||||
@ -55,7 +58,8 @@ class JitCode : public gc::BarrieredCell<JitCode>
|
||||
: code_(nullptr),
|
||||
pool_(nullptr)
|
||||
{ }
|
||||
JitCode(uint8_t *code, uint32_t bufferSize, JSC::ExecutablePool *pool)
|
||||
JitCode(uint8_t *code, uint32_t bufferSize, uint32_t headerSize, JSC::ExecutablePool *pool,
|
||||
JSC::CodeKind kind)
|
||||
: code_(code),
|
||||
pool_(pool),
|
||||
bufferSize_(bufferSize),
|
||||
@ -64,8 +68,13 @@ class JitCode : public gc::BarrieredCell<JitCode>
|
||||
jumpRelocTableBytes_(0),
|
||||
dataRelocTableBytes_(0),
|
||||
preBarrierTableBytes_(0),
|
||||
headerSize_(headerSize),
|
||||
kind_(kind),
|
||||
invalidated_(false)
|
||||
{ }
|
||||
{
|
||||
MOZ_ASSERT(JSC::CodeKind(kind_) == kind);
|
||||
MOZ_ASSERT(headerSize_ == headerSize);
|
||||
}
|
||||
|
||||
uint32_t dataOffset() const {
|
||||
return insnSize_;
|
||||
@ -126,7 +135,8 @@ class JitCode : public gc::BarrieredCell<JitCode>
|
||||
// object can be allocated, nullptr is returned. On failure, |pool| is
|
||||
// automatically released, so the code may be freed.
|
||||
template <AllowGC allowGC>
|
||||
static JitCode *New(JSContext *cx, uint8_t *code, uint32_t bufferSize, JSC::ExecutablePool *pool);
|
||||
static JitCode *New(JSContext *cx, uint8_t *code, uint32_t bufferSize, uint32_t headerSize,
|
||||
JSC::ExecutablePool *pool, JSC::CodeKind kind);
|
||||
|
||||
public:
|
||||
static inline ThingRootKind rootKind() { return THING_ROOT_JIT_CODE; }
|
||||
|
@ -44,6 +44,9 @@ class Linker
|
||||
if (bytesNeeded >= MAX_BUFFER_SIZE)
|
||||
return fail(cx);
|
||||
|
||||
// ExecutableAllocator requires bytesNeeded to be word-size aligned.
|
||||
bytesNeeded = AlignBytes(bytesNeeded, sizeof(void *));
|
||||
|
||||
uint8_t *result = (uint8_t *)execAlloc->alloc(bytesNeeded, &pool, kind);
|
||||
if (!result)
|
||||
return fail(cx);
|
||||
@ -54,8 +57,8 @@ class Linker
|
||||
// Bump the code up to a nice alignment.
|
||||
codeStart = (uint8_t *)AlignBytes((uintptr_t)codeStart, CodeAlignment);
|
||||
uint32_t headerSize = codeStart - result;
|
||||
JitCode *code = JitCode::New<allowGC>(cx, codeStart,
|
||||
bytesNeeded - headerSize, pool);
|
||||
JitCode *code = JitCode::New<allowGC>(cx, codeStart, bytesNeeded - headerSize,
|
||||
headerSize, pool, kind);
|
||||
if (!code)
|
||||
return nullptr;
|
||||
if (masm.oom())
|
||||
|
@ -2549,7 +2549,7 @@ DefineConstructorAndPrototype(JSContext *cx, HandleObject obj, JSProtoKey key, H
|
||||
* (FIXME: remove this dependency on the exact identity of the parent,
|
||||
* perhaps as part of bug 638316.)
|
||||
*/
|
||||
RootedFunction fun(cx, NewFunction(cx, NullPtr(), constructor, nargs,
|
||||
RootedFunction fun(cx, NewFunction(cx, js::NullPtr(), constructor, nargs,
|
||||
JSFunction::NATIVE_CTOR, obj, atom, ctorKind));
|
||||
if (!fun)
|
||||
goto bad;
|
||||
|
@ -82,16 +82,16 @@ public:
|
||||
bool isFallBack() { return m_needFallBack; }
|
||||
|
||||
#ifdef YARR_8BIT_CHAR_SUPPORT
|
||||
bool has8BitCode() const { return m_ref8.size(); }
|
||||
bool has8BitCode() const { return m_ref8.allocSize(); }
|
||||
void set8BitCode(MacroAssemblerCodeRef ref) { m_ref8 = ref; }
|
||||
bool has8BitCodeMatchOnly() const { return m_matchOnly8.size(); }
|
||||
bool has8BitCodeMatchOnly() const { return m_matchOnly8.allocSize(); }
|
||||
void set8BitCodeMatchOnly(MacroAssemblerCodeRef matchOnly) { m_matchOnly8 = matchOnly; }
|
||||
#endif
|
||||
|
||||
bool has16BitCode() const { return m_ref16.size(); }
|
||||
bool has16BitCode() const { return m_ref16.allocSize(); }
|
||||
void set16BitCode(MacroAssemblerCodeRef ref) { m_ref16 = ref; }
|
||||
|
||||
bool has16BitCodeMatchOnly() const { return m_matchOnly16.size(); }
|
||||
bool has16BitCodeMatchOnly() const { return m_matchOnly16.allocSize(); }
|
||||
void set16BitCodeMatchOnly(MacroAssemblerCodeRef matchOnly) { m_matchOnly16 = matchOnly; }
|
||||
|
||||
#if YARR_8BIT_CHAR_SUPPORT
|
||||
|
@ -3761,9 +3761,6 @@ FrameLayerBuilder::DrawThebesLayer(ThebesLayer* aLayer,
|
||||
nsRefPtr<nsRenderingContext> rc = new nsRenderingContext();
|
||||
rc->Init(presContext->DeviceContext(), aContext);
|
||||
|
||||
nsIntRegion temp = builder->GetRegionToClear();
|
||||
builder->ResetRegionToClear();
|
||||
|
||||
if (shouldDrawRectsSeparately) {
|
||||
nsIntRegionRectIterator it(aRegionToDraw);
|
||||
while (const nsIntRect* iterRect = it.Next()) {
|
||||
@ -3805,12 +3802,6 @@ FrameLayerBuilder::DrawThebesLayer(ThebesLayer* aLayer,
|
||||
if (!aRegionToInvalidate.IsEmpty()) {
|
||||
aLayer->AddInvalidRect(aRegionToInvalidate.GetBounds());
|
||||
}
|
||||
|
||||
if (!builder->GetRegionToClear().IsEmpty()) {
|
||||
aLayer->Manager()->SetRegionToClear(builder->GetRegionToClear());
|
||||
}
|
||||
builder->ResetRegionToClear();
|
||||
builder->AddRegionToClear(temp);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -854,7 +854,8 @@ nsCaret::GetCaretFrameForNodeOffset(nsIContent* aContentNode,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsCaret::CheckCaretDrawingState()
|
||||
void
|
||||
nsCaret::CheckCaretDrawingState()
|
||||
{
|
||||
if (mDrawn) {
|
||||
// The caret is drawn; if it shouldn't be, erase it.
|
||||
@ -867,7 +868,6 @@ nsresult nsCaret::CheckCaretDrawingState()
|
||||
if (mPendingDraw && (mVisible && MustDrawCaret(true)))
|
||||
DrawCaret(true);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
@ -163,7 +163,7 @@ class nsCaret : public nsISelectionListener
|
||||
nsIFrame** aReturnFrame,
|
||||
int32_t* aReturnOffset);
|
||||
|
||||
NS_IMETHOD CheckCaretDrawingState();
|
||||
void CheckCaretDrawingState();
|
||||
|
||||
protected:
|
||||
|
||||
|
@ -2358,6 +2358,7 @@ nsDisplayThemedBackground::nsDisplayThemedBackground(nsDisplayListBuilder* aBuil
|
||||
case NS_THEME_WINDOW_TITLEBAR:
|
||||
case NS_THEME_WINDOW_BUTTON_BOX:
|
||||
case NS_THEME_MOZ_MAC_FULLSCREEN_BUTTON:
|
||||
case NS_THEME_WINDOW_BUTTON_BOX_MAXIMIZED:
|
||||
RegisterThemeGeometry(aBuilder, aFrame);
|
||||
break;
|
||||
case NS_THEME_WIN_BORDERLESS_GLASS:
|
||||
@ -2445,11 +2446,7 @@ nsDisplayThemedBackground::PaintInternal(nsDisplayListBuilder* aBuilder,
|
||||
theme->GetWidgetOverflow(presContext->DeviceContext(), mFrame, mAppearance,
|
||||
&drawing);
|
||||
drawing.IntersectRect(drawing, aBounds);
|
||||
nsIntRegion clear;
|
||||
theme->DrawWidgetBackground(aCtx, mFrame, mAppearance, borderArea, drawing, &clear);
|
||||
MOZ_ASSERT(clear.IsEmpty() || ReferenceFrame() == aBuilder->RootReferenceFrame(),
|
||||
"Can't add to clear region if we're transformed!");
|
||||
aBuilder->AddRegionToClear(clear);
|
||||
theme->DrawWidgetBackground(aCtx, mFrame, mAppearance, borderArea, drawing);
|
||||
}
|
||||
|
||||
bool nsDisplayThemedBackground::IsWindowActive()
|
||||
|
@ -641,10 +641,6 @@ public:
|
||||
|
||||
DisplayListClipState& ClipState() { return mClipState; }
|
||||
|
||||
void AddRegionToClear(const nsIntRegion& aRegion) { mRegionToClear.Or(mRegionToClear, aRegion); }
|
||||
const nsIntRegion& GetRegionToClear() { return mRegionToClear; }
|
||||
void ResetRegionToClear() { mRegionToClear.SetEmpty(); }
|
||||
|
||||
private:
|
||||
void MarkOutOfFlowFrameForDisplay(nsIFrame* aDirtyFrame, nsIFrame* aFrame,
|
||||
const nsRect& aDirtyRect);
|
||||
@ -678,8 +674,6 @@ private:
|
||||
const nsIFrame* mCachedReferenceFrame;
|
||||
nsPoint mCachedOffset;
|
||||
nsRegion mExcludedGlassRegion;
|
||||
// Area of the window (in pixels) to clear so the OS can draw them.
|
||||
nsIntRegion mRegionToClear;
|
||||
// The display item for the Windows window glass background, if any
|
||||
nsDisplayItem* mGlassDisplayItem;
|
||||
nsTArray<DisplayItemClip*> mDisplayItemClipsToDestroy;
|
||||
|
@ -503,6 +503,9 @@ public class BrowserToolbar extends GeckoRelativeLayout
|
||||
break;
|
||||
|
||||
case SELECTED:
|
||||
flags.add(UpdateFlags.PRIVATE_MODE);
|
||||
setPrivateMode(tab.isPrivate());
|
||||
// Fall through.
|
||||
case LOAD_ERROR:
|
||||
flags.add(UpdateFlags.TITLE);
|
||||
// Fall through.
|
||||
@ -511,12 +514,9 @@ public class BrowserToolbar extends GeckoRelativeLayout
|
||||
// us of a title change, so we don't update the title here.
|
||||
flags.add(UpdateFlags.FAVICON);
|
||||
flags.add(UpdateFlags.SITE_IDENTITY);
|
||||
flags.add(UpdateFlags.PRIVATE_MODE);
|
||||
|
||||
updateBackButton(tab);
|
||||
updateForwardButton(tab);
|
||||
|
||||
setPrivateMode(tab.isPrivate());
|
||||
break;
|
||||
|
||||
case TITLE:
|
||||
|
@ -5,7 +5,7 @@
|
||||
MOZ_APP_BASENAME=Fennec
|
||||
MOZ_APP_VENDOR=Mozilla
|
||||
|
||||
MOZ_APP_VERSION=30.0a1
|
||||
MOZ_APP_VERSION=31.0a1
|
||||
MOZ_APP_UA_NAME=Firefox
|
||||
|
||||
MOZ_BRANDING_DIRECTORY=mobile/android/branding/unofficial
|
||||
|
@ -294,6 +294,7 @@ pref("media.tabstreaming.time_per_frame", 40);
|
||||
|
||||
// TextTrack support
|
||||
pref("media.webvtt.enabled", true);
|
||||
pref("media.webvtt.regions.enabled", false);
|
||||
|
||||
// Whether to enable MediaSource support
|
||||
pref("media.mediasource.enabled", false);
|
||||
|
@ -3,7 +3,7 @@
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
# Definitions used by constants.js.
|
||||
weave_version := 1.32.0
|
||||
weave_version := 1.33.0
|
||||
weave_id := {340c2bbc-ce74-4362-90b5-7c26312808ef}
|
||||
|
||||
# Preprocess files.
|
||||
|
@ -63,7 +63,7 @@ XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "OS",
|
||||
"resource://gre/modules/osfile.jsm")
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Promise",
|
||||
"resource://gre/modules/commonjs/sdk/core/promise.js");
|
||||
"resource://gre/modules/Promise.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Services",
|
||||
"resource://gre/modules/Services.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Task",
|
||||
@ -411,27 +411,48 @@ this.Download.prototype = {
|
||||
}
|
||||
}
|
||||
|
||||
// In case the download was restarted while cancellation was in progress,
|
||||
// but the previous attempt actually succeeded before cancellation could
|
||||
// be processed, it is possible that the download has already finished.
|
||||
if (this.succeeded) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// Disallow download if parental controls service restricts it.
|
||||
if (yield DownloadIntegration.shouldBlockForParentalControls(this)) {
|
||||
throw new DownloadError({ becauseBlockedByParentalControls: true });
|
||||
}
|
||||
|
||||
// We should check if we have been canceled in the meantime, after all
|
||||
// the previous asynchronous operations have been executed and just
|
||||
// before we call the "execute" method of the saver.
|
||||
if (this._promiseCanceled) {
|
||||
// The exception will become a cancellation in the "catch" block.
|
||||
throw undefined;
|
||||
}
|
||||
|
||||
// Execute the actual download through the saver object.
|
||||
this._saverExecuting = true;
|
||||
yield this.saver.execute(DS_setProgressBytes.bind(this),
|
||||
DS_setProperties.bind(this));
|
||||
|
||||
// Check for application reputation, which requires the entire file to
|
||||
// be downloaded.
|
||||
if (yield DownloadIntegration.shouldBlockForReputationCheck(this)) {
|
||||
// Delete the target file that BackgroundFileSaver already moved
|
||||
// into place.
|
||||
// be downloaded. After that, check for the last time if the download
|
||||
// has been canceled. Both cases require the target file to be deleted,
|
||||
// thus we process both in the same block of code.
|
||||
if ((yield DownloadIntegration.shouldBlockForReputationCheck(this)) ||
|
||||
this._promiseCanceled) {
|
||||
try {
|
||||
yield OS.File.remove(this.target.path);
|
||||
} catch (ex) {
|
||||
Cu.reportError(ex);
|
||||
}
|
||||
// If this is actually a cancellation, this exception will be changed
|
||||
// in the catch block below.
|
||||
throw new DownloadError({ becauseBlockedByReputationCheck: true });
|
||||
}
|
||||
|
||||
// Update the status properties for a successful download.
|
||||
this.progress = 100;
|
||||
this.succeeded = true;
|
||||
@ -461,6 +482,7 @@ this.Download.prototype = {
|
||||
throw ex;
|
||||
} finally {
|
||||
// Any cancellation request has now been processed.
|
||||
this._saverExecuting = false;
|
||||
this._promiseCanceled = null;
|
||||
|
||||
// Update the status properties, unless a new attempt already started.
|
||||
@ -546,6 +568,12 @@ this.Download.prototype = {
|
||||
*/
|
||||
_promiseCanceled: null,
|
||||
|
||||
/**
|
||||
* True between the call to the "execute" method of the saver and the
|
||||
* completion of the current download attempt.
|
||||
*/
|
||||
_saverExecuting: false,
|
||||
|
||||
/**
|
||||
* Cancels the download.
|
||||
*
|
||||
@ -589,8 +617,12 @@ this.Download.prototype = {
|
||||
this.canceled = true;
|
||||
this._notifyChange();
|
||||
|
||||
// Execute the actual cancellation through the saver object.
|
||||
this.saver.cancel();
|
||||
// Execute the actual cancellation through the saver object, in case it
|
||||
// has already started. Otherwise, the cancellation will be handled just
|
||||
// before the saver is started.
|
||||
if (this._saverExecuting) {
|
||||
this.saver.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
return this._promiseCanceled;
|
||||
@ -1363,31 +1395,6 @@ this.DownloadSaver.prototype = {
|
||||
targetUri);
|
||||
},
|
||||
|
||||
/**
|
||||
* Return true if the request's response has been blocked by Windows parental
|
||||
* controls with an HTTP 450 error code.
|
||||
*
|
||||
* @param aRequest
|
||||
* nsIRequest object
|
||||
* @return True if the response is blocked.
|
||||
*/
|
||||
isResponseParentalBlocked: function(aRequest)
|
||||
{
|
||||
// If the HTTP status is 450, then Windows Parental Controls have
|
||||
// blocked this download.
|
||||
if (aRequest instanceof Ci.nsIHttpChannel &&
|
||||
aRequest.responseStatus == 450) {
|
||||
// Cancel the request, but set a flag on the download that can be
|
||||
// retrieved later when handling the cancellation so that the proper
|
||||
// blocked by parental controls error can be thrown.
|
||||
this.download._blockedByParentalControls = true;
|
||||
aRequest.cancel(Cr.NS_BINDING_ABORTED);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns a static representation of the current object state.
|
||||
*
|
||||
@ -1612,7 +1619,14 @@ this.DownloadCopySaver.prototype = {
|
||||
onStartRequest: function (aRequest, aContext) {
|
||||
backgroundFileSaver.onStartRequest(aRequest, aContext);
|
||||
|
||||
if (this.isResponseParentalBlocked(aRequest)) {
|
||||
// Check if the request's response has been blocked by Windows
|
||||
// Parental Controls with an HTTP 450 error code.
|
||||
if (aRequest instanceof Ci.nsIHttpChannel &&
|
||||
aRequest.responseStatus == 450) {
|
||||
// Set a flag that can be retrieved later when handling the
|
||||
// cancellation so that the proper error can be thrown.
|
||||
this.download._blockedByParentalControls = true;
|
||||
aRequest.cancel(Cr.NS_BINDING_ABORTED);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1707,6 +1721,13 @@ this.DownloadCopySaver.prototype = {
|
||||
}.bind(copySaver),
|
||||
}, null);
|
||||
|
||||
// We should check if we have been canceled in the meantime, after
|
||||
// all the previous asynchronous operations have been executed and
|
||||
// just before we set the _backgroundFileSaver property.
|
||||
if (this._canceled) {
|
||||
throw new DownloadError({ message: "Saver canceled." });
|
||||
}
|
||||
|
||||
// If the operation succeeded, store the object to allow cancellation.
|
||||
this._backgroundFileSaver = backgroundFileSaver;
|
||||
} catch (ex) {
|
||||
@ -1930,10 +1951,6 @@ this.DownloadLegacySaver.prototype = {
|
||||
ex.result == Cr.NS_ERROR_NOT_RESUMABLE) { }
|
||||
}
|
||||
|
||||
if (this.isResponseParentalBlocked(aRequest)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// For legacy downloads, we must update the referrer at this time.
|
||||
if (aRequest instanceof Ci.nsIHttpChannel && aRequest.referrer) {
|
||||
this.download.source.referrer = aRequest.referrer.spec;
|
||||
|
@ -46,7 +46,7 @@ XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
|
||||
"resource://gre/modules/PlacesUtils.jsm");
|
||||
#endif
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Promise",
|
||||
"resource://gre/modules/commonjs/sdk/core/promise.js");
|
||||
"resource://gre/modules/Promise.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Services",
|
||||
"resource://gre/modules/Services.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Task",
|
||||
|
@ -29,7 +29,7 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Downloads",
|
||||
"resource://gre/modules/Downloads.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Promise",
|
||||
"resource://gre/modules/commonjs/sdk/core/promise.js");
|
||||
"resource://gre/modules/Promise.jsm");
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// DownloadLegacyTransfer
|
||||
@ -89,9 +89,25 @@ DownloadLegacyTransfer.prototype = {
|
||||
|
||||
if ((aStateFlags & Ci.nsIWebProgressListener.STATE_START) &&
|
||||
(aStateFlags & Ci.nsIWebProgressListener.STATE_IS_NETWORK)) {
|
||||
|
||||
// If the request's response has been blocked by Windows Parental Controls
|
||||
// with an HTTP 450 error code, we must cancel the request synchronously.
|
||||
let blockedByParentalControls = aRequest instanceof Ci.nsIHttpChannel &&
|
||||
aRequest.responseStatus == 450;
|
||||
if (blockedByParentalControls) {
|
||||
aRequest.cancel(Cr.NS_BINDING_ABORTED);
|
||||
}
|
||||
|
||||
// The main request has just started. Wait for the associated Download
|
||||
// object to be available before notifying.
|
||||
this._deferDownload.promise.then(download => {
|
||||
// If the request was blocked, now that we have the download object we
|
||||
// should set a flag that can be retrieved later when handling the
|
||||
// cancellation so that the proper error can be thrown.
|
||||
if (blockedByParentalControls) {
|
||||
download._blockedByParentalControls = true;
|
||||
}
|
||||
|
||||
download.saver.onTransferStarted(
|
||||
aRequest,
|
||||
this._cancelable instanceof Ci.nsIHelperAppLauncher);
|
||||
|
@ -37,7 +37,7 @@ const Cr = Components.results;
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Promise",
|
||||
"resource://gre/modules/commonjs/sdk/core/promise.js");
|
||||
"resource://gre/modules/Promise.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Task",
|
||||
"resource://gre/modules/Task.jsm");
|
||||
|
||||
|
@ -27,7 +27,7 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "OS",
|
||||
"resource://gre/modules/osfile.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Promise",
|
||||
"resource://gre/modules/commonjs/sdk/core/promise.js");
|
||||
"resource://gre/modules/Promise.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Services",
|
||||
"resource://gre/modules/Services.jsm");
|
||||
|
||||
|
@ -36,7 +36,7 @@ XPCOMUtils.defineLazyModuleGetter(this, "DownloadSummary",
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "DownloadUIHelper",
|
||||
"resource://gre/modules/DownloadUIHelper.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Promise",
|
||||
"resource://gre/modules/commonjs/sdk/core/promise.js");
|
||||
"resource://gre/modules/Promise.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Task",
|
||||
"resource://gre/modules/Task.jsm");
|
||||
|
||||
|
@ -806,7 +806,10 @@ add_task(function test_cancel_immediately_restart_immediately()
|
||||
continueResponses();
|
||||
try {
|
||||
yield promiseAttempt;
|
||||
do_throw("The download should have been canceled.");
|
||||
// If we get here, it means that the first attempt actually succeeded. In
|
||||
// fact, this could be a valid outcome, because the cancellation request may
|
||||
// not have been processed in time before the download finished.
|
||||
do_print("The download should have been canceled.");
|
||||
} catch (ex if ex instanceof Downloads.Error) {
|
||||
do_check_false(ex.becauseSourceFailed);
|
||||
do_check_false(ex.becauseTargetFailed);
|
||||
|
@ -34,7 +34,7 @@ XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
|
||||
"resource://gre/modules/PlacesUtils.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Promise",
|
||||
"resource://gre/modules/commonjs/sdk/core/promise.js");
|
||||
"resource://gre/modules/Promise.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Services",
|
||||
"resource://gre/modules/Services.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Task",
|
||||
@ -731,6 +731,15 @@ add_task(function test_common_initialize()
|
||||
gHttpServer.registerDirectory("/", do_get_file("../data"));
|
||||
gHttpServer.start(-1);
|
||||
|
||||
// Cache locks might prevent concurrent requests to the same resource, and
|
||||
// this may block tests that use the interruptible handlers.
|
||||
Services.prefs.setBoolPref("browser.cache.disk.enable", false);
|
||||
Services.prefs.setBoolPref("browser.cache.memory.enable", false);
|
||||
do_register_cleanup(function () {
|
||||
Services.prefs.clearUserPref("browser.cache.disk.enable");
|
||||
Services.prefs.clearUserPref("browser.cache.memory.enable");
|
||||
});
|
||||
|
||||
registerInterruptibleHandler("/interruptible.txt",
|
||||
function firstPart(aRequest, aResponse) {
|
||||
aResponse.setHeader("Content-Type", "text/plain", false);
|
||||
|
@ -25,6 +25,15 @@ This is likely the same like id.heading in crashes.dtd. -->
|
||||
<!ENTITY aboutSupport.extensionVersion "Version">
|
||||
<!ENTITY aboutSupport.extensionId "ID">
|
||||
|
||||
<!ENTITY aboutSupport.experimentsTitle "Experimental Features">
|
||||
<!ENTITY aboutSupport.experimentName "Name">
|
||||
<!ENTITY aboutSupport.experimentId "ID">
|
||||
<!ENTITY aboutSupport.experimentDescription "Description">
|
||||
<!ENTITY aboutSupport.experimentActive "Active">
|
||||
<!ENTITY aboutSupport.experimentEndDate "End Date">
|
||||
<!ENTITY aboutSupport.experimentHomepage "Homepage">
|
||||
|
||||
|
||||
<!ENTITY aboutSupport.appBasicsTitle "Application Basics">
|
||||
<!ENTITY aboutSupport.appBasicsName "Name">
|
||||
<!ENTITY aboutSupport.appBasicsVersion "Version">
|
||||
|
@ -14,20 +14,21 @@ XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
|
||||
"nsIMessageSender");
|
||||
|
||||
function paymentSuccess(aRequestId) {
|
||||
return paymentCallback(aRequestId, "Payment:Success");
|
||||
return function(aResult) {
|
||||
closePaymentWindow(aRequestId, function() {
|
||||
cpmm.sendAsyncMessage("Payment:Success", { requestId: aRequestId,
|
||||
result: aResult });
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function paymentFailed(aRequestId) {
|
||||
return paymentCallback(aRequestId, "Payment:Failed");
|
||||
}
|
||||
|
||||
function paymentCallback(aRequestId, aMsg) {
|
||||
return function(aResult) {
|
||||
closePaymentWindow(aRequestId, function() {
|
||||
cpmm.sendAsyncMessage(aMsg, { result: aResult,
|
||||
requestId: aRequestId });
|
||||
});
|
||||
};
|
||||
return function(aErrorMsg) {
|
||||
closePaymentWindow(aRequestId, function() {
|
||||
cpmm.sendAsyncMessage("Payment:Failed", { requestId: aRequestId,
|
||||
errorMsg: aErrorMsg });
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
let payments = {};
|
||||
|
@ -1,11 +1,22 @@
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
let { PaymentManager } = Cu.import("resource://gre/modules/Payment.jsm", {});
|
||||
Cu.import("resource://webapprt/modules/WebappRT.jsm");
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
let providerWindow = null;
|
||||
let providerUri = "https://example.com:443/webapprtChrome/webapprt/test/chrome/mozpay-success.html?req=";
|
||||
let curTest = 0;
|
||||
|
||||
let tests = [];
|
||||
tests.push({
|
||||
providerUri: "https://example.com:443/webapprtChrome/webapprt/test/chrome/mozpay-success.html?req=",
|
||||
message: "Success."
|
||||
});
|
||||
tests.push({
|
||||
providerUri: "https://example.com:443/webapprtChrome/webapprt/test/chrome/mozpay-failure.html?req=",
|
||||
message: "Chocolate rejected."
|
||||
});
|
||||
|
||||
let jwt = "eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyJhdWQiOiAibW9j" +
|
||||
"a3BheXByb3ZpZGVyLnBocGZvZ2FwcC5jb20iLCAiaXNzIjogIkVudGVyI" +
|
||||
"HlvdSBhcHAga2V5IGhlcmUhIiwgInJlcXVlc3QiOiB7Im5hbWUiOiAiUG" +
|
||||
@ -21,17 +32,19 @@ function test() {
|
||||
PaymentManager.registeredProviders["mock/payments/inapp/v1"] = {
|
||||
name: "mockprovider",
|
||||
description: "Mock Payment Provider",
|
||||
uri: providerUri,
|
||||
uri: tests[curTest].providerUri,
|
||||
requestMethod: "GET"
|
||||
};
|
||||
|
||||
let providerWindow;
|
||||
|
||||
let winObserver = function(win, topic) {
|
||||
if (topic == "domwindowopened") {
|
||||
win.addEventListener("load", function onLoadWindow() {
|
||||
win.removeEventListener("load", onLoadWindow, false);
|
||||
|
||||
if (win.document.getElementById("content").getAttribute("src") ==
|
||||
(providerUri + jwt)) {
|
||||
(tests[curTest].providerUri + jwt)) {
|
||||
ok(true, "Payment provider window shown.");
|
||||
providerWindow = win;
|
||||
}
|
||||
@ -43,25 +56,45 @@ function test() {
|
||||
|
||||
let mutObserver = null;
|
||||
|
||||
loadWebapp("mozpay.webapp", undefined, function onLoad() {
|
||||
function onLoad() {
|
||||
let msg = gAppBrowser.contentDocument.getElementById("msg");
|
||||
mutObserver = new MutationObserver(function(mutations) {
|
||||
if (msg.textContent == "Success.") {
|
||||
ok(true, "Payment success.");
|
||||
} else {
|
||||
ok(false, "Payment success.");
|
||||
}
|
||||
is(msg.textContent, tests[curTest].message, "Got: " + tests[curTest].message);
|
||||
|
||||
if (providerWindow == null) {
|
||||
if (!providerWindow) {
|
||||
ok(false, "Payment provider window shown.");
|
||||
} else {
|
||||
providerWindow.close();
|
||||
providerWindow = null;
|
||||
}
|
||||
|
||||
finish();
|
||||
runNextTest();
|
||||
});
|
||||
mutObserver.observe(msg, { childList: true });
|
||||
});
|
||||
}
|
||||
|
||||
loadWebapp("mozpay.webapp", undefined, onLoad);
|
||||
|
||||
function runNextTest() {
|
||||
providerWindow = null;
|
||||
if (mutObserver) {
|
||||
mutObserver.disconnect();
|
||||
}
|
||||
|
||||
curTest++;
|
||||
|
||||
if (curTest < tests.length) {
|
||||
PaymentManager.registeredProviders["mock/payments/inapp/v1"].uri = tests[curTest].providerUri;
|
||||
|
||||
gAppBrowser.addEventListener("load", function onLoadH() {
|
||||
gAppBrowser.removeEventListener("load", onLoadH, true);
|
||||
onLoad();
|
||||
}, true);
|
||||
gAppBrowser.reload();
|
||||
} else {
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
Services.ww.unregisterNotification(winObserver);
|
||||
|
12
webapprt/test/chrome/mozpay-failure.html
Normal file
12
webapprt/test/chrome/mozpay-failure.html
Normal file
@ -0,0 +1,12 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
mozPaymentProvider.paymentFailed('Chocolate rejected.');
|
||||
</script>
|
||||
<p id="msg">Webapp waiting to pay...</p>
|
||||
</body>
|
||||
</html>
|
@ -37,7 +37,7 @@
|
||||
document.getElementById("msg").textContent = "Success.";
|
||||
};
|
||||
request.onerror = function onerror() {
|
||||
document.getElementById("msg").textContent = "Failure.";
|
||||
document.getElementById("msg").textContent = request.error.name;
|
||||
};
|
||||
</script>
|
||||
<p id="msg">Webapp waiting to be paid...</p>
|
||||
|
@ -26,6 +26,7 @@ support-files =
|
||||
mozpay.webapp^headers^
|
||||
mozpay.html
|
||||
mozpay-success.html
|
||||
mozpay-failure.html
|
||||
getUserMedia.webapp
|
||||
getUserMedia.webapp^headers^
|
||||
getUserMedia.html
|
||||
|
@ -34,8 +34,7 @@ public:
|
||||
nsIFrame* aFrame,
|
||||
uint8_t aWidgetType,
|
||||
const nsRect& aRect,
|
||||
const nsRect& aDirtyRect,
|
||||
nsIntRegion* aRegionToClear);
|
||||
const nsRect& aDirtyRect);
|
||||
NS_IMETHOD GetWidgetBorder(nsDeviceContext* aContext,
|
||||
nsIFrame* aFrame,
|
||||
uint8_t aWidgetType,
|
||||
|
@ -2080,8 +2080,7 @@ nsNativeThemeCocoa::DrawWidgetBackground(nsRenderingContext* aContext,
|
||||
nsIFrame* aFrame,
|
||||
uint8_t aWidgetType,
|
||||
const nsRect& aRect,
|
||||
const nsRect& aDirtyRect,
|
||||
nsIntRegion* aRegionToClear)
|
||||
const nsRect& aDirtyRect)
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
|
||||
|
||||
|
@ -752,8 +752,7 @@ nsNativeThemeGTK::DrawWidgetBackground(nsRenderingContext* aContext,
|
||||
nsIFrame* aFrame,
|
||||
uint8_t aWidgetType,
|
||||
const nsRect& aRect,
|
||||
const nsRect& aDirtyRect,
|
||||
nsIntRegion* aRegionToClear)
|
||||
const nsRect& aDirtyRect)
|
||||
{
|
||||
GtkWidgetState state;
|
||||
GtkThemeWidgetType gtkWidgetType;
|
||||
|
@ -24,8 +24,7 @@ public:
|
||||
NS_IMETHOD DrawWidgetBackground(nsRenderingContext* aContext,
|
||||
nsIFrame* aFrame, uint8_t aWidgetType,
|
||||
const nsRect& aRect,
|
||||
const nsRect& aDirtyRect,
|
||||
nsIntRegion* aRegionToClear);
|
||||
const nsRect& aDirtyRect);
|
||||
|
||||
NS_IMETHOD GetWidgetBorder(nsDeviceContext* aContext, nsIFrame* aFrame,
|
||||
uint8_t aWidgetType, nsIntMargin* aResult);
|
||||
|
@ -1536,8 +1536,7 @@ nsNativeThemeWin::DrawWidgetBackground(nsRenderingContext* aContext,
|
||||
nsIFrame* aFrame,
|
||||
uint8_t aWidgetType,
|
||||
const nsRect& aRect,
|
||||
const nsRect& aDirtyRect,
|
||||
nsIntRegion* aRegionToClear)
|
||||
const nsRect& aDirtyRect)
|
||||
{
|
||||
HANDLE theme = GetTheme(aWidgetType);
|
||||
if (!theme)
|
||||
@ -1568,6 +1567,10 @@ nsNativeThemeWin::DrawWidgetBackground(nsRenderingContext* aContext,
|
||||
case NS_THEME_WIN_BORDERLESS_GLASS:
|
||||
// Nothing to draw, this is the glass background.
|
||||
return NS_OK;
|
||||
case NS_THEME_WINDOW_BUTTON_BOX:
|
||||
case NS_THEME_WINDOW_BUTTON_BOX_MAXIMIZED:
|
||||
// We handle these through nsIWidget::UpdateThemeGeometries
|
||||
return NS_OK;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1900,20 +1903,6 @@ RENDER_AGAIN:
|
||||
DrawThemeBackground(theme, hdc, gripPart, state, &widgetRect, &clipRect);
|
||||
}
|
||||
}
|
||||
else if ((aWidgetType == NS_THEME_WINDOW_BUTTON_BOX ||
|
||||
aWidgetType == NS_THEME_WINDOW_BUTTON_BOX_MAXIMIZED) &&
|
||||
nsUXThemeData::CheckForCompositor())
|
||||
{
|
||||
// The caption buttons are drawn by the DWM, we just need to clear the area where they
|
||||
// are because we might have drawn something above them (like a background-image).
|
||||
NS_ASSERTION(aRegionToClear, "Must have a clear region to set!");
|
||||
if (aRegionToClear) {
|
||||
// Create a rounded rectangle to follow the buttons' look.
|
||||
*aRegionToClear = nsIntRect(dr.X(), dr.Y(), dr.Width(), dr.Height() - 2.0);
|
||||
aRegionToClear->Or(*aRegionToClear, nsIntRect(dr.X() + 1.0, dr.YMost() - 2.0, dr.Width() - 1.0, 1.0));
|
||||
aRegionToClear->Or(*aRegionToClear, nsIntRect(dr.X() + 2.0, dr.YMost() - 1.0, dr.Width() - 3.0, 1.0));
|
||||
}
|
||||
}
|
||||
|
||||
nativeDrawing.EndNativeDrawing();
|
||||
|
||||
|
@ -31,8 +31,7 @@ public:
|
||||
nsIFrame* aFrame,
|
||||
uint8_t aWidgetType,
|
||||
const nsRect& aRect,
|
||||
const nsRect& aDirtyRect,
|
||||
nsIntRegion* aRegionToClear);
|
||||
const nsRect& aDirtyRect);
|
||||
|
||||
NS_IMETHOD GetWidgetBorder(nsDeviceContext* aContext,
|
||||
nsIFrame* aFrame,
|
||||
|
@ -127,6 +127,7 @@
|
||||
#include "nsToolkitCompsCID.h"
|
||||
#include "nsIAppStartup.h"
|
||||
#include "mozilla/WindowsVersion.h"
|
||||
#include "nsThemeConstants.h"
|
||||
|
||||
#ifdef MOZ_ENABLE_D3D9_LAYER
|
||||
#include "LayerManagerD3D9.h"
|
||||
@ -3556,6 +3557,28 @@ nsWindow::EndRemoteDrawing()
|
||||
mCompositeDC = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
nsWindow::UpdateThemeGeometries(const nsTArray<ThemeGeometry>& aThemeGeometries)
|
||||
{
|
||||
nsIntRegion clearRegion;
|
||||
for (size_t i = 0; i < aThemeGeometries.Length(); i++) {
|
||||
if ((aThemeGeometries[i].mWidgetType == NS_THEME_WINDOW_BUTTON_BOX ||
|
||||
aThemeGeometries[i].mWidgetType == NS_THEME_WINDOW_BUTTON_BOX_MAXIMIZED) &&
|
||||
nsUXThemeData::CheckForCompositor())
|
||||
{
|
||||
nsIntRect bounds = aThemeGeometries[i].mRect;
|
||||
clearRegion = nsIntRect(bounds.X(), bounds.Y(), bounds.Width(), bounds.Height() - 2.0);
|
||||
clearRegion.Or(clearRegion, nsIntRect(bounds.X() + 1.0, bounds.YMost() - 2.0, bounds.Width() - 1.0, 1.0));
|
||||
clearRegion.Or(clearRegion, nsIntRect(bounds.X() + 2.0, bounds.YMost() - 1.0, bounds.Width() - 3.0, 1.0));
|
||||
}
|
||||
}
|
||||
|
||||
nsRefPtr<LayerManager> layerManager = GetLayerManager();
|
||||
if (layerManager) {
|
||||
layerManager->SetRegionToClear(clearRegion);
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************
|
||||
**************************************************************
|
||||
**
|
||||
|
@ -196,6 +196,8 @@ public:
|
||||
mozilla::TemporaryRef<mozilla::gfx::DrawTarget> StartRemoteDrawing() MOZ_OVERRIDE;
|
||||
virtual void EndRemoteDrawing() MOZ_OVERRIDE;
|
||||
|
||||
virtual void UpdateThemeGeometries(const nsTArray<ThemeGeometry>& aThemeGeometries) MOZ_OVERRIDE;
|
||||
|
||||
/**
|
||||
* Event helpers
|
||||
*/
|
||||
|
@ -21,7 +21,7 @@ namespace mozilla {
|
||||
*/
|
||||
struct Module
|
||||
{
|
||||
static const unsigned int kVersion = 30;
|
||||
static const unsigned int kVersion = 31;
|
||||
|
||||
struct CIDEntry;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user