зеркало из https://github.com/mozilla/gecko-dev.git
Merge last PGO-green changeset of mozilla-inbound to mozilla-central
This commit is contained in:
Коммит
28207192bd
|
@ -14,7 +14,6 @@ this.EXPORTED_SYMBOLS = ['AccessFu'];
|
|||
Cu.import('resource://gre/modules/Services.jsm');
|
||||
|
||||
Cu.import('resource://gre/modules/accessibility/Utils.jsm');
|
||||
Cu.import('resource://gre/modules/accessibility/TouchAdapter.jsm');
|
||||
|
||||
const ACCESSFU_DISABLE = 0;
|
||||
const ACCESSFU_ENABLE = 1;
|
||||
|
@ -58,6 +57,8 @@ this.AccessFu = {
|
|||
this._activatePref = ACCESSFU_DISABLE;
|
||||
}
|
||||
|
||||
Input.quickNavMode.updateModes(this.prefsBranch);
|
||||
|
||||
this._enableOrDisable();
|
||||
},
|
||||
|
||||
|
@ -76,9 +77,6 @@ this.AccessFu = {
|
|||
|
||||
Logger.info('enable');
|
||||
|
||||
this.touchAdapter = (Utils.MozBuildApp == 'mobile/android') ?
|
||||
AndroidTouchAdapter : TouchAdapter;
|
||||
|
||||
for each (let mm in Utils.getAllMessageManagers(this.chromeWin))
|
||||
this._loadFrameScript(mm);
|
||||
|
||||
|
@ -91,7 +89,7 @@ this.AccessFu = {
|
|||
|
||||
Input.attach(this.chromeWin);
|
||||
Output.attach(this.chromeWin);
|
||||
this.touchAdapter.attach(this.chromeWin);
|
||||
TouchAdapter.attach(this.chromeWin);
|
||||
|
||||
Services.obs.addObserver(this, 'remote-browser-frame-shown', false);
|
||||
Services.obs.addObserver(this, 'Accessibility:NextObject', false);
|
||||
|
@ -117,7 +115,7 @@ this.AccessFu = {
|
|||
mm.sendAsyncMessage('AccessFu:Stop');
|
||||
|
||||
Input.detach();
|
||||
this.touchAdapter.detach(this.chromeWin);
|
||||
TouchAdapter.detach(this.chromeWin);
|
||||
|
||||
this.chromeWin.removeEventListener('TabOpen', this);
|
||||
this.chromeWin.removeEventListener('TabSelect', this);
|
||||
|
@ -205,6 +203,8 @@ this.AccessFu = {
|
|||
if (aData == 'activate') {
|
||||
this._activatePref = this.prefsBranch.getIntPref('activate');
|
||||
this._enableOrDisable();
|
||||
} else if (aData == 'quicknav_modes') {
|
||||
Input.quickNavMode.updateModes(this.prefsBranch);
|
||||
}
|
||||
break;
|
||||
case 'remote-browser-frame-shown':
|
||||
|
@ -389,7 +389,7 @@ var Input = {
|
|||
this._handleKeypress(aEvent);
|
||||
break;
|
||||
case 'mozAccessFuGesture':
|
||||
this._handleGesture(aEvent);
|
||||
this._handleGesture(aEvent.detail);
|
||||
break;
|
||||
}
|
||||
} catch (x) {
|
||||
|
@ -397,44 +397,56 @@ var Input = {
|
|||
}
|
||||
},
|
||||
|
||||
_handleGesture: function _handleGesture(aEvent) {
|
||||
let detail = aEvent.detail;
|
||||
Logger.info('Gesture', detail.type,
|
||||
'(fingers: ' + detail.touches.length + ')');
|
||||
_handleGesture: function _handleGesture(aGesture) {
|
||||
let gestureName = aGesture.type + aGesture.touches.length;
|
||||
Logger.info('Gesture', aGesture.type,
|
||||
'(fingers: ' + aGesture.touches.length + ')');
|
||||
|
||||
if (detail.touches.length == 1) {
|
||||
switch (detail.type) {
|
||||
case 'swiperight':
|
||||
this.moveCursor('moveNext', 'Simple', 'gestures');
|
||||
break;
|
||||
case 'swipeleft':
|
||||
this.moveCursor('movePrevious', 'Simple', 'gesture');
|
||||
break;
|
||||
case 'doubletap':
|
||||
this.activateCurrent();
|
||||
break;
|
||||
case 'explore':
|
||||
this.moveCursor('moveToPoint', 'Simple', 'gesture',
|
||||
detail.x, detail.y);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (detail.touches.length == 3) {
|
||||
switch (detail.type) {
|
||||
case 'swiperight':
|
||||
this.scroll(-1, true);
|
||||
break;
|
||||
case 'swipedown':
|
||||
this.scroll(-1);
|
||||
break;
|
||||
case 'swipeleft':
|
||||
this.scroll(1, true);
|
||||
break;
|
||||
case 'swipeup':
|
||||
this.scroll(1);
|
||||
break;
|
||||
}
|
||||
switch (gestureName) {
|
||||
case 'dwell1':
|
||||
case 'explore1':
|
||||
this.moveCursor('moveToPoint', 'Simple', 'gesture',
|
||||
aGesture.x, aGesture.y);
|
||||
break;
|
||||
case 'doubletap1':
|
||||
this.activateCurrent();
|
||||
break;
|
||||
case 'swiperight1':
|
||||
this.moveCursor('moveNext', 'Simple', 'gestures');
|
||||
break;
|
||||
case 'swipeleft1':
|
||||
this.moveCursor('movePrevious', 'Simple', 'gesture');
|
||||
break;
|
||||
case 'swiperight2':
|
||||
this.scroll(-1, true);
|
||||
break;
|
||||
case 'swipedown2':
|
||||
this.scroll(-1);
|
||||
break;
|
||||
case 'swipeleft2':
|
||||
this.scroll(1, true);
|
||||
break;
|
||||
case 'swipeup2':
|
||||
this.scroll(1);
|
||||
break;
|
||||
case 'explore2':
|
||||
Utils.getCurrentBrowser(this.chromeWin).contentWindow.scrollBy(
|
||||
-aGesture.deltaX, -aGesture.deltaY);
|
||||
break;
|
||||
case 'swiperight3':
|
||||
this.moveCursor('moveNext', this.quickNavMode.current, 'gesture');
|
||||
break;
|
||||
case 'swipeleft3':
|
||||
this.moveCursor('movePrevious', this.quickNavMode.current, 'gesture');
|
||||
break;
|
||||
case 'swipedown3':
|
||||
this.quickNavMode.next();
|
||||
AccessFu.announce('quicknav_' + this.quickNavMode.current);
|
||||
break;
|
||||
case 'swipeup3':
|
||||
this.quickNavMode.previous();
|
||||
AccessFu.announce('quicknav_' + this.quickNavMode.current);
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -568,5 +580,34 @@ var Input = {
|
|||
x: ['moveNext', 'Checkbox'],
|
||||
X: ['movePrevious', 'Checkbox']
|
||||
};
|
||||
|
||||
return this.keyMap;
|
||||
},
|
||||
|
||||
quickNavMode: {
|
||||
get current() {
|
||||
return this.modes[this._currentIndex];
|
||||
},
|
||||
|
||||
previous: function quickNavMode_previous() {
|
||||
if (--this._currentIndex < 0)
|
||||
this._currentIndex = this.modes.length - 1;
|
||||
},
|
||||
|
||||
next: function quickNavMode_next() {
|
||||
if (++this._currentIndex >= this.modes.length)
|
||||
this._currentIndex = 0;
|
||||
},
|
||||
|
||||
updateModes: function updateModes(aPrefsBranch) {
|
||||
try {
|
||||
this.modes = aPrefsBranch.getCharPref('quicknav_modes').split(',');
|
||||
} catch (x) {
|
||||
// Fallback
|
||||
this.modes = [];
|
||||
}
|
||||
},
|
||||
|
||||
_currentIndex: -1
|
||||
}
|
||||
};
|
||||
|
|
|
@ -9,7 +9,7 @@ const Ci = Components.interfaces;
|
|||
const Cu = Components.utils;
|
||||
const Cr = Components.results;
|
||||
|
||||
this.EXPORTED_SYMBOLS = ['TouchAdapter', 'AndroidTouchAdapter'];
|
||||
this.EXPORTED_SYMBOLS = ['TouchAdapter'];
|
||||
|
||||
Cu.import('resource://gre/modules/accessibility/Utils.jsm');
|
||||
|
||||
|
@ -39,6 +39,9 @@ this.TouchAdapter = {
|
|||
// maximum distance the mouse could move during a tap in inches
|
||||
TAP_MAX_RADIUS: 0.2,
|
||||
|
||||
// The virtual touch ID generated by an Android hover event.
|
||||
HOVER_ID: 'hover',
|
||||
|
||||
attach: function TouchAdapter_attach(aWindow) {
|
||||
if (this.chromeWin)
|
||||
return;
|
||||
|
@ -53,14 +56,26 @@ this.TouchAdapter = {
|
|||
this._dpi = this.chromeWin.QueryInterface(Ci.nsIInterfaceRequestor).
|
||||
getInterface(Ci.nsIDOMWindowUtils).displayDPI;
|
||||
|
||||
this.glass = this.chromeWin.document.
|
||||
createElementNS('http://www.w3.org/1999/xhtml', 'div');
|
||||
this.glass.id = 'accessfu-glass';
|
||||
this.chromeWin.document.documentElement.appendChild(this.glass);
|
||||
let target = this.chromeWin;
|
||||
|
||||
this.glass.addEventListener('touchend', this, true, true);
|
||||
this.glass.addEventListener('touchmove', this, true, true);
|
||||
this.glass.addEventListener('touchstart', this, true, true);
|
||||
if (Utils.MozBuildApp == 'b2g') {
|
||||
this.glass = this.chromeWin.document.
|
||||
createElementNS('http://www.w3.org/1999/xhtml', 'div');
|
||||
this.glass.id = 'accessfu-glass';
|
||||
this.chromeWin.document.documentElement.appendChild(this.glass);
|
||||
target = this.glass;
|
||||
}
|
||||
|
||||
target.addEventListener('mousemove', this, true, true);
|
||||
target.addEventListener('mouseenter', this, true, true);
|
||||
target.addEventListener('mouseleave', this, true, true);
|
||||
target.addEventListener('mousedown', this, true, true);
|
||||
target.addEventListener('mouseup', this, true, true);
|
||||
target.addEventListener('click', this, true, true);
|
||||
|
||||
target.addEventListener('touchend', this, true, true);
|
||||
target.addEventListener('touchmove', this, true, true);
|
||||
target.addEventListener('touchstart', this, true, true);
|
||||
|
||||
if (Utils.OS != 'Android')
|
||||
Mouse2Touch.attach(aWindow);
|
||||
|
@ -72,10 +87,23 @@ this.TouchAdapter = {
|
|||
|
||||
Logger.info('TouchAdapter.detach');
|
||||
|
||||
this.glass.removeEventListener('touchend', this, true, true);
|
||||
this.glass.removeEventListener('touchmove', this, true, true);
|
||||
this.glass.removeEventListener('touchstart', this, true, true);
|
||||
this.glass.parentNode.removeChild(this.glass);
|
||||
let target = this.chromeWin;
|
||||
|
||||
if (Utils.MozBuildApp == 'b2g') {
|
||||
target = this.glass;
|
||||
this.glass.parentNode.removeChild(this.glass);
|
||||
}
|
||||
|
||||
target.removeEventListener('mousemove', this, true, true);
|
||||
target.removeEventListener('mouseenter', this, true, true);
|
||||
target.removeEventListener('mouseleave', this, true, true);
|
||||
target.removeEventListener('mousedown', this, true, true);
|
||||
target.removeEventListener('mouseup', this, true, true);
|
||||
target.removeEventListener('click', this, true, true);
|
||||
|
||||
target.removeEventListener('touchend', this, true, true);
|
||||
target.removeEventListener('touchmove', this, true, true);
|
||||
target.removeEventListener('touchstart', this, true, true);
|
||||
|
||||
if (Utils.OS != 'Android')
|
||||
Mouse2Touch.detach(aWindow);
|
||||
|
@ -84,16 +112,23 @@ this.TouchAdapter = {
|
|||
},
|
||||
|
||||
handleEvent: function TouchAdapter_handleEvent(aEvent) {
|
||||
let touches = aEvent.changedTouches;
|
||||
if (this._delayedEvent) {
|
||||
this.chromeWin.clearTimeout(this._delayedEvent);
|
||||
delete this._delayedEvent;
|
||||
}
|
||||
|
||||
let changedTouches = aEvent.changedTouches || [aEvent];
|
||||
|
||||
// XXX: Until bug 77992 is resolved, on desktop we get microseconds
|
||||
// instead of milliseconds.
|
||||
let timeStamp = (Utils.OS == 'Android') ? aEvent.timeStamp : Date.now();
|
||||
switch (aEvent.type) {
|
||||
case 'mouseenter':
|
||||
case 'touchstart':
|
||||
for (var i = 0; i < touches.length; i++) {
|
||||
let touch = touches[i];
|
||||
for (var i = 0; i < changedTouches.length; i++) {
|
||||
let touch = changedTouches[i];
|
||||
let touchPoint = new TouchPoint(touch, timeStamp, this._dpi);
|
||||
this._touchPoints[touch.identifier] = touchPoint;
|
||||
this._touchPoints[touch.identifier || this.HOVER_ID] = touchPoint;
|
||||
this._lastExploreTime = timeStamp + this.SWIPE_MAX_DURATION;
|
||||
}
|
||||
this._dwellTimeout = this.chromeWin.setTimeout(
|
||||
|
@ -101,27 +136,34 @@ this.TouchAdapter = {
|
|||
this.compileAndEmit(timeStamp + this.DWELL_THRESHOLD);
|
||||
}).bind(this), this.DWELL_THRESHOLD);
|
||||
break;
|
||||
case 'mousemove':
|
||||
case 'touchmove':
|
||||
for (var i = 0; i < touches.length; i++) {
|
||||
let touch = touches[i];
|
||||
let touchPoint = this._touchPoints[touch.identifier];
|
||||
touchPoint.update(touch, timeStamp);
|
||||
for (var i = 0; i < changedTouches.length; i++) {
|
||||
let touch = changedTouches[i];
|
||||
let touchPoint = this._touchPoints[touch.identifier || this.HOVER_ID];
|
||||
if (touchPoint)
|
||||
touchPoint.update(touch, timeStamp);
|
||||
}
|
||||
if (timeStamp - this._lastExploreTime >= EXPLORE_THROTTLE) {
|
||||
this.compileAndEmit(timeStamp);
|
||||
this._lastExploreTime = timeStamp;
|
||||
}
|
||||
break;
|
||||
case 'mouseleave':
|
||||
case 'touchend':
|
||||
for (var i = 0; i < touches.length; i++) {
|
||||
let touch = touches[i];
|
||||
let touchPoint = this._touchPoints[touch.identifier];
|
||||
touchPoint.update(touch, timeStamp);
|
||||
touchPoint.finish();
|
||||
for (var i = 0; i < changedTouches.length; i++) {
|
||||
let touch = changedTouches[i];
|
||||
let touchPoint = this._touchPoints[touch.identifier || this.HOVER_ID];
|
||||
if (touchPoint) {
|
||||
touchPoint.update(touch, timeStamp);
|
||||
touchPoint.finish();
|
||||
}
|
||||
}
|
||||
this.compileAndEmit(timeStamp);
|
||||
break;
|
||||
}
|
||||
|
||||
aEvent.preventDefault();
|
||||
},
|
||||
|
||||
cleanupTouches: function cleanupTouches() {
|
||||
|
@ -170,12 +212,22 @@ this.TouchAdapter = {
|
|||
if (timeDelta > this.MAX_CONSECUTIVE_GESTURE_DELAY) {
|
||||
delete this._prevGestures[idhash];
|
||||
} else {
|
||||
if (details.type == 'tap' && prevGesture.type == 'tap')
|
||||
details.type = 'doubletap';
|
||||
if (details.type == 'tap' && prevGesture.type == 'doubletap')
|
||||
details.type = 'tripletap';
|
||||
if (details.type == 'dwell' && prevGesture.type == 'tap')
|
||||
details.type = 'taphold';
|
||||
let sequence = prevGesture.type + '-' + details.type;
|
||||
switch (sequence) {
|
||||
case 'tap-tap':
|
||||
details.type = 'doubletap';
|
||||
break;
|
||||
case 'doubletap-tap':
|
||||
details.type = 'tripletap';
|
||||
break;
|
||||
case 'tap-dwell':
|
||||
details.type = 'taphold';
|
||||
break;
|
||||
case 'explore-explore':
|
||||
details.deltaX = details.x - prevGesture.x;
|
||||
details.deltaY = details.y - prevGesture.y;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -189,9 +241,36 @@ this.TouchAdapter = {
|
|||
},
|
||||
|
||||
emitGesture: function TouchAdapter_emitGesture(aDetails) {
|
||||
let evt = this.chromeWin.document.createEvent('CustomEvent');
|
||||
evt.initCustomEvent('mozAccessFuGesture', true, true, aDetails);
|
||||
this.chromeWin.dispatchEvent(evt);
|
||||
let emitDelay = 0;
|
||||
|
||||
// Unmutate gestures we are getting from Android when EBT is enabled.
|
||||
// Two finger gestures are translated to one. Double taps are translated
|
||||
// to single taps.
|
||||
if (Utils.MozBuildApp == 'mobile/android' &&
|
||||
Utils.AndroidSdkVersion >= 14 &&
|
||||
aDetails.touches[0] != this.HOVER_ID) {
|
||||
if (aDetails.touches.length == 1) {
|
||||
if (aDetails.type == 'tap') {
|
||||
emitDelay = 50;
|
||||
aDetails.type = 'doubletap';
|
||||
} else {
|
||||
aDetails.touches.push(this.HOVER_ID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let emit = function emit() {
|
||||
let evt = this.chromeWin.document.createEvent('CustomEvent');
|
||||
evt.initCustomEvent('mozAccessFuGesture', true, true, aDetails);
|
||||
this.chromeWin.dispatchEvent(evt);
|
||||
delete this._delayedEvent;
|
||||
}.bind(this);
|
||||
|
||||
if (emitDelay) {
|
||||
this._delayedEvent = this.chromeWin.setTimeout(emit, emitDelay);
|
||||
} else {
|
||||
emit();
|
||||
}
|
||||
},
|
||||
|
||||
compileAndEmit: function TouchAdapter_compileAndEmit(aTime) {
|
||||
|
@ -364,41 +443,3 @@ var Mouse2Touch = {
|
|||
aEvent.stopImmediatePropagation();
|
||||
}
|
||||
};
|
||||
|
||||
this.AndroidTouchAdapter = {
|
||||
attach: function AndroidTouchAdapter_attach(aWindow) {
|
||||
if (this.chromeWin)
|
||||
return;
|
||||
|
||||
Logger.info('AndroidTouchAdapter.attach');
|
||||
|
||||
this.chromeWin = aWindow;
|
||||
this.chromeWin.addEventListener('mousemove', this, true, true);
|
||||
this._lastExploreTime = 0;
|
||||
},
|
||||
|
||||
detach: function AndroidTouchAdapter_detach(aWindow) {
|
||||
if (!this.chromeWin)
|
||||
return;
|
||||
|
||||
Logger.info('AndroidTouchAdapter.detach');
|
||||
|
||||
this.chromeWin.removeEventListener('mousemove', this, true, true);
|
||||
delete this.chromeWin;
|
||||
},
|
||||
|
||||
handleEvent: function AndroidTouchAdapter_handleEvent(aEvent) {
|
||||
// On non-Android we use the shift key to simulate touch.
|
||||
if (Utils.MozBuildApp != 'mobile/android' && !aEvent.shiftKey)
|
||||
return;
|
||||
|
||||
if (aEvent.timeStamp - this._lastExploreTime >= EXPLORE_THROTTLE) {
|
||||
let evt = this.chromeWin.document.createEvent('CustomEvent');
|
||||
evt.initCustomEvent(
|
||||
'mozAccessFuGesture', true, true,
|
||||
{type: 'explore', x: aEvent.screenX, y: aEvent.screenY, touches: [1]});
|
||||
this.chromeWin.dispatchEvent(evt);
|
||||
this._lastExploreTime = aEvent.timeStamp;
|
||||
}
|
||||
}
|
||||
};
|
|
@ -234,16 +234,25 @@ pref("editor.singleLine.pasteNewlines", 2);
|
|||
pref("ui.dragThresholdX", 25);
|
||||
pref("ui.dragThresholdY", 25);
|
||||
|
||||
// Layers Acceleration
|
||||
pref("layers.acceleration.disabled", false);
|
||||
#ifndef XP_WIN
|
||||
//TODO: turn this on for Windows in bug 808016
|
||||
// Layers Acceleration. We can only have nice things on gonk, because
|
||||
// they're not maintained anywhere else.
|
||||
#ifndef MOZ_WIDGET_GONK
|
||||
pref("dom.ipc.tabs.disabled", true);
|
||||
pref("layers.offmainthreadcomposition.enabled", false);
|
||||
pref("layers.offmainthreadcomposition.animate-opacity", false);
|
||||
pref("layers.offmainthreadcomposition.animate-transform", false);
|
||||
pref("layers.offmainthreadcomposition.throttle-animations", false);
|
||||
pref("layers.async-video.enabled", false);
|
||||
#else
|
||||
pref("dom.ipc.tabs.disabled", false);
|
||||
pref("layers.offmainthreadcomposition.enabled", true);
|
||||
#endif
|
||||
pref("layers.acceleration.disabled", false);
|
||||
pref("layers.offmainthreadcomposition.animate-opacity", true);
|
||||
pref("layers.offmainthreadcomposition.animate-transform", true);
|
||||
pref("layers.offmainthreadcomposition.throttle-animations", true);
|
||||
pref("layers.async-video.enabled", true);
|
||||
pref("layers.async-pan-zoom.enabled", true);
|
||||
#endif
|
||||
|
||||
// Web Notifications
|
||||
pref("notification.feature.enabled", true);
|
||||
|
@ -379,7 +388,6 @@ pref("dom.mozBrowserFramesEnabled", true);
|
|||
// We'll run out of PIDs on UNIX-y systems before we hit this limit.
|
||||
pref("dom.ipc.processCount", 100000);
|
||||
|
||||
pref("dom.ipc.tabs.disabled", false);
|
||||
pref("dom.ipc.browser_frames.oop_by_default", false);
|
||||
|
||||
// Temporary permission hack for WebSMS
|
||||
|
|
|
@ -168,10 +168,6 @@ int main(int argc, char* argv[])
|
|||
{
|
||||
char exePath[MAXPATHLEN];
|
||||
|
||||
#if defined(MOZ_X11)
|
||||
putenv("MOZ_USE_OMTC=1");
|
||||
#endif
|
||||
|
||||
nsresult rv = mozilla::BinaryPath::Get(argv[0], exePath);
|
||||
if (NS_FAILED(rv)) {
|
||||
Output("Couldn't calculate the application directory.\n");
|
||||
|
|
|
@ -150,6 +150,9 @@ function runSocialTestWithProvider(manifest, callback) {
|
|||
Social.enabled = true;
|
||||
|
||||
registerCleanupFunction(function () {
|
||||
// disable social before removing the providers to avoid providers
|
||||
// being activated immediately before we get around to removing it.
|
||||
Services.prefs.clearUserPref("social.enabled");
|
||||
// if one test happens to fail, it is likely finishSocialTest will not
|
||||
// be called, causing most future social tests to also fail as they
|
||||
// attempt to add a provider which already exists - so work
|
||||
|
@ -159,7 +162,6 @@ function runSocialTestWithProvider(manifest, callback) {
|
|||
SocialService.removeProvider(m.origin, finish);
|
||||
} catch (ex) {}
|
||||
});
|
||||
Services.prefs.clearUserPref("social.enabled");
|
||||
});
|
||||
function finishSocialTest() {
|
||||
SocialService.removeProvider(provider.origin, finish);
|
||||
|
|
|
@ -14,8 +14,6 @@ include $(DEPTH)/config/autoconf.mk
|
|||
MOCHITEST_BROWSER_FILES = \
|
||||
browser_dbg_cmd_break.html \
|
||||
browser_dbg_cmd_break.js \
|
||||
browser_dbg_cmd.html \
|
||||
browser_dbg_cmd.js \
|
||||
browser_cmd_addon.js \
|
||||
browser_cmd_commands.js \
|
||||
browser_cmd_cookie.js \
|
||||
|
@ -67,10 +65,13 @@ endif
|
|||
|
||||
ifneq ($(OS_ARCH),WINNT)
|
||||
MOCHITEST_BROWSER_FILES += \
|
||||
browser_dbg_cmd.html \
|
||||
browser_dbg_cmd.js \
|
||||
browser_cmd_calllog.js \
|
||||
browser_cmd_calllog_chrome.js \
|
||||
$(NULL)
|
||||
else
|
||||
$(filter disabled-temporarily--bug-820221, browser_dbg_cmd.js)
|
||||
$(filter disabled-temporarily--bug-817304, browser_cmd_calllog.js)
|
||||
$(filter disabled-temporarily--bug-819017, browser_cmd_calllog_chrome.js)
|
||||
endif
|
||||
|
|
|
@ -11,14 +11,8 @@ include $(DEPTH)/config/autoconf.mk
|
|||
|
||||
DIRS = communicator
|
||||
|
||||
ICON_FILES := icon.png
|
||||
ICON_DEST = $(FINAL_TARGET)/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}
|
||||
INSTALL_TARGETS += ICON
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
FILES := \
|
||||
icon.png \
|
||||
$(NULL)
|
||||
|
||||
libs:: $(FILES)
|
||||
$(INSTALL) $(foreach f,$^,"$f") $(DIST)/bin/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}
|
||||
|
||||
install:: $(FILES)
|
||||
$(SYSINSTALL) $(IFLAGS1) $(foreach f,$^,"$f") $(DESTDIR)$(mozappdir)/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}
|
||||
|
|
|
@ -11,14 +11,8 @@ include $(DEPTH)/config/autoconf.mk
|
|||
|
||||
DIRS = communicator
|
||||
|
||||
ICON_FILES := icon.png
|
||||
ICON_DEST = $(FINAL_TARGET)/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}
|
||||
INSTALL_TARGETS += ICON
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
FILES := \
|
||||
icon.png \
|
||||
$(NULL)
|
||||
|
||||
libs:: $(FILES)
|
||||
$(INSTALL) $(foreach f,$^,"$f") $(DIST)/bin/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}
|
||||
|
||||
install:: $(FILES)
|
||||
$(SYSINSTALL) $(IFLAGS1) $(foreach f,$^,"$f") $(DESTDIR)$(mozappdir)/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}
|
||||
|
|
|
@ -11,14 +11,8 @@ include $(DEPTH)/config/autoconf.mk
|
|||
|
||||
DIRS = communicator
|
||||
|
||||
ICON_FILES := icon.png
|
||||
ICON_DEST = $(FINAL_TARGET)/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}
|
||||
INSTALL_TARGETS += ICON
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
FILES := \
|
||||
icon.png \
|
||||
$(NULL)
|
||||
|
||||
libs:: $(FILES)
|
||||
$(INSTALL) $(foreach f,$^,"$f") $(DIST)/bin/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}
|
||||
|
||||
install:: $(FILES)
|
||||
$(SYSINSTALL) $(IFLAGS1) $(foreach f,$^,"$f") $(DESTDIR)$(mozappdir)/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}
|
||||
|
|
|
@ -86,8 +86,35 @@ def touch(args):
|
|||
"""
|
||||
Emulate the behavior of touch(1).
|
||||
"""
|
||||
try:
|
||||
opts, args = getopt(args, "t:")
|
||||
except GetoptError, e:
|
||||
raise PythonException, ("touch: %s" % e, 1)
|
||||
opts = dict(opts)
|
||||
times = None
|
||||
if '-t' in opts:
|
||||
import re
|
||||
from time import mktime, localtime
|
||||
m = re.match('^(?P<Y>(?:\d\d)?\d\d)?(?P<M>\d\d)(?P<D>\d\d)(?P<h>\d\d)(?P<m>\d\d)(?:\.(?P<s>\d\d))?$', opts['-t'])
|
||||
if not m:
|
||||
raise PythonException, ("touch: invalid date format '%s'" % opts['-t'], 1)
|
||||
def normalized_field(m, f):
|
||||
if f == 'Y':
|
||||
if m.group(f) is None:
|
||||
return localtime()[0]
|
||||
y = int(m.group(f))
|
||||
if y < 69:
|
||||
y += 2000
|
||||
elif y < 100:
|
||||
y += 1900
|
||||
return y
|
||||
if m.group(f) is None:
|
||||
return localtime()[0] if f == 'Y' else 0
|
||||
return int(m.group(f))
|
||||
time = [normalized_field(m, f) for f in ['Y', 'M', 'D', 'h', 'm', 's']] + [0, 0, -1]
|
||||
time = mktime(time)
|
||||
times = (time, time)
|
||||
for f in args:
|
||||
if os.path.exists(f):
|
||||
os.utime(f, None)
|
||||
else:
|
||||
open(f, 'w').close()
|
||||
if not os.path.exists(f):
|
||||
open(f, 'a').close()
|
||||
os.utime(f, times)
|
||||
|
|
|
@ -1414,9 +1414,9 @@ class _NativeWrapper(_CommandWrapper):
|
|||
# get the module and method to call
|
||||
parts, badchar = process.clinetoargv(self.cline, self.kwargs['cwd'])
|
||||
if parts is None:
|
||||
raise DataError("native command '%s': shell metacharacter '%s' in command line" % (cline, badchar), self.loc)
|
||||
raise DataError("native command '%s': shell metacharacter '%s' in command line" % (self.cline, badchar), self.loc)
|
||||
if len(parts) < 2:
|
||||
raise DataError("native command '%s': no method name specified" % cline, self.loc)
|
||||
raise DataError("native command '%s': no method name specified" % self.cline, self.loc)
|
||||
module = parts[0]
|
||||
method = parts[1]
|
||||
cline_list = parts[2:]
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
TOUCH ?= touch
|
||||
|
||||
foo:
|
||||
$(TOUCH) bar
|
||||
$(TOUCH) baz
|
||||
$(MAKE) -f $(TESTPATH)/native-touch.mk baz
|
||||
$(TOUCH) -t 198007040802 baz
|
||||
$(MAKE) -f $(TESTPATH)/native-touch.mk baz
|
||||
|
||||
bar:
|
||||
$(TOUCH) $@
|
||||
|
||||
baz: bar
|
||||
echo TEST-PASS
|
||||
$(TOUCH) $@
|
|
@ -76,9 +76,9 @@ LIBXUL_DIST ?= $(DIST)
|
|||
# build products (typelibs, components, chrome).
|
||||
#
|
||||
# If XPI_NAME is set, the files will be shipped to $(DIST)/xpi-stage/$(XPI_NAME)
|
||||
# If DIST_SUBDIR is set, the files will be shipped to $(DIST)/$(DIST_SUBDIR)
|
||||
# Otherwise, the default $(DIST)/bin will be used.
|
||||
FINAL_TARGET = $(if $(XPI_NAME),$(DIST)/xpi-stage/$(XPI_NAME),$(if $(DIST_SUBDIR),$(DIST)/bin/$(DIST_SUBDIR),$(DIST)/bin))
|
||||
# instead of $(DIST)/bin. In both cases, if DIST_SUBDIR is set, the files will be
|
||||
# shipped to a $(DIST_SUBDIR) subdirectory.
|
||||
FINAL_TARGET = $(if $(XPI_NAME),$(DIST)/xpi-stage/$(XPI_NAME),$(DIST)/bin)$(DIST_SUBDIR:%=/%)
|
||||
|
||||
ifdef XPI_NAME
|
||||
DEFINES += -DXPI_NAME=$(XPI_NAME)
|
||||
|
|
|
@ -56,18 +56,18 @@ mkdir_deps =$(foreach dir,$(getargv),$(call slash_strip,$(dir)/.mkdir.done))
|
|||
#######################
|
||||
|
||||
%/.mkdir.done: # mkdir -p -p => mkdir -p
|
||||
$(subst $(space)-p,$(null),$(MKDIR)) -p $(dir $@)
|
||||
$(subst $(space)-p,$(null),$(MKDIR)) -p "$(dir $@)"
|
||||
# Make the timestamp old enough for not being a problem with symbolic links
|
||||
# targets depending on it. Use Jan 3, 1980 to accomodate any timezone where
|
||||
# 198001010000 would translate to something older than FAT epoch.
|
||||
@touch -t 198001030000 $@
|
||||
@$(TOUCH) -t 198001030000 "$@"
|
||||
|
||||
# A handful of makefiles are attempting "mkdir dot". Likely not intended
|
||||
# or stale logic so add a stub target to handle the request and warn for now.
|
||||
.mkdir.done:
|
||||
ifndef NOWARN_AUTOTARGETS # {
|
||||
@echo "WARNING: $(MKDIR) -dot- requested by $(MAKE) -C $(CURDIR) $(MAKECMDGOALS)"
|
||||
@touch -t 198001030000 $@
|
||||
@$(TOUCH) -t 198001030000 $@
|
||||
endif #}
|
||||
|
||||
INCLUDED_AUTOTARGETS_MK = 1
|
||||
|
|
|
@ -1544,7 +1544,7 @@ define install_file_template
|
|||
$(or $(3),libs):: $(2)/$(notdir $(1))
|
||||
$(call install_cmd_override,$(2)/$(notdir $(1)))
|
||||
$(2)/$(notdir $(1)): $(1) $$(call mkdir_deps,$(2))
|
||||
$$(call install_cmd,$(4) $$< $${@D})
|
||||
$$(call install_cmd,$(4) "$$<" "$${@D}")
|
||||
endef
|
||||
$(foreach category,$(INSTALL_TARGETS),\
|
||||
$(if $($(category)_DEST),,$(error Missing $(category)_DEST))\
|
||||
|
@ -1591,8 +1591,8 @@ $(foreach category,$(INSTALL_TARGETS),\
|
|||
# makefile_target, extra_flags)
|
||||
define preprocess_file_template
|
||||
$(2): $(1) $$(call mkdir_deps,$(dir $(2))) $$(GLOBAL_DEPS)
|
||||
$$(RM) $$@
|
||||
$$(PYTHON) $$(topsrcdir)/config/Preprocessor.py $(4) $$(DEFINES) $$(ACDEFINES) $$(XULPPFLAGS) $$< > $$@
|
||||
$$(RM) "$$@"
|
||||
$$(PYTHON) $$(topsrcdir)/config/Preprocessor.py $(4) $$(DEFINES) $$(ACDEFINES) $$(XULPPFLAGS) "$$<" > "$$@"
|
||||
$(3):: $(2)
|
||||
endef
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ def build_dict(env=os.environ):
|
|||
known_os = {"Linux": "linux",
|
||||
"WINNT": "win",
|
||||
"Darwin": "mac",
|
||||
"Android": "android"}
|
||||
"Android": "b2g" if env["MOZ_WIDGET_TOOLKIT"] == "gonk" else "android"}
|
||||
if o in known_os:
|
||||
d["os"] = known_os[o]
|
||||
else:
|
||||
|
|
|
@ -7,8 +7,7 @@
|
|||
#ifndef DirectionalityUtils_h___
|
||||
#define DirectionalityUtils_h___
|
||||
|
||||
#include "prtypes.h"
|
||||
#include "mozilla/StandardInteger.h"
|
||||
#include "nscore.h"
|
||||
|
||||
class nsIContent;
|
||||
class nsIDocument;
|
||||
|
|
|
@ -27,4 +27,17 @@ enum mozFlushType {
|
|||
Flush_Display = 6 /* As above, plus flush painting */
|
||||
};
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
struct ChangesToFlush {
|
||||
ChangesToFlush(mozFlushType aFlushType, bool aFlushAnimations)
|
||||
: mFlushType(aFlushType)
|
||||
, mFlushAnimations(aFlushAnimations)
|
||||
{}
|
||||
|
||||
mozFlushType mFlushType;
|
||||
bool mFlushAnimations;
|
||||
};
|
||||
|
||||
}
|
||||
#endif /* mozFlushType_h___ */
|
||||
|
|
|
@ -34,8 +34,6 @@
|
|||
#include "nsThreadUtils.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsCharSeparatedTokenizer.h"
|
||||
#include "gfxContext.h"
|
||||
#include "gfxFont.h"
|
||||
#include "nsContentList.h"
|
||||
|
||||
#include "mozilla/AutoRestore.h"
|
||||
|
@ -102,7 +100,6 @@ struct nsIntMargin;
|
|||
class nsPIDOMWindow;
|
||||
class nsIDocumentLoaderFactory;
|
||||
class nsIDOMHTMLInputElement;
|
||||
class gfxTextObjectPaint;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
|
@ -2122,13 +2119,6 @@ public:
|
|||
|
||||
static nsIEditor* GetHTMLEditor(nsPresContext* aPresContext);
|
||||
|
||||
static bool PaintSVGGlyph(Element *aElement, gfxContext *aContext,
|
||||
gfxFont::DrawMode aDrawMode,
|
||||
gfxTextObjectPaint *aObjectPaint);
|
||||
|
||||
static bool GetSVGGlyphExtents(Element *aElement, const gfxMatrix& aSVGToAppSpace,
|
||||
gfxRect *aResult);
|
||||
|
||||
/**
|
||||
* Check whether a spec feature/version is supported.
|
||||
* @param aObject the object, which should support the feature,
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
#include "nsCOMPtr.h"
|
||||
#include "nsString.h"
|
||||
#include "nsIXMLHttpRequest.h"
|
||||
#include "prmem.h"
|
||||
#include "nsAutoPtr.h"
|
||||
|
||||
#include "mozilla/GuardObjects.h"
|
||||
|
@ -201,8 +200,7 @@ public:
|
|||
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsDOMFileCC, nsIDOMFile)
|
||||
};
|
||||
|
||||
class nsDOMFileFile : public nsDOMFile,
|
||||
public nsIJSNativeInitializer
|
||||
class nsDOMFileFile : public nsDOMFile
|
||||
{
|
||||
public:
|
||||
// Create as a file
|
||||
|
@ -290,15 +288,6 @@ public:
|
|||
mName.SetIsVoid(true);
|
||||
}
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
// nsIJSNativeInitializer
|
||||
NS_IMETHOD Initialize(nsISupports* aOwner,
|
||||
JSContext* aCx,
|
||||
JSObject* aObj,
|
||||
uint32_t aArgc,
|
||||
jsval* aArgv);
|
||||
|
||||
// Overrides
|
||||
NS_IMETHOD GetSize(uint64_t* aSize);
|
||||
NS_IMETHOD GetType(nsAString& aType);
|
||||
|
@ -307,10 +296,6 @@ public:
|
|||
NS_IMETHOD GetMozFullPathInternal(nsAString& aFullPath);
|
||||
NS_IMETHOD GetInternalStream(nsIInputStream**);
|
||||
|
||||
// DOMClassInfo constructor (for File("foo"))
|
||||
static nsresult
|
||||
NewFile(nsISupports* *aNewObject);
|
||||
|
||||
protected:
|
||||
// Create slice
|
||||
nsDOMFileFile(const nsDOMFileFile* aOther, uint64_t aStart, uint64_t aLength,
|
||||
|
@ -423,7 +408,7 @@ protected:
|
|||
sDataOwners = nullptr;
|
||||
}
|
||||
|
||||
PR_Free(mData);
|
||||
moz_free(mData);
|
||||
}
|
||||
|
||||
static void EnsureMemoryReporterRegistered();
|
||||
|
|
|
@ -273,7 +273,7 @@ inline static bool NodeAffectsDirAutoAncestor(nsINode* aTextNode)
|
|||
* first-strong algorithm defined in http://unicode.org/reports/tr9/#P2
|
||||
*
|
||||
* @param[out] aFirstStrong the offset to the first character in the string with
|
||||
* strong directionality, or PR_UINT32_MAX if there is none (return
|
||||
* strong directionality, or UINT32_MAX if there is none (return
|
||||
value is eDir_NotSet).
|
||||
* @return the directionality of the string
|
||||
*/
|
||||
|
@ -304,7 +304,7 @@ GetDirectionFromText(const PRUnichar* aText, const uint32_t aLength,
|
|||
}
|
||||
|
||||
if (aFirstStrong) {
|
||||
*aFirstStrong = PR_UINT32_MAX;
|
||||
*aFirstStrong = UINT32_MAX;
|
||||
}
|
||||
return eDir_NotSet;
|
||||
}
|
||||
|
@ -330,7 +330,7 @@ GetDirectionFromText(const char* aText, const uint32_t aLength,
|
|||
}
|
||||
|
||||
if (aFirstStrong) {
|
||||
*aFirstStrong = PR_UINT32_MAX;
|
||||
*aFirstStrong = UINT32_MAX;
|
||||
}
|
||||
return eDir_NotSet;
|
||||
}
|
||||
|
|
|
@ -42,7 +42,6 @@
|
|||
#include "xpcpublic.h"
|
||||
#include "nsContentPolicyUtils.h"
|
||||
#include "jsfriendapi.h"
|
||||
#include "prmem.h"
|
||||
#include "nsDOMFile.h"
|
||||
#include "nsWrapperCacheInlines.h"
|
||||
#include "nsDOMEventTargetHelper.h"
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
|
||||
#include "nsAttrAndChildArray.h"
|
||||
#include "nsMappedAttributeElement.h"
|
||||
#include "prmem.h"
|
||||
#include "prbit.h"
|
||||
#include "nsString.h"
|
||||
#include "nsHTMLStyleSheet.h"
|
||||
|
@ -100,7 +99,7 @@ nsAttrAndChildArray::~nsAttrAndChildArray()
|
|||
|
||||
Clear();
|
||||
|
||||
PR_Free(mImpl);
|
||||
moz_free(mImpl);
|
||||
}
|
||||
|
||||
nsIContent*
|
||||
|
@ -616,11 +615,11 @@ nsAttrAndChildArray::Compact()
|
|||
// Then resize or free buffer
|
||||
uint32_t newSize = attrCount * ATTRSIZE + childCount;
|
||||
if (!newSize && !mImpl->mMappedAttrs) {
|
||||
PR_Free(mImpl);
|
||||
moz_free(mImpl);
|
||||
mImpl = nullptr;
|
||||
}
|
||||
else if (newSize < mImpl->mBufferSize) {
|
||||
mImpl = static_cast<Impl*>(PR_Realloc(mImpl, (newSize + NS_IMPL_EXTRA_SIZE) * sizeof(nsIContent*)));
|
||||
mImpl = static_cast<Impl*>(moz_realloc(mImpl, (newSize + NS_IMPL_EXTRA_SIZE) * sizeof(nsIContent*)));
|
||||
NS_ASSERTION(mImpl, "failed to reallocate to smaller buffer");
|
||||
|
||||
mImpl->mBufferSize = newSize;
|
||||
|
@ -757,7 +756,7 @@ nsAttrAndChildArray::GrowBy(uint32_t aGrowSize)
|
|||
}
|
||||
|
||||
bool needToInitialize = !mImpl;
|
||||
Impl* newImpl = static_cast<Impl*>(PR_Realloc(mImpl, size * sizeof(void*)));
|
||||
Impl* newImpl = static_cast<Impl*>(moz_realloc(mImpl, size * sizeof(void*)));
|
||||
NS_ENSURE_TRUE(newImpl, false);
|
||||
|
||||
mImpl = newImpl;
|
||||
|
|
|
@ -122,10 +122,6 @@
|
|||
#include "nsILoadContext.h"
|
||||
#include "nsTextFragment.h"
|
||||
#include "mozilla/Selection.h"
|
||||
#include "nsSVGUtils.h"
|
||||
#include "nsISVGChildFrame.h"
|
||||
#include "nsRenderingContext.h"
|
||||
#include "gfxSVGGlyphs.h"
|
||||
|
||||
#ifdef IBMBIDI
|
||||
#include "nsIBidiKeyboard.h"
|
||||
|
@ -6136,7 +6132,7 @@ nsContentUtils::CreateBlobBuffer(JSContext* aCx,
|
|||
jsval& aBlob)
|
||||
{
|
||||
uint32_t blobLen = aData.Length();
|
||||
void* blobData = PR_Malloc(blobLen);
|
||||
void* blobData = moz_malloc(blobLen);
|
||||
nsCOMPtr<nsIDOMBlob> blob;
|
||||
if (blobData) {
|
||||
memcpy(blobData, aData.BeginReading(), blobLen);
|
||||
|
@ -6904,60 +6900,6 @@ nsContentUtils::JSArrayToAtomArray(JSContext* aCx, const JS::Value& aJSArray,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
/* static */
|
||||
bool
|
||||
nsContentUtils::PaintSVGGlyph(Element *aElement, gfxContext *aContext,
|
||||
gfxFont::DrawMode aDrawMode,
|
||||
gfxTextObjectPaint *aObjectPaint)
|
||||
{
|
||||
nsIFrame *frame = aElement->GetPrimaryFrame();
|
||||
if (!frame) {
|
||||
NS_WARNING("No frame for SVG glyph");
|
||||
return false;
|
||||
}
|
||||
|
||||
nsISVGChildFrame *displayFrame = do_QueryFrame(frame);
|
||||
if (!displayFrame) {
|
||||
NS_WARNING("Non SVG frame for SVG glyph");
|
||||
return false;
|
||||
}
|
||||
|
||||
nsRenderingContext context;
|
||||
|
||||
context.Init(frame->PresContext()->DeviceContext(), aContext);
|
||||
context.AddUserData(&gfxTextObjectPaint::sUserDataKey, aObjectPaint, nullptr);
|
||||
|
||||
nsresult rv = displayFrame->PaintSVG(&context, nullptr);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* static */
|
||||
bool
|
||||
nsContentUtils::GetSVGGlyphExtents(Element *aElement, const gfxMatrix& aSVGToAppSpace,
|
||||
gfxRect *aResult)
|
||||
{
|
||||
nsIFrame *frame = aElement->GetPrimaryFrame();
|
||||
if (!frame) {
|
||||
NS_WARNING("No frame for SVG glyph");
|
||||
return false;
|
||||
}
|
||||
|
||||
nsISVGChildFrame *displayFrame = do_QueryFrame(frame);
|
||||
if (!displayFrame) {
|
||||
NS_WARNING("Non SVG frame for SVG glyph");
|
||||
return false;
|
||||
}
|
||||
|
||||
*aResult = displayFrame->GetBBoxContribution(aSVGToAppSpace,
|
||||
nsSVGUtils::eBBoxIncludeFill | nsSVGUtils::eBBoxIncludeFillGeometry |
|
||||
nsSVGUtils::eBBoxIncludeStroke | nsSVGUtils::eBBoxIncludeStrokeGeometry |
|
||||
nsSVGUtils::eBBoxIncludeMarkers);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// static
|
||||
void
|
||||
nsContentUtils::GetSelectionInTextControl(Selection* aSelection,
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "nsDOMBlobBuilder.h"
|
||||
#include "jsfriendapi.h"
|
||||
#include "mozilla/dom/BlobBinding.h"
|
||||
#include "mozilla/dom/FileBinding.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsDOMClassInfoID.h"
|
||||
#include "nsIMultiplexInputStream.h"
|
||||
|
@ -171,14 +172,17 @@ nsDOMMultipartFile::Initialize(nsISupports* aOwner,
|
|||
uint32_t aArgc,
|
||||
jsval* aArgv)
|
||||
{
|
||||
return InitInternal(aCx, aArgc, aArgv, GetXPConnectNative);
|
||||
if (!mIsFile) {
|
||||
return InitBlob(aCx, aArgc, aArgv, GetXPConnectNative);
|
||||
}
|
||||
return InitFile(aCx, aArgc, aArgv);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMMultipartFile::InitInternal(JSContext* aCx,
|
||||
uint32_t aArgc,
|
||||
jsval* aArgv,
|
||||
UnwrapFuncPtr aUnwrapFunc)
|
||||
nsDOMMultipartFile::InitBlob(JSContext* aCx,
|
||||
uint32_t aArgc,
|
||||
jsval* aArgv,
|
||||
UnwrapFuncPtr aUnwrapFunc)
|
||||
{
|
||||
bool nativeEOL = false;
|
||||
if (aArgc > 1) {
|
||||
|
@ -260,6 +264,100 @@ nsDOMMultipartFile::InitInternal(JSContext* aCx,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMMultipartFile::InitFile(JSContext* aCx,
|
||||
uint32_t aArgc,
|
||||
jsval* aArgv)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
NS_ASSERTION(!mImmutable, "Something went wrong ...");
|
||||
NS_ENSURE_TRUE(!mImmutable, NS_ERROR_UNEXPECTED);
|
||||
|
||||
if (!nsContentUtils::IsCallerChrome()) {
|
||||
return NS_ERROR_DOM_SECURITY_ERR; // Real short trip
|
||||
}
|
||||
|
||||
NS_ENSURE_TRUE(aArgc > 0, NS_ERROR_UNEXPECTED);
|
||||
|
||||
bool nativeEOL = false;
|
||||
if (aArgc > 1) {
|
||||
FilePropertyBag d;
|
||||
if (!d.Init(aCx, nullptr, aArgv[1])) {
|
||||
return NS_ERROR_TYPE_ERR;
|
||||
}
|
||||
mName = d.name;
|
||||
mContentType = d.type;
|
||||
nativeEOL = d.endings == EndingTypesValues::Native;
|
||||
}
|
||||
|
||||
// We expect to get a path to represent as a File object,
|
||||
// an nsIFile, or an nsIDOMFile.
|
||||
nsCOMPtr<nsIFile> file;
|
||||
nsCOMPtr<nsIDOMFile> domFile;
|
||||
if (!aArgv[0].isString()) {
|
||||
// Lets see if it's an nsIFile
|
||||
if (!aArgv[0].isObject()) {
|
||||
return NS_ERROR_UNEXPECTED; // We're not interested
|
||||
}
|
||||
|
||||
JSObject* obj = &aArgv[0].toObject();
|
||||
|
||||
nsISupports* supports =
|
||||
nsContentUtils::XPConnect()->GetNativeOfWrapper(aCx, obj);
|
||||
if (!supports) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
domFile = do_QueryInterface(supports);
|
||||
file = do_QueryInterface(supports);
|
||||
if (!domFile && !file) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
} else {
|
||||
// It's a string
|
||||
JSString* str = JS_ValueToString(aCx, aArgv[0]);
|
||||
NS_ENSURE_TRUE(str, NS_ERROR_XPC_BAD_CONVERT_JS);
|
||||
|
||||
nsDependentJSString xpcomStr;
|
||||
if (!xpcomStr.init(aCx, str)) {
|
||||
return NS_ERROR_XPC_BAD_CONVERT_JS;
|
||||
}
|
||||
|
||||
rv = NS_NewLocalFile(xpcomStr, false, getter_AddRefs(file));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
if (file) {
|
||||
bool exists;
|
||||
rv = file->Exists(&exists);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ENSURE_TRUE(exists, NS_ERROR_FILE_NOT_FOUND);
|
||||
|
||||
bool isDir;
|
||||
rv = file->IsDirectory(&isDir);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ENSURE_FALSE(isDir, NS_ERROR_FILE_IS_DIRECTORY);
|
||||
|
||||
if (mName.IsEmpty()) {
|
||||
file->GetLeafName(mName);
|
||||
}
|
||||
|
||||
domFile = new nsDOMFileFile(file);
|
||||
}
|
||||
|
||||
// XXXkhuey this is terrible
|
||||
if (mContentType.IsEmpty()) {
|
||||
domFile->GetType(mContentType);
|
||||
}
|
||||
|
||||
BlobSet blobSet;
|
||||
blobSet.AppendBlob(domFile);
|
||||
mBlobs = blobSet.GetBlobs();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
BlobSet::AppendVoidPtr(const void* aData, uint32_t aLength)
|
||||
{
|
||||
|
|
|
@ -54,10 +54,13 @@ public:
|
|||
jsval* aArgv);
|
||||
|
||||
typedef nsIDOMBlob* (*UnwrapFuncPtr)(JSContext*, JSObject*);
|
||||
nsresult InitInternal(JSContext* aCx,
|
||||
uint32_t aArgc,
|
||||
jsval* aArgv,
|
||||
UnwrapFuncPtr aUnwrapFunc);
|
||||
nsresult InitBlob(JSContext* aCx,
|
||||
uint32_t aArgc,
|
||||
jsval* aArgv,
|
||||
UnwrapFuncPtr aUnwrapFunc);
|
||||
nsresult InitFile(JSContext* aCx,
|
||||
uint32_t aArgc,
|
||||
jsval* aArgv);
|
||||
|
||||
already_AddRefed<nsIDOMBlob>
|
||||
CreateSlice(uint64_t aStart, uint64_t aLength, const nsAString& aContentType);
|
||||
|
@ -72,6 +75,16 @@ public:
|
|||
static nsresult
|
||||
NewBlob(nsISupports* *aNewObject);
|
||||
|
||||
// DOMClassInfo constructor (for File([b1, "foo"], { type: "image/png",
|
||||
// name: "foo.png" }))
|
||||
inline static nsresult
|
||||
NewFile(nsISupports* *aNewObject)
|
||||
{
|
||||
// Initialization will set the filename, so we can pass in an empty string
|
||||
// for now.
|
||||
return NewFile(EmptyString(), aNewObject);
|
||||
}
|
||||
|
||||
virtual const nsTArray<nsCOMPtr<nsIDOMBlob> >*
|
||||
GetSubBlobs() const { return &mBlobs; }
|
||||
|
||||
|
@ -119,8 +132,7 @@ protected:
|
|||
if (!bufferLen.isValid())
|
||||
return false;
|
||||
|
||||
// PR_ memory functions are still fallible
|
||||
void* data = PR_Realloc(mData, bufferLen.value());
|
||||
void* data = moz_realloc(mData, bufferLen.value());
|
||||
if (!data)
|
||||
return false;
|
||||
|
||||
|
|
|
@ -335,7 +335,7 @@ nsDOMDataChannel::GetSendParams(nsIVariant* aData, nsCString& aStringOut,
|
|||
uint64_t blobLen;
|
||||
rv = blob->GetSize(&blobLen);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (blobLen > PR_UINT32_MAX) {
|
||||
if (blobLen > UINT32_MAX) {
|
||||
return NS_ERROR_FILE_TOO_BIG;
|
||||
}
|
||||
aOutgoingLength = static_cast<uint32_t>(blobLen);
|
||||
|
|
|
@ -36,8 +36,6 @@
|
|||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
|
||||
#include "plbase64.h"
|
||||
#include "prmem.h"
|
||||
#include "mozilla/dom/FileListBinding.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
@ -470,9 +468,6 @@ NS_IMPL_CYCLE_COLLECTING_RELEASE(nsDOMFileCC)
|
|||
////////////////////////////////////////////////////////////////////////////
|
||||
// nsDOMFileFile implementation
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED1(nsDOMFileFile, nsDOMFile,
|
||||
nsIJSNativeInitializer)
|
||||
|
||||
already_AddRefed<nsIDOMBlob>
|
||||
nsDOMFileFile::CreateSlice(uint64_t aStart, uint64_t aLength,
|
||||
const nsAString& aContentType)
|
||||
|
@ -481,14 +476,6 @@ nsDOMFileFile::CreateSlice(uint64_t aStart, uint64_t aLength,
|
|||
return t.forget();
|
||||
}
|
||||
|
||||
/* static */ nsresult
|
||||
nsDOMFileFile::NewFile(nsISupports* *aNewObject)
|
||||
{
|
||||
nsCOMPtr<nsISupports> file = do_QueryObject(new nsDOMFileFile());
|
||||
file.forget(aNewObject);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMFileFile::GetMozFullPathInternal(nsAString &aFilename)
|
||||
{
|
||||
|
@ -593,71 +580,6 @@ nsDOMFileFile::GetInternalStream(nsIInputStream **aStream)
|
|||
-1, -1, sFileStreamFlags);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMFileFile::Initialize(nsISupports* aOwner,
|
||||
JSContext* aCx,
|
||||
JSObject* aObj,
|
||||
uint32_t aArgc,
|
||||
JS::Value* aArgv)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
NS_ASSERTION(!mImmutable, "Something went wrong ...");
|
||||
NS_ENSURE_TRUE(!mImmutable, NS_ERROR_UNEXPECTED);
|
||||
|
||||
if (!nsContentUtils::IsCallerChrome()) {
|
||||
return NS_ERROR_DOM_SECURITY_ERR; // Real short trip
|
||||
}
|
||||
|
||||
NS_ENSURE_TRUE(aArgc > 0, NS_ERROR_UNEXPECTED);
|
||||
|
||||
// We expect to get a path to represent as a File object,
|
||||
// or an nsIFile
|
||||
nsCOMPtr<nsIFile> file;
|
||||
if (!aArgv[0].isString()) {
|
||||
// Lets see if it's an nsIFile
|
||||
if (!aArgv[0].isObject()) {
|
||||
return NS_ERROR_UNEXPECTED; // We're not interested
|
||||
}
|
||||
|
||||
JSObject* obj = &aArgv[0].toObject();
|
||||
|
||||
// Is it an nsIFile
|
||||
file = do_QueryInterface(
|
||||
nsContentUtils::XPConnect()->
|
||||
GetNativeOfWrapper(aCx, obj));
|
||||
if (!file)
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
} else {
|
||||
// It's a string
|
||||
JSString* str = JS_ValueToString(aCx, aArgv[0]);
|
||||
NS_ENSURE_TRUE(str, NS_ERROR_XPC_BAD_CONVERT_JS);
|
||||
|
||||
nsDependentJSString xpcomStr;
|
||||
if (!xpcomStr.init(aCx, str)) {
|
||||
return NS_ERROR_XPC_BAD_CONVERT_JS;
|
||||
}
|
||||
|
||||
rv = NS_NewLocalFile(xpcomStr, false, getter_AddRefs(file));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
bool exists;
|
||||
rv = file->Exists(&exists);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ENSURE_TRUE(exists, NS_ERROR_FILE_NOT_FOUND);
|
||||
|
||||
bool isDir;
|
||||
rv = file->IsDirectory(&isDir);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ENSURE_FALSE(isDir, NS_ERROR_FILE_IS_DIRECTORY);
|
||||
|
||||
mFile = file;
|
||||
file->GetLeafName(mName);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// nsDOMMemoryFile implementation
|
||||
|
||||
|
|
|
@ -20,9 +20,6 @@
|
|||
#include "nsNetCID.h"
|
||||
#include "nsNetUtil.h"
|
||||
|
||||
#include "plbase64.h"
|
||||
#include "prmem.h"
|
||||
|
||||
#include "nsLayoutCID.h"
|
||||
#include "nsXPIDLString.h"
|
||||
#include "nsReadableUtils.h"
|
||||
|
@ -39,6 +36,7 @@
|
|||
#include "nsLayoutStatics.h"
|
||||
#include "nsIScriptObjectPrincipal.h"
|
||||
#include "nsHostObjectProtocolHandler.h"
|
||||
#include "mozilla/Base64.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/dom/EncodingUtils.h"
|
||||
#include "xpcpublic.h"
|
||||
|
@ -319,7 +317,7 @@ nsDOMFileReader::DoOnDataAvailable(nsIRequest *aRequest,
|
|||
// PR_Realloc doesn't support over 4GB memory size even if 64-bit OS
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
mFileData = (char *)PR_Realloc(mFileData, aOffset + aCount);
|
||||
mFileData = (char *)moz_realloc(mFileData, aOffset + aCount);
|
||||
NS_ENSURE_TRUE(mFileData, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
uint32_t bytesRead = 0;
|
||||
|
@ -491,26 +489,11 @@ nsDOMFileReader::GetAsDataURL(nsIDOMBlob *aFile,
|
|||
}
|
||||
aResult.AppendLiteral(";base64,");
|
||||
|
||||
uint32_t totalRead = 0;
|
||||
while (aDataLen > totalRead) {
|
||||
uint32_t numEncode = 4096;
|
||||
uint32_t amtRemaining = aDataLen - totalRead;
|
||||
if (numEncode > amtRemaining)
|
||||
numEncode = amtRemaining;
|
||||
nsCString encodedData;
|
||||
rv = Base64Encode(Substring(aFileData, aDataLen), encodedData);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
//Unless this is the end of the file, encode in multiples of 3
|
||||
if (numEncode > 3) {
|
||||
uint32_t leftOver = numEncode % 3;
|
||||
numEncode -= leftOver;
|
||||
}
|
||||
|
||||
//Out buffer should be at least 4/3rds the read buf, plus a terminator
|
||||
char *base64 = PL_Base64Encode(aFileData + totalRead, numEncode, nullptr);
|
||||
AppendASCIItoUTF16(nsDependentCString(base64), aResult);
|
||||
PR_Free(base64);
|
||||
|
||||
totalRead += numEncode;
|
||||
}
|
||||
AppendASCIItoUTF16(encodedData, aResult);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
#include "nsCOMPtr.h"
|
||||
#include "nsIStreamLoader.h"
|
||||
#include "nsIChannel.h"
|
||||
#include "prmem.h"
|
||||
|
||||
#include "FileIOObject.h"
|
||||
|
||||
|
@ -81,7 +80,7 @@ protected:
|
|||
nsresult ConvertStream(const char *aFileData, uint32_t aDataLen, const char *aCharset, nsAString &aResult);
|
||||
|
||||
void FreeFileData() {
|
||||
PR_Free(mFileData);
|
||||
moz_free(mFileData);
|
||||
mFileData = nullptr;
|
||||
mDataLen = 0;
|
||||
}
|
||||
|
|
|
@ -420,7 +420,7 @@ nsDOMParser::InitInternal(nsISupports* aOwner, nsIPrincipal* prin,
|
|||
|
||||
nsCOMPtr<nsIDocument> doc;
|
||||
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aOwner);
|
||||
if (aOwner) {
|
||||
if (window) {
|
||||
nsCOMPtr<nsIDOMDocument> domdoc = window->GetExtantDocument();
|
||||
doc = do_QueryInterface(domdoc);
|
||||
}
|
||||
|
|
|
@ -6,26 +6,29 @@
|
|||
#include "nsIVariant.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsIDOMFile.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsHTMLFormElement.h"
|
||||
#include "mozilla/dom/FormDataBinding.h"
|
||||
|
||||
nsFormData::nsFormData()
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
||||
nsFormData::nsFormData(nsISupports* aOwner)
|
||||
: nsFormSubmission(NS_LITERAL_CSTRING("UTF-8"), nullptr)
|
||||
, mOwner(aOwner)
|
||||
{
|
||||
SetIsDOMBinding();
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// nsISupports
|
||||
|
||||
DOMCI_DATA(FormData, nsFormData)
|
||||
|
||||
NS_IMPL_ADDREF(nsFormData)
|
||||
NS_IMPL_RELEASE(nsFormData)
|
||||
NS_INTERFACE_MAP_BEGIN(nsFormData)
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_1(nsFormData, mOwner)
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsFormData)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsFormData)
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsFormData)
|
||||
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMFormData)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIXHRSendable)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIJSNativeInitializer)
|
||||
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(FormData)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMFormData)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
|
@ -39,28 +42,22 @@ nsFormData::GetEncodedSubmission(nsIURI* aURI,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsFormData::AddNameValuePair(const nsAString& aName,
|
||||
const nsAString& aValue)
|
||||
void
|
||||
nsFormData::Append(const nsAString& aName, const nsAString& aValue)
|
||||
{
|
||||
FormDataTuple* data = mFormData.AppendElement();
|
||||
data->name = aName;
|
||||
data->stringValue = aValue;
|
||||
data->valueIsFile = false;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsFormData::AddNameFilePair(const nsAString& aName,
|
||||
nsIDOMBlob* aBlob)
|
||||
void
|
||||
nsFormData::Append(const nsAString& aName, nsIDOMBlob* aBlob)
|
||||
{
|
||||
FormDataTuple* data = mFormData.AppendElement();
|
||||
data->name = aName;
|
||||
data->fileValue = aBlob;
|
||||
data->valueIsFile = true;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
@ -84,7 +81,8 @@ nsFormData::Append(const nsAString& aName, nsIVariant* aValue)
|
|||
|
||||
nsCOMPtr<nsIDOMBlob> domBlob = do_QueryInterface(supports);
|
||||
if (domBlob) {
|
||||
return AddNameFilePair(aName, domBlob);
|
||||
Append(aName, domBlob);
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -96,7 +94,27 @@ nsFormData::Append(const nsAString& aName, nsIVariant* aValue)
|
|||
nsString valAsString;
|
||||
valAsString.Adopt(stringData, stringLen);
|
||||
|
||||
return AddNameValuePair(aName, valAsString);
|
||||
Append(aName, valAsString);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* virtual */ JSObject*
|
||||
nsFormData::WrapObject(JSContext* aCx, JSObject* aScope, bool* aTriedToWrap)
|
||||
{
|
||||
return FormDataBinding::Wrap(aCx, aScope, this, aTriedToWrap);
|
||||
}
|
||||
|
||||
/* static */ already_AddRefed<nsFormData>
|
||||
nsFormData::Constructor(nsISupports* aGlobal,
|
||||
const Optional<nsHTMLFormElement*>& aFormElement,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
nsRefPtr<nsFormData> formData = new nsFormData(aGlobal);
|
||||
if (aFormElement.WasPassed()) {
|
||||
MOZ_ASSERT(aFormElement.Value());
|
||||
aRv = aFormElement.Value()->WalkFormElements(formData);
|
||||
}
|
||||
return formData.forget();
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
@ -124,35 +142,3 @@ nsFormData::GetSendInfo(nsIInputStream** aBody, uint64_t* aContentLength,
|
|||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// nsIJSNativeInitializer
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFormData::Initialize(nsISupports* aOwner,
|
||||
JSContext* aCx,
|
||||
JSObject* aObj,
|
||||
uint32_t aArgc,
|
||||
jsval* aArgv)
|
||||
{
|
||||
if (aArgc > 0) {
|
||||
if (JSVAL_IS_PRIMITIVE(aArgv[0])) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
nsCOMPtr<nsIContent> formCont = do_QueryInterface(
|
||||
nsContentUtils::XPConnect()->
|
||||
GetNativeOfWrapper(aCx, JSVAL_TO_OBJECT(aArgv[0])));
|
||||
|
||||
if (!formCont || !formCont->IsHTML(nsGkAtoms::form)) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
nsresult rv = static_cast<nsHTMLFormElement*>(formCont.get())->
|
||||
WalkFormElements(this);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -8,34 +8,72 @@
|
|||
#include "nsIDOMFormData.h"
|
||||
#include "nsIXMLHttpRequest.h"
|
||||
#include "nsFormSubmission.h"
|
||||
#include "nsIJSNativeInitializer.h"
|
||||
#include "nsWrapperCache.h"
|
||||
#include "nsTArray.h"
|
||||
#include "mozilla/ErrorResult.h"
|
||||
|
||||
class nsHTMLFormElement;
|
||||
class nsIDOMFile;
|
||||
|
||||
namespace mozilla {
|
||||
class ErrorResult;
|
||||
|
||||
namespace dom {
|
||||
template<class> class Optional;
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
class nsFormData : public nsIDOMFormData,
|
||||
public nsIXHRSendable,
|
||||
public nsIJSNativeInitializer,
|
||||
public nsFormSubmission
|
||||
public nsFormSubmission,
|
||||
public nsWrapperCache
|
||||
{
|
||||
public:
|
||||
nsFormData();
|
||||
nsFormData(nsISupports* aOwner = nullptr);
|
||||
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsFormData,
|
||||
nsIDOMFormData)
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIDOMFORMDATA
|
||||
NS_DECL_NSIXHRSENDABLE
|
||||
|
||||
// nsWrapperCache
|
||||
virtual JSObject*
|
||||
WrapObject(JSContext* aCx, JSObject* aScope, bool* aTriedToWrap) MOZ_OVERRIDE;
|
||||
|
||||
// WebIDL
|
||||
nsISupports*
|
||||
GetParentObject() const
|
||||
{
|
||||
return mOwner;
|
||||
}
|
||||
static already_AddRefed<nsFormData>
|
||||
Constructor(nsISupports* aGlobal,
|
||||
const mozilla::dom::Optional<nsHTMLFormElement*>& aFormElement,
|
||||
mozilla::ErrorResult& aRv);
|
||||
void Append(const nsAString& aName, const nsAString& aValue);
|
||||
void Append(const nsAString& aName, nsIDOMBlob* aBlob);
|
||||
|
||||
// nsFormSubmission
|
||||
virtual nsresult GetEncodedSubmission(nsIURI* aURI,
|
||||
nsIInputStream** aPostDataStream);
|
||||
virtual nsresult AddNameValuePair(const nsAString& aName,
|
||||
const nsAString& aValue);
|
||||
const nsAString& aValue)
|
||||
{
|
||||
Append(aName, aValue);
|
||||
return NS_OK;
|
||||
}
|
||||
virtual nsresult AddNameFilePair(const nsAString& aName,
|
||||
nsIDOMBlob* aBlob);
|
||||
nsIDOMBlob* aBlob)
|
||||
{
|
||||
Append(aName, aBlob);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHOD Initialize(nsISupports* aOwner, JSContext* aCx, JSObject* aObj,
|
||||
uint32_t aArgc, jsval* aArgv);
|
||||
private:
|
||||
nsCOMPtr<nsISupports> mOwner;
|
||||
|
||||
struct FormDataTuple
|
||||
{
|
||||
nsString name;
|
||||
|
@ -43,7 +81,7 @@ private:
|
|||
nsCOMPtr<nsIDOMBlob> fileValue;
|
||||
bool valueIsFile;
|
||||
};
|
||||
|
||||
|
||||
nsTArray<FormDataTuple> mFormData;
|
||||
};
|
||||
|
||||
|
|
|
@ -79,9 +79,10 @@
|
|||
#include "nsIPermissionManager.h"
|
||||
#include "nsMimeTypes.h"
|
||||
#include "nsIHttpChannelInternal.h"
|
||||
#include "nsFormData.h"
|
||||
#include "nsStreamListenerWrapper.h"
|
||||
|
||||
#include "nsWrapperCacheInlines.h"
|
||||
#include "nsStreamListenerWrapper.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
@ -2666,11 +2667,9 @@ nsXMLHttpRequest::GetRequestBody(nsIVariant* aVariant,
|
|||
}
|
||||
case nsXMLHttpRequest::RequestBody::FormData:
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIXHRSendable> sendable = do_QueryInterface(value.mFormData, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return ::GetRequestBody(sendable, aResult, aContentLength, aContentType, aCharset);
|
||||
MOZ_ASSERT(value.mFormData);
|
||||
return ::GetRequestBody(value.mFormData, aResult, aContentLength,
|
||||
aContentType, aCharset);
|
||||
}
|
||||
case nsXMLHttpRequest::RequestBody::InputStream:
|
||||
{
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
class nsILoadGroup;
|
||||
class AsyncVerifyRedirectCallbackForwarder;
|
||||
class nsIUnicodeDecoder;
|
||||
class nsIDOMFormData;
|
||||
class nsFormData;
|
||||
|
||||
class nsXHREventTarget : public nsDOMEventTargetHelper,
|
||||
public nsIXMLHttpRequestEventTarget
|
||||
|
@ -288,9 +288,9 @@ private:
|
|||
{
|
||||
mValue.mString = &aString;
|
||||
}
|
||||
RequestBody(nsIDOMFormData* aFormData) : mType(FormData)
|
||||
RequestBody(nsFormData& aFormData) : mType(FormData)
|
||||
{
|
||||
mValue.mFormData = aFormData;
|
||||
mValue.mFormData = &aFormData;
|
||||
}
|
||||
RequestBody(nsIInputStream* aStream) : mType(InputStream)
|
||||
{
|
||||
|
@ -311,7 +311,7 @@ private:
|
|||
nsIDOMBlob* mBlob;
|
||||
nsIDocument* mDocument;
|
||||
const nsAString* mString;
|
||||
nsIDOMFormData* mFormData;
|
||||
nsFormData* mFormData;
|
||||
nsIInputStream* mStream;
|
||||
};
|
||||
|
||||
|
@ -376,9 +376,8 @@ public:
|
|||
aRv = Send(RequestBody(aString));
|
||||
}
|
||||
}
|
||||
void Send(nsIDOMFormData* aFormData, ErrorResult& aRv)
|
||||
void Send(nsFormData& aFormData, ErrorResult& aRv)
|
||||
{
|
||||
NS_ASSERTION(aFormData, "Null should go to string version");
|
||||
aRv = Send(RequestBody(aFormData));
|
||||
}
|
||||
void Send(nsIInputStream* aStream, ErrorResult& aRv)
|
||||
|
|
|
@ -159,6 +159,7 @@ WebGLContext::WebGLContext()
|
|||
mGLMaxTextureUnits = 0;
|
||||
mGLMaxTextureSize = 0;
|
||||
mGLMaxCubeMapTextureSize = 0;
|
||||
mGLMaxRenderbufferSize = 0;
|
||||
mGLMaxTextureImageUnits = 0;
|
||||
mGLMaxVertexTextureImageUnits = 0;
|
||||
mGLMaxVaryingVectors = 0;
|
||||
|
|
|
@ -858,6 +858,7 @@ protected:
|
|||
int32_t mGLMaxTextureUnits;
|
||||
int32_t mGLMaxTextureSize;
|
||||
int32_t mGLMaxCubeMapTextureSize;
|
||||
int32_t mGLMaxRenderbufferSize;
|
||||
int32_t mGLMaxTextureImageUnits;
|
||||
int32_t mGLMaxVertexTextureImageUnits;
|
||||
int32_t mGLMaxVaryingVectors;
|
||||
|
@ -1127,6 +1128,8 @@ protected:
|
|||
template <typename WebGLObjectType>
|
||||
JSObject* WebGLObjectAsJSObject(JSContext *cx, const WebGLObjectType *, ErrorResult& rv) const;
|
||||
|
||||
void ReattachTextureToAnyFramebufferToWorkAroundBugs(WebGLTexture *tex, WebGLint level);
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
// see bug 713305. This RAII helper guarantees that we're on the discrete GPU, during its lifetime
|
||||
// Debouncing note: we don't want to switch GPUs too frequently, so try to not create and destroy
|
||||
|
|
|
@ -748,6 +748,9 @@ WebGLContext::CopyTexSubImage2D_base(WebGLenum target,
|
|||
|
||||
gl->fCopyTexSubImage2D(target, level, actual_xoffset, actual_yoffset, actual_x, actual_y, actual_width, actual_height);
|
||||
}
|
||||
|
||||
if (!sub)
|
||||
ReattachTextureToAnyFramebufferToWorkAroundBugs(tex, level);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1962,15 +1965,12 @@ WebGLContext::GetParameter(JSContext* cx, WebGLenum pname, ErrorResult& rv)
|
|||
case LOCAL_GL_UNPACK_ALIGNMENT:
|
||||
case LOCAL_GL_PACK_ALIGNMENT:
|
||||
case LOCAL_GL_SUBPIXEL_BITS:
|
||||
case LOCAL_GL_MAX_TEXTURE_SIZE:
|
||||
case LOCAL_GL_MAX_CUBE_MAP_TEXTURE_SIZE:
|
||||
case LOCAL_GL_SAMPLE_BUFFERS:
|
||||
case LOCAL_GL_SAMPLES:
|
||||
case LOCAL_GL_MAX_VERTEX_ATTRIBS:
|
||||
case LOCAL_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
|
||||
case LOCAL_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
|
||||
case LOCAL_GL_MAX_TEXTURE_IMAGE_UNITS:
|
||||
case LOCAL_GL_MAX_RENDERBUFFER_SIZE:
|
||||
case LOCAL_GL_RED_BITS:
|
||||
case LOCAL_GL_GREEN_BITS:
|
||||
case LOCAL_GL_BLUE_BITS:
|
||||
|
@ -1993,6 +1993,15 @@ WebGLContext::GetParameter(JSContext* cx, WebGLenum pname, ErrorResult& rv)
|
|||
return JS::NullValue();
|
||||
}
|
||||
|
||||
case LOCAL_GL_MAX_TEXTURE_SIZE:
|
||||
return JS::Int32Value(mGLMaxTextureSize);
|
||||
|
||||
case LOCAL_GL_MAX_CUBE_MAP_TEXTURE_SIZE:
|
||||
return JS::Int32Value(mGLMaxCubeMapTextureSize);
|
||||
|
||||
case LOCAL_GL_MAX_RENDERBUFFER_SIZE:
|
||||
return JS::Int32Value(mGLMaxRenderbufferSize);
|
||||
|
||||
case LOCAL_GL_MAX_VERTEX_UNIFORM_VECTORS:
|
||||
return JS::Int32Value(mGLMaxVertexUniformVectors);
|
||||
|
||||
|
@ -3373,8 +3382,8 @@ WebGLContext::RenderbufferStorage(WebGLenum target, WebGLenum internalformat, We
|
|||
if (width < 0 || height < 0)
|
||||
return ErrorInvalidValue("renderbufferStorage: width and height must be >= 0");
|
||||
|
||||
if (!mBoundRenderbuffer || !mBoundRenderbuffer->GLName())
|
||||
return ErrorInvalidOperation("renderbufferStorage called on renderbuffer 0");
|
||||
if (width > mGLMaxRenderbufferSize || height > mGLMaxRenderbufferSize)
|
||||
return ErrorInvalidValue("renderbufferStorage: width or height exceeds maximum renderbuffer size");
|
||||
|
||||
// certain OpenGL ES renderbuffer formats may not exist on desktop OpenGL
|
||||
WebGLenum internalformatForGL = internalformat;
|
||||
|
@ -4183,7 +4192,8 @@ WebGLContext::CompileShader(WebGLShader *shader)
|
|||
targetShaderSourceLanguage,
|
||||
&resources);
|
||||
|
||||
int compileOptions = SH_ATTRIBUTES_UNIFORMS;
|
||||
int compileOptions = SH_ATTRIBUTES_UNIFORMS |
|
||||
SH_ENFORCE_PACKING_RESTRICTIONS;
|
||||
if (useShaderSourceTranslation) {
|
||||
compileOptions |= SH_OBJECT_CODE
|
||||
| SH_MAP_LONG_VARIABLE_NAMES;
|
||||
|
@ -4345,6 +4355,8 @@ WebGLContext::CompressedTexImage2D(WebGLenum target, WebGLint level, WebGLenum i
|
|||
|
||||
gl->fCompressedTexImage2D(target, level, internalformat, width, height, border, byteLength, view.Data());
|
||||
tex->SetImageInfo(target, level, width, height, internalformat, LOCAL_GL_UNSIGNED_BYTE);
|
||||
|
||||
ReattachTextureToAnyFramebufferToWorkAroundBugs(tex, level);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -4857,13 +4869,15 @@ WebGLContext::TexImage2D_base(WebGLenum target, WebGLint level, WebGLenum intern
|
|||
|
||||
free(tempZeroData);
|
||||
}
|
||||
|
||||
|
||||
if (error) {
|
||||
GenerateWarning("texImage2D generated error %s", ErrorName(error));
|
||||
return;
|
||||
}
|
||||
|
||||
tex->SetImageInfo(target, level, width, height, format, type);
|
||||
|
||||
ReattachTextureToAnyFramebufferToWorkAroundBugs(tex, level);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -5276,3 +5290,43 @@ InternalFormatForFormatAndType(WebGLenum format, WebGLenum type, bool isGLES2)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
WebGLContext::ReattachTextureToAnyFramebufferToWorkAroundBugs(WebGLTexture *tex,
|
||||
WebGLint level)
|
||||
{
|
||||
MOZ_ASSERT(tex);
|
||||
|
||||
if (!gl->WorkAroundDriverBugs())
|
||||
return;
|
||||
|
||||
if (!mIsMesa)
|
||||
return;
|
||||
|
||||
MakeContextCurrent();
|
||||
|
||||
for(WebGLFramebuffer *framebuffer = mFramebuffers.getFirst();
|
||||
framebuffer;
|
||||
framebuffer = framebuffer->getNext())
|
||||
{
|
||||
if (framebuffer->ColorAttachment().Texture() == tex) {
|
||||
framebuffer->FramebufferTexture2D(
|
||||
LOCAL_GL_FRAMEBUFFER, LOCAL_GL_COLOR_ATTACHMENT0,
|
||||
tex->Target(), tex, level);
|
||||
}
|
||||
if (framebuffer->DepthAttachment().Texture() == tex) {
|
||||
framebuffer->FramebufferTexture2D(
|
||||
LOCAL_GL_FRAMEBUFFER, LOCAL_GL_DEPTH_ATTACHMENT,
|
||||
tex->Target(), tex, level);
|
||||
}
|
||||
if (framebuffer->StencilAttachment().Texture() == tex) {
|
||||
framebuffer->FramebufferTexture2D(
|
||||
LOCAL_GL_FRAMEBUFFER, LOCAL_GL_STENCIL_ATTACHMENT,
|
||||
tex->Target(), tex, level);
|
||||
}
|
||||
if (framebuffer->DepthStencilAttachment().Texture() == tex) {
|
||||
framebuffer->FramebufferTexture2D(
|
||||
LOCAL_GL_FRAMEBUFFER, LOCAL_GL_DEPTH_STENCIL_ATTACHMENT,
|
||||
tex->Target(), tex, level);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -912,11 +912,13 @@ WebGLContext::InitAndValidateGL()
|
|||
if (MinCapabilityMode()) {
|
||||
mGLMaxTextureSize = MINVALUE_GL_MAX_TEXTURE_SIZE;
|
||||
mGLMaxCubeMapTextureSize = MINVALUE_GL_MAX_CUBE_MAP_TEXTURE_SIZE;
|
||||
mGLMaxRenderbufferSize = MINVALUE_GL_MAX_RENDERBUFFER_SIZE;
|
||||
mGLMaxTextureImageUnits = MINVALUE_GL_MAX_TEXTURE_IMAGE_UNITS;
|
||||
mGLMaxVertexTextureImageUnits = MINVALUE_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS;
|
||||
} else {
|
||||
gl->fGetIntegerv(LOCAL_GL_MAX_TEXTURE_SIZE, &mGLMaxTextureSize);
|
||||
gl->fGetIntegerv(LOCAL_GL_MAX_CUBE_MAP_TEXTURE_SIZE, &mGLMaxCubeMapTextureSize);
|
||||
gl->fGetIntegerv(LOCAL_GL_MAX_RENDERBUFFER_SIZE, &mGLMaxRenderbufferSize);
|
||||
gl->fGetIntegerv(LOCAL_GL_MAX_TEXTURE_IMAGE_UNITS, &mGLMaxTextureImageUnits);
|
||||
gl->fGetIntegerv(LOCAL_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &mGLMaxVertexTextureImageUnits);
|
||||
}
|
||||
|
|
|
@ -379,8 +379,18 @@ static bool
|
|||
IsOffsetParent(nsIFrame* aFrame)
|
||||
{
|
||||
nsIAtom* frameType = aFrame->GetType();
|
||||
return (IS_TABLE_CELL(frameType) ||
|
||||
frameType == nsGkAtoms::tableFrame);
|
||||
|
||||
if (IS_TABLE_CELL(frameType) || frameType == nsGkAtoms::tableFrame) {
|
||||
// Per the IDL for Element, only td, th, and table are acceptable offsetParents
|
||||
// apart from body or positioned elements; we need to check the content type as
|
||||
// well as the frame type so we ignore anonymous tables created by an element
|
||||
// with display: table-cell with no actual table
|
||||
nsIContent* content = aFrame->GetContent();
|
||||
|
||||
return content->IsHTML(nsGkAtoms::table) || content->IsHTML(nsGkAtoms::td)
|
||||
|| content->IsHTML(nsGkAtoms::th);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Element*
|
||||
|
|
|
@ -270,6 +270,7 @@ MOCHITEST_FILES = \
|
|||
test_bug786564.html \
|
||||
test_bug797113.html \
|
||||
test_bug787134.html \
|
||||
test_bug803677.html \
|
||||
test_iframe_sandbox_inheritance.html \
|
||||
file_iframe_sandbox_a_if1.html \
|
||||
file_iframe_sandbox_a_if2.html \
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=803677
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for Bug 803677</title>
|
||||
<script type="application/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script src="reflect.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<style>
|
||||
.base { border:1px solid gray; }
|
||||
.bad-table { display:table-cell; border:1px solid red; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=803677">Mozilla Bug 803677</a>
|
||||
<p id="display"></p>
|
||||
<div id="content">
|
||||
<p class="base">1</p>
|
||||
<p class="base">2</p>
|
||||
<p class="base">3</p>
|
||||
<p class="base bad-table">4</p>
|
||||
<p class="base">7</p>
|
||||
<p class="base">8</p>
|
||||
<p class="base">9</p>
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
var p = document.querySelectorAll(".base");
|
||||
var parent = document.querySelector("body");
|
||||
var prevOffset = 0;
|
||||
for (var i = 0; i < p.length; i++) {
|
||||
var t = 0, e = p[i];
|
||||
is(e.offsetParent, parent, "Offset parent of all paragraphs should be the body.");
|
||||
while (e) {
|
||||
t += e.offsetTop;
|
||||
e = e.offsetParent;
|
||||
}
|
||||
p[i].innerHTML = t;
|
||||
|
||||
ok(t > prevOffset, "Offset should increase down the page");
|
||||
prevOffset = t;
|
||||
}
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -14,6 +14,7 @@
|
|||
#include "nsIDOMSVGAnimationElement.h"
|
||||
#include "nsSMILTimedElement.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
@ -366,14 +367,8 @@ nsSMILAnimationController::DoSample(bool aSkipUnchangedContainers)
|
|||
mResampleNeeded = false;
|
||||
// Set running sample flag -- do this before flushing styles so that when we
|
||||
// flush styles we don't end up requesting extra samples
|
||||
AutoRestore<bool> autoRestoreRunningSample(mRunningSample);
|
||||
mRunningSample = true;
|
||||
nsCOMPtr<nsIDocument> kungFuDeathGrip(mDocument); // keeps 'this' alive too
|
||||
mDocument->FlushPendingNotifications(Flush_Style);
|
||||
|
||||
// WARNING:
|
||||
// WARNING: the above flush may have destroyed the pres shell and/or
|
||||
// WARNING: frames and other layout related objects.
|
||||
// WARNING:
|
||||
|
||||
// STEP 1: Bring model up to date
|
||||
// (i) Rewind elements where necessary
|
||||
|
@ -441,13 +436,26 @@ nsSMILAnimationController::DoSample(bool aSkipUnchangedContainers)
|
|||
mLastCompositorTable->EnumerateEntries(DoClearAnimationEffects, nullptr);
|
||||
}
|
||||
|
||||
// return early if there are no active animations to avoid a style flush
|
||||
if (currentCompositorTable->Count() == 0) {
|
||||
mLastCompositorTable = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocument> kungFuDeathGrip(mDocument); // keeps 'this' alive too
|
||||
mDocument->FlushPendingNotifications(Flush_Style);
|
||||
|
||||
// WARNING:
|
||||
// WARNING: the above flush may have destroyed the pres shell and/or
|
||||
// WARNING: frames and other layout related objects.
|
||||
// WARNING:
|
||||
|
||||
// STEP 5: Compose currently-animated attributes.
|
||||
// XXXdholbert: This step traverses our animation targets in an effectively
|
||||
// random order. For animation from/to 'inherit' values to work correctly
|
||||
// when the inherited value is *also* being animated, we really should be
|
||||
// traversing our animated nodes in an ancestors-first order (bug 501183)
|
||||
currentCompositorTable->EnumerateEntries(DoComposeAttribute, nullptr);
|
||||
mRunningSample = false;
|
||||
|
||||
// Update last compositor table
|
||||
mLastCompositorTable = currentCompositorTable.forget();
|
||||
|
|
|
@ -240,7 +240,7 @@ protected:
|
|||
/**
|
||||
* The builder observers.
|
||||
*/
|
||||
nsCOMPtr<nsISupportsArray> mObservers;
|
||||
nsCOMArray<nsIXULTreeBuilderObserver> mObservers;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
@ -282,22 +282,11 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsXULTreeBuilder, nsXULTemplateB
|
|||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mObservers)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
static bool TraverseObservers(nsISupports* aElement, void *aData)
|
||||
{
|
||||
nsCycleCollectionTraversalCallback *cb =
|
||||
static_cast<nsCycleCollectionTraversalCallback*>(aData);
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(*cb, "mObservers[i]");
|
||||
cb->NoteXPCOMChild(aElement);
|
||||
return true;
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsXULTreeBuilder, nsXULTemplateBuilder)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mBoxObject)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSelection)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPersistStateStore)
|
||||
if (tmp->mObservers) {
|
||||
tmp->mObservers->EnumerateForwards(TraverseObservers, &cb);
|
||||
}
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mObservers)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
DOMCI_DATA(XULTreeBuilder, nsXULTreeBuilder)
|
||||
|
@ -361,20 +350,13 @@ nsXULTreeBuilder::GetIndexOfResource(nsIRDFResource* aResource, int32_t* aResult
|
|||
NS_IMETHODIMP
|
||||
nsXULTreeBuilder::AddObserver(nsIXULTreeBuilderObserver* aObserver)
|
||||
{
|
||||
nsresult rv;
|
||||
if (!mObservers) {
|
||||
rv = NS_NewISupportsArray(getter_AddRefs(mObservers));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
}
|
||||
|
||||
return mObservers->AppendElement(aObserver);
|
||||
return mObservers.AppendObject(aObserver) ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULTreeBuilder::RemoveObserver(nsIXULTreeBuilderObserver* aObserver)
|
||||
{
|
||||
return mObservers ? mObservers->RemoveElement(aObserver) : NS_ERROR_FAILURE;
|
||||
return mObservers.RemoveObject(aObserver) ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -855,14 +837,11 @@ nsXULTreeBuilder::ToggleOpenState(int32_t aIndex)
|
|||
return rv;
|
||||
}
|
||||
|
||||
if (mObservers) {
|
||||
uint32_t count;
|
||||
mObservers->Count(&count);
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
nsCOMPtr<nsIXULTreeBuilderObserver> observer = do_QueryElementAt(mObservers, i);
|
||||
if (observer)
|
||||
observer->OnToggleOpenState(aIndex);
|
||||
}
|
||||
uint32_t count = mObservers.Count();
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
nsCOMPtr<nsIXULTreeBuilderObserver> observer = mObservers.SafeObjectAt(i);
|
||||
if (observer)
|
||||
observer->OnToggleOpenState(aIndex);
|
||||
}
|
||||
|
||||
if (mPersistStateStore) {
|
||||
|
@ -908,17 +887,14 @@ nsXULTreeBuilder::CycleHeader(nsITreeColumn* aCol)
|
|||
nsCOMPtr<nsIDOMElement> element;
|
||||
aCol->GetElement(getter_AddRefs(element));
|
||||
|
||||
if (mObservers) {
|
||||
nsAutoString id;
|
||||
aCol->GetId(id);
|
||||
nsAutoString id;
|
||||
aCol->GetId(id);
|
||||
|
||||
uint32_t count;
|
||||
mObservers->Count(&count);
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
nsCOMPtr<nsIXULTreeBuilderObserver> observer = do_QueryElementAt(mObservers, i);
|
||||
if (observer)
|
||||
observer->OnCycleHeader(id.get(), element);
|
||||
}
|
||||
uint32_t count = mObservers.Count();
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
nsCOMPtr<nsIXULTreeBuilderObserver> observer = mObservers.SafeObjectAt(i);
|
||||
if (observer)
|
||||
observer->OnCycleHeader(id.get(), element);
|
||||
}
|
||||
|
||||
return Sort(element);
|
||||
|
@ -927,14 +903,11 @@ nsXULTreeBuilder::CycleHeader(nsITreeColumn* aCol)
|
|||
NS_IMETHODIMP
|
||||
nsXULTreeBuilder::SelectionChanged()
|
||||
{
|
||||
if (mObservers) {
|
||||
uint32_t count;
|
||||
mObservers->Count(&count);
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
nsCOMPtr<nsIXULTreeBuilderObserver> observer = do_QueryElementAt(mObservers, i);
|
||||
if (observer)
|
||||
observer->OnSelectionChanged();
|
||||
}
|
||||
uint32_t count = mObservers.Count();
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
nsCOMPtr<nsIXULTreeBuilderObserver> observer = mObservers.SafeObjectAt(i);
|
||||
if (observer)
|
||||
observer->OnSelectionChanged();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -944,17 +917,15 @@ NS_IMETHODIMP
|
|||
nsXULTreeBuilder::CycleCell(int32_t aRow, nsITreeColumn* aCol)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aCol);
|
||||
if (mObservers) {
|
||||
nsAutoString id;
|
||||
aCol->GetId(id);
|
||||
|
||||
uint32_t count;
|
||||
mObservers->Count(&count);
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
nsCOMPtr<nsIXULTreeBuilderObserver> observer = do_QueryElementAt(mObservers, i);
|
||||
if (observer)
|
||||
observer->OnCycleCell(aRow, id.get());
|
||||
}
|
||||
nsAutoString id;
|
||||
aCol->GetId(id);
|
||||
|
||||
uint32_t count = mObservers.Count();
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
nsCOMPtr<nsIXULTreeBuilderObserver> observer = mObservers.SafeObjectAt(i);
|
||||
if (observer)
|
||||
observer->OnCycleCell(aRow, id.get());
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -1029,14 +1000,11 @@ nsXULTreeBuilder::SetCellText(int32_t aRow, nsITreeColumn* aCol, const nsAString
|
|||
NS_IMETHODIMP
|
||||
nsXULTreeBuilder::PerformAction(const PRUnichar* aAction)
|
||||
{
|
||||
if (mObservers) {
|
||||
uint32_t count;
|
||||
mObservers->Count(&count);
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
nsCOMPtr<nsIXULTreeBuilderObserver> observer = do_QueryElementAt(mObservers, i);
|
||||
if (observer)
|
||||
observer->OnPerformAction(aAction);
|
||||
}
|
||||
uint32_t count = mObservers.Count();
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
nsCOMPtr<nsIXULTreeBuilderObserver> observer = mObservers.SafeObjectAt(i);
|
||||
if (observer)
|
||||
observer->OnPerformAction(aAction);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -1045,14 +1013,11 @@ nsXULTreeBuilder::PerformAction(const PRUnichar* aAction)
|
|||
NS_IMETHODIMP
|
||||
nsXULTreeBuilder::PerformActionOnRow(const PRUnichar* aAction, int32_t aRow)
|
||||
{
|
||||
if (mObservers) {
|
||||
uint32_t count;
|
||||
mObservers->Count(&count);
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
nsCOMPtr<nsIXULTreeBuilderObserver> observer = do_QueryElementAt(mObservers, i);
|
||||
if (observer)
|
||||
observer->OnPerformActionOnRow(aAction, aRow);
|
||||
}
|
||||
uint32_t count = mObservers.Count();
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
nsCOMPtr<nsIXULTreeBuilderObserver> observer = mObservers.SafeObjectAt(i);
|
||||
if (observer)
|
||||
observer->OnPerformActionOnRow(aAction, aRow);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -1062,17 +1027,14 @@ NS_IMETHODIMP
|
|||
nsXULTreeBuilder::PerformActionOnCell(const PRUnichar* aAction, int32_t aRow, nsITreeColumn* aCol)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aCol);
|
||||
if (mObservers) {
|
||||
nsAutoString id;
|
||||
aCol->GetId(id);
|
||||
nsAutoString id;
|
||||
aCol->GetId(id);
|
||||
|
||||
uint32_t count;
|
||||
mObservers->Count(&count);
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
nsCOMPtr<nsIXULTreeBuilderObserver> observer = do_QueryElementAt(mObservers, i);
|
||||
if (observer)
|
||||
observer->OnPerformActionOnCell(aAction, aRow, id.get());
|
||||
}
|
||||
uint32_t count = mObservers.Count();
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
nsCOMPtr<nsIXULTreeBuilderObserver> observer = mObservers.SafeObjectAt(i);
|
||||
if (observer)
|
||||
observer->OnPerformActionOnCell(aAction, aRow, id.get());
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -1083,8 +1045,7 @@ void
|
|||
nsXULTreeBuilder::NodeWillBeDestroyed(const nsINode* aNode)
|
||||
{
|
||||
nsCOMPtr<nsIMutationObserver> kungFuDeathGrip(this);
|
||||
if (mObservers)
|
||||
mObservers->Clear();
|
||||
mObservers.Clear();
|
||||
|
||||
nsXULTemplateBuilder::NodeWillBeDestroyed(aNode);
|
||||
}
|
||||
|
@ -1918,16 +1879,13 @@ nsXULTreeBuilder::CanDrop(int32_t index, int32_t orientation,
|
|||
nsIDOMDataTransfer* dataTransfer, bool *_retval)
|
||||
{
|
||||
*_retval = false;
|
||||
if (mObservers) {
|
||||
uint32_t count;
|
||||
mObservers->Count(&count);
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
nsCOMPtr<nsIXULTreeBuilderObserver> observer = do_QueryElementAt(mObservers, i);
|
||||
if (observer) {
|
||||
observer->CanDrop(index, orientation, dataTransfer, _retval);
|
||||
if (*_retval)
|
||||
break;
|
||||
}
|
||||
uint32_t count = mObservers.Count();
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
nsCOMPtr<nsIXULTreeBuilderObserver> observer = mObservers.SafeObjectAt(i);
|
||||
if (observer) {
|
||||
observer->CanDrop(index, orientation, dataTransfer, _retval);
|
||||
if (*_retval)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1937,17 +1895,14 @@ nsXULTreeBuilder::CanDrop(int32_t index, int32_t orientation,
|
|||
NS_IMETHODIMP
|
||||
nsXULTreeBuilder::Drop(int32_t row, int32_t orient, nsIDOMDataTransfer* dataTransfer)
|
||||
{
|
||||
if (mObservers) {
|
||||
uint32_t count;
|
||||
mObservers->Count(&count);
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
nsCOMPtr<nsIXULTreeBuilderObserver> observer = do_QueryElementAt(mObservers, i);
|
||||
if (observer) {
|
||||
bool canDrop = false;
|
||||
observer->CanDrop(row, orient, dataTransfer, &canDrop);
|
||||
if (canDrop)
|
||||
observer->OnDrop(row, orient, dataTransfer);
|
||||
}
|
||||
uint32_t count = mObservers.Count();
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
nsCOMPtr<nsIXULTreeBuilderObserver> observer = mObservers.SafeObjectAt(i);
|
||||
if (observer) {
|
||||
bool canDrop = false;
|
||||
observer->CanDrop(row, orient, dataTransfer, &canDrop);
|
||||
if (canDrop)
|
||||
observer->OnDrop(row, orient, dataTransfer);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -206,6 +206,7 @@ this.DOMApplicationRegistry = {
|
|||
|
||||
// Installs a 3rd party packaged app.
|
||||
installPreinstalledPackage: function installPreinstalledPackage(aId) {
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
let app = this.webapps[aId];
|
||||
let baseDir;
|
||||
try {
|
||||
|
@ -267,6 +268,7 @@ this.DOMApplicationRegistry = {
|
|||
} finally {
|
||||
zipReader.close();
|
||||
}
|
||||
#endif
|
||||
},
|
||||
|
||||
// Implements the core of bug 787439
|
||||
|
@ -937,9 +939,11 @@ this.DOMApplicationRegistry = {
|
|||
}
|
||||
|
||||
let manifest = new ManifestHelper(aJSON, app.installOrigin);
|
||||
this.downloadPackage(manifest, { manifestURL: aManifestURL,
|
||||
origin: app.origin }, isUpdate,
|
||||
function(aId, aManifest) {
|
||||
this.downloadPackage(manifest, {
|
||||
manifestURL: aManifestURL,
|
||||
origin: app.origin,
|
||||
downloadSize: app.downloadSize
|
||||
}, isUpdate, function(aId, aManifest) {
|
||||
// Success! Keep the zip in of TmpD, we'll move it out when
|
||||
// applyDownload() will be called.
|
||||
let tmpDir = FileUtils.getDir("TmpD", ["webapps", aId], true, true);
|
||||
|
|
|
@ -752,7 +752,7 @@ Navigator::Vibrate(const jsval& aPattern, JSContext* cx)
|
|||
nsCOMPtr<nsPIDOMWindow> win = do_QueryReferent(mWindow);
|
||||
NS_ENSURE_TRUE(win, NS_OK);
|
||||
|
||||
nsIDOMDocument* domDoc = win->GetExtantDocument();
|
||||
nsCOMPtr<nsIDOMDocument> domDoc = win->GetExtantDocument();
|
||||
NS_ENSURE_TRUE(domDoc, NS_ERROR_FAILURE);
|
||||
|
||||
bool hidden = true;
|
||||
|
|
|
@ -13,14 +13,16 @@ this.EXPORTED_SYMBOLS = ["ObjectWrapper"];
|
|||
// Makes sure that we expose correctly chrome JS objects to content.
|
||||
|
||||
this.ObjectWrapper = {
|
||||
getObjectKind: function objWrapper_getobjectkind(aObject) {
|
||||
getObjectKind: function objWrapper_getObjectKind(aObject) {
|
||||
if (!aObject) {
|
||||
return "null";
|
||||
}
|
||||
|
||||
if (Array.isArray(aObject)) {
|
||||
return "array";
|
||||
} else if (aObject.mozSlice && (typeof aObject.mozSlice == "function")) {
|
||||
} else if (aObject instanceof Ci.nsIDOMFile) {
|
||||
return "file";
|
||||
} else if (aObject instanceof Ci.nsIDOMBlob) {
|
||||
return "blob";
|
||||
} else if (typeof aObject == "object") {
|
||||
return "object";
|
||||
|
@ -30,48 +32,35 @@ this.ObjectWrapper = {
|
|||
},
|
||||
|
||||
wrap: function objWrapper_wrap(aObject, aCtxt) {
|
||||
if (!aObject) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// First check wich kind of object we have.
|
||||
let kind = this.getObjectKind(aObject);
|
||||
if (kind == "array") {
|
||||
if (kind == "null") {
|
||||
return null;
|
||||
} else if (kind == "array") {
|
||||
let res = Cu.createArrayIn(aCtxt);
|
||||
aObject.forEach(function(aObj) {
|
||||
res.push(this.wrap(aObj, aCtxt));
|
||||
}, this);
|
||||
return res;
|
||||
} else if (kind == "file") {
|
||||
return new aCtxt.File(aObject,
|
||||
{ name: aObject.name,
|
||||
type: aObject.type });
|
||||
} else if (kind == "blob") {
|
||||
return new aCtxt.Blob([aObject]);
|
||||
} else if (kind == "primitive") {
|
||||
return aObject;
|
||||
}
|
||||
|
||||
// Fall-through, we now have a dictionnary object.
|
||||
// Fall-through, we now have a dictionnary object.
|
||||
let res = Cu.createObjectIn(aCtxt);
|
||||
let propList = { };
|
||||
for (let prop in aObject) {
|
||||
let value;
|
||||
let objProp = aObject[prop];
|
||||
let propKind = this.getObjectKind(objProp);
|
||||
if (propKind == "array") {
|
||||
value = Cu.createArrayIn(aCtxt);
|
||||
objProp.forEach(function(aObj) {
|
||||
value.push(this.wrap(aObj, aCtxt));
|
||||
}, this);
|
||||
} else if (propKind == "blob") {
|
||||
value = new aCtxt.Blob([objProp]);
|
||||
} else if (propKind == "object") {
|
||||
value = this.wrap(objProp, aCtxt);
|
||||
} else {
|
||||
value = objProp;
|
||||
}
|
||||
propList[prop] = {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: true,
|
||||
value: value
|
||||
value: this.wrap(aObject[prop], aCtxt)
|
||||
}
|
||||
}
|
||||
Object.defineProperties(res, propList);
|
||||
|
|
|
@ -427,7 +427,6 @@
|
|||
|
||||
#include "nsDOMFile.h"
|
||||
#include "nsDOMFileReader.h"
|
||||
#include "nsIDOMFormData.h"
|
||||
#include "ArchiveReader.h"
|
||||
#include "ArchiveRequest.h"
|
||||
|
||||
|
@ -1566,9 +1565,6 @@ static nsDOMClassInfoData sClassInfoData[] = {
|
|||
NS_DEFINE_CHROME_ONLY_CLASSINFO_DATA(ChromeMessageSender, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
|
||||
NS_DEFINE_CLASSINFO_DATA(FormData, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
|
||||
NS_DEFINE_CLASSINFO_DATA(DesktopNotification, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
NS_DEFINE_CLASSINFO_DATA(DesktopNotificationCenter, nsDOMGenericSH,
|
||||
|
@ -1709,7 +1705,6 @@ static nsDOMClassInfoData sClassInfoData[] = {
|
|||
|
||||
NS_DEFINE_CONTRACT_CTOR(FileReader, NS_FILEREADER_CONTRACTID)
|
||||
NS_DEFINE_CONTRACT_CTOR(ArchiveReader, NS_ARCHIVEREADER_CONTRACTID)
|
||||
NS_DEFINE_CONTRACT_CTOR(FormData, NS_FORMDATA_CONTRACTID)
|
||||
NS_DEFINE_CONTRACT_CTOR(XPathEvaluator, NS_XPATH_EVALUATOR_CONTRACTID)
|
||||
NS_DEFINE_CONTRACT_CTOR(XSLTProcessor,
|
||||
"@mozilla.org/document-transformer;1?type=xslt")
|
||||
|
@ -1757,7 +1752,7 @@ struct nsConstructorFuncMapData
|
|||
static const nsConstructorFuncMapData kConstructorFuncMap[] =
|
||||
{
|
||||
NS_DEFINE_CONSTRUCTOR_FUNC_DATA(Blob, nsDOMMultipartFile::NewBlob)
|
||||
NS_DEFINE_CONSTRUCTOR_FUNC_DATA(File, nsDOMFileFile::NewFile)
|
||||
NS_DEFINE_CONSTRUCTOR_FUNC_DATA(File, nsDOMMultipartFile::NewFile)
|
||||
NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(Event)
|
||||
NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(UIEvent)
|
||||
NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(MouseEvent)
|
||||
|
@ -1774,7 +1769,6 @@ static const nsConstructorFuncMapData kConstructorFuncMap[] =
|
|||
NS_DEFINE_CONSTRUCTOR_FUNC_DATA(MozSmsFilter, sms::SmsFilter::NewSmsFilter)
|
||||
NS_DEFINE_CONSTRUCTOR_FUNC_DATA(FileReader, FileReaderCtor)
|
||||
NS_DEFINE_CONSTRUCTOR_FUNC_DATA(ArchiveReader, ArchiveReaderCtor)
|
||||
NS_DEFINE_CONSTRUCTOR_FUNC_DATA(FormData, FormDataCtor)
|
||||
NS_DEFINE_CONSTRUCTOR_FUNC_DATA(XPathEvaluator, XPathEvaluatorCtor)
|
||||
NS_DEFINE_CONSTRUCTOR_FUNC_DATA(XSLTProcessor, XSLTProcessorCtor)
|
||||
NS_DEFINE_CONSTRUCTOR_FUNC_DATA(EventSource, EventSourceCtor)
|
||||
|
@ -4201,10 +4195,6 @@ nsDOMClassInfo::Init()
|
|||
DOM_CLASSINFO_MAP_ENTRY(nsIMessageSender)
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
||||
DOM_CLASSINFO_MAP_BEGIN(FormData, nsIDOMFormData)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMFormData)
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
||||
DOM_CLASSINFO_MAP_BEGIN(DesktopNotification, nsIDOMDesktopNotification)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMDesktopNotification)
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
|
|
@ -448,8 +448,6 @@ DOMCI_CLASS(ContentFrameMessageManager)
|
|||
DOMCI_CLASS(ChromeMessageBroadcaster)
|
||||
DOMCI_CLASS(ChromeMessageSender)
|
||||
|
||||
DOMCI_CLASS(FormData)
|
||||
|
||||
DOMCI_CLASS(DesktopNotification)
|
||||
DOMCI_CLASS(DesktopNotificationCenter)
|
||||
|
||||
|
|
|
@ -2546,6 +2546,13 @@ nsDOMWindowUtils::PreventFurtherDialogs()
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
static nsIDOMBlob*
|
||||
GetXPConnectNative(JSContext* aCx, JSObject* aObj) {
|
||||
nsCOMPtr<nsIDOMBlob> blob = do_QueryInterface(
|
||||
nsContentUtils::XPConnect()->GetNativeOfWrapper(aCx, aObj));
|
||||
return blob;
|
||||
}
|
||||
|
||||
static nsresult
|
||||
GetFileOrBlob(const nsAString& aName, const jsval& aBlobParts,
|
||||
const jsval& aParameters, JSContext* aCx,
|
||||
|
@ -2567,12 +2574,12 @@ GetFileOrBlob(const nsAString& aName, const jsval& aBlobParts,
|
|||
}
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIJSNativeInitializer> initializer = do_QueryInterface(file);
|
||||
NS_ASSERTION(initializer, "what?");
|
||||
nsDOMMultipartFile* domFile =
|
||||
static_cast<nsDOMMultipartFile*>(static_cast<nsIDOMFile*>(file.get()));
|
||||
|
||||
jsval args[2] = { aBlobParts, aParameters };
|
||||
|
||||
rv = initializer->Initialize(nullptr, aCx, nullptr, aOptionalArgCount, args);
|
||||
rv = domFile->InitBlob(aCx, aOptionalArgCount, args, GetXPConnectNative);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
file.forget(aResult);
|
||||
|
|
|
@ -245,8 +245,13 @@ DOMInterfaces = {
|
|||
},
|
||||
|
||||
'FormData': [
|
||||
{
|
||||
'nativeType': 'nsFormData'
|
||||
},
|
||||
{
|
||||
'workers': True,
|
||||
'skipGen': True,
|
||||
'nativeType': 'JSObject'
|
||||
}],
|
||||
|
||||
'GainNode': [
|
||||
|
@ -743,6 +748,7 @@ def addExternalHTMLElement(element):
|
|||
headerFile=nativeElement + '.h')
|
||||
|
||||
addExternalHTMLElement('HTMLCanvasElement')
|
||||
addExternalHTMLElement('HTMLFormElement')
|
||||
addExternalHTMLElement('HTMLImageElement')
|
||||
addExternalHTMLElement('HTMLMenuElement')
|
||||
addExternalHTMLElement('HTMLOptionElement')
|
||||
|
|
|
@ -2196,6 +2196,7 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None,
|
|||
if not isOptional:
|
||||
typeName = CGWrapper(typeName, pre="const ")
|
||||
|
||||
# NOTE: Keep this in sync with variadic conversions as needed
|
||||
templateBody = ("""JSObject* seq = &${val}.toObject();\n
|
||||
if (!IsArrayLike(cx, seq)) {
|
||||
%s
|
||||
|
@ -3042,9 +3043,6 @@ class CGArgumentConverter(CGThing):
|
|||
invalidEnumValueFatal=True, lenientFloatCode=None):
|
||||
CGThing.__init__(self)
|
||||
self.argument = argument
|
||||
if argument.variadic:
|
||||
raise TypeError("We don't support variadic arguments yet " +
|
||||
str(argument.location))
|
||||
assert(not argument.defaultValue or argument.optional)
|
||||
|
||||
replacer = {
|
||||
|
@ -3074,19 +3072,70 @@ class CGArgumentConverter(CGThing):
|
|||
self.lenientFloatCode = lenientFloatCode
|
||||
|
||||
def define(self):
|
||||
return instantiateJSToNativeConversionTemplate(
|
||||
getJSToNativeConversionTemplate(self.argument.type,
|
||||
self.descriptorProvider,
|
||||
isOptional=(self.argcAndIndex is not None),
|
||||
invalidEnumValueFatal=self.invalidEnumValueFatal,
|
||||
defaultValue=self.argument.defaultValue,
|
||||
treatNullAs=self.argument.treatNullAs,
|
||||
treatUndefinedAs=self.argument.treatUndefinedAs,
|
||||
isEnforceRange=self.argument.enforceRange,
|
||||
isClamp=self.argument.clamp,
|
||||
lenientFloatCode=self.lenientFloatCode),
|
||||
self.replacementVariables,
|
||||
self.argcAndIndex).define()
|
||||
typeConversion = getJSToNativeConversionTemplate(
|
||||
self.argument.type,
|
||||
self.descriptorProvider,
|
||||
isOptional=(self.argcAndIndex is not None and
|
||||
not self.argument.variadic),
|
||||
invalidEnumValueFatal=self.invalidEnumValueFatal,
|
||||
defaultValue=self.argument.defaultValue,
|
||||
treatNullAs=self.argument.treatNullAs,
|
||||
treatUndefinedAs=self.argument.treatUndefinedAs,
|
||||
isEnforceRange=self.argument.enforceRange,
|
||||
isClamp=self.argument.clamp,
|
||||
lenientFloatCode=self.lenientFloatCode,
|
||||
isMember=self.argument.variadic)
|
||||
|
||||
if not self.argument.variadic:
|
||||
return instantiateJSToNativeConversionTemplate(
|
||||
typeConversion,
|
||||
self.replacementVariables,
|
||||
self.argcAndIndex).define()
|
||||
|
||||
# Variadic arguments get turned into a sequence.
|
||||
(elementTemplate, elementDeclType,
|
||||
elementHolderType, dealWithOptional) = typeConversion
|
||||
if dealWithOptional:
|
||||
raise TypeError("Shouldn't have optional things in variadics")
|
||||
if elementHolderType is not None:
|
||||
raise TypeError("Shouldn't need holders for variadics")
|
||||
|
||||
replacer = dict(self.argcAndIndex, **self.replacementVariables)
|
||||
replacer["seqType"] = CGWrapper(elementDeclType, pre="Sequence< ", post=" >").define()
|
||||
replacer["elemType"] = elementDeclType.define()
|
||||
|
||||
# NOTE: Keep this in sync with sequence conversions as needed
|
||||
variadicConversion = string.Template("""const ${seqType} ${declName};
|
||||
if (${argc} > ${index}) {
|
||||
${seqType}& arr = const_cast< ${seqType}& >(${declName});
|
||||
if (!arr.SetCapacity(${argc} - ${index})) {
|
||||
JS_ReportOutOfMemory(cx);
|
||||
return false;
|
||||
}
|
||||
for (uint32_t variadicArg = ${index}; variadicArg < ${argc}; ++variadicArg) {
|
||||
${elemType}& slot = *arr.AppendElement();
|
||||
""").substitute(replacer)
|
||||
|
||||
val = string.Template("${argv}[variadicArg]").substitute(replacer)
|
||||
variadicConversion += CGIndenter(CGGeneric(
|
||||
string.Template(elementTemplate).substitute(
|
||||
{
|
||||
"val" : val,
|
||||
"valPtr": "&" + val,
|
||||
"declName" : "slot",
|
||||
# We only need holderName here to handle isExternal()
|
||||
# interfaces, which use an internal holder for the
|
||||
# conversion even when forceOwningType ends up true.
|
||||
"holderName": "tempHolder",
|
||||
# Use the same ${obj} as for the variadic arg itself
|
||||
"obj": replacer["obj"]
|
||||
}
|
||||
)), 4).define()
|
||||
|
||||
variadicConversion += ("\n"
|
||||
" }\n"
|
||||
"}")
|
||||
return variadicConversion
|
||||
|
||||
def getWrapTemplateForType(type, descriptorProvider, result, successCode,
|
||||
isCreator, exceptionCode):
|
||||
|
@ -3777,16 +3826,44 @@ class CGMethodCall(CGThing):
|
|||
|
||||
distinguishingIndex = method.distinguishingIndexForArgCount(argCount)
|
||||
|
||||
for (_, args) in possibleSignatures:
|
||||
def distinguishingArgument(signature):
|
||||
args = signature[1]
|
||||
if distinguishingIndex < len(args):
|
||||
return args[distinguishingIndex]
|
||||
assert args[-1].variadic
|
||||
return args[-1]
|
||||
|
||||
def distinguishingType(signature):
|
||||
return distinguishingArgument(signature).type
|
||||
|
||||
for sig in possibleSignatures:
|
||||
# We should not have "any" args at distinguishingIndex,
|
||||
# since we have multiple possible signatures remaining,
|
||||
# but "any" is never distinguishable from anything else.
|
||||
assert not args[distinguishingIndex].type.isAny()
|
||||
assert not distinguishingType(sig).isAny()
|
||||
# We can't handle unions at the distinguishing index.
|
||||
if args[distinguishingIndex].type.isUnion():
|
||||
if distinguishingType(sig).isUnion():
|
||||
raise TypeError("No support for unions as distinguishing "
|
||||
"arguments yet: %s",
|
||||
args[distinguishingIndex].location)
|
||||
distinguishingArgument(sig).location)
|
||||
# We don't support variadics as the distinguishingArgument yet.
|
||||
# If you want to add support, consider this case:
|
||||
#
|
||||
# void(long... foo);
|
||||
# void(long bar, Int32Array baz);
|
||||
#
|
||||
# in which we have to convert argument 0 to long before picking
|
||||
# an overload... but all the variadic stuff needs to go into a
|
||||
# single array in case we pick that overload, so we have to have
|
||||
# machinery for converting argument 0 to long and then either
|
||||
# placing it in the variadic bit or not. Or something. We may
|
||||
# be able to loosen this restriction if the variadic arg is in
|
||||
# fact at distinguishingIndex, perhaps. Would need to
|
||||
# double-check.
|
||||
if distinguishingArgument(sig).variadic:
|
||||
raise TypeError("No support for variadics as distinguishing "
|
||||
"arguments yet: %s",
|
||||
distinguishingArgument(sig).location)
|
||||
|
||||
# Convert all our arguments up to the distinguishing index.
|
||||
# Doesn't matter which of the possible signatures we use, since
|
||||
|
@ -3816,9 +3893,6 @@ class CGMethodCall(CGThing):
|
|||
return True
|
||||
return False
|
||||
|
||||
def distinguishingType(signature):
|
||||
return signature[1][distinguishingIndex].type
|
||||
|
||||
def tryCall(signature, indent, isDefinitelyObject=False,
|
||||
isNullOrUndefined=False):
|
||||
assert not isDefinitelyObject or not isNullOrUndefined
|
||||
|
@ -6818,7 +6892,7 @@ class CGBindingRoot(CGThing):
|
|||
class CGNativeMember(ClassMethod):
|
||||
def __init__(self, descriptor, member, name, signature, extendedAttrs,
|
||||
breakAfter=True, passCxAsNeeded=True, visibility="public",
|
||||
jsObjectsArePtr=False):
|
||||
jsObjectsArePtr=False, variadicIsSequence=False):
|
||||
"""
|
||||
If jsObjectsArePtr is true, typed arrays and "object" will be
|
||||
passed as JSObject*
|
||||
|
@ -6830,6 +6904,7 @@ class CGNativeMember(ClassMethod):
|
|||
self.extendedAttrs)
|
||||
self.passCxAsNeeded = passCxAsNeeded
|
||||
self.jsObjectsArePtr = jsObjectsArePtr
|
||||
self.variadicIsSequence = variadicIsSequence
|
||||
breakAfterSelf = "\n" if breakAfter else ""
|
||||
ClassMethod.__init__(self, name,
|
||||
self.getReturnType(signature[0], False),
|
||||
|
@ -7110,7 +7185,8 @@ class CGNativeMember(ClassMethod):
|
|||
decl = CGWrapper(decl, pre="Nullable< ", post=" >")
|
||||
ref = True
|
||||
if variadic:
|
||||
decl = CGWrapper(decl, pre="nsTArray< ", post=" >")
|
||||
arrayType = "Sequence" if self.variadicIsSequence else "nsTArray"
|
||||
decl = CGWrapper(decl, pre="%s< " % arrayType, post=" >")
|
||||
ref = True
|
||||
elif optional:
|
||||
# Note: All variadic args claim to be optional, but we can just use
|
||||
|
@ -7140,7 +7216,8 @@ class CGExampleMethod(CGNativeMember):
|
|||
method),
|
||||
signature,
|
||||
descriptor.getExtendedAttributes(method),
|
||||
breakAfter)
|
||||
breakAfter=breakAfter,
|
||||
variadicIsSequence=True)
|
||||
def define(self, cgClass):
|
||||
return ''
|
||||
|
||||
|
|
|
@ -2607,24 +2607,32 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
|
|||
return [overload for overload in self._overloads if
|
||||
len(overload.arguments) == argc or
|
||||
(len(overload.arguments) > argc and
|
||||
overload.arguments[argc].optional)]
|
||||
overload.arguments[argc].optional) or
|
||||
(len(overload.arguments) < argc and
|
||||
len(overload.arguments) > 0 and
|
||||
overload.arguments[-1].variadic)]
|
||||
|
||||
def signaturesForArgCount(self, argc):
|
||||
return [(overload.returnType, overload.arguments) for overload
|
||||
in self.overloadsForArgCount(argc)]
|
||||
|
||||
def locationsForArgCount(self, argc):
|
||||
return [overload.location for overload in self._overloads if
|
||||
len(overload.arguments) == argc or
|
||||
(len(overload.arguments) > argc and
|
||||
overload.arguments[argc].optional)]
|
||||
return [overload.location for overload in self.overloadsForArgCount(argc)]
|
||||
|
||||
def distinguishingIndexForArgCount(self, argc):
|
||||
def isValidDistinguishingIndex(idx, signatures):
|
||||
for (firstSigIndex, (firstRetval, firstArgs)) in enumerate(signatures[:-1]):
|
||||
for (secondRetval, secondArgs) in signatures[firstSigIndex+1:]:
|
||||
firstType = firstArgs[idx].type
|
||||
secondType = secondArgs[idx].type
|
||||
if idx < len(firstArgs):
|
||||
firstType = firstArgs[idx].type
|
||||
else:
|
||||
assert(firstArgs[-1].variadic)
|
||||
firstType = firstArgs[-1].type
|
||||
if idx < len(secondArgs):
|
||||
secondType = secondArgs[idx].type
|
||||
else:
|
||||
assert(secondArgs[-1].variadic)
|
||||
secondType = secondArgs[-1].type
|
||||
if not firstType.isDistinguishableFrom(secondType):
|
||||
return False
|
||||
return True
|
||||
|
|
|
@ -8,6 +8,9 @@ def WebIDLTest(parser, harness):
|
|||
boolean abitharder(TestOverloads foo);
|
||||
boolean abitharder(boolean foo);
|
||||
void abitharder(ArrayBuffer? foo);
|
||||
void withVariadics(long... numbers);
|
||||
void withVariadics(TestOverloads iface);
|
||||
void withVariadics(long num, TestOverloads iface);
|
||||
};
|
||||
""")
|
||||
|
||||
|
@ -20,7 +23,7 @@ def WebIDLTest(parser, harness):
|
|||
"Should be an IDLInterface")
|
||||
harness.check(iface.identifier.QName(), "::TestOverloads", "Interface has the right QName")
|
||||
harness.check(iface.identifier.name, "TestOverloads", "Interface has the right name")
|
||||
harness.check(len(iface.members), 2, "Expect %s members" % 2)
|
||||
harness.check(len(iface.members), 3, "Expect %s members" % 3)
|
||||
|
||||
member = iface.members[0]
|
||||
harness.check(member.identifier.QName(), "::TestOverloads::basic", "Method has the right QName")
|
||||
|
|
|
@ -37,3 +37,16 @@ def WebIDLTest(parser, harness):
|
|||
threw = True
|
||||
|
||||
harness.ok(threw, "Should have thrown.")
|
||||
|
||||
threw = False
|
||||
try:
|
||||
results = parser.parse("""
|
||||
interface VariadicConstraints4 {
|
||||
void foo(byte... arg1 = 0);
|
||||
};
|
||||
""")
|
||||
|
||||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(threw, "Should have thrown on variadic argument with default value.")
|
||||
|
|
|
@ -154,6 +154,7 @@ public:
|
|||
void PassOptionalByteWithDefault(int8_t);
|
||||
void PassNullableByte(const Nullable<int8_t>&);
|
||||
void PassOptionalNullableByte(const Optional< Nullable<int8_t> >&);
|
||||
void PassVariadicByte(const Sequence<int8_t>&);
|
||||
|
||||
int16_t ReadonlyShort();
|
||||
int16_t WritableShort();
|
||||
|
@ -381,6 +382,7 @@ public:
|
|||
void PassOptionalStringWithDefaultValue(const nsAString&);
|
||||
void PassOptionalNullableString(const Optional<nsAString>&);
|
||||
void PassOptionalNullableStringWithDefaultValue(const nsAString&);
|
||||
void PassVariadicString(const Sequence<nsString>&);
|
||||
|
||||
// Enumerated types
|
||||
void PassEnum(TestEnum);
|
||||
|
@ -473,6 +475,14 @@ public:
|
|||
static bool StaticAttribute(nsISupports*);
|
||||
static void SetStaticAttribute(nsISupports*, bool);
|
||||
|
||||
// Overload resolution tests
|
||||
bool Overload1(TestInterface&);
|
||||
TestInterface* Overload1(const nsAString&, TestInterface&);
|
||||
|
||||
// Variadic handling
|
||||
void PassVariadicThirdArg(const nsAString&, int32_t,
|
||||
const Sequence<OwningNonNull<TestInterface> >&);
|
||||
|
||||
// Miscellania
|
||||
int32_t AttrWithLenientThis();
|
||||
void SetAttrWithLenientThis(int32_t);
|
||||
|
@ -522,6 +532,7 @@ private:
|
|||
void PassOptionalByte(const Optional<T>&) MOZ_DELETE;
|
||||
template<typename T>
|
||||
void PassOptionalByteWithDefault(T) MOZ_DELETE;
|
||||
void PassVariadicByte(Sequence<int8_t>&) MOZ_DELETE;
|
||||
|
||||
void SetReadonlyShort(int16_t) MOZ_DELETE;
|
||||
template<typename T>
|
||||
|
@ -631,7 +642,7 @@ private:
|
|||
void PassOptionalStringWithDefaultValue(nsAString&) MOZ_DELETE;
|
||||
void PassOptionalNullableString(Optional<nsAString>&) MOZ_DELETE;
|
||||
void PassOptionalNullableStringWithDefaultValue(nsAString&) MOZ_DELETE;
|
||||
|
||||
void PassVariadicString(Sequence<nsString>&) MOZ_DELETE;
|
||||
};
|
||||
|
||||
class TestIndexedGetterInterface : public nsISupports,
|
||||
|
|
|
@ -100,6 +100,7 @@ interface TestInterface {
|
|||
void passOptionalByteWithDefault(optional byte arg = 0);
|
||||
void passNullableByte(byte? arg);
|
||||
void passOptionalNullableByte(optional byte? arg);
|
||||
void passVariadicByte(byte... arg);
|
||||
|
||||
readonly attribute short readonlyShort;
|
||||
attribute short writableShort;
|
||||
|
@ -333,6 +334,7 @@ interface TestInterface {
|
|||
void passOptionalStringWithDefaultValue(optional DOMString arg = "abc");
|
||||
void passOptionalNullableString(optional DOMString? arg);
|
||||
void passOptionalNullableStringWithDefaultValue(optional DOMString? arg = null);
|
||||
void passVariadicString(DOMString... arg);
|
||||
|
||||
// Enumerated types
|
||||
void passEnum(TestEnum arg);
|
||||
|
@ -424,6 +426,14 @@ interface TestInterface {
|
|||
static attribute boolean staticAttribute;
|
||||
static void staticMethod(boolean arg);
|
||||
|
||||
// Overload resolution tests
|
||||
//void overload1(DOMString... strs);
|
||||
boolean overload1(TestInterface arg);
|
||||
TestInterface overload1(DOMString strs, TestInterface arg);
|
||||
|
||||
// Variadic handling
|
||||
void passVariadicThirdArg(DOMString arg1, long arg2, TestInterface... arg3);
|
||||
|
||||
// Miscellania
|
||||
[LenientThis] attribute long attrWithLenientThis;
|
||||
[Unforgeable] readonly attribute long unforgeableAttr;
|
||||
|
|
|
@ -21,6 +21,7 @@ interface TestExampleInterface {
|
|||
void passOptionalByteWithDefault(optional byte arg = 0);
|
||||
void passNullableByte(byte? arg);
|
||||
void passOptionalNullableByte(optional byte? arg);
|
||||
void passVariadicByte(byte... arg);
|
||||
|
||||
readonly attribute short readonlyShort;
|
||||
attribute short writableShort;
|
||||
|
@ -254,6 +255,7 @@ interface TestExampleInterface {
|
|||
void passOptionalStringWithDefaultValue(optional DOMString arg = "abc");
|
||||
void passOptionalNullableString(optional DOMString? arg);
|
||||
void passOptionalNullableStringWithDefaultValue(optional DOMString? arg = null);
|
||||
void passVariadicString(DOMString... arg);
|
||||
|
||||
// Enumerated types
|
||||
void passEnum(TestEnum arg);
|
||||
|
@ -345,6 +347,14 @@ interface TestExampleInterface {
|
|||
static attribute boolean staticAttribute;
|
||||
static void staticMethod(boolean arg);
|
||||
|
||||
// Overload resolution tests
|
||||
//void overload1(DOMString... strs);
|
||||
boolean overload1(TestInterface arg);
|
||||
TestInterface overload1(DOMString strs, TestInterface arg);
|
||||
|
||||
// Variadic handling
|
||||
void passVariadicThirdArg(DOMString arg1, long arg2, TestInterface... arg3);
|
||||
|
||||
// Miscellania
|
||||
[LenientThis] attribute long attrWithLenientThis;
|
||||
[Unforgeable] readonly attribute long unforgeableAttr;
|
||||
|
|
|
@ -151,6 +151,7 @@ static const char* sBluetoothDBusSignals[] =
|
|||
static nsAutoPtr<RawDBusConnection> gThreadConnection;
|
||||
static nsDataHashtable<nsStringHashKey, DBusMessage* > sPairingReqTable;
|
||||
static nsDataHashtable<nsStringHashKey, DBusMessage* > sAuthorizeReqTable;
|
||||
static bool sIsPairing = false;
|
||||
typedef void (*UnpackFunc)(DBusMessage*, DBusError*, BluetoothValue&, nsAString&);
|
||||
|
||||
class DistributeBluetoothSignalTask : public nsRunnable {
|
||||
|
@ -819,8 +820,12 @@ RunDBusCallback(DBusMessage* aMsg, void* aBluetoothReplyRunnable,
|
|||
void
|
||||
GetObjectPathCallback(DBusMessage* aMsg, void* aBluetoothReplyRunnable)
|
||||
{
|
||||
RunDBusCallback(aMsg, aBluetoothReplyRunnable,
|
||||
UnpackObjectPathMessage);
|
||||
if (sIsPairing) {
|
||||
RunDBusCallback(aMsg, aBluetoothReplyRunnable,
|
||||
UnpackObjectPathMessage);
|
||||
|
||||
sIsPairing = false;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1566,6 +1571,8 @@ BluetoothDBusService::StopInternal()
|
|||
sAuthorizeReqTable.EnumerateRead(UnrefDBusMessages, nullptr);
|
||||
sAuthorizeReqTable.Clear();
|
||||
|
||||
sIsPairing = false;
|
||||
|
||||
StopDBus();
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -2087,6 +2094,21 @@ BluetoothDBusService::CreatePairedDeviceInternal(const nsAString& aAdapterPath,
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* FIXME: Bug 820274
|
||||
*
|
||||
* If the user turns off Bluetooth in the middle of pairing process, the
|
||||
* callback function GetObjectPathCallback (see the third argument of the
|
||||
* function call above) may still be called while enabling next time by
|
||||
* dbus daemon. To prevent this from happening, added a flag to distinguish
|
||||
* if Bluetooth has been turned off. Nevertheless, we need a check if there
|
||||
* is a better solution.
|
||||
*
|
||||
* Please see Bug 818696 for more information.
|
||||
*/
|
||||
sIsPairing = true;
|
||||
|
||||
runnable.forget();
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "nsThread.h"
|
||||
#include <media/MediaProfiles.h>
|
||||
#include "mozilla/FileUtils.h"
|
||||
#include "mozilla/Services.h"
|
||||
#include "nsAlgorithm.h"
|
||||
#include <media/mediaplayer.h>
|
||||
#include "nsPrintfCString.h"
|
||||
|
|
|
@ -2,14 +2,5 @@
|
|||
"XMLHttpRequest interface constructor": true,
|
||||
"XMLHttpRequest interface: operation open(DOMString,DOMString,boolean,DOMString,DOMString)": true,
|
||||
"XMLHttpRequest interface: operation send(union)": true,
|
||||
"FormData interface: existence and properties of interface object": true,
|
||||
"FormData interface constructor": true,
|
||||
"FormData interface: existence and properties of interface prototype object": true,
|
||||
"FormData interface: existence and properties of interface prototype object's \"constructor\" property": true,
|
||||
"Stringification of new FormData()": "debug",
|
||||
"FormData interface: calling append(DOMString,Blob,DOMString) on new FormData() with too few arguments must throw TypeError": true,
|
||||
"FormData interface: calling append(DOMString,DOMString) on new FormData() with too few arguments must throw TypeError": true,
|
||||
"Stringification of new FormData(form)": "debug",
|
||||
"FormData interface: calling append(DOMString,Blob,DOMString) on new FormData(form) with too few arguments must throw TypeError": true,
|
||||
"FormData interface: calling append(DOMString,DOMString) on new FormData(form) with too few arguments must throw TypeError": true
|
||||
"FormData interface constructor": true
|
||||
}
|
||||
|
|
|
@ -113,4 +113,22 @@ stateTraversed = visited
|
|||
|
||||
# App modes
|
||||
editingMode = editing
|
||||
navigationMode = navigating
|
||||
navigationMode = navigating
|
||||
|
||||
# Quick navigation modes
|
||||
quicknav_Simple = Default
|
||||
quicknav_Anchor = Anchors
|
||||
quicknav_Button = Buttons
|
||||
quicknav_Combobox = Combo boxes
|
||||
quicknav_Entry = Entries
|
||||
quicknav_FormElement = Form elements
|
||||
quicknav_Graphic = Images
|
||||
quicknav_Heading = Headings
|
||||
quicknav_ListItem = List items
|
||||
quicknav_Link = Links
|
||||
quicknav_List = Lists
|
||||
quicknav_PageTab = Page tabs
|
||||
quicknav_RadioButton = Radio buttons
|
||||
quicknav_Separator = Separators
|
||||
quicknav_Table = Tables
|
||||
quicknav_Checkbox = Check boxes
|
|
@ -23,9 +23,11 @@ const PC_MANAGER_CID = Components.ID("{7293e901-2be3-4c02-b4bd-cbef6fc24f78}");
|
|||
// a page is torn down. (Maps inner window ID to an array of PC objects).
|
||||
function GlobalPCList() {
|
||||
this._list = [];
|
||||
this._networkdown = false; // XXX Need to query current state somehow
|
||||
Services.obs.addObserver(this, "inner-window-destroyed", true);
|
||||
Services.obs.addObserver(this, "profile-change-net-teardown", true);
|
||||
Services.obs.addObserver(this, "network:offline-about-to-go-offline", true);
|
||||
Services.obs.addObserver(this, "network:offline-status-changed", true);
|
||||
}
|
||||
GlobalPCList.prototype = {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
|
||||
|
@ -89,6 +91,15 @@ GlobalPCList.prototype = {
|
|||
pc._pc = null;
|
||||
});
|
||||
};
|
||||
this._networkdown = true;
|
||||
}
|
||||
else if (topic == "network:offline-status-changed") {
|
||||
if (data == "offline") {
|
||||
// this._list shold be empty here
|
||||
this._networkdown = true;
|
||||
} else if (data == "online") {
|
||||
this._networkdown = false;
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
@ -228,6 +239,9 @@ PeerConnection.prototype = {
|
|||
if (this._win) {
|
||||
throw new Error("Constructor already called");
|
||||
}
|
||||
if (_globalPCList._networkdown) {
|
||||
throw new Error("Can't create RTPPeerConnections when the network is down");
|
||||
}
|
||||
|
||||
this._pc = Cc["@mozilla.org/peerconnection;1"].
|
||||
createInstance(Ci.IPeerConnection);
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
// Used to provide information on the OS
|
||||
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "nsDirectoryServiceUtils.h"
|
||||
#include "nsIXULRuntime.h"
|
||||
#include "nsXPCOMCIDInternal.h"
|
||||
|
@ -91,6 +93,7 @@ nsresult GetPathToSpecialDir(const char *aKey, nsString& aOutPath)
|
|||
nsCOMPtr<nsIFile> file;
|
||||
nsresult rv = NS_GetSpecialDirectory(aKey, getter_AddRefs(file));
|
||||
if (NS_FAILED(rv) || !file) {
|
||||
aOutPath.SetIsVoid(true);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -101,6 +104,46 @@ nsresult GetPathToSpecialDir(const char *aKey, nsString& aOutPath)
|
|||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
* In some cases, OSFileConstants may be instantiated before the
|
||||
* profile is setup. In such cases, |OS.Constants.Path.profileDir| and
|
||||
* |OS.Constants.Path.localProfileDir| are undefined. However, we want
|
||||
* to ensure that this does not break existing code, so that future
|
||||
* workers spawned after the profile is setup have these constants.
|
||||
*
|
||||
* For this purpose, we register an observer to set |gPaths->profileDir|
|
||||
* and |gPaths->localProfileDir| once the profile is setup.
|
||||
*/
|
||||
class DelayedPathSetter MOZ_FINAL: public nsIObserver
|
||||
{
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIOBSERVER
|
||||
|
||||
DelayedPathSetter() {}
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS1(DelayedPathSetter, nsIObserver)
|
||||
|
||||
NS_IMETHODIMP
|
||||
DelayedPathSetter::Observe(nsISupports*, const char * aTopic, const PRUnichar*)
|
||||
{
|
||||
if (gPaths == nullptr) {
|
||||
// Initialization of gPaths has not taken place, something is wrong,
|
||||
// don't make things worse.
|
||||
return NS_OK;
|
||||
}
|
||||
nsresult rv = GetPathToSpecialDir(NS_APP_USER_PROFILE_50_DIR, gPaths->profileDir);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
rv = GetPathToSpecialDir(NS_APP_USER_PROFILE_LOCAL_50_DIR, gPaths->localProfileDir);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform the part of initialization that can only be
|
||||
* executed on the main thread.
|
||||
|
@ -134,12 +177,32 @@ nsresult InitOSFileConstants()
|
|||
return rv;
|
||||
}
|
||||
|
||||
// Setup profileDir and localProfileDir immediately if possible (we
|
||||
// assume that NS_APP_USER_PROFILE_50_DIR and
|
||||
// NS_APP_USER_PROFILE_LOCAL_50_DIR are set simultaneously)
|
||||
rv = GetPathToSpecialDir(NS_APP_USER_PROFILE_50_DIR, paths->profileDir);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = GetPathToSpecialDir(NS_APP_USER_PROFILE_LOCAL_50_DIR, paths->localProfileDir);
|
||||
}
|
||||
|
||||
// Otherwise, delay setup of profileDir/localProfileDir until they
|
||||
// become available.
|
||||
if (NS_FAILED(rv)) {
|
||||
nsCOMPtr<nsIObserverService> obsService = do_GetService(NS_OBSERVERSERVICE_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
nsRefPtr<DelayedPathSetter> pathSetter = new DelayedPathSetter();
|
||||
rv = obsService->AddObserver(pathSetter, "profile-do-change", false);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
// For other directories, ignore errors (they may be undefined on
|
||||
// some platforms or in non-Firefox embeddings of Gecko).
|
||||
|
||||
GetPathToSpecialDir(NS_OS_TEMP_DIR, paths->tmpDir);
|
||||
GetPathToSpecialDir(NS_APP_USER_PROFILE_50_DIR, paths->profileDir);
|
||||
GetPathToSpecialDir(NS_APP_USER_PROFILE_LOCAL_50_DIR, paths->localProfileDir);
|
||||
|
||||
gPaths = paths.forget();
|
||||
return NS_OK;
|
||||
|
@ -679,11 +742,15 @@ bool DefineOSFileConstants(JSContext *cx, JSObject *global)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!SetStringProperty(cx, objPath, "profileDir", gPaths->profileDir)) {
|
||||
// Configure profileDir only if it is available at this stage
|
||||
if (!gPaths->profileDir.IsVoid()
|
||||
&& !SetStringProperty(cx, objPath, "profileDir", gPaths->profileDir)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!SetStringProperty(cx, objPath, "localProfileDir", gPaths->localProfileDir)) {
|
||||
// Configure localProfileDir only if it is available at this stage
|
||||
if (!gPaths->localProfileDir.IsVoid()
|
||||
&& !SetStringProperty(cx, objPath, "localProfileDir", gPaths->localProfileDir)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "TimeZoneSettingObserver.h"
|
||||
#endif
|
||||
#include "mozilla/ipc/Ril.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
|
|
@ -422,6 +422,7 @@ this.ICC_EF_CBMIR = 0x6f50;
|
|||
this.ICC_EF_AD = 0x6fad;
|
||||
this.ICC_EF_PHASE = 0x6fae;
|
||||
this.ICC_EF_PNN = 0x6fc5;
|
||||
this.ICC_EF_OPL = 0x6fc6;
|
||||
this.ICC_EF_MBDN = 0x6fc7;
|
||||
this.ICC_EF_EXT6 = 0x6fc8; // Ext record for EF[MBDN]
|
||||
this.ICC_EF_MBI = 0x6fc9;
|
||||
|
@ -581,6 +582,11 @@ this.COMPREHENSIONTLV_TAG_BROADCAST_NETWORK_INFO = 0x7a;
|
|||
this.SPDI_TAG_SPDI = 0xa3;
|
||||
this.SPDI_TAG_PLMN_LIST = 0x80;
|
||||
|
||||
// MM INFORMATION message content IEIs
|
||||
// See 3GPP TS 24.008 table 9.2.18
|
||||
this.PNN_IEI_FULL_NETWORK_NAME = 0x43;
|
||||
this.PNN_IEI_SHORT_NETWORK_NAME = 0x45;
|
||||
|
||||
// Device identifiers, see TS 11.14, clause 12.7
|
||||
this.STK_DEVICE_ID_KEYPAD = 0x01;
|
||||
this.STK_DEVICE_ID_DISPLAY = 0x02;
|
||||
|
@ -988,6 +994,8 @@ this.GECKO_ICC_SERVICES = {
|
|||
DATA_DOWNLOAD_SMS_PP: 26,
|
||||
CBMIR: 30,
|
||||
BDN: 31,
|
||||
PNN: 51,
|
||||
OPL: 52,
|
||||
SPDI: 56
|
||||
},
|
||||
usim: {
|
||||
|
@ -998,6 +1006,8 @@ this.GECKO_ICC_SERVICES = {
|
|||
CBMIR: 16,
|
||||
SPN: 19,
|
||||
DATA_DOWNLOAD_SMS_PP: 28,
|
||||
PNN: 45,
|
||||
OPL: 46,
|
||||
SPDI: 51
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1671,6 +1671,219 @@ let RIL = {
|
|||
(serviceTable[index] & bitmask)) != 0;
|
||||
},
|
||||
|
||||
/**
|
||||
* Choose network names using EF_OPL and EF_PNN
|
||||
* See 3GPP TS 31.102 sec. 4.2.58 and sec. 4.2.59 for USIM,
|
||||
* 3GPP TS 51.011 sec. 10.3.41 and sec. 10.3.42 for SIM.
|
||||
*/
|
||||
updateNetworkName: function updateNetworkName() {
|
||||
let iccInfoPriv = this.iccInfoPrivate;
|
||||
let iccInfo = this.iccInfo;
|
||||
|
||||
// We won't update network name if voice registration isn't ready
|
||||
// or PNN file haven't been retrieved.
|
||||
if (!iccInfoPriv.PNN ||
|
||||
!this.voiceRegistrationState.cell ||
|
||||
this.voiceRegistrationState.cell.gsmLocationAreaCode == -1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let pnnEntry;
|
||||
let lac = this.voiceRegistrationState.cell.gsmLocationAreaCode;
|
||||
let mcc = this.operator.mcc;
|
||||
let mnc = this.operator.mnc;
|
||||
|
||||
// According to 3GPP TS 31.102 Sec. 4.2.59 and 3GPP TS 51.011 Sec. 10.3.42,
|
||||
// the ME shall use this EF_OPL in association with the EF_PNN in place
|
||||
// of any network name stored within the ME's internal list and any network
|
||||
// name received when registered to the PLMN.
|
||||
if (iccInfoPriv.OPL) {
|
||||
for (let i in iccInfoPriv.OPL) {
|
||||
let opl = iccInfoPriv.OPL[i];
|
||||
// Try to match the MCC/MNC.
|
||||
if (mcc != opl.mcc || mnc != opl.mnc) {
|
||||
continue;
|
||||
}
|
||||
// Try to match the location area code. If current local area code is
|
||||
// covered by lac range that specified in the OPL entry, use the PNN
|
||||
// that specified in the OPL entry.
|
||||
if ((opl.lacTacStart == 0x0 && opl.lacTacEnd == 0xFFFE) ||
|
||||
(opl.lacTacStart <= lac && opl.lacTacEnd >= lac)) {
|
||||
if (opl.pnnRecordId == 0) {
|
||||
// See 3GPP TS 31.102 Sec. 4.2.59 and 3GPP TS 51.011 Sec. 10.3.42,
|
||||
// A value of '00' indicates that the name is to be taken from other
|
||||
// sources.
|
||||
return null;
|
||||
}
|
||||
pnnEntry = iccInfoPriv.PNN[opl.pnnRecordId - 1]
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// According to 3GPP TS 31.102 Sec. 4.2.58 and 3GPP TS 51.011 Sec. 10.3.41,
|
||||
// the first record in this EF is used for the default network name when
|
||||
// registered to the HPLMN.
|
||||
// If we haven't get pnnEntry assigned, we should try to assign default
|
||||
// value to it.
|
||||
if (!pnnEntry && mcc == iccInfo.mcc && mnc == iccInfo.mnc) {
|
||||
pnnEntry = iccInfoPriv.PNN[0]
|
||||
}
|
||||
|
||||
if (DEBUG) {
|
||||
if (pnnEntry) {
|
||||
debug("updateNetworkName: Network names will be overriden: longName = " +
|
||||
pnnEntry.fullName + ", shortName = " + pnnEntry.shortName);
|
||||
} else {
|
||||
debug("updateNetworkName: Network names will not be overriden");
|
||||
}
|
||||
}
|
||||
|
||||
if (pnnEntry) {
|
||||
return [pnnEntry.fullName, pnnEntry.shortName];
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Read OPL (Operator PLMN List) from USIM.
|
||||
*
|
||||
* See 3GPP TS 31.102 Sec. 4.2.59 for USIM
|
||||
* 3GPP TS 51.011 Sec. 10.3.42 for SIM.
|
||||
*/
|
||||
getOPL: function getOPL() {
|
||||
let opl = [];
|
||||
function callback(options) {
|
||||
let len = Buf.readUint32();
|
||||
// The first 7 bytes are LAI (for UMTS) and the format of LAI is defined
|
||||
// in 3GPP TS 23.003, Sec 4.1
|
||||
// +-------------+---------+
|
||||
// | Octet 1 - 3 | MCC/MNC |
|
||||
// +-------------+---------+
|
||||
// | Octet 4 - 7 | LAC |
|
||||
// +-------------+---------+
|
||||
let mccMnc = [GsmPDUHelper.readHexOctet(),
|
||||
GsmPDUHelper.readHexOctet(),
|
||||
GsmPDUHelper.readHexOctet()];
|
||||
if (mccMnc[0] != 0xFF || mccMnc[1] != 0xFF || mccMnc[2] != 0xFF) {
|
||||
let oplElement = {};
|
||||
let semiOctets = [];
|
||||
for (let i = 0; i < mccMnc.length; i++) {
|
||||
semiOctets.push((mccMnc[i] & 0xf0) >> 4);
|
||||
semiOctets.push(mccMnc[i] & 0x0f);
|
||||
}
|
||||
let reformat = [semiOctets[1], semiOctets[0], semiOctets[3],
|
||||
semiOctets[5], semiOctets[4], semiOctets[2]];
|
||||
let buf = "";
|
||||
for (let i = 0; i < reformat.length; i++) {
|
||||
if (reformat[i] != 0xF) {
|
||||
buf += GsmPDUHelper.semiOctetToBcdChar(reformat[i]);
|
||||
}
|
||||
if (i === 2) {
|
||||
// 0-2: MCC
|
||||
oplElement.mcc = parseInt(buf);
|
||||
buf = "";
|
||||
} else if (i === 5) {
|
||||
// 3-5: MNC
|
||||
oplElement.mnc = parseInt(buf);
|
||||
}
|
||||
}
|
||||
// LAC/TAC
|
||||
oplElement.lacTacStart =
|
||||
(GsmPDUHelper.readHexOctet() << 8) | GsmPDUHelper.readHexOctet();
|
||||
oplElement.lacTacEnd =
|
||||
(GsmPDUHelper.readHexOctet() << 8) | GsmPDUHelper.readHexOctet();
|
||||
// PLMN Network Name Record Identifier
|
||||
oplElement.pnnRecordId = GsmPDUHelper.readHexOctet();
|
||||
if (DEBUG) {
|
||||
debug("OPL: [" + (opl.length + 1) + "]: " + JSON.stringify(oplElement));
|
||||
}
|
||||
opl.push(oplElement);
|
||||
}
|
||||
Buf.readStringDelimiter(len);
|
||||
if (options.p1 < options.totalRecords) {
|
||||
options.p1++;
|
||||
this.iccIO(options);
|
||||
} else {
|
||||
this.iccInfoPrivate.OPL = opl;
|
||||
}
|
||||
}
|
||||
|
||||
this.iccIO({
|
||||
command: ICC_COMMAND_GET_RESPONSE,
|
||||
fileId: ICC_EF_OPL,
|
||||
pathId: this._getPathIdForICCRecord(ICC_EF_OPL),
|
||||
p1: 0, // For GET_RESPONSE, p1 = 0
|
||||
p2: 0, // For GET_RESPONSE, p2 = 0
|
||||
p3: GET_RESPONSE_EF_SIZE_BYTES,
|
||||
data: null,
|
||||
pin2: null,
|
||||
type: EF_TYPE_LINEAR_FIXED,
|
||||
callback: callback,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Read PNN (PLMN Network Name) from USIM.
|
||||
*
|
||||
* See 3GPP TS 31.102 Sec. 4.2.58 for USIM
|
||||
* 3GPP TS 51.011 Sec. 10.3.41 for SIM.
|
||||
*/
|
||||
getPNN: function getPNN() {
|
||||
let pnn = [];
|
||||
function callback(options) {
|
||||
let pnnElement = this.iccInfoPrivate.PNN = {};
|
||||
let len = Buf.readUint32();
|
||||
let readLen = 0;
|
||||
while (len > readLen) {
|
||||
let tlvTag = GsmPDUHelper.readHexOctet();
|
||||
readLen = readLen + 2; // 1 Hex octet
|
||||
if (tlvTag == 0xFF) {
|
||||
// Unused byte
|
||||
continue;
|
||||
}
|
||||
let tlvLen = GsmPDUHelper.readHexOctet();
|
||||
let name;
|
||||
switch (tlvTag) {
|
||||
case PNN_IEI_FULL_NETWORK_NAME:
|
||||
pnnElement.fullName = GsmPDUHelper.readNetworkName(tlvLen);
|
||||
break;
|
||||
case PNN_IEI_SHORT_NETWORK_NAME:
|
||||
pnnElement.shortName = GsmPDUHelper.readNetworkName(tlvLen);
|
||||
break;
|
||||
default:
|
||||
Buf.seekIncoming(PDU_HEX_OCTET_SIZE * tlvLen);
|
||||
}
|
||||
readLen += (tlvLen * 2 + 2);
|
||||
}
|
||||
if (DEBUG) {
|
||||
debug("PNN: [" + (pnn.length + 1) + "]: " + JSON.stringify(pnnElement));
|
||||
}
|
||||
Buf.readStringDelimiter(len);
|
||||
pnn.push(pnnElement);
|
||||
|
||||
if (options.p1 < options.totalRecords) {
|
||||
options.p1++;
|
||||
this.iccIO(options);
|
||||
} else {
|
||||
this.iccInfoPrivate.PNN = pnn;
|
||||
}
|
||||
}
|
||||
|
||||
this.iccIO({
|
||||
command: ICC_COMMAND_GET_RESPONSE,
|
||||
fileId: ICC_EF_PNN,
|
||||
pathId: this._getPathIdForICCRecord(ICC_EF_PNN),
|
||||
p1: 0, // For GET_RESPONSE, p1 = 0
|
||||
p2: 0, // For GET_RESPONSE, p2 = 0
|
||||
p3: GET_RESPONSE_EF_SIZE_BYTES,
|
||||
data: null,
|
||||
pin2: null,
|
||||
type: EF_TYPE_LINEAR_FIXED,
|
||||
callback: callback,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Read the (U)SIM Service Table from the ICC.
|
||||
*/
|
||||
|
@ -1705,6 +1918,20 @@ let RIL = {
|
|||
if (DEBUG) debug("SPDI: SPDI service is not available");
|
||||
}
|
||||
|
||||
if (this.isICCServiceAvailable("PNN")) {
|
||||
if (DEBUG) debug("PNN: PNN is available");
|
||||
this.getPNN();
|
||||
} else {
|
||||
if (DEBUG) debug("PNN: PNN is not available");
|
||||
}
|
||||
|
||||
if (this.isICCServiceAvailable("OPL")) {
|
||||
if (DEBUG) debug("OPL: OPL is available");
|
||||
this.getOPL();
|
||||
} else {
|
||||
if (DEBUG) debug("OPL: OPL is not available");
|
||||
}
|
||||
|
||||
if (this.isICCServiceAvailable("CBMI")) {
|
||||
this.getCBMI();
|
||||
} else {
|
||||
|
@ -2543,7 +2770,8 @@ let RIL = {
|
|||
* String containing the processId for the SmsRequestManager.
|
||||
*/
|
||||
sendSMS: function sendSMS(options) {
|
||||
//TODO: verify values on 'options'
|
||||
options.langIndex = options.langIndex || PDU_NL_IDENTIFIER_DEFAULT;
|
||||
options.langShiftIndex = options.langShiftIndex || PDU_NL_IDENTIFIER_DEFAULT;
|
||||
|
||||
if (!options.retryCount) {
|
||||
options.retryCount = 0;
|
||||
|
@ -3643,6 +3871,8 @@ let RIL = {
|
|||
case ICC_EF_SPDI:
|
||||
case ICC_EF_CBMI:
|
||||
case ICC_EF_CBMIR:
|
||||
case ICC_EF_OPL:
|
||||
case ICC_EF_PNN:
|
||||
return EF_PATH_MF_SIM + EF_PATH_ADF_USIM;
|
||||
|
||||
default:
|
||||
|
@ -3968,8 +4198,15 @@ let RIL = {
|
|||
this.operator.shortName !== shortName ||
|
||||
thisTuple !== networkTuple) {
|
||||
|
||||
this.operator.longName = longName;
|
||||
this.operator.shortName = shortName;
|
||||
let networkName = this.updateNetworkName();
|
||||
if (networkName) {
|
||||
this.operator.longName = networkName[0];
|
||||
this.operator.shortName = networkName[1];
|
||||
} else {
|
||||
this.operator.longName = longName;
|
||||
this.operator.shortName = shortName;
|
||||
}
|
||||
|
||||
this.operator.mcc = 0;
|
||||
this.operator.mnc = 0;
|
||||
|
||||
|
@ -5970,7 +6207,7 @@ RIL[UNSOLICITED_NITZ_TIME_RECEIVED] = function UNSOLICITED_NITZ_TIME_RECEIVED()
|
|||
debug("DateTimeZone string " + dateString);
|
||||
|
||||
let now = Date.now();
|
||||
|
||||
|
||||
let year = parseInt(dateString.substr(0, 2), 10);
|
||||
let month = parseInt(dateString.substr(3, 2), 10);
|
||||
let day = parseInt(dateString.substr(6, 2), 10);
|
||||
|
@ -6821,16 +7058,18 @@ let GsmPDUHelper = {
|
|||
this.writeHexOctet(options.segmentSeq & 0xFF);
|
||||
}
|
||||
|
||||
if (options.langIndex != PDU_NL_IDENTIFIER_DEFAULT) {
|
||||
this.writeHexOctet(PDU_IEI_NATIONAL_LANGUAGE_LOCKING_SHIFT);
|
||||
this.writeHexOctet(1);
|
||||
this.writeHexOctet(options.langIndex);
|
||||
}
|
||||
if (options.dcs == PDU_DCS_MSG_CODING_7BITS_ALPHABET) {
|
||||
if (options.langIndex != PDU_NL_IDENTIFIER_DEFAULT) {
|
||||
this.writeHexOctet(PDU_IEI_NATIONAL_LANGUAGE_LOCKING_SHIFT);
|
||||
this.writeHexOctet(1);
|
||||
this.writeHexOctet(options.langIndex);
|
||||
}
|
||||
|
||||
if (options.langShiftIndex != PDU_NL_IDENTIFIER_DEFAULT) {
|
||||
this.writeHexOctet(PDU_IEI_NATIONAL_LANGUAGE_SINGLE_SHIFT);
|
||||
this.writeHexOctet(1);
|
||||
this.writeHexOctet(options.langShiftIndex);
|
||||
if (options.langShiftIndex != PDU_NL_IDENTIFIER_DEFAULT) {
|
||||
this.writeHexOctet(PDU_IEI_NATIONAL_LANGUAGE_SINGLE_SHIFT);
|
||||
this.writeHexOctet(1);
|
||||
this.writeHexOctet(options.langShiftIndex);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -7848,6 +8087,60 @@ let GsmPDUHelper = {
|
|||
|
||||
return msg;
|
||||
},
|
||||
|
||||
/**
|
||||
* Read network name.
|
||||
*
|
||||
* @param len Length of the information element.
|
||||
* @return
|
||||
* {
|
||||
* networkName: network name.
|
||||
* shouldIncludeCi: Should Country's initials included in text string.
|
||||
* }
|
||||
* @see TS 24.008 clause 10.5.3.5a.
|
||||
*/
|
||||
readNetworkName: function readNetworkName(len) {
|
||||
// According to TS 24.008 Sec. 10.5.3.5a, the first octet is:
|
||||
// bit 8: must be 1.
|
||||
// bit 5-7: Text encoding.
|
||||
// 000 - GSM default alphabet.
|
||||
// 001 - UCS2 (16 bit).
|
||||
// else - reserved.
|
||||
// bit 4: MS should add the letters for Country's Initials and a space
|
||||
// to the text string if this bit is true.
|
||||
// bit 1-3: number of spare bits in last octet.
|
||||
|
||||
let codingInfo = GsmPDUHelper.readHexOctet();
|
||||
if (!(codingInfo & 0x80)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let textEncoding = (codingInfo & 0x70) >> 4,
|
||||
shouldIncludeCountryInitials = !!(codingInfo & 0x08),
|
||||
spareBits = codingInfo & 0x07;
|
||||
let resultString;
|
||||
|
||||
switch (textEncoding) {
|
||||
case 0:
|
||||
// GSM Default alphabet.
|
||||
resultString = GsmPDUHelper.readSeptetsToString(
|
||||
((len - 1) * 8 - spareBits) / 7, 0,
|
||||
PDU_NL_IDENTIFIER_DEFAULT,
|
||||
PDU_NL_IDENTIFIER_DEFAULT);
|
||||
break;
|
||||
case 1:
|
||||
// UCS2 encoded.
|
||||
resultString = this.readUCS2String(len - 1);
|
||||
break;
|
||||
default:
|
||||
// Not an available text coding.
|
||||
return null;
|
||||
}
|
||||
|
||||
// TODO - Bug 820286: According to shouldIncludeCountryInitials, add
|
||||
// country initials to the resulting string.
|
||||
return resultString;
|
||||
}
|
||||
};
|
||||
|
||||
let StkCommandParamsFactory = {
|
||||
|
|
|
@ -623,6 +623,7 @@ add_test(function test_spn_display_condition() {
|
|||
[0, 123, 456, 123, 457, false, true],
|
||||
], run_next_test);
|
||||
});
|
||||
|
||||
/**
|
||||
* Verify Proactive Command : More Time
|
||||
*/
|
||||
|
@ -652,6 +653,143 @@ add_test(function test_stk_proactive_command_more_time() {
|
|||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function read_network_name() {
|
||||
let worker = newUint8Worker();
|
||||
let helper = worker.GsmPDUHelper;
|
||||
let buf = worker.Buf;
|
||||
|
||||
// Returning length of byte.
|
||||
function writeNetworkName(isUCS2, requireCi, name) {
|
||||
let codingOctet = 0x80;
|
||||
let len;
|
||||
if (requireCi) {
|
||||
codingOctet |= 0x08;
|
||||
}
|
||||
|
||||
if (isUCS2) {
|
||||
codingOctet |= 0x10;
|
||||
len = name.length * 2;
|
||||
} else {
|
||||
let spare = (8 - (name.length * 7) % 8) % 8;
|
||||
codingOctet |= spare;
|
||||
len = Math.ceil(name.length * 7 / 8);
|
||||
}
|
||||
helper.writeHexOctet(codingOctet);
|
||||
|
||||
if (isUCS2) {
|
||||
helper.writeUCS2String(name);
|
||||
} else {
|
||||
helper.writeStringAsSeptets(name, 0, 0, 0);
|
||||
}
|
||||
|
||||
return len + 1; // codingOctet.
|
||||
}
|
||||
|
||||
function testNetworkName(isUCS2, requireCi, name) {
|
||||
let len = writeNetworkName(isUCS2, requireCi, name);
|
||||
do_check_eq(helper.readNetworkName(len), name);
|
||||
}
|
||||
|
||||
testNetworkName( true, true, "Test Network Name1");
|
||||
testNetworkName( true, false, "Test Network Name2");
|
||||
testNetworkName(false, true, "Test Network Name3");
|
||||
testNetworkName(false, false, "Test Network Name4");
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_update_network_name() {
|
||||
let RIL = newWorker({
|
||||
postRILMessage: function fakePostRILMessage(data) {
|
||||
// Do nothing
|
||||
},
|
||||
postMessage: function fakePostMessage(message) {
|
||||
// Do nothing
|
||||
}
|
||||
}).RIL;
|
||||
|
||||
function testNetworkNameIsNull(operatorMcc, operatorMnc) {
|
||||
RIL.operator.mcc = operatorMcc;
|
||||
RIL.operator.mnc = operatorMnc;
|
||||
do_check_eq(RIL.updateNetworkName(), null);
|
||||
}
|
||||
|
||||
function testNetworkName(operatorMcc, operatorMnc,
|
||||
expectedLongName, expectedShortName) {
|
||||
RIL.operator.mcc = operatorMcc;
|
||||
RIL.operator.mnc = operatorMnc;
|
||||
let result = RIL.updateNetworkName();
|
||||
|
||||
do_check_eq(result[0], expectedLongName);
|
||||
do_check_eq(result[1], expectedShortName);
|
||||
}
|
||||
|
||||
// Before EF_OPL and EF_PNN have been loaded.
|
||||
do_check_eq(RIL.updateNetworkName(), null);
|
||||
|
||||
// Set HPLMN
|
||||
RIL.iccInfo.mcc = 123;
|
||||
RIL.iccInfo.mnc = 456;
|
||||
|
||||
RIL.voiceRegistrationState = {
|
||||
cell: {
|
||||
gsmLocationAreaCode: 0x1000
|
||||
}
|
||||
};
|
||||
RIL.operator = {};
|
||||
|
||||
// Set EF_PNN
|
||||
RIL.iccInfoPrivate = {
|
||||
PNN: [
|
||||
{"fullName": "PNN1Long", "shortName": "PNN1Short"},
|
||||
{"fullName": "PNN2Long", "shortName": "PNN2Short"},
|
||||
{"fullName": "PNN3Long", "shortName": "PNN3Short"},
|
||||
{"fullName": "PNN4Long", "shortName": "PNN4Short"}
|
||||
]
|
||||
};
|
||||
|
||||
// EF_OPL isn't available and current isn't in HPLMN,
|
||||
testNetworkNameIsNull(123, 457);
|
||||
|
||||
// EF_OPL isn't available and current is in HPLMN,
|
||||
// the first record of PNN should be returned.
|
||||
testNetworkName(123, 456, "PNN1Long", "PNN1Short");
|
||||
|
||||
// Set EF_OPL
|
||||
RIL.iccInfoPrivate.OPL = [
|
||||
{
|
||||
"mcc": 123,
|
||||
"mnc": 456,
|
||||
"lacTacStart": 0,
|
||||
"lacTacEnd": 0xFFFE,
|
||||
"pnnRecordId": 4
|
||||
},
|
||||
{
|
||||
"mcc": 123,
|
||||
"mnc": 457,
|
||||
"lacTacStart": 0,
|
||||
"lacTacEnd": 0x0010,
|
||||
"pnnRecordId": 3
|
||||
},
|
||||
{
|
||||
"mcc": 123,
|
||||
"mnc": 457,
|
||||
"lacTacStart": 0,
|
||||
"lacTacEnd": 0x1010,
|
||||
"pnnRecordId": 2
|
||||
}
|
||||
];
|
||||
|
||||
// Both EF_PNN and EF_OPL are presented, and current PLMN is HPLMN,
|
||||
testNetworkName(123, 456, "PNN4Long", "PNN4Short");
|
||||
|
||||
// Current PLMN is not HPLMN, and according to LAC, we should get
|
||||
// the second PNN record.
|
||||
testNetworkName(123, 457, "PNN2Long", "PNN2Short");
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
/**
|
||||
* Verify Proactive Command : Provide Local Information
|
||||
*/
|
||||
|
|
|
@ -714,6 +714,52 @@ for (let lst = 0; lst < PDU_NL_LOCKING_SHIFT_TABLES.length; lst++) {
|
|||
}
|
||||
test_receiving_ucs2_alphabets(ucs2str);
|
||||
|
||||
// Bug 820220: B2G SMS: wrong order and truncated content in multi-part messages
|
||||
add_test(function test_sendSMS_UCS2_without_langIndex_langShiftIndex_defined() {
|
||||
let worker = newWriteHexOctetAsUint8Worker();
|
||||
|
||||
worker.Buf.sendParcel = function () {
|
||||
// Each sendParcel() call represents one outgoing segment of a multipart
|
||||
// SMS message. Here, we have the first segment send, so it's "Hello "
|
||||
// only.
|
||||
//
|
||||
// 4(parcel size) + 4(request type) + 4(token)
|
||||
// + 4(two messages) + 4(null SMSC) + 4(message string length)
|
||||
// + 1(first octet) + 1(message reference)
|
||||
// + 2(DA len, TOA) + 4(addr)
|
||||
// + 1(pid) + 1(dcs)
|
||||
// + 1(UDL) + 6(UDHL, type, len, ref, max, seq)
|
||||
// + 12(2 * strlen("Hello "))
|
||||
// + 4(two delimitors) = 57
|
||||
//
|
||||
// If we have additional 6(type, len, langIndex, type len, langShiftIndex)
|
||||
// octets here, then bug 809553 is not fixed.
|
||||
do_check_eq(this.outgoingIndex, 57);
|
||||
|
||||
run_next_test();
|
||||
};
|
||||
|
||||
worker.RIL.sendSMS({
|
||||
number: "1",
|
||||
segmentMaxSeq: 2,
|
||||
fullBody: "Hello World!",
|
||||
dcs: PDU_DCS_MSG_CODING_16BITS_ALPHABET,
|
||||
segmentRef16Bit: false,
|
||||
userDataHeaderLength: 5,
|
||||
strict7BitEncoding: false,
|
||||
requestStatusReport: true,
|
||||
segments: [
|
||||
{
|
||||
body: "Hello ",
|
||||
encodedBodyLength: 12,
|
||||
}, {
|
||||
body: "World!",
|
||||
encodedBodyLength: 12,
|
||||
}
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Verify GsmPDUHelper#readAddress
|
||||
*/
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#include "TimeChangeObserver.h"
|
||||
#include "mozilla/ClearOnShutdown.h"
|
||||
#include "mozilla/Services.h"
|
||||
#include "mozilla/StaticPtr.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsDOMEvent.h"
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
dictionary FilePropertyBag : BlobPropertyBag {
|
||||
DOMString name = "";
|
||||
};
|
|
@ -0,0 +1,18 @@
|
|||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* The origin of this IDL file is
|
||||
* http://xhr.spec.whatwg.org
|
||||
*/
|
||||
|
||||
interface HTMLFormElement;
|
||||
|
||||
[Constructor(optional HTMLFormElement form)]
|
||||
interface FormData {
|
||||
// Not supported (bug 739174)
|
||||
// void append(DOMString name, Blob value, optional DOMString filename);
|
||||
void append(DOMString name, Blob value);
|
||||
void append(DOMString name, DOMString value);
|
||||
};
|
|
@ -33,9 +33,11 @@ webidl_files = \
|
|||
EventHandler.webidl \
|
||||
EventListener.webidl \
|
||||
EventTarget.webidl \
|
||||
File.webidl \
|
||||
FileHandle.webidl \
|
||||
FileList.webidl \
|
||||
FileReaderSync.webidl \
|
||||
FormData.webidl \
|
||||
Function.webidl \
|
||||
GainNode.webidl \
|
||||
HTMLCollection.webidl \
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
|
||||
interface Document;
|
||||
interface Blob;
|
||||
interface FormData;
|
||||
interface InputStream;
|
||||
interface MozChannel;
|
||||
interface IID;
|
||||
|
|
|
@ -88,8 +88,7 @@ private:
|
|||
Construct(JSContext* aCx, unsigned aArgc, jsval* aVp)
|
||||
{
|
||||
nsRefPtr<nsDOMMultipartFile> file = new nsDOMMultipartFile();
|
||||
nsresult rv = file->InitInternal(aCx, aArgc, JS_ARGV(aCx, aVp),
|
||||
Unwrap);
|
||||
nsresult rv = file->InitBlob(aCx, aArgc, JS_ARGV(aCx, aVp), Unwrap);
|
||||
if (NS_FAILED(rv)) {
|
||||
ThrowDOMExceptionForNSResult(aCx, rv);
|
||||
return false;
|
||||
|
|
|
@ -178,6 +178,12 @@ public:
|
|||
void
|
||||
Send(JSObject* aBody, ErrorResult& aRv);
|
||||
|
||||
void
|
||||
Send(JSObject& aBody, ErrorResult& aRv)
|
||||
{
|
||||
Send(&aBody, aRv);
|
||||
}
|
||||
|
||||
void
|
||||
Send(ArrayBuffer& aBody, ErrorResult& aRv) {
|
||||
return Send(aBody.Obj(), aRv);
|
||||
|
|
|
@ -76,6 +76,7 @@ CPPSRCS = \
|
|||
Lexer.cpp \
|
||||
Preprocessor.cpp \
|
||||
Token.cpp \
|
||||
VariablePacker.cpp \
|
||||
$(NULL)
|
||||
|
||||
# flex/yacc generated files
|
||||
|
|
|
@ -0,0 +1,732 @@
|
|||
# HG changeset patch
|
||||
# Parent ef5d80327785b28df0bd778acc86f4987ba5a678
|
||||
|
||||
diff --git a/gfx/angle/Makefile.in b/gfx/angle/Makefile.in
|
||||
--- a/gfx/angle/Makefile.in
|
||||
+++ b/gfx/angle/Makefile.in
|
||||
@@ -71,16 +71,17 @@ CPPSRCS = \
|
||||
ForLoopUnroll.cpp \
|
||||
MapLongVariableNames.cpp \
|
||||
spooky.cpp \
|
||||
BuiltInFunctionEmulator.cpp \
|
||||
Input.cpp \
|
||||
Lexer.cpp \
|
||||
Preprocessor.cpp \
|
||||
Token.cpp \
|
||||
+ VariablePacker.cpp \
|
||||
$(NULL)
|
||||
|
||||
# flex/yacc generated files
|
||||
CPPSRCS += \
|
||||
glslang_lex.cpp \
|
||||
glslang_tab.cpp \
|
||||
$(NULL)
|
||||
|
||||
diff --git a/gfx/angle/include/GLSLANG/ShaderLang.h b/gfx/angle/include/GLSLANG/ShaderLang.h
|
||||
--- a/gfx/angle/include/GLSLANG/ShaderLang.h
|
||||
+++ b/gfx/angle/include/GLSLANG/ShaderLang.h
|
||||
@@ -137,17 +137,20 @@ typedef enum {
|
||||
SH_TIMING_RESTRICTIONS = 0x0200,
|
||||
|
||||
// This flag prints the dependency graph that is used to enforce timing
|
||||
// restrictions on fragment shaders.
|
||||
// This flag only has an effect if all of the following are true:
|
||||
// - The shader spec is SH_WEBGL_SPEC.
|
||||
// - The compile options contain the SH_TIMING_RESTRICTIONS flag.
|
||||
// - The shader type is SH_FRAGMENT_SHADER.
|
||||
- SH_DEPENDENCY_GRAPH = 0x0400
|
||||
+ SH_DEPENDENCY_GRAPH = 0x0400,
|
||||
+
|
||||
+ // Enforce the GLSL 1.017 Appendix A section 7 packing restrictions.
|
||||
+ SH_ENFORCE_PACKING_RESTRICTIONS = 0x0800,
|
||||
} ShCompileOptions;
|
||||
|
||||
//
|
||||
// Driver must call this first, once, before doing any other
|
||||
// compiler operations.
|
||||
// If the function succeeds, the return value is nonzero, else zero.
|
||||
//
|
||||
COMPILER_EXPORT int ShInitialize();
|
||||
diff --git a/gfx/angle/src/compiler/Compiler.cpp b/gfx/angle/src/compiler/Compiler.cpp
|
||||
--- a/gfx/angle/src/compiler/Compiler.cpp
|
||||
+++ b/gfx/angle/src/compiler/Compiler.cpp
|
||||
@@ -9,16 +9,17 @@
|
||||
#include "compiler/ForLoopUnroll.h"
|
||||
#include "compiler/Initialize.h"
|
||||
#include "compiler/InitializeParseContext.h"
|
||||
#include "compiler/MapLongVariableNames.h"
|
||||
#include "compiler/ParseHelper.h"
|
||||
#include "compiler/RenameFunction.h"
|
||||
#include "compiler/ShHandle.h"
|
||||
#include "compiler/ValidateLimitations.h"
|
||||
+#include "compiler/VariablePacker.h"
|
||||
#include "compiler/depgraph/DependencyGraph.h"
|
||||
#include "compiler/depgraph/DependencyGraphOutput.h"
|
||||
#include "compiler/timing/RestrictFragmentShaderTiming.h"
|
||||
#include "compiler/timing/RestrictVertexShaderTiming.h"
|
||||
|
||||
bool isWebGLBasedSpec(ShShaderSpec spec)
|
||||
{
|
||||
return spec == SH_WEBGL_SPEC || spec == SH_CSS_SHADERS_SPEC;
|
||||
@@ -108,16 +109,19 @@ TCompiler::TCompiler(ShShaderType type,
|
||||
TCompiler::~TCompiler()
|
||||
{
|
||||
ASSERT(longNameMap);
|
||||
longNameMap->Release();
|
||||
}
|
||||
|
||||
bool TCompiler::Init(const ShBuiltInResources& resources)
|
||||
{
|
||||
+ maxUniformVectors = (shaderType == SH_VERTEX_SHADER) ?
|
||||
+ resources.MaxVertexUniformVectors :
|
||||
+ resources.MaxFragmentUniformVectors;
|
||||
TScopedPoolAllocator scopedAlloc(&allocator, false);
|
||||
|
||||
// Generate built-in symbol table.
|
||||
if (!InitBuiltInSymbolTable(resources))
|
||||
return false;
|
||||
InitExtensionBehavior(resources, extensionBehavior);
|
||||
|
||||
return true;
|
||||
@@ -187,18 +191,25 @@ bool TCompiler::compile(const char* cons
|
||||
builtInFunctionEmulator.MarkBuiltInFunctionsForEmulation(root);
|
||||
|
||||
// Call mapLongVariableNames() before collectAttribsUniforms() so in
|
||||
// collectAttribsUniforms() we already have the mapped symbol names and
|
||||
// we could composite mapped and original variable names.
|
||||
if (success && (compileOptions & SH_MAP_LONG_VARIABLE_NAMES))
|
||||
mapLongVariableNames(root);
|
||||
|
||||
- if (success && (compileOptions & SH_ATTRIBUTES_UNIFORMS))
|
||||
+ if (success && (compileOptions & SH_ATTRIBUTES_UNIFORMS)) {
|
||||
collectAttribsUniforms(root);
|
||||
+ if (compileOptions & SH_ENFORCE_PACKING_RESTRICTIONS) {
|
||||
+ success = enforcePackingRestrictions();
|
||||
+ if (!success) {
|
||||
+ infoSink.info.message(EPrefixError, "too many uniforms");
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
|
||||
if (success && (compileOptions & SH_INTERMEDIATE_TREE))
|
||||
intermediate.outputTree(root);
|
||||
|
||||
if (success && (compileOptions & SH_OBJECT_CODE))
|
||||
translate(root);
|
||||
}
|
||||
|
||||
@@ -305,16 +316,22 @@ bool TCompiler::enforceVertexShaderTimin
|
||||
}
|
||||
|
||||
void TCompiler::collectAttribsUniforms(TIntermNode* root)
|
||||
{
|
||||
CollectAttribsUniforms collect(attribs, uniforms);
|
||||
root->traverse(&collect);
|
||||
}
|
||||
|
||||
+bool TCompiler::enforcePackingRestrictions()
|
||||
+{
|
||||
+ VariablePacker packer;
|
||||
+ return packer.CheckVariablesWithinPackingLimits(maxUniformVectors, uniforms);
|
||||
+}
|
||||
+
|
||||
void TCompiler::mapLongVariableNames(TIntermNode* root)
|
||||
{
|
||||
ASSERT(longNameMap);
|
||||
MapLongVariableNames map(longNameMap);
|
||||
root->traverse(&map);
|
||||
}
|
||||
|
||||
int TCompiler::getMappedNameMaxLength() const
|
||||
diff --git a/gfx/angle/src/compiler/ShHandle.h b/gfx/angle/src/compiler/ShHandle.h
|
||||
--- a/gfx/angle/src/compiler/ShHandle.h
|
||||
+++ b/gfx/angle/src/compiler/ShHandle.h
|
||||
@@ -83,32 +83,37 @@ protected:
|
||||
// functionality mandated in GLSL 1.0 spec Appendix A.
|
||||
bool validateLimitations(TIntermNode* root);
|
||||
// Collect info for all attribs and uniforms.
|
||||
void collectAttribsUniforms(TIntermNode* root);
|
||||
// Map long variable names into shorter ones.
|
||||
void mapLongVariableNames(TIntermNode* root);
|
||||
// Translate to object code.
|
||||
virtual void translate(TIntermNode* root) = 0;
|
||||
+ // Returns true if, after applying the packing rules in the GLSL 1.017 spec
|
||||
+ // Appendix A, section 7, the shader does not use too many uniforms.
|
||||
+ bool enforcePackingRestrictions();
|
||||
// Returns true if the shader passes the restrictions that aim to prevent timing attacks.
|
||||
bool enforceTimingRestrictions(TIntermNode* root, bool outputGraph);
|
||||
// Returns true if the shader does not use samplers.
|
||||
bool enforceVertexShaderTimingRestrictions(TIntermNode* root);
|
||||
// Returns true if the shader does not use sampler dependent values to affect control
|
||||
// flow or in operations whose time can depend on the input values.
|
||||
bool enforceFragmentShaderTimingRestrictions(const TDependencyGraph& graph);
|
||||
// Get built-in extensions with default behavior.
|
||||
const TExtensionBehavior& getExtensionBehavior() const;
|
||||
|
||||
const BuiltInFunctionEmulator& getBuiltInFunctionEmulator() const;
|
||||
|
||||
private:
|
||||
ShShaderType shaderType;
|
||||
ShShaderSpec shaderSpec;
|
||||
|
||||
+ int maxUniformVectors;
|
||||
+
|
||||
// Built-in symbol table for the given language, spec, and resources.
|
||||
// It is preserved from compile-to-compile.
|
||||
TSymbolTable symbolTable;
|
||||
// Built-in extensions with default behavior.
|
||||
TExtensionBehavior extensionBehavior;
|
||||
|
||||
BuiltInFunctionEmulator builtInFunctionEmulator;
|
||||
|
||||
diff --git a/gfx/angle/src/compiler/VariableInfo.cpp b/gfx/angle/src/compiler/VariableInfo.cpp
|
||||
--- a/gfx/angle/src/compiler/VariableInfo.cpp
|
||||
+++ b/gfx/angle/src/compiler/VariableInfo.cpp
|
||||
@@ -133,16 +133,26 @@ void getUserDefinedVariableInfo(const TT
|
||||
const TType* fieldType = (*structure)[i].type;
|
||||
getVariableInfo(*fieldType,
|
||||
name + "." + fieldType->getFieldName(),
|
||||
mappedName + "." + fieldType->getFieldName(),
|
||||
infoList);
|
||||
}
|
||||
}
|
||||
|
||||
+TVariableInfo::TVariableInfo()
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+TVariableInfo::TVariableInfo(ShDataType type, int size)
|
||||
+ : type(type),
|
||||
+ size(size)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
CollectAttribsUniforms::CollectAttribsUniforms(TVariableInfoList& attribs,
|
||||
TVariableInfoList& uniforms)
|
||||
: mAttribs(attribs),
|
||||
mUniforms(uniforms)
|
||||
{
|
||||
}
|
||||
|
||||
// We are only interested in attribute and uniform variable declaration.
|
||||
diff --git a/gfx/angle/src/compiler/VariableInfo.h b/gfx/angle/src/compiler/VariableInfo.h
|
||||
--- a/gfx/angle/src/compiler/VariableInfo.h
|
||||
+++ b/gfx/angle/src/compiler/VariableInfo.h
|
||||
@@ -8,16 +8,19 @@
|
||||
#define COMPILER_VARIABLE_INFO_H_
|
||||
|
||||
#include "GLSLANG/ShaderLang.h"
|
||||
#include "compiler/intermediate.h"
|
||||
|
||||
// Provides information about a variable.
|
||||
// It is currently being used to store info about active attribs and uniforms.
|
||||
struct TVariableInfo {
|
||||
+ TVariableInfo(ShDataType type, int size);
|
||||
+ TVariableInfo();
|
||||
+
|
||||
TPersistString name;
|
||||
TPersistString mappedName;
|
||||
ShDataType type;
|
||||
int size;
|
||||
};
|
||||
typedef std::vector<TVariableInfo> TVariableInfoList;
|
||||
|
||||
// Traverses intermediate tree to collect all attributes and uniforms.
|
||||
diff --git a/gfx/angle/src/compiler/VariablePacker.cpp b/gfx/angle/src/compiler/VariablePacker.cpp
|
||||
new file mode 100644
|
||||
--- /dev/null
|
||||
+++ b/gfx/angle/src/compiler/VariablePacker.cpp
|
||||
@@ -0,0 +1,297 @@
|
||||
+//
|
||||
+// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
|
||||
+// Use of this source code is governed by a BSD-style license that can be
|
||||
+// found in the LICENSE file.
|
||||
+//
|
||||
+#include "compiler/VariablePacker.h"
|
||||
+
|
||||
+#include <algorithm>
|
||||
+#include "compiler/ShHandle.h"
|
||||
+
|
||||
+namespace {
|
||||
+int GetSortOrder(ShDataType type)
|
||||
+{
|
||||
+ switch (type) {
|
||||
+ case SH_FLOAT_MAT4:
|
||||
+ return 0;
|
||||
+ case SH_FLOAT_MAT2:
|
||||
+ return 1;
|
||||
+ case SH_FLOAT_VEC4:
|
||||
+ case SH_INT_VEC4:
|
||||
+ case SH_BOOL_VEC4:
|
||||
+ return 2;
|
||||
+ case SH_FLOAT_MAT3:
|
||||
+ return 3;
|
||||
+ case SH_FLOAT_VEC3:
|
||||
+ case SH_INT_VEC3:
|
||||
+ case SH_BOOL_VEC3:
|
||||
+ return 4;
|
||||
+ case SH_FLOAT_VEC2:
|
||||
+ case SH_INT_VEC2:
|
||||
+ case SH_BOOL_VEC2:
|
||||
+ return 5;
|
||||
+ case SH_FLOAT:
|
||||
+ case SH_INT:
|
||||
+ case SH_BOOL:
|
||||
+ case SH_SAMPLER_2D:
|
||||
+ case SH_SAMPLER_CUBE:
|
||||
+ case SH_SAMPLER_EXTERNAL_OES:
|
||||
+ case SH_SAMPLER_2D_RECT_ARB:
|
||||
+ return 6;
|
||||
+ default:
|
||||
+ ASSERT(false);
|
||||
+ return 7;
|
||||
+ }
|
||||
+}
|
||||
+} // namespace
|
||||
+
|
||||
+int VariablePacker::GetNumComponentsPerRow(ShDataType type)
|
||||
+{
|
||||
+ switch (type) {
|
||||
+ case SH_FLOAT_MAT4:
|
||||
+ case SH_FLOAT_MAT2:
|
||||
+ case SH_FLOAT_VEC4:
|
||||
+ case SH_INT_VEC4:
|
||||
+ case SH_BOOL_VEC4:
|
||||
+ return 4;
|
||||
+ case SH_FLOAT_MAT3:
|
||||
+ case SH_FLOAT_VEC3:
|
||||
+ case SH_INT_VEC3:
|
||||
+ case SH_BOOL_VEC3:
|
||||
+ return 3;
|
||||
+ case SH_FLOAT_VEC2:
|
||||
+ case SH_INT_VEC2:
|
||||
+ case SH_BOOL_VEC2:
|
||||
+ return 2;
|
||||
+ case SH_FLOAT:
|
||||
+ case SH_INT:
|
||||
+ case SH_BOOL:
|
||||
+ case SH_SAMPLER_2D:
|
||||
+ case SH_SAMPLER_CUBE:
|
||||
+ case SH_SAMPLER_EXTERNAL_OES:
|
||||
+ case SH_SAMPLER_2D_RECT_ARB:
|
||||
+ return 1;
|
||||
+ default:
|
||||
+ ASSERT(false);
|
||||
+ return 5;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+int VariablePacker::GetNumRows(ShDataType type)
|
||||
+{
|
||||
+ switch (type) {
|
||||
+ case SH_FLOAT_MAT4:
|
||||
+ return 4;
|
||||
+ case SH_FLOAT_MAT3:
|
||||
+ return 3;
|
||||
+ case SH_FLOAT_MAT2:
|
||||
+ return 1;
|
||||
+ case SH_FLOAT_VEC4:
|
||||
+ case SH_INT_VEC4:
|
||||
+ case SH_BOOL_VEC4:
|
||||
+ case SH_FLOAT_VEC3:
|
||||
+ case SH_INT_VEC3:
|
||||
+ case SH_BOOL_VEC3:
|
||||
+ case SH_FLOAT_VEC2:
|
||||
+ case SH_INT_VEC2:
|
||||
+ case SH_BOOL_VEC2:
|
||||
+ case SH_FLOAT:
|
||||
+ case SH_INT:
|
||||
+ case SH_BOOL:
|
||||
+ case SH_SAMPLER_2D:
|
||||
+ case SH_SAMPLER_CUBE:
|
||||
+ case SH_SAMPLER_EXTERNAL_OES:
|
||||
+ case SH_SAMPLER_2D_RECT_ARB:
|
||||
+ return 1;
|
||||
+ default:
|
||||
+ ASSERT(false);
|
||||
+ return 100000;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+struct TVariableInfoComparer {
|
||||
+ bool operator()(const TVariableInfo& lhs, const TVariableInfo& rhs) const
|
||||
+ {
|
||||
+ int lhsSortOrder = GetSortOrder(lhs.type);
|
||||
+ int rhsSortOrder = GetSortOrder(rhs.type);
|
||||
+ if (lhsSortOrder != rhsSortOrder) {
|
||||
+ return lhsSortOrder < rhsSortOrder;
|
||||
+ }
|
||||
+ // Sort by largest first.
|
||||
+ return lhs.size > rhs.size;
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
+unsigned VariablePacker::makeColumnFlags(int column, int numComponentsPerRow)
|
||||
+{
|
||||
+ return ((kColumnMask << (kNumColumns - numComponentsPerRow)) &
|
||||
+ kColumnMask) >> column;
|
||||
+}
|
||||
+
|
||||
+void VariablePacker::fillColumns(int topRow, int numRows, int column, int numComponentsPerRow)
|
||||
+{
|
||||
+ unsigned columnFlags = makeColumnFlags(column, numComponentsPerRow);
|
||||
+ for (int r = 0; r < numRows; ++r) {
|
||||
+ int row = topRow + r;
|
||||
+ ASSERT((rows_[row] & columnFlags) == 0);
|
||||
+ rows_[row] |= columnFlags;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+bool VariablePacker::searchColumn(int column, int numRows, int* destRow, int* destSize)
|
||||
+{
|
||||
+ ASSERT(destRow);
|
||||
+
|
||||
+ for (; topNonFullRow_ < maxRows_ && rows_[topNonFullRow_] == kColumnMask;
|
||||
+ ++topNonFullRow_) {
|
||||
+ }
|
||||
+
|
||||
+ for (; bottomNonFullRow_ >= 0 && rows_[bottomNonFullRow_] == kColumnMask;
|
||||
+ --bottomNonFullRow_) {
|
||||
+ }
|
||||
+
|
||||
+ if (bottomNonFullRow_ - topNonFullRow_ + 1 < numRows) {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ unsigned columnFlags = makeColumnFlags(column, 1);
|
||||
+ int topGoodRow = 0;
|
||||
+ int smallestGoodTop = -1;
|
||||
+ int smallestGoodSize = maxRows_ + 1;
|
||||
+ int bottomRow = bottomNonFullRow_ + 1;
|
||||
+ bool found = false;
|
||||
+ for (int row = topNonFullRow_; row <= bottomRow; ++row) {
|
||||
+ bool rowEmpty = row < bottomRow ? ((rows_[row] & columnFlags) == 0) : false;
|
||||
+ if (rowEmpty) {
|
||||
+ if (!found) {
|
||||
+ topGoodRow = row;
|
||||
+ found = true;
|
||||
+ }
|
||||
+ } else {
|
||||
+ if (found) {
|
||||
+ int size = row - topGoodRow;
|
||||
+ if (size >= numRows && size < smallestGoodSize) {
|
||||
+ smallestGoodSize = size;
|
||||
+ smallestGoodTop = topGoodRow;
|
||||
+ }
|
||||
+ }
|
||||
+ found = false;
|
||||
+ }
|
||||
+ }
|
||||
+ if (smallestGoodTop < 0) {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ *destRow = smallestGoodTop;
|
||||
+ if (destSize) {
|
||||
+ *destSize = smallestGoodSize;
|
||||
+ }
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
+bool VariablePacker::CheckVariablesWithinPackingLimits(int maxVectors, const TVariableInfoList& in_variables)
|
||||
+{
|
||||
+ ASSERT(maxVectors > 0);
|
||||
+ maxRows_ = maxVectors;
|
||||
+ topNonFullRow_ = 0;
|
||||
+ bottomNonFullRow_ = maxRows_ - 1;
|
||||
+ TVariableInfoList variables(in_variables);
|
||||
+
|
||||
+ // As per GLSL 1.017 Appendix A, Section 7 variables are packed in specific
|
||||
+ // order by type, then by size of array, largest first.
|
||||
+ std::sort(variables.begin(), variables.end(), TVariableInfoComparer());
|
||||
+ rows_.clear();
|
||||
+ rows_.resize(maxVectors, 0);
|
||||
+
|
||||
+ // Packs the 4 column variables.
|
||||
+ size_t ii = 0;
|
||||
+ for (; ii < variables.size(); ++ii) {
|
||||
+ const TVariableInfo& variable = variables[ii];
|
||||
+ if (GetNumComponentsPerRow(variable.type) != 4) {
|
||||
+ break;
|
||||
+ }
|
||||
+ topNonFullRow_ += GetNumRows(variable.type) * variable.size;
|
||||
+ }
|
||||
+
|
||||
+ if (topNonFullRow_ > maxRows_) {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ // Packs the 3 column variables.
|
||||
+ int num3ColumnRows = 0;
|
||||
+ for (; ii < variables.size(); ++ii) {
|
||||
+ const TVariableInfo& variable = variables[ii];
|
||||
+ if (GetNumComponentsPerRow(variable.type) != 3) {
|
||||
+ break;
|
||||
+ }
|
||||
+ num3ColumnRows += GetNumRows(variable.type) * variable.size;
|
||||
+ }
|
||||
+
|
||||
+ if (topNonFullRow_ + num3ColumnRows > maxRows_) {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ fillColumns(topNonFullRow_, num3ColumnRows, 0, 3);
|
||||
+
|
||||
+ // Packs the 2 column variables.
|
||||
+ int top2ColumnRow = topNonFullRow_ + num3ColumnRows;
|
||||
+ int twoColumnRowsAvailable = maxRows_ - top2ColumnRow;
|
||||
+ int rowsAvailableInColumns01 = twoColumnRowsAvailable;
|
||||
+ int rowsAvailableInColumns23 = twoColumnRowsAvailable;
|
||||
+ for (; ii < variables.size(); ++ii) {
|
||||
+ const TVariableInfo& variable = variables[ii];
|
||||
+ if (GetNumComponentsPerRow(variable.type) != 2) {
|
||||
+ break;
|
||||
+ }
|
||||
+ int numRows = GetNumRows(variable.type) * variable.size;
|
||||
+ if (numRows <= rowsAvailableInColumns01) {
|
||||
+ rowsAvailableInColumns01 -= numRows;
|
||||
+ } else if (numRows <= rowsAvailableInColumns23) {
|
||||
+ rowsAvailableInColumns23 -= numRows;
|
||||
+ } else {
|
||||
+ return false;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ int numRowsUsedInColumns01 =
|
||||
+ twoColumnRowsAvailable - rowsAvailableInColumns01;
|
||||
+ int numRowsUsedInColumns23 =
|
||||
+ twoColumnRowsAvailable - rowsAvailableInColumns23;
|
||||
+ fillColumns(top2ColumnRow, numRowsUsedInColumns01, 0, 2);
|
||||
+ fillColumns(maxRows_ - numRowsUsedInColumns23, numRowsUsedInColumns23,
|
||||
+ 2, 2);
|
||||
+
|
||||
+ // Packs the 1 column variables.
|
||||
+ for (; ii < variables.size(); ++ii) {
|
||||
+ const TVariableInfo& variable = variables[ii];
|
||||
+ ASSERT(1 == GetNumComponentsPerRow(variable.type));
|
||||
+ int numRows = GetNumRows(variable.type) * variable.size;
|
||||
+ int smallestColumn = -1;
|
||||
+ int smallestSize = maxRows_ + 1;
|
||||
+ int topRow = -1;
|
||||
+ for (int column = 0; column < kNumColumns; ++column) {
|
||||
+ int row = 0;
|
||||
+ int size = 0;
|
||||
+ if (searchColumn(column, numRows, &row, &size)) {
|
||||
+ if (size < smallestSize) {
|
||||
+ smallestSize = size;
|
||||
+ smallestColumn = column;
|
||||
+ topRow = row;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (smallestColumn < 0) {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ fillColumns(topRow, numRows, smallestColumn, 1);
|
||||
+ }
|
||||
+
|
||||
+ ASSERT(variables.size() == ii);
|
||||
+
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+
|
||||
diff --git a/gfx/angle/src/compiler/VariablePacker.h b/gfx/angle/src/compiler/VariablePacker.h
|
||||
new file mode 100644
|
||||
--- /dev/null
|
||||
+++ b/gfx/angle/src/compiler/VariablePacker.h
|
||||
@@ -0,0 +1,41 @@
|
||||
+//
|
||||
+// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
|
||||
+// Use of this source code is governed by a BSD-style license that can be
|
||||
+// found in the LICENSE file.
|
||||
+//
|
||||
+
|
||||
+#ifndef _VARIABLEPACKER_INCLUDED_
|
||||
+#define _VARIABLEPACKER_INCLUDED_
|
||||
+
|
||||
+#include <vector>
|
||||
+#include "compiler/ShHandle.h"
|
||||
+
|
||||
+class VariablePacker {
|
||||
+ public:
|
||||
+ // Returns true if the passed in variables pack in maxVectors following
|
||||
+ // the packing rules from the GLSL 1.017 spec, Appendix A, section 7.
|
||||
+ bool CheckVariablesWithinPackingLimits(
|
||||
+ int maxVectors,
|
||||
+ const TVariableInfoList& in_variables);
|
||||
+
|
||||
+ // Gets how many components in a row a data type takes.
|
||||
+ static int GetNumComponentsPerRow(ShDataType type);
|
||||
+
|
||||
+ // Gets how many rows a data type takes.
|
||||
+ static int GetNumRows(ShDataType type);
|
||||
+
|
||||
+ private:
|
||||
+ static const int kNumColumns = 4;
|
||||
+ static const unsigned kColumnMask = (1 << kNumColumns) - 1;
|
||||
+
|
||||
+ unsigned makeColumnFlags(int column, int numComponentsPerRow);
|
||||
+ void fillColumns(int topRow, int numRows, int column, int numComponentsPerRow);
|
||||
+ bool searchColumn(int column, int numRows, int* destRow, int* destSize);
|
||||
+
|
||||
+ int topNonFullRow_;
|
||||
+ int bottomNonFullRow_;
|
||||
+ int maxRows_;
|
||||
+ std::vector<unsigned> rows_;
|
||||
+};
|
||||
+
|
||||
+#endif // _VARIABLEPACKER_INCLUDED_
|
||||
diff --git a/gfx/angle/src/libGLESv2/Makefile.in b/gfx/angle/src/libGLESv2/Makefile.in
|
||||
--- a/gfx/angle/src/libGLESv2/Makefile.in
|
||||
+++ b/gfx/angle/src/libGLESv2/Makefile.in
|
||||
@@ -84,16 +84,17 @@ CPPSRCS = \
|
||||
ForLoopUnroll.cpp \
|
||||
MapLongVariableNames.cpp \
|
||||
spooky.cpp \
|
||||
BuiltInFunctionEmulator.cpp \
|
||||
Input.cpp \
|
||||
Lexer.cpp \
|
||||
Preprocessor.cpp \
|
||||
Token.cpp \
|
||||
+ VariablePacker.cpp \
|
||||
$(NULL)
|
||||
|
||||
# flex/yacc generated files
|
||||
CPPSRCS += \
|
||||
glslang_lex.cpp \
|
||||
glslang_tab.cpp \
|
||||
$(NULL)
|
||||
|
||||
diff --git a/gfx/angle/tests/build_tests.gyp b/gfx/angle/tests/build_tests.gyp
|
||||
--- a/gfx/angle/tests/build_tests.gyp
|
||||
+++ b/gfx/angle/tests/build_tests.gyp
|
||||
@@ -58,16 +58,35 @@
|
||||
'preprocessor_tests/pragma_test.cpp',
|
||||
'preprocessor_tests/PreprocessorTest.cpp',
|
||||
'preprocessor_tests/PreprocessorTest.h',
|
||||
'preprocessor_tests/space_test.cpp',
|
||||
'preprocessor_tests/token_test.cpp',
|
||||
'preprocessor_tests/version_test.cpp',
|
||||
],
|
||||
},
|
||||
+ {
|
||||
+ 'target_name': 'compiler_tests',
|
||||
+ 'type': 'executable',
|
||||
+ 'dependencies': [
|
||||
+ '../src/build_angle.gyp:translator_common',
|
||||
+ 'gtest',
|
||||
+ 'gmock',
|
||||
+ ],
|
||||
+ 'include_dirs': [
|
||||
+ '../include',
|
||||
+ '../src',
|
||||
+ '../third_party/googletest/include',
|
||||
+ '../third_party/googlemock/include',
|
||||
+ ],
|
||||
+ 'sources': [
|
||||
+ '../third_party/googlemock/src/gmock_main.cc',
|
||||
+ 'compiler_tests/VariablePacker_test.cpp',
|
||||
+ ],
|
||||
+ },
|
||||
],
|
||||
}
|
||||
|
||||
# Local Variables:
|
||||
# tab-width:2
|
||||
# indent-tabs-mode:nil
|
||||
# End:
|
||||
# vim: set expandtab tabstop=2 shiftwidth=2:
|
||||
diff --git a/gfx/angle/tests/compiler_tests/VariablePacker_test.cpp b/gfx/angle/tests/compiler_tests/VariablePacker_test.cpp
|
||||
new file mode 100644
|
||||
--- /dev/null
|
||||
+++ b/gfx/angle/tests/compiler_tests/VariablePacker_test.cpp
|
||||
@@ -0,0 +1,85 @@
|
||||
+//
|
||||
+// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
|
||||
+// Use of this source code is governed by a BSD-style license that can be
|
||||
+// found in the LICENSE file.
|
||||
+//
|
||||
+#include "compiler/VariablePacker.h"
|
||||
+#include "gtest/gtest.h"
|
||||
+
|
||||
+TEST(VariablePacking, Pack) {
|
||||
+ VariablePacker packer;
|
||||
+ TVariableInfoList vars;
|
||||
+ const int kMaxRows = 16;
|
||||
+ // test no vars.
|
||||
+ EXPECT_TRUE(packer.CheckVariablesWithinPackingLimits(kMaxRows, vars));
|
||||
+
|
||||
+ ShDataType types[] = {
|
||||
+ SH_FLOAT_MAT4, // 0
|
||||
+ SH_FLOAT_MAT2, // 1
|
||||
+ SH_FLOAT_VEC4, // 2
|
||||
+ SH_INT_VEC4, // 3
|
||||
+ SH_BOOL_VEC4, // 4
|
||||
+ SH_FLOAT_MAT3, // 5
|
||||
+ SH_FLOAT_VEC3, // 6
|
||||
+ SH_INT_VEC3, // 7
|
||||
+ SH_BOOL_VEC3, // 8
|
||||
+ SH_FLOAT_VEC2, // 9
|
||||
+ SH_INT_VEC2, // 10
|
||||
+ SH_BOOL_VEC2, // 11
|
||||
+ SH_FLOAT, // 12
|
||||
+ SH_INT, // 13
|
||||
+ SH_BOOL, // 14
|
||||
+ SH_SAMPLER_2D, // 15
|
||||
+ SH_SAMPLER_CUBE, // 16
|
||||
+ SH_SAMPLER_EXTERNAL_OES, // 17
|
||||
+ SH_SAMPLER_2D_RECT_ARB, // 18
|
||||
+ };
|
||||
+
|
||||
+ for (size_t tt = 0; tt < sizeof(types) / sizeof(types[0]); ++tt) {
|
||||
+ ShDataType type = types[tt];
|
||||
+ int num_rows = VariablePacker::GetNumRows(type);
|
||||
+ int num_components_per_row = VariablePacker::GetNumComponentsPerRow(type);
|
||||
+ // Check 1 of the type.
|
||||
+ vars.clear();
|
||||
+ vars.push_back(TVariableInfo(type, 1));
|
||||
+ EXPECT_TRUE(packer.CheckVariablesWithinPackingLimits(kMaxRows, vars));
|
||||
+
|
||||
+ // Check exactly the right amount of 1 type as an array.
|
||||
+ int num_vars = kMaxRows / num_rows;
|
||||
+ vars.clear();
|
||||
+ vars.push_back(TVariableInfo(type, num_vars));
|
||||
+ EXPECT_TRUE(packer.CheckVariablesWithinPackingLimits(kMaxRows, vars));
|
||||
+
|
||||
+ // test too many
|
||||
+ vars.clear();
|
||||
+ vars.push_back(TVariableInfo(type, num_vars + 1));
|
||||
+ EXPECT_FALSE(packer.CheckVariablesWithinPackingLimits(kMaxRows, vars));
|
||||
+
|
||||
+ // Check exactly the right amount of 1 type as individual vars.
|
||||
+ num_vars = kMaxRows / num_rows *
|
||||
+ ((num_components_per_row > 2) ? 1 : (4 / num_components_per_row));
|
||||
+ vars.clear();
|
||||
+ for (int ii = 0; ii < num_vars; ++ii) {
|
||||
+ vars.push_back(TVariableInfo(type, 1));
|
||||
+ }
|
||||
+ EXPECT_TRUE(packer.CheckVariablesWithinPackingLimits(kMaxRows, vars));
|
||||
+
|
||||
+ // Check 1 too many.
|
||||
+ vars.push_back(TVariableInfo( type, 1));
|
||||
+ EXPECT_FALSE(packer.CheckVariablesWithinPackingLimits(kMaxRows, vars));
|
||||
+ }
|
||||
+
|
||||
+ // Test example from GLSL ES 3.0 spec chapter 11.
|
||||
+ vars.clear();
|
||||
+ vars.push_back(TVariableInfo(SH_FLOAT_VEC4, 1));
|
||||
+ vars.push_back(TVariableInfo(SH_FLOAT_MAT3, 1));
|
||||
+ vars.push_back(TVariableInfo(SH_FLOAT_MAT3, 1));
|
||||
+ vars.push_back(TVariableInfo(SH_FLOAT_VEC2, 6));
|
||||
+ vars.push_back(TVariableInfo(SH_FLOAT_VEC2, 4));
|
||||
+ vars.push_back(TVariableInfo(SH_FLOAT_VEC2, 1));
|
||||
+ vars.push_back(TVariableInfo(SH_FLOAT, 3));
|
||||
+ vars.push_back(TVariableInfo(SH_FLOAT, 2));
|
||||
+ vars.push_back(TVariableInfo(SH_FLOAT, 1));
|
||||
+ EXPECT_TRUE(packer.CheckVariablesWithinPackingLimits(kMaxRows, vars));
|
||||
+}
|
||||
+
|
|
@ -142,7 +142,10 @@ typedef enum {
|
|||
// - The shader spec is SH_WEBGL_SPEC.
|
||||
// - The compile options contain the SH_TIMING_RESTRICTIONS flag.
|
||||
// - The shader type is SH_FRAGMENT_SHADER.
|
||||
SH_DEPENDENCY_GRAPH = 0x0400
|
||||
SH_DEPENDENCY_GRAPH = 0x0400,
|
||||
|
||||
// Enforce the GLSL 1.017 Appendix A section 7 packing restrictions.
|
||||
SH_ENFORCE_PACKING_RESTRICTIONS = 0x0800,
|
||||
} ShCompileOptions;
|
||||
|
||||
//
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "compiler/RenameFunction.h"
|
||||
#include "compiler/ShHandle.h"
|
||||
#include "compiler/ValidateLimitations.h"
|
||||
#include "compiler/VariablePacker.h"
|
||||
#include "compiler/depgraph/DependencyGraph.h"
|
||||
#include "compiler/depgraph/DependencyGraphOutput.h"
|
||||
#include "compiler/timing/RestrictFragmentShaderTiming.h"
|
||||
|
@ -113,6 +114,9 @@ TCompiler::~TCompiler()
|
|||
|
||||
bool TCompiler::Init(const ShBuiltInResources& resources)
|
||||
{
|
||||
maxUniformVectors = (shaderType == SH_VERTEX_SHADER) ?
|
||||
resources.MaxVertexUniformVectors :
|
||||
resources.MaxFragmentUniformVectors;
|
||||
TScopedPoolAllocator scopedAlloc(&allocator, false);
|
||||
|
||||
// Generate built-in symbol table.
|
||||
|
@ -192,8 +196,15 @@ bool TCompiler::compile(const char* const shaderStrings[],
|
|||
if (success && (compileOptions & SH_MAP_LONG_VARIABLE_NAMES))
|
||||
mapLongVariableNames(root);
|
||||
|
||||
if (success && (compileOptions & SH_ATTRIBUTES_UNIFORMS))
|
||||
if (success && (compileOptions & SH_ATTRIBUTES_UNIFORMS)) {
|
||||
collectAttribsUniforms(root);
|
||||
if (compileOptions & SH_ENFORCE_PACKING_RESTRICTIONS) {
|
||||
success = enforcePackingRestrictions();
|
||||
if (!success) {
|
||||
infoSink.info.message(EPrefixError, "too many uniforms");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (success && (compileOptions & SH_INTERMEDIATE_TREE))
|
||||
intermediate.outputTree(root);
|
||||
|
@ -310,6 +321,12 @@ void TCompiler::collectAttribsUniforms(TIntermNode* root)
|
|||
root->traverse(&collect);
|
||||
}
|
||||
|
||||
bool TCompiler::enforcePackingRestrictions()
|
||||
{
|
||||
VariablePacker packer;
|
||||
return packer.CheckVariablesWithinPackingLimits(maxUniformVectors, uniforms);
|
||||
}
|
||||
|
||||
void TCompiler::mapLongVariableNames(TIntermNode* root)
|
||||
{
|
||||
ASSERT(longNameMap);
|
||||
|
|
|
@ -88,6 +88,9 @@ protected:
|
|||
void mapLongVariableNames(TIntermNode* root);
|
||||
// Translate to object code.
|
||||
virtual void translate(TIntermNode* root) = 0;
|
||||
// Returns true if, after applying the packing rules in the GLSL 1.017 spec
|
||||
// Appendix A, section 7, the shader does not use too many uniforms.
|
||||
bool enforcePackingRestrictions();
|
||||
// Returns true if the shader passes the restrictions that aim to prevent timing attacks.
|
||||
bool enforceTimingRestrictions(TIntermNode* root, bool outputGraph);
|
||||
// Returns true if the shader does not use samplers.
|
||||
|
@ -104,6 +107,8 @@ private:
|
|||
ShShaderType shaderType;
|
||||
ShShaderSpec shaderSpec;
|
||||
|
||||
int maxUniformVectors;
|
||||
|
||||
// Built-in symbol table for the given language, spec, and resources.
|
||||
// It is preserved from compile-to-compile.
|
||||
TSymbolTable symbolTable;
|
||||
|
|
|
@ -138,6 +138,16 @@ void getUserDefinedVariableInfo(const TType& type,
|
|||
}
|
||||
}
|
||||
|
||||
TVariableInfo::TVariableInfo()
|
||||
{
|
||||
}
|
||||
|
||||
TVariableInfo::TVariableInfo(ShDataType type, int size)
|
||||
: type(type),
|
||||
size(size)
|
||||
{
|
||||
}
|
||||
|
||||
CollectAttribsUniforms::CollectAttribsUniforms(TVariableInfoList& attribs,
|
||||
TVariableInfoList& uniforms)
|
||||
: mAttribs(attribs),
|
||||
|
|
|
@ -13,6 +13,9 @@
|
|||
// Provides information about a variable.
|
||||
// It is currently being used to store info about active attribs and uniforms.
|
||||
struct TVariableInfo {
|
||||
TVariableInfo(ShDataType type, int size);
|
||||
TVariableInfo();
|
||||
|
||||
TPersistString name;
|
||||
TPersistString mappedName;
|
||||
ShDataType type;
|
||||
|
|
|
@ -0,0 +1,297 @@
|
|||
//
|
||||
// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
#include "compiler/VariablePacker.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include "compiler/ShHandle.h"
|
||||
|
||||
namespace {
|
||||
int GetSortOrder(ShDataType type)
|
||||
{
|
||||
switch (type) {
|
||||
case SH_FLOAT_MAT4:
|
||||
return 0;
|
||||
case SH_FLOAT_MAT2:
|
||||
return 1;
|
||||
case SH_FLOAT_VEC4:
|
||||
case SH_INT_VEC4:
|
||||
case SH_BOOL_VEC4:
|
||||
return 2;
|
||||
case SH_FLOAT_MAT3:
|
||||
return 3;
|
||||
case SH_FLOAT_VEC3:
|
||||
case SH_INT_VEC3:
|
||||
case SH_BOOL_VEC3:
|
||||
return 4;
|
||||
case SH_FLOAT_VEC2:
|
||||
case SH_INT_VEC2:
|
||||
case SH_BOOL_VEC2:
|
||||
return 5;
|
||||
case SH_FLOAT:
|
||||
case SH_INT:
|
||||
case SH_BOOL:
|
||||
case SH_SAMPLER_2D:
|
||||
case SH_SAMPLER_CUBE:
|
||||
case SH_SAMPLER_EXTERNAL_OES:
|
||||
case SH_SAMPLER_2D_RECT_ARB:
|
||||
return 6;
|
||||
default:
|
||||
ASSERT(false);
|
||||
return 7;
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
int VariablePacker::GetNumComponentsPerRow(ShDataType type)
|
||||
{
|
||||
switch (type) {
|
||||
case SH_FLOAT_MAT4:
|
||||
case SH_FLOAT_MAT2:
|
||||
case SH_FLOAT_VEC4:
|
||||
case SH_INT_VEC4:
|
||||
case SH_BOOL_VEC4:
|
||||
return 4;
|
||||
case SH_FLOAT_MAT3:
|
||||
case SH_FLOAT_VEC3:
|
||||
case SH_INT_VEC3:
|
||||
case SH_BOOL_VEC3:
|
||||
return 3;
|
||||
case SH_FLOAT_VEC2:
|
||||
case SH_INT_VEC2:
|
||||
case SH_BOOL_VEC2:
|
||||
return 2;
|
||||
case SH_FLOAT:
|
||||
case SH_INT:
|
||||
case SH_BOOL:
|
||||
case SH_SAMPLER_2D:
|
||||
case SH_SAMPLER_CUBE:
|
||||
case SH_SAMPLER_EXTERNAL_OES:
|
||||
case SH_SAMPLER_2D_RECT_ARB:
|
||||
return 1;
|
||||
default:
|
||||
ASSERT(false);
|
||||
return 5;
|
||||
}
|
||||
}
|
||||
|
||||
int VariablePacker::GetNumRows(ShDataType type)
|
||||
{
|
||||
switch (type) {
|
||||
case SH_FLOAT_MAT4:
|
||||
return 4;
|
||||
case SH_FLOAT_MAT3:
|
||||
return 3;
|
||||
case SH_FLOAT_MAT2:
|
||||
return 1;
|
||||
case SH_FLOAT_VEC4:
|
||||
case SH_INT_VEC4:
|
||||
case SH_BOOL_VEC4:
|
||||
case SH_FLOAT_VEC3:
|
||||
case SH_INT_VEC3:
|
||||
case SH_BOOL_VEC3:
|
||||
case SH_FLOAT_VEC2:
|
||||
case SH_INT_VEC2:
|
||||
case SH_BOOL_VEC2:
|
||||
case SH_FLOAT:
|
||||
case SH_INT:
|
||||
case SH_BOOL:
|
||||
case SH_SAMPLER_2D:
|
||||
case SH_SAMPLER_CUBE:
|
||||
case SH_SAMPLER_EXTERNAL_OES:
|
||||
case SH_SAMPLER_2D_RECT_ARB:
|
||||
return 1;
|
||||
default:
|
||||
ASSERT(false);
|
||||
return 100000;
|
||||
}
|
||||
}
|
||||
|
||||
struct TVariableInfoComparer {
|
||||
bool operator()(const TVariableInfo& lhs, const TVariableInfo& rhs) const
|
||||
{
|
||||
int lhsSortOrder = GetSortOrder(lhs.type);
|
||||
int rhsSortOrder = GetSortOrder(rhs.type);
|
||||
if (lhsSortOrder != rhsSortOrder) {
|
||||
return lhsSortOrder < rhsSortOrder;
|
||||
}
|
||||
// Sort by largest first.
|
||||
return lhs.size > rhs.size;
|
||||
}
|
||||
};
|
||||
|
||||
unsigned VariablePacker::makeColumnFlags(int column, int numComponentsPerRow)
|
||||
{
|
||||
return ((kColumnMask << (kNumColumns - numComponentsPerRow)) &
|
||||
kColumnMask) >> column;
|
||||
}
|
||||
|
||||
void VariablePacker::fillColumns(int topRow, int numRows, int column, int numComponentsPerRow)
|
||||
{
|
||||
unsigned columnFlags = makeColumnFlags(column, numComponentsPerRow);
|
||||
for (int r = 0; r < numRows; ++r) {
|
||||
int row = topRow + r;
|
||||
ASSERT((rows_[row] & columnFlags) == 0);
|
||||
rows_[row] |= columnFlags;
|
||||
}
|
||||
}
|
||||
|
||||
bool VariablePacker::searchColumn(int column, int numRows, int* destRow, int* destSize)
|
||||
{
|
||||
ASSERT(destRow);
|
||||
|
||||
for (; topNonFullRow_ < maxRows_ && rows_[topNonFullRow_] == kColumnMask;
|
||||
++topNonFullRow_) {
|
||||
}
|
||||
|
||||
for (; bottomNonFullRow_ >= 0 && rows_[bottomNonFullRow_] == kColumnMask;
|
||||
--bottomNonFullRow_) {
|
||||
}
|
||||
|
||||
if (bottomNonFullRow_ - topNonFullRow_ + 1 < numRows) {
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned columnFlags = makeColumnFlags(column, 1);
|
||||
int topGoodRow = 0;
|
||||
int smallestGoodTop = -1;
|
||||
int smallestGoodSize = maxRows_ + 1;
|
||||
int bottomRow = bottomNonFullRow_ + 1;
|
||||
bool found = false;
|
||||
for (int row = topNonFullRow_; row <= bottomRow; ++row) {
|
||||
bool rowEmpty = row < bottomRow ? ((rows_[row] & columnFlags) == 0) : false;
|
||||
if (rowEmpty) {
|
||||
if (!found) {
|
||||
topGoodRow = row;
|
||||
found = true;
|
||||
}
|
||||
} else {
|
||||
if (found) {
|
||||
int size = row - topGoodRow;
|
||||
if (size >= numRows && size < smallestGoodSize) {
|
||||
smallestGoodSize = size;
|
||||
smallestGoodTop = topGoodRow;
|
||||
}
|
||||
}
|
||||
found = false;
|
||||
}
|
||||
}
|
||||
if (smallestGoodTop < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*destRow = smallestGoodTop;
|
||||
if (destSize) {
|
||||
*destSize = smallestGoodSize;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool VariablePacker::CheckVariablesWithinPackingLimits(int maxVectors, const TVariableInfoList& in_variables)
|
||||
{
|
||||
ASSERT(maxVectors > 0);
|
||||
maxRows_ = maxVectors;
|
||||
topNonFullRow_ = 0;
|
||||
bottomNonFullRow_ = maxRows_ - 1;
|
||||
TVariableInfoList variables(in_variables);
|
||||
|
||||
// As per GLSL 1.017 Appendix A, Section 7 variables are packed in specific
|
||||
// order by type, then by size of array, largest first.
|
||||
std::sort(variables.begin(), variables.end(), TVariableInfoComparer());
|
||||
rows_.clear();
|
||||
rows_.resize(maxVectors, 0);
|
||||
|
||||
// Packs the 4 column variables.
|
||||
size_t ii = 0;
|
||||
for (; ii < variables.size(); ++ii) {
|
||||
const TVariableInfo& variable = variables[ii];
|
||||
if (GetNumComponentsPerRow(variable.type) != 4) {
|
||||
break;
|
||||
}
|
||||
topNonFullRow_ += GetNumRows(variable.type) * variable.size;
|
||||
}
|
||||
|
||||
if (topNonFullRow_ > maxRows_) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Packs the 3 column variables.
|
||||
int num3ColumnRows = 0;
|
||||
for (; ii < variables.size(); ++ii) {
|
||||
const TVariableInfo& variable = variables[ii];
|
||||
if (GetNumComponentsPerRow(variable.type) != 3) {
|
||||
break;
|
||||
}
|
||||
num3ColumnRows += GetNumRows(variable.type) * variable.size;
|
||||
}
|
||||
|
||||
if (topNonFullRow_ + num3ColumnRows > maxRows_) {
|
||||
return false;
|
||||
}
|
||||
|
||||
fillColumns(topNonFullRow_, num3ColumnRows, 0, 3);
|
||||
|
||||
// Packs the 2 column variables.
|
||||
int top2ColumnRow = topNonFullRow_ + num3ColumnRows;
|
||||
int twoColumnRowsAvailable = maxRows_ - top2ColumnRow;
|
||||
int rowsAvailableInColumns01 = twoColumnRowsAvailable;
|
||||
int rowsAvailableInColumns23 = twoColumnRowsAvailable;
|
||||
for (; ii < variables.size(); ++ii) {
|
||||
const TVariableInfo& variable = variables[ii];
|
||||
if (GetNumComponentsPerRow(variable.type) != 2) {
|
||||
break;
|
||||
}
|
||||
int numRows = GetNumRows(variable.type) * variable.size;
|
||||
if (numRows <= rowsAvailableInColumns01) {
|
||||
rowsAvailableInColumns01 -= numRows;
|
||||
} else if (numRows <= rowsAvailableInColumns23) {
|
||||
rowsAvailableInColumns23 -= numRows;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
int numRowsUsedInColumns01 =
|
||||
twoColumnRowsAvailable - rowsAvailableInColumns01;
|
||||
int numRowsUsedInColumns23 =
|
||||
twoColumnRowsAvailable - rowsAvailableInColumns23;
|
||||
fillColumns(top2ColumnRow, numRowsUsedInColumns01, 0, 2);
|
||||
fillColumns(maxRows_ - numRowsUsedInColumns23, numRowsUsedInColumns23,
|
||||
2, 2);
|
||||
|
||||
// Packs the 1 column variables.
|
||||
for (; ii < variables.size(); ++ii) {
|
||||
const TVariableInfo& variable = variables[ii];
|
||||
ASSERT(1 == GetNumComponentsPerRow(variable.type));
|
||||
int numRows = GetNumRows(variable.type) * variable.size;
|
||||
int smallestColumn = -1;
|
||||
int smallestSize = maxRows_ + 1;
|
||||
int topRow = -1;
|
||||
for (int column = 0; column < kNumColumns; ++column) {
|
||||
int row = 0;
|
||||
int size = 0;
|
||||
if (searchColumn(column, numRows, &row, &size)) {
|
||||
if (size < smallestSize) {
|
||||
smallestSize = size;
|
||||
smallestColumn = column;
|
||||
topRow = row;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (smallestColumn < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
fillColumns(topRow, numRows, smallestColumn, 1);
|
||||
}
|
||||
|
||||
ASSERT(variables.size() == ii);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
//
|
||||
// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
#ifndef _VARIABLEPACKER_INCLUDED_
|
||||
#define _VARIABLEPACKER_INCLUDED_
|
||||
|
||||
#include <vector>
|
||||
#include "compiler/ShHandle.h"
|
||||
|
||||
class VariablePacker {
|
||||
public:
|
||||
// Returns true if the passed in variables pack in maxVectors following
|
||||
// the packing rules from the GLSL 1.017 spec, Appendix A, section 7.
|
||||
bool CheckVariablesWithinPackingLimits(
|
||||
int maxVectors,
|
||||
const TVariableInfoList& in_variables);
|
||||
|
||||
// Gets how many components in a row a data type takes.
|
||||
static int GetNumComponentsPerRow(ShDataType type);
|
||||
|
||||
// Gets how many rows a data type takes.
|
||||
static int GetNumRows(ShDataType type);
|
||||
|
||||
private:
|
||||
static const int kNumColumns = 4;
|
||||
static const unsigned kColumnMask = (1 << kNumColumns) - 1;
|
||||
|
||||
unsigned makeColumnFlags(int column, int numComponentsPerRow);
|
||||
void fillColumns(int topRow, int numRows, int column, int numComponentsPerRow);
|
||||
bool searchColumn(int column, int numRows, int* destRow, int* destSize);
|
||||
|
||||
int topNonFullRow_;
|
||||
int bottomNonFullRow_;
|
||||
int maxRows_;
|
||||
std::vector<unsigned> rows_;
|
||||
};
|
||||
|
||||
#endif // _VARIABLEPACKER_INCLUDED_
|
|
@ -89,6 +89,7 @@ CPPSRCS = \
|
|||
Lexer.cpp \
|
||||
Preprocessor.cpp \
|
||||
Token.cpp \
|
||||
VariablePacker.cpp \
|
||||
$(NULL)
|
||||
|
||||
# flex/yacc generated files
|
||||
|
|
|
@ -63,6 +63,25 @@
|
|||
'preprocessor_tests/version_test.cpp',
|
||||
],
|
||||
},
|
||||
{
|
||||
'target_name': 'compiler_tests',
|
||||
'type': 'executable',
|
||||
'dependencies': [
|
||||
'../src/build_angle.gyp:translator_common',
|
||||
'gtest',
|
||||
'gmock',
|
||||
],
|
||||
'include_dirs': [
|
||||
'../include',
|
||||
'../src',
|
||||
'../third_party/googletest/include',
|
||||
'../third_party/googlemock/include',
|
||||
],
|
||||
'sources': [
|
||||
'../third_party/googlemock/src/gmock_main.cc',
|
||||
'compiler_tests/VariablePacker_test.cpp',
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
//
|
||||
// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
#include "compiler/VariablePacker.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
TEST(VariablePacking, Pack) {
|
||||
VariablePacker packer;
|
||||
TVariableInfoList vars;
|
||||
const int kMaxRows = 16;
|
||||
// test no vars.
|
||||
EXPECT_TRUE(packer.CheckVariablesWithinPackingLimits(kMaxRows, vars));
|
||||
|
||||
ShDataType types[] = {
|
||||
SH_FLOAT_MAT4, // 0
|
||||
SH_FLOAT_MAT2, // 1
|
||||
SH_FLOAT_VEC4, // 2
|
||||
SH_INT_VEC4, // 3
|
||||
SH_BOOL_VEC4, // 4
|
||||
SH_FLOAT_MAT3, // 5
|
||||
SH_FLOAT_VEC3, // 6
|
||||
SH_INT_VEC3, // 7
|
||||
SH_BOOL_VEC3, // 8
|
||||
SH_FLOAT_VEC2, // 9
|
||||
SH_INT_VEC2, // 10
|
||||
SH_BOOL_VEC2, // 11
|
||||
SH_FLOAT, // 12
|
||||
SH_INT, // 13
|
||||
SH_BOOL, // 14
|
||||
SH_SAMPLER_2D, // 15
|
||||
SH_SAMPLER_CUBE, // 16
|
||||
SH_SAMPLER_EXTERNAL_OES, // 17
|
||||
SH_SAMPLER_2D_RECT_ARB, // 18
|
||||
};
|
||||
|
||||
for (size_t tt = 0; tt < sizeof(types) / sizeof(types[0]); ++tt) {
|
||||
ShDataType type = types[tt];
|
||||
int num_rows = VariablePacker::GetNumRows(type);
|
||||
int num_components_per_row = VariablePacker::GetNumComponentsPerRow(type);
|
||||
// Check 1 of the type.
|
||||
vars.clear();
|
||||
vars.push_back(TVariableInfo(type, 1));
|
||||
EXPECT_TRUE(packer.CheckVariablesWithinPackingLimits(kMaxRows, vars));
|
||||
|
||||
// Check exactly the right amount of 1 type as an array.
|
||||
int num_vars = kMaxRows / num_rows;
|
||||
vars.clear();
|
||||
vars.push_back(TVariableInfo(type, num_vars));
|
||||
EXPECT_TRUE(packer.CheckVariablesWithinPackingLimits(kMaxRows, vars));
|
||||
|
||||
// test too many
|
||||
vars.clear();
|
||||
vars.push_back(TVariableInfo(type, num_vars + 1));
|
||||
EXPECT_FALSE(packer.CheckVariablesWithinPackingLimits(kMaxRows, vars));
|
||||
|
||||
// Check exactly the right amount of 1 type as individual vars.
|
||||
num_vars = kMaxRows / num_rows *
|
||||
((num_components_per_row > 2) ? 1 : (4 / num_components_per_row));
|
||||
vars.clear();
|
||||
for (int ii = 0; ii < num_vars; ++ii) {
|
||||
vars.push_back(TVariableInfo(type, 1));
|
||||
}
|
||||
EXPECT_TRUE(packer.CheckVariablesWithinPackingLimits(kMaxRows, vars));
|
||||
|
||||
// Check 1 too many.
|
||||
vars.push_back(TVariableInfo( type, 1));
|
||||
EXPECT_FALSE(packer.CheckVariablesWithinPackingLimits(kMaxRows, vars));
|
||||
}
|
||||
|
||||
// Test example from GLSL ES 3.0 spec chapter 11.
|
||||
vars.clear();
|
||||
vars.push_back(TVariableInfo(SH_FLOAT_VEC4, 1));
|
||||
vars.push_back(TVariableInfo(SH_FLOAT_MAT3, 1));
|
||||
vars.push_back(TVariableInfo(SH_FLOAT_MAT3, 1));
|
||||
vars.push_back(TVariableInfo(SH_FLOAT_VEC2, 6));
|
||||
vars.push_back(TVariableInfo(SH_FLOAT_VEC2, 4));
|
||||
vars.push_back(TVariableInfo(SH_FLOAT_VEC2, 1));
|
||||
vars.push_back(TVariableInfo(SH_FLOAT, 3));
|
||||
vars.push_back(TVariableInfo(SH_FLOAT, 2));
|
||||
vars.push_back(TVariableInfo(SH_FLOAT, 1));
|
||||
EXPECT_TRUE(packer.CheckVariablesWithinPackingLimits(kMaxRows, vars));
|
||||
}
|
||||
|
|
@ -295,7 +295,8 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl)
|
|||
"NVIDIA",
|
||||
"ATI",
|
||||
"Qualcomm",
|
||||
"Imagination"
|
||||
"Imagination",
|
||||
"nouveau"
|
||||
};
|
||||
mVendor = VendorOther;
|
||||
for (int i = 0; i < VendorOther; ++i) {
|
||||
|
@ -514,11 +515,20 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl)
|
|||
#ifdef XP_MACOSX
|
||||
if (mWorkAroundDriverBugs &&
|
||||
mVendor == VendorIntel) {
|
||||
// see bug 737182 for 2D textures, bug 684822 for cube map textures.
|
||||
// see bug 737182 for 2D textures, bug 684882 for cube map textures.
|
||||
mMaxTextureSize = NS_MIN(mMaxTextureSize, 4096);
|
||||
mMaxCubeMapTextureSize = NS_MIN(mMaxCubeMapTextureSize, 512);
|
||||
// for good measure, we align renderbuffers on what we do for 2D textures
|
||||
mMaxRenderbufferSize = NS_MIN(mMaxRenderbufferSize, 4096);
|
||||
mNeedsTextureSizeChecks = true;
|
||||
}
|
||||
#endif
|
||||
#ifdef MOZ_X11
|
||||
if (mWorkAroundDriverBugs &&
|
||||
mVendor == VendorNouveau) {
|
||||
// see bug 814716. Clamp MaxCubeMapTextureSize at 2K for Nouveau.
|
||||
mMaxCubeMapTextureSize = NS_MIN(mMaxCubeMapTextureSize, 2048);
|
||||
mNeedsTextureSizeChecks = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -165,6 +165,7 @@ public:
|
|||
mMaxCubeMapTextureSize(0),
|
||||
mMaxTextureImageSize(0),
|
||||
mMaxRenderbufferSize(0),
|
||||
mNeedsTextureSizeChecks(false),
|
||||
mWorkAroundDriverBugs(true)
|
||||
#ifdef DEBUG
|
||||
, mGLError(LOCAL_GL_NO_ERROR)
|
||||
|
@ -341,6 +342,7 @@ public:
|
|||
VendorATI,
|
||||
VendorQualcomm,
|
||||
VendorImagination,
|
||||
VendorNouveau,
|
||||
VendorOther
|
||||
};
|
||||
|
||||
|
@ -1330,7 +1332,6 @@ public:
|
|||
static bool ListHasExtension(const GLubyte *extensions,
|
||||
const char *extension);
|
||||
|
||||
GLint GetMaxTextureSize() { return mMaxTextureSize; }
|
||||
GLint GetMaxTextureImageSize() { return mMaxTextureImageSize; }
|
||||
void SetFlipped(bool aFlipped) { mFlipped = aFlipped; }
|
||||
|
||||
|
@ -1581,16 +1582,17 @@ protected:
|
|||
GLint mMaxCubeMapTextureSize;
|
||||
GLint mMaxTextureImageSize;
|
||||
GLint mMaxRenderbufferSize;
|
||||
bool mNeedsTextureSizeChecks;
|
||||
bool mWorkAroundDriverBugs;
|
||||
|
||||
bool IsTextureSizeSafeToPassToDriver(GLenum target, GLsizei width, GLsizei height) const {
|
||||
#ifdef XP_MACOSX
|
||||
if (mWorkAroundDriverBugs &&
|
||||
mVendor == VendorIntel) {
|
||||
// see bug 737182 for 2D textures, bug 684822 for cube map textures.
|
||||
// some drivers handle incorrectly some large texture sizes that are below the
|
||||
if (mNeedsTextureSizeChecks) {
|
||||
// some drivers incorrectly handle some large texture sizes that are below the
|
||||
// max texture size that they report. So we check ourselves against our own values
|
||||
// (mMax[CubeMap]TextureSize).
|
||||
// see bug 737182 for Mac Intel 2D textures
|
||||
// see bug 684882 for Mac Intel cube map textures
|
||||
// see bug 814716 for Mesa Nouveau
|
||||
GLsizei maxSize = target == LOCAL_GL_TEXTURE_CUBE_MAP ||
|
||||
(target >= LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X &&
|
||||
target <= LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z)
|
||||
|
@ -1598,7 +1600,6 @@ protected:
|
|||
: mMaxTextureSize;
|
||||
return width <= maxSize && height <= maxSize;
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -200,8 +200,11 @@ TiledTextureImage::TiledTextureImage(GLContext* aGL,
|
|||
, mGL(aGL)
|
||||
, mTextureState(Created)
|
||||
{
|
||||
mTileSize = (!(aFlags & TextureImage::ForceSingleTile) && mGL->WantsSmallTiles())
|
||||
? 256 : mGL->GetMaxTextureSize();
|
||||
if (!(aFlags & TextureImage::ForceSingleTile) && mGL->WantsSmallTiles()) {
|
||||
mTileSize = 256;
|
||||
} else {
|
||||
mGL->fGetIntegerv(LOCAL_GL_MAX_TEXTURE_SIZE, (GLint*) &mTileSize);
|
||||
}
|
||||
if (aSize.width != 0 && aSize.height != 0) {
|
||||
Resize(aSize);
|
||||
}
|
||||
|
|
|
@ -289,7 +289,8 @@ Layer::Layer(LayerManager* aManager, void* aImplData) :
|
|||
mUseClipRect(false),
|
||||
mUseTileSourceRect(false),
|
||||
mIsFixedPosition(false),
|
||||
mDebugColorIndex(0)
|
||||
mDebugColorIndex(0),
|
||||
mAnimationGeneration(0)
|
||||
{}
|
||||
|
||||
Layer::~Layer()
|
||||
|
|
|
@ -804,6 +804,9 @@ public:
|
|||
AnimationArray& GetAnimations() { return mAnimations; }
|
||||
InfallibleTArray<AnimData>& GetAnimationData() { return mAnimationData; }
|
||||
|
||||
uint64_t GetAnimationGeneration() { return mAnimationGeneration; }
|
||||
void SetAnimationGeneration(uint64_t aCount) { mAnimationGeneration = aCount; }
|
||||
|
||||
/**
|
||||
* DRAWING PHASE ONLY
|
||||
*
|
||||
|
@ -1108,6 +1111,9 @@ protected:
|
|||
bool mIsFixedPosition;
|
||||
gfxPoint mAnchor;
|
||||
DebugOnly<uint32_t> mDebugColorIndex;
|
||||
// If this layer is used for OMTA, then this counter is used to ensure we
|
||||
// stay in sync with the animation manager
|
||||
uint64_t mAnimationGeneration;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -818,7 +818,7 @@ CompositorParent::TransformShadowTree(TimeStamp aCurrentFrame)
|
|||
|
||||
// NB: we must sample animations *before* sampling pan/zoom
|
||||
// transforms.
|
||||
wantNextFrame |= SampleAnimations(root, mLastCompose);
|
||||
wantNextFrame |= SampleAnimations(root, aCurrentFrame);
|
||||
|
||||
const FrameMetrics& metrics = container->GetFrameMetrics();
|
||||
// We must apply the resolution scale before a pan/zoom transform, so we call
|
||||
|
|
|
@ -162,7 +162,8 @@ CanvasLayerOGL::Initialize(const Data& aData)
|
|||
|
||||
// Check the maximum texture size supported by GL. glTexImage2D supports
|
||||
// images of up to 2 + GL_MAX_TEXTURE_SIZE
|
||||
GLint texSize = gl()->GetMaxTextureSize();
|
||||
GLint texSize;
|
||||
gl()->fGetIntegerv(LOCAL_GL_MAX_TEXTURE_SIZE, &texSize);
|
||||
if (mBounds.width > (2 + texSize) || mBounds.height > (2 + texSize)) {
|
||||
mDelayedUpdates = true;
|
||||
MakeTextureIfNeeded(gl(), mTexture);
|
||||
|
|
|
@ -62,7 +62,9 @@ LayerManagerOGL::Initialize(bool force)
|
|||
int32_t
|
||||
LayerManagerOGL::GetMaxTextureSize() const
|
||||
{
|
||||
return mGLContext->GetMaxTextureSize();
|
||||
int32_t maxSize;
|
||||
mGLContext->fGetIntegerv(LOCAL_GL_MAX_TEXTURE_SIZE, &maxSize);
|
||||
return maxSize;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -43,7 +43,6 @@
|
|||
#include "nsIDOMNodeList.h"
|
||||
#include "nsString.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsPrintfCString.h"
|
||||
#include "nsICategoryManager.h"
|
||||
#include "nsIDocumentLoaderFactory.h"
|
||||
#include "nsIContentViewer.h"
|
||||
|
@ -56,11 +55,11 @@
|
|||
#include "nsXMLContentSink.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsStringStream.h"
|
||||
#include "nsStreamUtils.h"
|
||||
#include "nsIPrincipal.h"
|
||||
#include "Element.h"
|
||||
#include "nsSVGUtils.h"
|
||||
|
||||
#define SVG_CONTENT_TYPE NS_LITERAL_CSTRING("image/svg+xml")
|
||||
#define UTF8_CHARSET NS_LITERAL_CSTRING("utf-8")
|
||||
|
@ -230,7 +229,7 @@ gfxSVGGlyphs::RenderGlyph(gfxContext *aContext, uint32_t aGlyphId,
|
|||
Element *glyph = mGlyphIdMap.Get(aGlyphId);
|
||||
NS_ASSERTION(glyph, "No glyph element. Should check with HasSVGGlyph() first!");
|
||||
|
||||
return nsContentUtils::PaintSVGGlyph(glyph, aContext, aDrawMode, aObjectPaint);
|
||||
return nsSVGUtils::PaintSVGGlyph(glyph, aContext, aDrawMode, aObjectPaint);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -240,7 +239,7 @@ gfxSVGGlyphs::GetGlyphExtents(uint32_t aGlyphId, const gfxMatrix& aSVGToAppSpace
|
|||
Element *glyph = mGlyphIdMap.Get(aGlyphId);
|
||||
NS_ASSERTION(glyph, "No glyph element. Should check with HasSVGGlyph() first!");
|
||||
|
||||
return nsContentUtils::GetSVGGlyphExtents(glyph, aSVGToAppSpace, aResult);
|
||||
return nsSVGUtils::GetSVGGlyphExtents(glyph, aSVGToAppSpace, aResult);
|
||||
}
|
||||
|
||||
Element *
|
||||
|
|
|
@ -76,9 +76,9 @@ LIBXUL_DIST ?= $(DIST)
|
|||
# build products (typelibs, components, chrome).
|
||||
#
|
||||
# If XPI_NAME is set, the files will be shipped to $(DIST)/xpi-stage/$(XPI_NAME)
|
||||
# If DIST_SUBDIR is set, the files will be shipped to $(DIST)/$(DIST_SUBDIR)
|
||||
# Otherwise, the default $(DIST)/bin will be used.
|
||||
FINAL_TARGET = $(if $(XPI_NAME),$(DIST)/xpi-stage/$(XPI_NAME),$(if $(DIST_SUBDIR),$(DIST)/bin/$(DIST_SUBDIR),$(DIST)/bin))
|
||||
# instead of $(DIST)/bin. In both cases, if DIST_SUBDIR is set, the files will be
|
||||
# shipped to a $(DIST_SUBDIR) subdirectory.
|
||||
FINAL_TARGET = $(if $(XPI_NAME),$(DIST)/xpi-stage/$(XPI_NAME),$(DIST)/bin)$(DIST_SUBDIR:%=/%)
|
||||
|
||||
ifdef XPI_NAME
|
||||
DEFINES += -DXPI_NAME=$(XPI_NAME)
|
||||
|
|
|
@ -56,18 +56,18 @@ mkdir_deps =$(foreach dir,$(getargv),$(call slash_strip,$(dir)/.mkdir.done))
|
|||
#######################
|
||||
|
||||
%/.mkdir.done: # mkdir -p -p => mkdir -p
|
||||
$(subst $(space)-p,$(null),$(MKDIR)) -p $(dir $@)
|
||||
$(subst $(space)-p,$(null),$(MKDIR)) -p "$(dir $@)"
|
||||
# Make the timestamp old enough for not being a problem with symbolic links
|
||||
# targets depending on it. Use Jan 3, 1980 to accomodate any timezone where
|
||||
# 198001010000 would translate to something older than FAT epoch.
|
||||
@touch -t 198001030000 $@
|
||||
@$(TOUCH) -t 198001030000 "$@"
|
||||
|
||||
# A handful of makefiles are attempting "mkdir dot". Likely not intended
|
||||
# or stale logic so add a stub target to handle the request and warn for now.
|
||||
.mkdir.done:
|
||||
ifndef NOWARN_AUTOTARGETS # {
|
||||
@echo "WARNING: $(MKDIR) -dot- requested by $(MAKE) -C $(CURDIR) $(MAKECMDGOALS)"
|
||||
@touch -t 198001030000 $@
|
||||
@$(TOUCH) -t 198001030000 $@
|
||||
endif #}
|
||||
|
||||
INCLUDED_AUTOTARGETS_MK = 1
|
||||
|
|
|
@ -1544,7 +1544,7 @@ define install_file_template
|
|||
$(or $(3),libs):: $(2)/$(notdir $(1))
|
||||
$(call install_cmd_override,$(2)/$(notdir $(1)))
|
||||
$(2)/$(notdir $(1)): $(1) $$(call mkdir_deps,$(2))
|
||||
$$(call install_cmd,$(4) $$< $${@D})
|
||||
$$(call install_cmd,$(4) "$$<" "$${@D}")
|
||||
endef
|
||||
$(foreach category,$(INSTALL_TARGETS),\
|
||||
$(if $($(category)_DEST),,$(error Missing $(category)_DEST))\
|
||||
|
@ -1591,8 +1591,8 @@ $(foreach category,$(INSTALL_TARGETS),\
|
|||
# makefile_target, extra_flags)
|
||||
define preprocess_file_template
|
||||
$(2): $(1) $$(call mkdir_deps,$(dir $(2))) $$(GLOBAL_DEPS)
|
||||
$$(RM) $$@
|
||||
$$(PYTHON) $$(topsrcdir)/config/Preprocessor.py $(4) $$(DEFINES) $$(ACDEFINES) $$(XULPPFLAGS) $$< > $$@
|
||||
$$(RM) "$$@"
|
||||
$$(PYTHON) $$(topsrcdir)/config/Preprocessor.py $(4) $$(DEFINES) $$(ACDEFINES) $$(XULPPFLAGS) "$$<" > "$$@"
|
||||
$(3):: $(2)
|
||||
endef
|
||||
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче