Merge last win pgo-green changeset from m-i to m-c.

This commit is contained in:
Richard Newman 2012-02-23 18:35:17 -08:00
commit e7b436563b
170 changed files with 3319 additions and 2751 deletions

View File

@ -353,9 +353,6 @@ pref("urlclassifier.gethashtables", "goog-phish-shavar,goog-malware-shavar");
// the database.
pref("urlclassifier.confirm-age", 2700);
// Maximum size of the sqlite3 cache during an update, in bytes
pref("urlclassifier.updatecachemax", 4194304);
// URL for checking the reason for a malware warning.
pref("browser.safebrowsing.malware.reportURL", "http://safebrowsing.clients.google.com/safebrowsing/diagnostic?client=%NAME%&hl=%LOCALE%&site=");
#endif

View File

@ -759,12 +759,6 @@ pref("urlclassifier.gethashtables", "goog-phish-shavar,goog-malware-shavar");
// the database.
pref("urlclassifier.confirm-age", 2700);
// Maximum size of the sqlite3 cache during an update, in bytes
pref("urlclassifier.updatecachemax", 41943040);
// Maximum size of the sqlite3 cache for lookups, in bytes
pref("urlclassifier.lookupcachemax", 1048576);
// URL for checking the reason for a malware warning.
pref("browser.safebrowsing.malware.reportURL", "http://safebrowsing.clients.google.com/safebrowsing/diagnostic?client=%NAME%&hl=%LOCALE%&site=");

View File

@ -3573,7 +3573,6 @@ const BrowserSearch = {
loadAddEngines: function BrowserSearch_loadAddEngines() {
var newWindowPref = gPrefService.getIntPref("browser.link.open_newwindow");
var where = newWindowPref == 3 ? "tab" : "window";
var regionBundle = document.getElementById("bundle_browser_region");
var searchEnginesURL = formatURL("browser.search.searchEnginesURL", true);
openUILinkIn(searchEnginesURL, where);
}

View File

@ -153,6 +153,7 @@ var gEngineManagerDialog = {
while (Services.prompt.prompt(window, title, msg, alias, null, {})) {
var bduplicate = false;
var eduplicate = false;
var dupName = "";
if (alias.value != "") {
try {
@ -168,6 +169,7 @@ var gEngineManagerDialog = {
if (engine.alias == alias.value &&
engine.name != selectedEngine.name) {
eduplicate = true;
dupName = engine.name;
break;
}
}
@ -177,8 +179,7 @@ var gEngineManagerDialog = {
if (eduplicate || bduplicate) {
var dtitle = strings.getString("duplicateTitle");
var bmsg = strings.getString("duplicateBookmarkMsg");
var emsg = strings.getFormattedString("duplicateEngineMsg",
[engine.name]);
var emsg = strings.getFormattedString("duplicateEngineMsg", [dupName]);
Services.prompt.alert(window, dtitle, eduplicate ? emsg : bmsg);
} else {

View File

@ -50,9 +50,9 @@
]>
<bindings id="SearchBindings"
xmlns="http://www.mozilla.org/xbl"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:xbl="http://www.mozilla.org/xbl">
xmlns="http://www.mozilla.org/xbl"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:xbl="http://www.mozilla.org/xbl">
<binding id="searchbar">
<resources>
@ -96,13 +96,12 @@
<xul:image class="search-go-button"
anonid="search-go-button"
onclick="handleSearchCommand(event);"
tooltiptext="&searchEndCap.label;" />
tooltiptext="&searchEndCap.label;"/>
</xul:hbox>
</xul:textbox>
</content>
<implementation implements="nsIObserver">
<constructor><![CDATA[
if (this.parentNode.parentNode.localName == "toolbarpaletteitem")
return;
@ -164,7 +163,7 @@
<getter><![CDATA[
var currentEngine = this.searchService.currentEngine;
// Return a dummy engine if there is no currentEngine
return currentEngine || {name:"", uri:null};
return currentEngine || {name: "", uri: null};
]]></getter>
</property>
@ -335,7 +334,8 @@
// indexes as items are removed.
var items = popup.childNodes;
for (var i = items.length - 1; i >= 0; i--) {
if (items[i].getAttribute("class").indexOf("addengine") != -1)
if (items[i].classList.contains("addengine-item") ||
items[i].classList.contains("addengine-separator"))
popup.removeChild(items[i]);
}
@ -444,7 +444,7 @@
<body><![CDATA[
// Find the new index
var newIndex = this.engines.indexOf(this.currentEngine);
newIndex += (isNextEngine) ? 1 : -1;
newIndex += isNextEngine ? 1 : -1;
if (newIndex >= 0 && newIndex < this.engines.length)
this.currentEngine = this.engines[newIndex];
@ -495,13 +495,12 @@
openUILinkIn(submission.uri.spec, aWhere, null, submission.postData);
]]></body>
</method>
</implementation>
<handlers>
<handler event="command"><![CDATA[
const target = event.originalTarget;
if (target.getAttribute("class").indexOf("addengine-item") != -1) {
if (target.classList.contains("addengine-item")) {
var searchService =
Components.classes["@mozilla.org/browser/search-service;1"]
.getService(Components.interfaces.nsIBrowserSearchService);
@ -719,7 +718,7 @@
</body>
</method>
<!-- overload |onTextEntered| in autocomplete.xml -->
<!-- override |onTextEntered| in autocomplete.xml -->
<method name="onTextEntered">
<parameter name="aEvent"/>
<body><![CDATA[

View File

@ -164,6 +164,7 @@
@BINPATH@/components/dom_indexeddb.xpt
@BINPATH@/components/dom_offline.xpt
@BINPATH@/components/dom_json.xpt
@BINPATH@/components/dom_power.xpt
@BINPATH@/components/dom_range.xpt
@BINPATH@/components/dom_sidebar.xpt
@BINPATH@/components/dom_sms.xpt

View File

@ -75,13 +75,13 @@ OrganizerQueryAllBookmarks=All Bookmarks
OrganizerQueryTags=Tags
# LOCALIZATION NOTE (tagResultLabel) :
# This is what we use to form the label (for screen readers)
# for url bar autocomplete results of type "tag"
# Noun used to describe the location bar autocomplete result type
# to users with screen readers
# See createResultLabel() in urlbarBindings.xml
tagResultLabel=Tag
# LOCALIZATION NOTE (bookmarkResultLabel) :
# This is what we use to form the label (for screen readers)
# for url bar autocomplete results of type "bookmark"
# Noun used to describe the location bar autocomplete result type
# to users with screen readers
# See createResultLabel() in urlbarBindings.xml
bookmarkResultLabel=Bookmark

View File

@ -61,7 +61,6 @@ class DMError(Exception):
def __str__(self):
return self.msg
def abstractmethod(method):
line = method.func_code.co_firstlineno
filename = method.func_code.co_filename
@ -70,9 +69,18 @@ def abstractmethod(method):
'should be implemented by a concrete class' %
(repr(method), filename,line))
return not_implemented
class DeviceManager:
@abstractmethod
def shell(self, cmd, outputfile, env=None, cwd=None):
"""
executes shell command on device
returns:
success: Return code from command
failure: None
"""
@abstractmethod
def pushFile(self, localname, destname):
"""
@ -168,25 +176,27 @@ class DeviceManager:
success: array of process tuples
failure: None
"""
@abstractmethod
def fireProcess(self, appname, failIfRunning=False):
"""
external function
DEPRECATED: Use shell() or launchApplication() for new code
returns:
success: pid
failure: None
"""
@abstractmethod
def launchProcess(self, cmd, outputFile = "process.txt", cwd = '', env = '', failIfRunning=False):
"""
external function
DEPRECATED: Use shell() or launchApplication() for new code
returns:
success: output filename
failure: None
"""
def communicate(self, process, timeout = 600, interval = 5):
"""
loops until 'process' has exited or 'timeout' seconds is reached
@ -581,3 +591,35 @@ class NetworkTools:
print "Socket error trying to find open port"
return seed
def _pop_last_line(file):
'''
Utility function to get the last line from a file (shared between ADB and
SUT device managers). Function also removes it from the file. Intended to
strip off the return code from a shell command.
'''
bytes_from_end = 1
file.seek(0, 2)
length = file.tell() + 1
while bytes_from_end <= length:
file.seek((-1)*bytes_from_end, 2)
data = file.read()
if bytes_from_end == length and len(data) == 0: # no data, return None
return None
if data[0] == '\n' or bytes_from_end == length:
# found the last line, which should have the return value
if data[0] == '\n':
data = data[1:]
# truncate off the return code line
file.truncate(length - bytes_from_end)
file.seek(0,2)
file.write('\0')
return data
bytes_from_end += 1
return None

View File

@ -1,5 +1,5 @@
import subprocess
from devicemanager import DeviceManager, DMError
from devicemanager import DeviceManager, DMError, _pop_last_line
import re
import os
import sys
@ -63,6 +63,47 @@ class DeviceManagerADB(DeviceManager):
else:
print "restarting as root failed"
# external function: executes shell command on device
# returns:
# success: <return code>
# failure: None
def shell(self, cmd, outputfile, env=None, cwd=None):
# need to quote special characters here
for (index, arg) in enumerate(cmd):
if arg.find(" ") or arg.find("(") or arg.find(")") or arg.find("\""):
cmd[index] = '\'%s\'' % arg
# This is more complex than you'd think because adb doesn't actually
# return the return code from a process, so we have to capture the output
# to get it
# FIXME: this function buffers all output of the command into memory,
# always. :(
cmdline = subprocess.list2cmdline(cmd) + "; echo $?"
# prepend cwd and env to command if necessary
if cwd:
cmdline = "cd %s; %s" % (cwd, cmdline)
if env:
envstr = '; '.join(map(lambda x: 'export %s=%s' % (x[0], x[1]), env.iteritems()))
cmdline = envstr + "; " + cmdline
# all output should be in stdout
proc = subprocess.Popen(["adb", "shell", cmdline],
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
(stdout, stderr) = proc.communicate()
outputfile.write(stdout.rstrip('\n'))
lastline = _pop_last_line(outputfile)
if lastline:
m = re.search('([0-9]+)', lastline)
if m:
return_code = m.group(1)
outputfile.seek(-2, 2)
outputfile.truncate() # truncate off the return code
return return_code
return None
# external function
# returns:
# success: True
@ -264,6 +305,7 @@ class DeviceManagerADB(DeviceManager):
return ret
# external function
# DEPRECATED: Use shell() or launchApplication() for new code
# returns:
# success: pid
# failure: None
@ -275,6 +317,7 @@ class DeviceManagerADB(DeviceManager):
return self.launchProcess(parts, failIfRunning)
# external function
# DEPRECATED: Use shell() or launchApplication() for new code
# returns:
# success: output filename
# failure: None
@ -327,6 +370,7 @@ class DeviceManagerADB(DeviceManager):
if name == appname:
p = self.runCmdAs(["shell", "kill", pid])
return p.stdout.read()
return None
# external function
@ -611,7 +655,7 @@ class DeviceManagerADB(DeviceManager):
args.insert(1, "run-as")
args.insert(2, self.packageName)
args.insert(0, "adb")
return subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
return subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
def runCmdAs(self, args):
if self.useRunAs:

View File

@ -47,7 +47,18 @@ import subprocess
from threading import Thread
import traceback
import sys
from devicemanager import DeviceManager, DMError, FileError, NetworkTools
import StringIO
from devicemanager import DeviceManager, DMError, FileError, NetworkTools, _pop_last_line
class AgentError(Exception):
"SUTAgent-specific exception."
def __init__(self, msg= '', fatal = False):
self.msg = msg
self.fatal = fatal
def __str__(self):
return self.msg
class DeviceManagerSUT(DeviceManager):
host = ''
@ -76,7 +87,7 @@ class DeviceManagerSUT(DeviceManager):
self._sock = None
self.getDeviceRoot()
def cmdNeedsResponse(self, cmd):
def _cmdNeedsResponse(self, cmd):
""" Not all commands need a response from the agent:
* if the cmd matches the pushRE then it is the first half of push
and therefore we want to wait until the second half before looking
@ -93,18 +104,44 @@ class DeviceManagerSUT(DeviceManager):
for c in noResponseCmds:
if (c.match(cmd)):
return False
# If the command is not in our list, then it gets a response
return True
def shouldCmdCloseSocket(self, cmd):
def _stripPrompt(self, data):
'''
internal function
take a data blob and strip instances of the prompt '$>\x00'
'''
promptre = re.compile(self.prompt_regex + '.*')
retVal = []
lines = data.split('\n')
for line in lines:
foundPrompt = False
try:
while (promptre.match(line)):
foundPrompt = True
pieces = line.split(self.prompt_sep)
index = pieces.index('$>')
pieces.pop(index)
line = self.prompt_sep.join(pieces)
except(ValueError):
pass
# we don't want to append lines that are blank after stripping the
# prompt (those are basically "prompts")
if not foundPrompt or line:
retVal.append(line)
return '\n'.join(retVal)
def _shouldCmdCloseSocket(self, cmd):
""" Some commands need to close the socket after they are sent:
* push
* rebt
* uninst
* quit
"""
socketClosingCmds = [re.compile('^push .*$'),
re.compile('^quit.*'),
re.compile('^rebt.*'),
@ -116,85 +153,86 @@ class DeviceManagerSUT(DeviceManager):
return False
# convenience function to enable checks for agent errors
def verifySendCMD(self, cmdline, newline = True):
return self.sendCMD(cmdline, newline, False)
#
# create a wrapper for sendCMD that loops up to self.retrylimit iterations.
# this allows us to move the retry logic outside of the _doCMD() to make it
# easier for debugging in the future.
# note that since cmdline is a list of commands, they will all be retried if
# one fails. this is necessary in particular for pushFile(), where we don't want
# to accidentally send extra data if a failure occurs during data transmission.
#
def sendCMD(self, cmdline, newline = True, ignoreAgentErrors = True):
def sendCmds(self, cmdlist, outputfile, timeout = None, newline = True):
'''
a wrapper for _doCmds that loops up to self.retrylimit iterations.
this allows us to move the retry logic outside of the _doCmds() to make it
easier for debugging in the future.
note that since cmdlist is a list of commands, they will all be retried if
one fails. this is necessary in particular for pushFile(), where we don't want
to accidentally send extra data if a failure occurs during data transmission.
'''
done = False
while (not done):
retVal = self._doCMD(cmdline, newline)
if (retVal is None):
while self.retries < self.retrylimit:
try:
self._doCmds(cmdlist, outputfile, timeout, newline)
return
except AgentError, err:
# re-raise error if it's fatal (i.e. the device got the command but
# couldn't execute it). retry otherwise
if err.fatal:
raise err
if self.debug >= 2:
print err
self.retries += 1
else:
self.retries = 0
if ignoreAgentErrors == False:
if (self.agentErrorRE.match(retVal)):
raise DMError("error on the agent executing '%s'" % cmdline)
return retVal
if (self.retries >= self.retrylimit):
done = True
raise AgentError("unable to connect to %s after %s attempts" % (self.host, self.retrylimit))
raise DMError("unable to connect to %s after %s attempts" % (self.host, self.retrylimit))
def runCmds(self, cmdlist, timeout = None, newline = True):
'''
similar to sendCmds, but just returns any output as a string instead of
writing to a file. this is normally what you want to call to send a set
of commands to the agent
'''
outputfile = StringIO.StringIO()
self.sendCmds(cmdlist, outputfile, timeout, newline)
outputfile.seek(0)
return outputfile.read()
def _doCMD(self, cmdline, newline = True):
def _doCmds(self, cmdlist, outputfile, timeout, newline):
promptre = re.compile(self.prompt_regex + '$')
data = ""
shouldCloseSocket = False
recvGuard = 1000
if (self._sock == None):
if not self._sock:
try:
if (self.debug >= 1):
if self.debug >= 1:
print "reconnecting socket"
self._sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except:
self._sock = None
if (self.debug >= 2):
print "unable to create socket"
return None
raise AgentError("unable to create socket")
try:
self._sock.connect((self.host, int(self.port)))
self._sock.recv(1024)
except:
self._sock.close()
self._sock = None
if (self.debug >= 2):
print "unable to connect socket"
return None
for cmd in cmdline:
raise AgentError("unable to connect socket")
for cmd in cmdlist:
if newline: cmd += '\r\n'
try:
numbytes = self._sock.send(cmd)
if (numbytes != len(cmd)):
print "ERROR: our cmd was " + str(len(cmd)) + " bytes and we only sent " + str(numbytes)
return None
raise AgentError("ERROR: our cmd was %s bytes and we only sent %s" % (len(cmd),
numbytes))
if (self.debug >= 4): print "send cmd: " + str(cmd)
except:
self._sock.close()
self._sock = None
return None
return False
# Check if the command should close the socket
shouldCloseSocket = self.shouldCmdCloseSocket(cmd)
shouldCloseSocket = self._shouldCmdCloseSocket(cmd)
# Handle responses from commands
if (self.cmdNeedsResponse(cmd)):
if (self._cmdNeedsResponse(cmd)):
found = False
loopguard = 0
data = ""
while (found == False and (loopguard < recvGuard)):
temp = ''
@ -207,14 +245,14 @@ class DeviceManagerSUT(DeviceManager):
except:
self._sock.close()
self._sock = None
return None
raise AgentError("Error receiving data from socket")
data += temp
# If something goes wrong in the agent it will send back a string that
# starts with '##AGENT-ERROR##'
if self.agentErrorRE.match(data):
break
raise AgentError("Agent Error processing command: %s" % cmd, fatal=True)
for line in data.splitlines():
if promptre.match(line):
@ -222,40 +260,54 @@ class DeviceManagerSUT(DeviceManager):
data = self._stripPrompt(data)
break
# periodically flush data to output file to make sure it doesn't get
# too big/unwieldly
if len(data) > 1024:
outputfile.write(data[0:1024])
data = data[1024:]
# If we violently lose the connection to the device, this loop tends to spin,
# this guard prevents that
if (temp == ''):
loopguard += 1
if (shouldCloseSocket == True):
# Write any remaining data to outputfile
outputfile.write(data)
if shouldCloseSocket:
try:
self._sock.close()
self._sock = None
except:
self._sock = None
return None
raise AgentError("Error closing socket")
return data
# internal function
# take a data blob and strip instances of the prompt '$>\x00'
def _stripPrompt(self, data):
promptre = re.compile(self.prompt_regex + '.*')
retVal = []
lines = data.split('\n')
for line in lines:
try:
while (promptre.match(line)):
pieces = line.split(self.prompt_sep)
index = pieces.index('$>')
pieces.pop(index)
line = self.prompt_sep.join(pieces)
except(ValueError):
pass
retVal.append(line)
# external function: executes shell command on device
# returns:
# success: <return code>
# failure: None
def shell(self, cmd, outputfile, env=None, cwd=None):
cmdline = subprocess.list2cmdline(cmd)
if env:
cmdline = '%s %s' % (self.formatEnvString(env), cmdline)
return '\n'.join(retVal)
try:
if cwd:
self.sendCmds(['execcwd %s %s' % (cwd, cmdline)], outputfile)
else:
self.sendCmds(['exec %s' % cmdline], outputfile)
except AgentError:
return None
# dig through the output to get the return code
lastline = _pop_last_line(outputfile)
if lastline:
m = re.search('return code \[([0-9]+)\]', lastline)
if m:
return m.group(1)
# woops, we couldn't find an end of line/return value
return None
# external function
# returns:
@ -286,8 +338,8 @@ class DeviceManagerSUT(DeviceManager):
f.close()
try:
retVal = self.verifySendCMD(['push ' + destname + ' ' + str(filesize) + '\r\n', data], newline = False)
except(DMError):
retVal = self.runCmds(['push ' + destname + ' ' + str(filesize) + '\r\n', data], newline = False)
except AgentError:
retVal = False
if (self.debug >= 3): print "push returned: " + str(retVal)
@ -323,8 +375,8 @@ class DeviceManagerSUT(DeviceManager):
return name
else:
try:
retVal = self.verifySendCMD(['mkdr ' + name])
except(DMError):
retVal = self.runCmds(['mkdr ' + name])
except AgentError:
retVal = None
return retVal
@ -376,8 +428,8 @@ class DeviceManagerSUT(DeviceManager):
match = ".*" + dirname + "$"
dirre = re.compile(match)
try:
data = self.verifySendCMD(['cd ' + dirname, 'cwd'])
except(DMError):
data = self.runCmds(['cd ' + dirname, 'cwd'])
except AgentError:
return False
found = False
@ -412,8 +464,8 @@ class DeviceManagerSUT(DeviceManager):
if (self.dirExists(rootdir) == False):
return []
try:
data = self.verifySendCMD(['cd ' + rootdir, 'ls'])
except(DMError):
data = self.runCmds(['cd ' + rootdir, 'ls'])
except AgentError:
return []
files = filter(lambda x: x, data.splitlines())
@ -429,8 +481,8 @@ class DeviceManagerSUT(DeviceManager):
def removeFile(self, filename):
if (self.debug>= 2): print "removing file: " + filename
try:
retVal = self.verifySendCMD(['rm ' + filename])
except(DMError):
retVal = self.runCmds(['rm ' + filename])
except AgentError:
return None
return retVal
@ -442,8 +494,8 @@ class DeviceManagerSUT(DeviceManager):
# failure: None
def removeDir(self, remoteDir):
try:
retVal = self.verifySendCMD(['rmdr ' + remoteDir])
except(DMError):
retVal = self.runCmds(['rmdr ' + remoteDir])
except AgentError:
return None
return retVal
@ -454,8 +506,8 @@ class DeviceManagerSUT(DeviceManager):
# failure: []
def getProcessList(self):
try:
data = self.verifySendCMD(['ps'])
except DMError:
data = self.runCmds(['ps'])
except AgentError:
return []
files = []
@ -470,6 +522,7 @@ class DeviceManagerSUT(DeviceManager):
return files
# external function
# DEPRECATED: Use shell() or launchApplication() for new code
# returns:
# success: pid
# failure: None
@ -486,8 +539,8 @@ class DeviceManagerSUT(DeviceManager):
return None
try:
data = self.verifySendCMD(['exec ' + appname])
except(DMError):
data = self.runCmds(['exec ' + appname])
except AgentError:
return None
# wait up to 30 seconds for process to start up
@ -503,6 +556,7 @@ class DeviceManagerSUT(DeviceManager):
return process
# external function
# DEPRECATED: Use shell() or launchApplication() for new code
# returns:
# success: output filename
# failure: None
@ -532,8 +586,8 @@ class DeviceManagerSUT(DeviceManager):
# failure: None
def killProcess(self, appname):
try:
data = self.verifySendCMD(['kill ' + appname])
except(DMError):
data = self.runCmds(['kill ' + appname])
except AgentError:
return None
return data
@ -544,8 +598,8 @@ class DeviceManagerSUT(DeviceManager):
# failure: None
def getTempDir(self):
try:
data = self.verifySendCMD(['tmpd'])
except(DMError):
data = self.runCmds(['tmpd'])
except AgentError:
return None
return data.strip()
@ -556,12 +610,12 @@ class DeviceManagerSUT(DeviceManager):
# failure: None
def catFile(self, remoteFile):
try:
data = self.verifySendCMD(['cat ' + remoteFile])
except(DMError):
data = self.runCmds(['cat ' + remoteFile])
except AgentError:
return None
return data
# external function
# returns:
# success: output of pullfile, string
@ -625,8 +679,8 @@ class DeviceManagerSUT(DeviceManager):
# or, if error,
# <filename>,-1\n<error message>
try:
data = self.verifySendCMD(['pull ' + remoteFile])
except(DMError):
data = self.runCmds(['pull ' + remoteFile])
except AgentError:
return None
# read metadata; buffer the rest
@ -744,8 +798,8 @@ class DeviceManagerSUT(DeviceManager):
# Throws a FileError exception when null (invalid dir/filename)
def isDir(self, remotePath):
try:
data = self.verifySendCMD(['isdir ' + remotePath])
except(DMError):
data = self.runCmds(['isdir ' + remotePath])
except AgentError:
# normally there should be no error here; a nonexistent file/directory will
# return the string "<filename>: No such file or directory".
# However, I've seen AGENT-WARNING returned before.
@ -780,8 +834,8 @@ class DeviceManagerSUT(DeviceManager):
# failure: None
def getRemoteHash(self, filename):
try:
data = self.verifySendCMD(['hash ' + filename])
except(DMError):
data = self.runCmds(['hash ' + filename])
except AgentError:
return None
retVal = None
@ -809,7 +863,7 @@ class DeviceManagerSUT(DeviceManager):
# failure: None
def getDeviceRoot(self):
try:
data = self.verifySendCMD(['testroot'])
data = self.runCmds(['testroot'])
except:
return None
@ -823,7 +877,7 @@ class DeviceManagerSUT(DeviceManager):
def getAppRoot(self, packageName):
try:
data = self.verifySendCMD(['getapproot '+packageName])
data = self.runCmds(['getapproot '+packageName])
except:
return None
@ -851,8 +905,8 @@ class DeviceManagerSUT(DeviceManager):
return None
try:
data = self.verifySendCMD(['cd ' + dir, 'unzp ' + filename])
except(DMError):
data = self.runCmds(['cd ' + dir, 'unzp ' + filename])
except AgentError:
return None
return data
@ -872,8 +926,8 @@ class DeviceManagerSUT(DeviceManager):
try:
destname = '/data/data/com.mozilla.SUTAgentAndroid/files/update.info'
data = "%s,%s\rrebooting\r" % (ipAddr, port)
self.verifySendCMD(['push ' + destname + ' ' + str(len(data)) + '\r\n', data], newline = False)
except(DMError):
self.runCmds(['push ' + destname + ' ' + str(len(data)) + '\r\n', data], newline = False)
except AgentError:
return None
ip, port = self.getCallbackIpAndPort(ipAddr, port)
@ -882,8 +936,8 @@ class DeviceManagerSUT(DeviceManager):
callbacksvr = callbackServer(ip, port, self.debug)
try:
status = self.verifySendCMD([cmd])
except(DMError):
status = self.runCmds([cmd])
except AgentError:
return None
if (ipAddr is not None):
@ -918,7 +972,7 @@ class DeviceManagerSUT(DeviceManager):
directives = [directive]
for d in directives:
data = self.verifySendCMD(['info ' + d])
data = self.runCmds(['info ' + d])
if (data is None):
continue
data = collapseSpaces.sub(' ', data)
@ -955,8 +1009,8 @@ class DeviceManagerSUT(DeviceManager):
if destPath:
cmd += ' ' + destPath
try:
data = self.verifySendCMD([cmd])
except(DMError):
data = self.runCmds([cmd])
except AgentError:
return None
f = re.compile('Failure')
@ -981,8 +1035,8 @@ class DeviceManagerSUT(DeviceManager):
if installPath:
cmd += ' ' + installPath
try:
data = self.verifySendCMD([cmd])
except(DMError):
data = self.runCmds([cmd])
except AgentError:
return None
if (self.debug > 3): print "uninstallAppAndReboot: " + str(data)
@ -1026,8 +1080,8 @@ class DeviceManagerSUT(DeviceManager):
if (self.debug >= 3): print "INFO: updateApp using command: " + str(cmd)
try:
status = self.verifySendCMD([cmd])
except(DMError):
status = self.runCmds([cmd])
except AgentError:
return None
if ipAddr is not None:
@ -1046,8 +1100,8 @@ class DeviceManagerSUT(DeviceManager):
# failure: None
def getCurrentTime(self):
try:
data = self.verifySendCMD(['clok'])
except(DMError):
data = self.runCmds(['clok'])
except AgentError:
return None
return data.strip()
@ -1079,8 +1133,8 @@ class DeviceManagerSUT(DeviceManager):
return None
try:
data = self.verifySendCMD(['cd ' + dir, 'unzp ' + filename])
except(DMError):
data = self.runCmds(['cd ' + dir, 'unzp ' + filename])
except AgentError:
return None
return data
@ -1150,9 +1204,9 @@ class DeviceManagerSUT(DeviceManager):
if (self.debug >= 3): print "INFO: adjusting screen resolution to %s, %s and rebooting" % (width, height)
try:
self.verifySendCMD(["exec setprop persist.tegra.dpy%s.mode.width %s" % (screentype, width)])
self.verifySendCMD(["exec setprop persist.tegra.dpy%s.mode.height %s" % (screentype, height)])
except(DMError):
self.runCmds(["exec setprop persist.tegra.dpy%s.mode.width %s" % (screentype, width)])
self.runCmds(["exec setprop persist.tegra.dpy%s.mode.height %s" % (screentype, height)])
except AgentError:
return False
return True

87
build/mobile/droid.py Normal file
View File

@ -0,0 +1,87 @@
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is Test Automation Framework.
#
# The Initial Developer of the Original Code is
# Mozilla foundation
#
# Portions created by the Initial Developer are Copyright (C) 2009
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Joel Maher <joel.maher@gmail.com> (Original Developer)
# William Lachance <wlachance@mozilla.com>
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
from devicemanagerADB import DeviceManagerADB
from devicemanagerSUT import DeviceManagerSUT
class DroidMixin(object):
"""Mixin to extend DeviceManager with Android-specific functionality"""
def launchApplication(self, app, activity="App",
intent="android.intent.action.VIEW", env=None,
url=None, extra_args=None):
"""
Launches an Android application
returns:
success: True
failure: False
"""
# only one instance of an application may be running at once
if self.processExist(app):
return False
acmd = [ "am", "start", "-a", intent, "-W", "-n", "%s/.%s" % (app, activity)]
if extra_args:
acmd.extend(["--es", "args", " ".join(args)])
if env:
envCnt = 0
# env is expected to be a dict of environment variables
for envkey, envval in env.iteritems():
acmd.extend(["--es", "env" + str(envCnt), envkey + "=" + envval])
envCnt += 1
if url:
acmd.extend(["-d", ''.join(['"', url, '"'])])
# shell output not that interesting and debugging logs should already
# show what's going on here... so just create an empty memory buffer
# and ignore
shellOutput = StringIO.StringIO()
if self.shell(acmd, shellOutput) == 0:
return True
return False
class DroidADB(DeviceManagerADB, DroidMixin):
pass
class DroidSUT(DeviceManagerSUT, DroidMixin):
pass

View File

@ -136,12 +136,13 @@ public class DoCommand {
String ffxProvider = "org.mozilla.ffxcp";
String fenProvider = "org.mozilla.fencp";
private final String prgVersion = "SUTAgentAndroid Version 1.05";
private final String prgVersion = "SUTAgentAndroid Version 1.06";
public enum Command
{
RUN ("run"),
EXEC ("exec"),
EXECCWD ("execcwd"),
ENVRUN ("envrun"),
KILL ("kill"),
PS ("ps"),
@ -692,7 +693,25 @@ public class DoCommand {
theArgs[lcv - 1] = Argv[lcv];
}
strReturn = StartPrg2(theArgs, cmdOut);
strReturn = StartPrg2(theArgs, cmdOut, null);
}
else
{
strReturn = sErrorPrefix + "Wrong number of arguments for " + Argv[0] + " command!";
}
break;
case EXECCWD:
if (Argc >= 3)
{
String [] theArgs = new String [Argc - 2];
for (int lcv = 2; lcv < Argc; lcv++)
{
theArgs[lcv - 2] = Argv[lcv];
}
strReturn = StartPrg2(theArgs, cmdOut, Argv[1]);
}
else
{
@ -1262,6 +1281,11 @@ private void CancelNotification()
{
String sRet = null;
File tmpFile = new java.io.File("/data/local/tests");
if (tmpFile.exists() && tmpFile.isDirectory())
{
return("/data/local");
}
if (Environment.getExternalStorageState().equalsIgnoreCase(Environment.MEDIA_MOUNTED))
{
sRet = Environment.getExternalStorageDirectory().getAbsolutePath();
@ -3463,7 +3487,7 @@ private void CancelNotification()
return (sRet);
}
public String StartPrg2(String [] progArray, OutputStream out)
public String StartPrg2(String [] progArray, OutputStream out, String cwd)
{
String sRet = "";
@ -3553,7 +3577,15 @@ private void CancelNotification()
if (theArgs[0].contains("/") || theArgs[0].contains("\\") || !theArgs[0].contains("."))
{
pProc = Runtime.getRuntime().exec(theArgs, envArray);
if (cwd != null)
{
File f = new File(cwd);
pProc = Runtime.getRuntime().exec(theArgs, envArray, f);
}
else
{
pProc = Runtime.getRuntime().exec(theArgs, envArray);
}
RedirOutputThread outThrd = new RedirOutputThread(pProc, out);
outThrd.start();

View File

@ -52,7 +52,7 @@ interface nsIContentSecurityPolicy;
[ptr] native JSContext(JSContext);
[ptr] native JSPrincipals(JSPrincipals);
[scriptable, uuid(B406A2DB-E547-4C95-B8E2-AD09ECB54CE0)]
[scriptable, uuid(1f83b0e0-6b63-4bdc-a50a-b9afe256bd25)]
interface nsIPrincipal : nsISerializable
{
/**
@ -206,6 +206,12 @@ interface nsIPrincipal : nsISerializable
*/
boolean subsumes(in nsIPrincipal other);
/**
* Same as the previous method, subsumes(), but for codebase principals
* ignores changes to document.domain.
*/
boolean subsumesIgnoringDomain(in nsIPrincipal other);
/**
* Checks whether this principal is allowed to load the network resource
* located at the given URI under the same-origin policy. This means that

View File

@ -336,6 +336,12 @@ nsNullPrincipal::Subsumes(nsIPrincipal *aOther, bool *aResult)
return NS_OK;
}
NS_IMETHODIMP
nsNullPrincipal::SubsumesIgnoringDomain(nsIPrincipal *aOther, bool *aResult)
{
return Subsumes(aOther, aResult);
}
NS_IMETHODIMP
nsNullPrincipal::CheckMayLoad(nsIURI* aURI, bool aReport)
{

View File

@ -377,6 +377,12 @@ nsPrincipal::Subsumes(nsIPrincipal *aOther, bool *aResult)
return Equals(aOther, aResult);
}
NS_IMETHODIMP
nsPrincipal::SubsumesIgnoringDomain(nsIPrincipal *aOther, bool *aResult)
{
return EqualsIgnoringDomain(aOther, aResult);
}
static bool
URIIsLocalFile(nsIURI *aURI)
{

View File

@ -125,6 +125,13 @@ nsSystemPrincipal::Subsumes(nsIPrincipal *other, bool *result)
return NS_OK;
}
NS_IMETHODIMP
nsSystemPrincipal::SubsumesIgnoringDomain(nsIPrincipal *other, bool *result)
{
*result = true;
return NS_OK;
}
NS_IMETHODIMP
nsSystemPrincipal::CheckMayLoad(nsIURI* uri, bool aReport)
{

View File

@ -697,6 +697,8 @@ JS_SHARED_LIBRARY = @JS_SHARED_LIBRARY@
MOZ_INSTRUMENT_EVENT_LOOP = @MOZ_INSTRUMENT_EVENT_LOOP@
MOZ_SYSTEM_PLY = @MOZ_SYSTEM_PLY@
# We only want to do the pymake sanity on Windows, other os's can cope
ifeq ($(HOST_OS_ARCH),WINNT)
# Ensure invariants between GNU Make and pymake

View File

@ -1049,6 +1049,16 @@ if test -z "$PYTHON"; then
AC_MSG_ERROR([python was not found in \$PATH])
fi
MOZ_ARG_WITH_BOOL(system-ply,
[ --with-system-ply Use system installed python ply library],
[if $PYTHON -c 'import ply' 2>&5; then
MOZ_SYSTEM_PLY=1
else
AC_MSG_ERROR([python ply library is not found but --with-system-ply was requested])
fi])
AC_SUBST(MOZ_SYSTEM_PLY)
if test -z "$COMPILE_ENVIRONMENT"; then
NSINSTALL_BIN='$(PYTHON) $(topsrcdir)/config/nsinstall.py'
fi
@ -3718,20 +3728,23 @@ AC_CHECK_FUNCS(random strerror lchown fchmod snprintf statvfs memmove rint stat6
AC_CHECK_FUNCS(flockfile getpagesize)
AC_CHECK_FUNCS(localtime_r strtok_r)
dnl check for clock_gettime(), the CLOCK_MONOTONIC clock, and -lrt
_SAVE_LDFLAGS=$LDFLAGS
LDFLAGS="$LDFLAGS -lrt"
AC_CACHE_CHECK(for clock_gettime(CLOCK_MONOTONIC) and -lrt,
ac_cv_have_clock_monotonic,
[AC_TRY_LINK([#include <time.h>],
[ struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts); ],
ac_cv_have_clock_monotonic=yes,
ac_cv_have_clock_monotonic=no)])
LDFLAGS=$_SAVE_LDFLAGS
if test "$ac_cv_have_clock_monotonic" = "yes"; then
dnl check for clock_gettime(), the CLOCK_MONOTONIC clock
AC_CACHE_CHECK(for clock_gettime(CLOCK_MONOTONIC),
ac_cv_clock_monotonic,
[for libs in "" -lrt; do
_SAVE_LDFLAGS="$LDFLAGS"
LDFLAGS="$LDFLAGS $libs"
AC_TRY_LINK([#include <time.h>],
[ struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts); ],
ac_cv_clock_monotonic=$libs
break,
ac_cv_clock_monotonic=no)
LDFLAGS="$_SAVE_LDFLAGS"
done])
if test "$ac_cv_clock_monotonic" != "no"; then
HAVE_CLOCK_MONOTONIC=1
REALTIME_LIBS=-lrt
REALTIME_LIBS=$ac_cv_clock_monotonic
AC_DEFINE(HAVE_CLOCK_MONOTONIC)
AC_SUBST(HAVE_CLOCK_MONOTONIC)
AC_SUBST(REALTIME_LIBS)

View File

@ -480,10 +480,14 @@ nsDOMAttribute::Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const
}
NS_IMETHODIMP
nsDOMAttribute::CloneNode(bool aDeep, nsIDOMNode** aResult)
nsDOMAttribute::CloneNode(bool aDeep, PRUint8 aOptionalArgc, nsIDOMNode** aResult)
{
OwnerDoc()->WarnOnceAbout(nsIDocument::eCloneNode);
if (!aOptionalArgc) {
aDeep = true;
}
return nsNodeUtils::CloneNodeImpl(this, aDeep, true, aResult);
}

View File

@ -5830,8 +5830,12 @@ nsDocument::AppendChild(nsIDOMNode* aNewChild, nsIDOMNode** aReturn)
}
NS_IMETHODIMP
nsDocument::CloneNode(bool aDeep, nsIDOMNode** aReturn)
nsDocument::CloneNode(bool aDeep, PRUint8 aOptionalArgc, nsIDOMNode** aReturn)
{
if (!aOptionalArgc) {
aDeep = true;
}
return nsNodeUtils::CloneNodeImpl(this, aDeep, !mCreatingStaticClone, aReturn);
}
@ -8062,7 +8066,7 @@ nsIDocument::CreateStaticClone(nsISupports* aCloneContainer)
nsCOMPtr<nsISupports> originalContainer = GetContainer();
SetContainer(aCloneContainer);
nsCOMPtr<nsIDOMNode> clonedNode;
nsresult rv = domDoc->CloneNode(true, getter_AddRefs(clonedNode));
nsresult rv = domDoc->CloneNode(true, 1, getter_AddRefs(clonedNode));
SetContainer(originalContainer);
nsCOMPtr<nsIDocument> clonedDoc;

View File

@ -143,8 +143,12 @@ public:
nsresult IsSupported(const nsAString& aFeature,
const nsAString& aVersion,
bool* aReturn);
nsresult CloneNode(bool aDeep, nsIDOMNode** aReturn)
nsresult CloneNode(bool aDeep, PRUint8 aOptionalArgc, nsIDOMNode** aReturn)
{
if (!aOptionalArgc) {
aDeep = true;
}
return nsNodeUtils::CloneNodeImpl(this, aDeep, true, aReturn);
}

View File

@ -437,8 +437,12 @@ public:
// nsIDOMElement method implementation
NS_DECL_NSIDOMELEMENT
nsresult CloneNode(bool aDeep, nsIDOMNode **aResult)
nsresult CloneNode(bool aDeep, PRUint8 aOptionalArgc, nsIDOMNode **aResult)
{
if (!aOptionalArgc) {
aDeep = true;
}
return nsNodeUtils::CloneNodeImpl(this, aDeep, true, aResult);
}

View File

@ -1596,7 +1596,7 @@ nsresult nsRange::CutContents(nsIDOMDocumentFragment** aFragment)
cutValue);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDOMNode> clone;
rv = charData->CloneNode(false, getter_AddRefs(clone));
rv = charData->CloneNode(false, 1, getter_AddRefs(clone));
NS_ENSURE_SUCCESS(rv, rv);
clone->SetNodeValue(cutValue);
nodeToResult = clone;
@ -1656,7 +1656,7 @@ nsresult nsRange::CutContents(nsIDOMDocumentFragment** aFragment)
{
if (retval) {
nsCOMPtr<nsIDOMNode> clone;
rv = node->CloneNode(false, getter_AddRefs(clone));
rv = node->CloneNode(false, 1, getter_AddRefs(clone));
NS_ENSURE_SUCCESS(rv, rv);
nodeToResult = clone;
}
@ -1827,7 +1827,7 @@ nsRange::CloneParentsBetween(nsIDOMNode *aAncestor,
{
nsCOMPtr<nsIDOMNode> clone, tmpNode;
res = parent->CloneNode(false, getter_AddRefs(clone));
res = parent->CloneNode(false, 1, getter_AddRefs(clone));
if (NS_FAILED(res)) return res;
if (!clone) return NS_ERROR_FAILURE;
@ -1928,7 +1928,7 @@ nsRange::CloneContents(nsIDOMDocumentFragment** aReturn)
// Clone the current subtree!
nsCOMPtr<nsIDOMNode> clone;
res = node->CloneNode(deepClone, getter_AddRefs(clone));
res = node->CloneNode(deepClone, 1, getter_AddRefs(clone));
if (NS_FAILED(res)) return res;
// If it's CharacterData, make sure we only clone what

View File

@ -555,6 +555,7 @@ _TEST_FILES2 = \
file_bug717511_2.html \
file_bug717511_2.html^headers^ \
test_bug726364.html \
test_bug698381.html \
$(NULL)
_CHROME_FILES = \

View File

@ -0,0 +1,56 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=698381
-->
<head>
<title>Test for Bug 698381</title>
<script type="text/javascript"
src="/tests/SimpleTest/SimpleTest.js"></script>
<script src="/tests/SimpleTest/EventUtils.js"
type="text/javascript"></script>
<link rel="stylesheet" type="text/css"
href="/tests/SimpleTest/test.css" />
</head>
<body onload="runTests();">
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=698381">
Mozilla Bug 698381</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<div id="noChildren" style="display: none"></div>
<div id="hasChildren" style="display: none">
<div id="childOne" style="display: none"></div>
</div>
<pre id="test">
<script type="text/javascript">
/*
Checks to see if default parameter handling is correct when 0
parameters are passed.
If none are passed, then Node.cloneNode should default aDeep
to true.
*/
SimpleTest.waitForExplicitFinish();
var hasChildren = document.getElementById("hasChildren"),
noChildren = document.getElementById("noChildren"),
clonedNode;
function runTests() {
// Test Node.cloneNode when no arguments are given
clonedNode = hasChildren.cloneNode();
is(clonedNode.hasChildNodes(), true, "Node.cloneNode with true " +
"default on a node with children clones the child nodes.");
clonedNode = noChildren.cloneNode();
is(clonedNode.hasChildNodes(), false, "Node.cloneNode with true " +
"default on a node without children doesn't clone child nodes." );
SimpleTest.finish();
}
</script>
</pre>
</body>
</html>

View File

@ -71,6 +71,7 @@ CPPSRCS += \
WebGLContextReporter.cpp \
WebGLContextValidate.cpp \
WebGLExtensionStandardDerivatives.cpp \
WebGLExtensionTextureFilterAnisotropic.cpp \
WebGLExtensionLoseContext.cpp \
$(NULL)

View File

@ -820,7 +820,6 @@ bool WebGLContext::IsExtensionSupported(WebGLExtensionID ei)
switch (ei) {
case WebGL_OES_texture_float:
MakeContextCurrent();
isSupported = gl->IsExtensionSupported(gl->IsGLES2() ? GLContext::OES_texture_float
: GLContext::ARB_texture_float);
break;
@ -828,6 +827,9 @@ bool WebGLContext::IsExtensionSupported(WebGLExtensionID ei)
// We always support this extension.
isSupported = true;
break;
case WebGL_EXT_texture_filter_anisotropic:
isSupported = gl->IsExtensionSupported(GLContext::EXT_texture_filter_anisotropic);
break;
case WebGL_MOZ_WEBGL_lose_context:
// We always support this extension.
isSupported = true;
@ -860,6 +862,10 @@ WebGLContext::GetExtension(const nsAString& aName, nsIWebGLExtension **retval)
if (IsExtensionSupported(WebGL_OES_standard_derivatives))
ei = WebGL_OES_standard_derivatives;
}
else if (aName.EqualsLiteral("MOZ_EXT_texture_filter_anisotropic")) {
if (IsExtensionSupported(WebGL_EXT_texture_filter_anisotropic))
ei = WebGL_EXT_texture_filter_anisotropic;
}
else if (aName.EqualsLiteral("MOZ_WEBGL_lose_context")) {
if (IsExtensionSupported(WebGL_MOZ_WEBGL_lose_context))
ei = WebGL_MOZ_WEBGL_lose_context;
@ -871,6 +877,9 @@ WebGLContext::GetExtension(const nsAString& aName, nsIWebGLExtension **retval)
case WebGL_OES_standard_derivatives:
mEnabledExtensions[ei] = new WebGLExtensionStandardDerivatives(this);
break;
case WebGL_EXT_texture_filter_anisotropic:
mEnabledExtensions[ei] = new WebGLExtensionTextureFilterAnisotropic(this);
break;
case WebGL_MOZ_WEBGL_lose_context:
mEnabledExtensions[ei] = new WebGLExtensionLoseContext(this);
break;
@ -1295,6 +1304,11 @@ NS_INTERFACE_MAP_BEGIN(WebGLExtensionStandardDerivatives)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(WebGLExtensionStandardDerivatives)
NS_INTERFACE_MAP_END_INHERITING(WebGLExtension)
NS_IMPL_ADDREF(WebGLExtensionTextureFilterAnisotropic)
NS_IMPL_RELEASE(WebGLExtensionTextureFilterAnisotropic)
DOMCI_DATA(WebGLExtensionTextureFilterAnisotropic, WebGLExtensionTextureFilterAnisotropic)
NS_IMPL_ADDREF(WebGLExtensionLoseContext)
NS_IMPL_RELEASE(WebGLExtensionLoseContext)
@ -1409,6 +1423,8 @@ WebGLContext::GetSupportedExtensions(nsIVariant **retval)
extList.InsertElementAt(extList.Length(), "OES_texture_float");
if (IsExtensionSupported(WebGL_OES_standard_derivatives))
extList.InsertElementAt(extList.Length(), "OES_standard_derivatives");
if (IsExtensionSupported(WebGL_EXT_texture_filter_anisotropic))
extList.InsertElementAt(extList.Length(), "MOZ_EXT_texture_filter_anisotropic");
if (IsExtensionSupported(WebGL_MOZ_WEBGL_lose_context))
extList.InsertElementAt(extList.Length(), "MOZ_WEBGL_lose_context");

View File

@ -745,6 +745,7 @@ protected:
enum WebGLExtensionID {
WebGL_OES_texture_float,
WebGL_OES_standard_derivatives,
WebGL_EXT_texture_filter_anisotropic,
WebGL_MOZ_WEBGL_lose_context,
WebGLExtensionID_Max
};

View File

@ -2210,6 +2210,15 @@ WebGLContext::GetParameter(PRUint32 pname, nsIVariant **retval)
break;
// float
case LOCAL_GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
if (mEnabledExtensions[WebGL_EXT_texture_filter_anisotropic]) {
GLfloat f = 0.f;
gl->fGetFloatv(pname, &f);
wrval->SetAsFloat(f);
} else {
return ErrorInvalidEnum("getParameter: parameter", pname);
}
break;
case LOCAL_GL_DEPTH_CLEAR_VALUE:
case LOCAL_GL_LINE_WIDTH:
case LOCAL_GL_POLYGON_OFFSET_FACTOR:
@ -2679,6 +2688,7 @@ nsresult WebGLContext::TexParameter_base(WebGLenum target, WebGLenum pname,
return ErrorInvalidOperation("texParameter: no texture is bound to this target");
bool pnameAndParamAreIncompatible = false;
bool paramValueInvalid = false;
switch (pname) {
case LOCAL_GL_TEXTURE_MIN_FILTER:
@ -2727,18 +2737,33 @@ nsresult WebGLContext::TexParameter_base(WebGLenum target, WebGLenum pname,
pnameAndParamAreIncompatible = true;
}
break;
case LOCAL_GL_TEXTURE_MAX_ANISOTROPY_EXT:
if (mEnabledExtensions[WebGL_EXT_texture_filter_anisotropic]) {
if (floatParamPtr && floatParam < 1.f)
paramValueInvalid = true;
else if (intParamPtr && intParam < 1)
paramValueInvalid = true;
}
else
pnameAndParamAreIncompatible = true;
break;
default:
return ErrorInvalidEnumInfo("texParameter: pname", pname);
}
if (pnameAndParamAreIncompatible) {
// note that currently all params are enums, and the tex-input-validation test wants INVALID_ENUM errors
// even for texParameterf. why not.
if (intParamPtr)
return ErrorInvalidEnum("texParameteri: pname %x and param %x (decimal %d) are mutually incompatible",
pname, intParam, intParam);
else
return ErrorInvalidEnum("texParameterf: pname %x and floating-point param %e are mutually incompatible",
return ErrorInvalidEnum("texParameterf: pname %x and param %g are mutually incompatible",
pname, floatParam);
} else if (paramValueInvalid) {
if (intParamPtr)
return ErrorInvalidValue("texParameteri: pname %x and param %x (decimal %d) is invalid",
pname, intParam, intParam);
else
return ErrorInvalidValue("texParameterf: pname %x and param %g is invalid",
pname, floatParam);
}
@ -2799,6 +2824,15 @@ WebGLContext::GetTexParameter(WebGLenum target, WebGLenum pname, nsIVariant **re
wrval->SetAsInt32(i);
}
break;
case LOCAL_GL_TEXTURE_MAX_ANISOTROPY_EXT:
if (mEnabledExtensions[WebGL_EXT_texture_filter_anisotropic]) {
GLfloat f = 0.f;
gl->fGetTexParameterfv(target, pname, &f);
wrval->SetAsFloat(f);
}
else
return ErrorInvalidEnumInfo("getTexParameter: parameter", pname);
break;
default:
return ErrorInvalidEnumInfo("getTexParameter: parameter", pname);

View File

@ -55,4 +55,5 @@ DOMCI_DATA(WebGLShaderPrecisionFormat, void)
DOMCI_DATA(WebGLActiveInfo, void)
DOMCI_DATA(WebGLExtension, void)
DOMCI_DATA(WebGLExtensionStandardDerivatives, void)
DOMCI_DATA(WebGLExtensionTextureFilterAnisotropic, void)
DOMCI_DATA(WebGLExtensionLoseContext, void)

View File

@ -0,0 +1,64 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Mozilla Corporation.
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Florian Boesch <pyalot@gmail.com> (original author)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include <stdarg.h>
#include "WebGLContext.h"
#include "WebGLExtensions.h"
#include "nsContentUtils.h"
#include "mozilla/Preferences.h"
using namespace mozilla;
NS_INTERFACE_MAP_BEGIN(WebGLExtensionTextureFilterAnisotropic)
NS_INTERFACE_MAP_ENTRY(nsIWebGLExtensionTextureFilterAnisotropic)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, WebGLExtension)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(WebGLExtensionTextureFilterAnisotropic)
NS_INTERFACE_MAP_END_INHERITING(WebGLExtension)
WebGLExtensionTextureFilterAnisotropic::WebGLExtensionTextureFilterAnisotropic(WebGLContext* context) :
WebGLExtension(context)
{
}
WebGLExtensionTextureFilterAnisotropic::~WebGLExtensionTextureFilterAnisotropic()
{
}

View File

@ -41,9 +41,6 @@
namespace mozilla {
class WebGLExtensionLoseContext;
class WebGLExtensionStandardDerivatives;
class WebGLExtensionLoseContext :
public nsIWebGLExtensionLoseContext,
public WebGLExtension
@ -68,6 +65,18 @@ public:
NS_DECL_NSIWEBGLEXTENSION
};
class WebGLExtensionTextureFilterAnisotropic :
public nsIWebGLExtensionTextureFilterAnisotropic,
public WebGLExtension
{
public:
WebGLExtensionTextureFilterAnisotropic(WebGLContext* context);
virtual ~WebGLExtensionTextureFilterAnisotropic();
NS_DECL_ISUPPORTS
NS_DECL_NSIWEBGLEXTENSION
};
}
#endif // WEBGLEXTENSIONS_H_

View File

@ -1,4 +1,5 @@
oes-standard-derivatives.html
ext-texture-filter-anisotropic.html
oes-texture-float.html
oes-vertex-array-object.html
webgl-debug-renderer-info.html

View File

@ -0,0 +1,157 @@
<!--
Copyright (c) 2012 Florian Boesch <pyalot@gmail.com>. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
-->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>WebGL EXT_texture_filter_anisotropic Conformance Tests</title>
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
<script src="../../resources/desktop-gl-constants.js" type="text/javascript"></script>
<script src="../../resources/js-test-pre.js"></script>
<script src="../resources/webgl-test.js"></script>
<script src="../resources/webgl-test-utils.js"></script>
</head>
<body>
<div id="description"></div>
<canvas id="canvas" style="width: 50px; height: 50px;"> </canvas>
<div id="console"></div>
<script>
description("This test verifies the functionality of the EXT_texture_filter_anisotropic extension, if it is available.");
debug("");
var wtu = WebGLTestUtils;
var canvas = document.getElementById("canvas");
var gl = create3DContext(canvas);
var ext = null;
if (!gl) {
testFailed("WebGL context does not exist");
} else {
testPassed("WebGL context exists");
// Run tests with extension disabled
runHintTestDisabled();
// Query the extension and store globally so shouldBe can access it
ext = gl.getExtension("MOZ_EXT_texture_filter_anisotropic");
if (!ext) {
testPassed("No EXT_texture_filter_anisotropic support -- this is legal");
runSupportedTest(false);
} else {
testPassed("Successfully enabled EXT_texture_filter_anisotropic extension");
runSupportedTest(true);
runHintTestEnabled();
}
}
function runSupportedTest(extensionEnabled) {
var supported = gl.getSupportedExtensions();
if (supported.indexOf("MOZ_EXT_texture_filter_anisotropic") >= 0) {
if (extensionEnabled) {
testPassed("EXT_texture_filter_anisotropic listed as supported and getExtension succeeded");
} else {
testFailed("EXT_texture_filter_anisotropic listed as supported but getExtension failed");
}
} else {
if (extensionEnabled) {
testFailed("EXT_texture_filter_anisotropic not listed as supported but getExtension succeeded");
} else {
testPassed("EXt_texture_filter_anisotropic not listed as supported and getExtension failed -- this is legal");
}
}
}
function runHintTestDisabled() {
debug("Testing MAX_TEXTURE_MAX_ANISOTROPY with extension disabled");
var MAX_TEXTURE_MAX_ANISOTROPY = 0x84FF;
gl.getParameter(MAX_TEXTURE_MAX_ANISOTROPY);
glErrorShouldBe(gl, gl.INVALID_ENUM, "MAX_TEXTURE_MAX_ANISOTROPY should not be queryable if extension is disabled");
debug("Testing TEXTURE_MAX_ANISOTROPY with extension disabled");
var TEXTURE_MAX_ANISOTROPY = 0x84FE;
var texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.getTexParameter(gl.TEXTURE_2D, TEXTURE_MAX_ANISOTROPY);
glErrorShouldBe(gl, gl.INVALID_ENUM, "TEXTURE_MAX_ANISOTROPY should not be queryable if extension is disabled");
gl.texParameterf(gl.TEXTURE_2D, TEXTURE_MAX_ANISOTROPY, 1);
glErrorShouldBe(gl, gl.INVALID_ENUM, "TEXTURE_MAX_ANISOTROPY should not be settable if extension is disabled");
gl.texParameteri(gl.TEXTURE_2D, TEXTURE_MAX_ANISOTROPY, 1);
glErrorShouldBe(gl, gl.INVALID_ENUM, "TEXTURE_MAX_ANISOTROPY should not be settable if extension is disabled");
gl.deleteTexture(texture);
}
function runHintTestEnabled() {
debug("Testing MAX_TEXTURE_MAX_ANISOTROPY with extension enabled");
shouldBe("ext.MAX_TEXTURE_MAX_ANISOTROPY", "0x84FF");
var max_anisotropy = gl.getParameter(ext.MAX_TEXTURE_MAX_ANISOTROPY);
glErrorShouldBe(gl, gl.NO_ERROR, "MAX_TEXTURE_MAX_ANISOTROPY query should succeed if extension is enabled");
if(max_anisotropy >= 2){
testPassed("Minimum value of MAX_TEXTURE_MAX_ANISOTROPY is 2.0");
}
else{
testFailed("Minimum value of MAX_TEXTURE_MAX_ANISOTROPY is 2.0, returned values was: " + max_anisotropy);
}
// TODO make a texture and verify initial value == 1 and setting to less than 1 is invalid value
debug("Testing TEXTURE_MAX_ANISOTROPY with extension disabled");
shouldBe("ext.TEXTURE_MAX_ANISOTROPY", "0x84FE");
var texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
var queried_value = gl.getTexParameter(gl.TEXTURE_2D, ext.TEXTURE_MAX_ANISOTROPY);
glErrorShouldBe(gl, gl.NO_ERROR, "TEXTURE_MAX_ANISOTROPY query should succeed if extension is enabled");
if(queried_value == 1){
testPassed("Initial value of TEXTURE_MAX_ANISOTROPY is 1.0");
}
else{
testFailed("Initial value of TEXTURE_MAX_ANISOTROPY should be 1.0, returned value was: " + queried_value);
}
gl.texParameterf(gl.TEXTURE_2D, ext.TEXTURE_MAX_ANISOTROPY, 0);
glErrorShouldBe(gl, gl.INVALID_VALUE, "texParameterf TEXTURE_MAX_ANISOTROPY set to < 1 should be an invalid value");
gl.texParameteri(gl.TEXTURE_2D, ext.TEXTURE_MAX_ANISOTROPY, 0);
glErrorShouldBe(gl, gl.INVALID_VALUE, "texParameteri TEXTURE_MAX_ANISOTROPY set to < 1 should be an invalid value");
gl.texParameterf(gl.TEXTURE_2D, ext.TEXTURE_MAX_ANISOTROPY, max_anisotropy);
glErrorShouldBe(gl, gl.NO_ERROR, "texParameterf TEXTURE_MAX_ANISOTROPY set to >= 2 should should succeed");
gl.texParameteri(gl.TEXTURE_2D, ext.TEXTURE_MAX_ANISOTROPY, max_anisotropy);
glErrorShouldBe(gl, gl.NO_ERROR, "texParameteri TEXTURE_MAX_ANISOTROPY set to >= 2 should should succeed");
var queried_value = gl.getTexParameter(gl.TEXTURE_2D, ext.TEXTURE_MAX_ANISOTROPY);
if(queried_value == max_anisotropy){
testPassed("Set value of TEXTURE_MAX_ANISOTROPY matches expecation");
}
else{
testFailed("Set value of TEXTURE_MAX_ANISOTROPY should be: " + max_anisotropy + " , returned value was: " + queried_value);
}
gl.deleteTexture(texture);
}
debug("");
successfullyParsed = true;
</script>
<script src="../../resources/js-test-post.js"></script>
</body>
</html>

View File

@ -0,0 +1,174 @@
diff --git a/content/canvas/test/webgl/conformance/extensions/00_test_list.txt b/content/canvas/test/webgl/conformance/extensions/00_test_list.txt
--- a/content/canvas/test/webgl/conformance/extensions/00_test_list.txt
+++ b/content/canvas/test/webgl/conformance/extensions/00_test_list.txt
@@ -1,7 +1,8 @@
oes-standard-derivatives.html
+ext-texture-filter-anisotropic.html
oes-texture-float.html
oes-vertex-array-object.html
webgl-debug-renderer-info.html
webgl-debug-shaders.html
--min-version 1.0.2 webgl-experimental-compressed-textures.html
diff --git a/content/canvas/test/webgl/conformance/extensions/ext-texture-filter-anisotropic.html b/content/canvas/test/webgl/conformance/extensions/ext-texture-filter-anisotropic.html
new file mode 100644
--- /dev/null
+++ b/content/canvas/test/webgl/conformance/extensions/ext-texture-filter-anisotropic.html
@@ -0,0 +1,157 @@
+<!--
+Copyright (c) 2012 Florian Boesch <pyalot@gmail.com>. All rights reserved.
+Use of this source code is governed by a BSD-style license that can be
+found in the LICENSE file.
+ -->
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL EXT_texture_filter_anisotropic Conformance Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../resources/desktop-gl-constants.js" type="text/javascript"></script>
+<script src="../../resources/js-test-pre.js"></script>
+<script src="../resources/webgl-test.js"></script>
+<script src="../resources/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<canvas id="canvas" style="width: 50px; height: 50px;"> </canvas>
+<div id="console"></div>
+
+<script>
+description("This test verifies the functionality of the EXT_texture_filter_anisotropic extension, if it is available.");
+
+debug("");
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+var gl = create3DContext(canvas);
+var ext = null;
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+
+ // Run tests with extension disabled
+ runHintTestDisabled();
+
+ // Query the extension and store globally so shouldBe can access it
+ ext = gl.getExtension("MOZ_EXT_texture_filter_anisotropic");
+ if (!ext) {
+ testPassed("No EXT_texture_filter_anisotropic support -- this is legal");
+
+ runSupportedTest(false);
+ } else {
+ testPassed("Successfully enabled EXT_texture_filter_anisotropic extension");
+
+ runSupportedTest(true);
+ runHintTestEnabled();
+ }
+}
+
+function runSupportedTest(extensionEnabled) {
+ var supported = gl.getSupportedExtensions();
+ if (supported.indexOf("MOZ_EXT_texture_filter_anisotropic") >= 0) {
+ if (extensionEnabled) {
+ testPassed("EXT_texture_filter_anisotropic listed as supported and getExtension succeeded");
+ } else {
+ testFailed("EXT_texture_filter_anisotropic listed as supported but getExtension failed");
+ }
+ } else {
+ if (extensionEnabled) {
+ testFailed("EXT_texture_filter_anisotropic not listed as supported but getExtension succeeded");
+ } else {
+ testPassed("EXt_texture_filter_anisotropic not listed as supported and getExtension failed -- this is legal");
+ }
+ }
+}
+
+function runHintTestDisabled() {
+ debug("Testing MAX_TEXTURE_MAX_ANISOTROPY with extension disabled");
+
+ var MAX_TEXTURE_MAX_ANISOTROPY = 0x84FF;
+ gl.getParameter(MAX_TEXTURE_MAX_ANISOTROPY);
+ glErrorShouldBe(gl, gl.INVALID_ENUM, "MAX_TEXTURE_MAX_ANISOTROPY should not be queryable if extension is disabled");
+
+ debug("Testing TEXTURE_MAX_ANISOTROPY with extension disabled");
+ var TEXTURE_MAX_ANISOTROPY = 0x84FE;
+ var texture = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+
+ gl.getTexParameter(gl.TEXTURE_2D, TEXTURE_MAX_ANISOTROPY);
+ glErrorShouldBe(gl, gl.INVALID_ENUM, "TEXTURE_MAX_ANISOTROPY should not be queryable if extension is disabled");
+
+ gl.texParameterf(gl.TEXTURE_2D, TEXTURE_MAX_ANISOTROPY, 1);
+ glErrorShouldBe(gl, gl.INVALID_ENUM, "TEXTURE_MAX_ANISOTROPY should not be settable if extension is disabled");
+
+ gl.texParameteri(gl.TEXTURE_2D, TEXTURE_MAX_ANISOTROPY, 1);
+ glErrorShouldBe(gl, gl.INVALID_ENUM, "TEXTURE_MAX_ANISOTROPY should not be settable if extension is disabled");
+
+ gl.deleteTexture(texture);
+}
+
+function runHintTestEnabled() {
+ debug("Testing MAX_TEXTURE_MAX_ANISOTROPY with extension enabled");
+
+ shouldBe("ext.MAX_TEXTURE_MAX_ANISOTROPY", "0x84FF");
+
+ var max_anisotropy = gl.getParameter(ext.MAX_TEXTURE_MAX_ANISOTROPY);
+ glErrorShouldBe(gl, gl.NO_ERROR, "MAX_TEXTURE_MAX_ANISOTROPY query should succeed if extension is enabled");
+
+ if(max_anisotropy >= 2){
+ testPassed("Minimum value of MAX_TEXTURE_MAX_ANISOTROPY is 2.0");
+ }
+ else{
+ testFailed("Minimum value of MAX_TEXTURE_MAX_ANISOTROPY is 2.0, returned values was: " + max_anisotropy);
+ }
+
+ // TODO make a texture and verify initial value == 1 and setting to less than 1 is invalid value
+
+ debug("Testing TEXTURE_MAX_ANISOTROPY with extension disabled");
+ shouldBe("ext.TEXTURE_MAX_ANISOTROPY", "0x84FE");
+
+ var texture = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+
+ var queried_value = gl.getTexParameter(gl.TEXTURE_2D, ext.TEXTURE_MAX_ANISOTROPY);
+ glErrorShouldBe(gl, gl.NO_ERROR, "TEXTURE_MAX_ANISOTROPY query should succeed if extension is enabled");
+
+ if(queried_value == 1){
+ testPassed("Initial value of TEXTURE_MAX_ANISOTROPY is 1.0");
+ }
+ else{
+ testFailed("Initial value of TEXTURE_MAX_ANISOTROPY should be 1.0, returned value was: " + queried_value);
+ }
+
+ gl.texParameterf(gl.TEXTURE_2D, ext.TEXTURE_MAX_ANISOTROPY, 0);
+ glErrorShouldBe(gl, gl.INVALID_VALUE, "texParameterf TEXTURE_MAX_ANISOTROPY set to < 1 should be an invalid value");
+
+ gl.texParameteri(gl.TEXTURE_2D, ext.TEXTURE_MAX_ANISOTROPY, 0);
+ glErrorShouldBe(gl, gl.INVALID_VALUE, "texParameteri TEXTURE_MAX_ANISOTROPY set to < 1 should be an invalid value");
+
+ gl.texParameterf(gl.TEXTURE_2D, ext.TEXTURE_MAX_ANISOTROPY, max_anisotropy);
+ glErrorShouldBe(gl, gl.NO_ERROR, "texParameterf TEXTURE_MAX_ANISOTROPY set to >= 2 should should succeed");
+
+ gl.texParameteri(gl.TEXTURE_2D, ext.TEXTURE_MAX_ANISOTROPY, max_anisotropy);
+ glErrorShouldBe(gl, gl.NO_ERROR, "texParameteri TEXTURE_MAX_ANISOTROPY set to >= 2 should should succeed");
+
+ var queried_value = gl.getTexParameter(gl.TEXTURE_2D, ext.TEXTURE_MAX_ANISOTROPY);
+ if(queried_value == max_anisotropy){
+ testPassed("Set value of TEXTURE_MAX_ANISOTROPY matches expecation");
+ }
+ else{
+ testFailed("Set value of TEXTURE_MAX_ANISOTROPY should be: " + max_anisotropy + " , returned value was: " + queried_value);
+ }
+
+ gl.deleteTexture(texture);
+}
+
+debug("");
+successfullyParsed = true;
+</script>
+<script src="../../resources/js-test-post.js"></script>
+
+</body>
+</html>

View File

@ -808,7 +808,7 @@ nsHTMLSelectElement::SetLength(PRUint32 aLength)
if (i + 1 < aLength) {
nsCOMPtr<nsIDOMNode> newNode;
rv = node->CloneNode(true, getter_AddRefs(newNode));
rv = node->CloneNode(true, 1, getter_AddRefs(newNode));
NS_ENSURE_SUCCESS(rv, rv);
node = newNode;

View File

@ -153,7 +153,7 @@ NS_IMETHODIMP nsXPathNamespace::HasChildNodes(bool *aResult)
}
/* nsIDOMNode cloneNode (in boolean deep); */
NS_IMETHODIMP nsXPathNamespace::CloneNode(bool deep, nsIDOMNode **aResult)
NS_IMETHODIMP nsXPathNamespace::CloneNode(bool deep, PRUint8 aOptionalArgc, nsIDOMNode **aResult)
{
return NS_ERROR_NOT_IMPLEMENTED;
}

View File

@ -677,7 +677,7 @@ nsXULContentBuilder::BuildContentFromTemplate(nsIContent *aTemplateNode,
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIDOMNode> clonedNode;
tmplTextNode->CloneNode(false, getter_AddRefs(clonedNode));
tmplTextNode->CloneNode(false, 1, getter_AddRefs(clonedNode));
nsCOMPtr<nsIContent> clonedContent = do_QueryInterface(clonedNode);
if (!clonedContent) {
NS_ERROR("failed to clone textnode");

View File

@ -2310,34 +2310,6 @@ nsDocShell::HistoryTransactionRemoved(PRInt32 aIndex)
return NS_OK;
}
static
nsresult
GetPrincipalDomain(nsIPrincipal* aPrincipal, nsACString& aDomain)
{
aDomain.Truncate();
nsCOMPtr<nsIURI> codebaseURI;
nsresult rv = aPrincipal->GetDomain(getter_AddRefs(codebaseURI));
NS_ENSURE_SUCCESS(rv, rv);
if (!codebaseURI) {
rv = aPrincipal->GetURI(getter_AddRefs(codebaseURI));
NS_ENSURE_SUCCESS(rv, rv);
}
if (!codebaseURI)
return NS_OK;
nsCOMPtr<nsIURI> innerURI = NS_GetInnermostURI(codebaseURI);
NS_ASSERTION(innerURI, "Failed to get innermost URI");
NS_ENSURE_SUCCESS(rv, rv);
rv = innerURI->GetAsciiHost(aDomain);
if (NS_FAILED(rv))
return rv;
return NS_OK;
}
NS_IMETHODIMP
nsDocShell::GetSessionStorageForPrincipal(nsIPrincipal* aPrincipal,
const nsAString& aDocumentURI,
@ -2367,15 +2339,15 @@ nsDocShell::GetSessionStorageForPrincipal(nsIPrincipal* aPrincipal,
aCreate,
aStorage);
nsCAutoString currentDomain;
rv = GetPrincipalDomain(aPrincipal, currentDomain);
nsXPIDLCString origin;
rv = aPrincipal->GetOrigin(getter_Copies(origin));
if (NS_FAILED(rv))
return rv;
if (currentDomain.IsEmpty())
if (origin.IsEmpty())
return NS_OK;
if (!mStorages.Get(currentDomain, aStorage) && aCreate) {
if (!mStorages.Get(origin, aStorage) && aCreate) {
nsCOMPtr<nsIDOMStorage> newstorage =
do_CreateInstance("@mozilla.org/dom/storage;2");
if (!newstorage)
@ -2384,11 +2356,12 @@ nsDocShell::GetSessionStorageForPrincipal(nsIPrincipal* aPrincipal,
nsCOMPtr<nsPIDOMStorage> pistorage = do_QueryInterface(newstorage);
if (!pistorage)
return NS_ERROR_FAILURE;
rv = pistorage->InitAsSessionStorage(aPrincipal, aDocumentURI);
if (NS_FAILED(rv))
return rv;
if (!mStorages.Put(currentDomain, newstorage))
if (!mStorages.Put(origin, newstorage))
return NS_ERROR_OUT_OF_MEMORY;
newstorage.swap(*aStorage);
@ -2399,22 +2372,32 @@ nsDocShell::GetSessionStorageForPrincipal(nsIPrincipal* aPrincipal,
#endif
}
else if (*aStorage) {
nsCOMPtr<nsPIDOMStorage> piStorage = do_QueryInterface(*aStorage);
if (piStorage) {
bool canAccess = piStorage->CanAccess(aPrincipal);
NS_ASSERTION(canAccess,
"GetSessionStorageForPrincipal got a storage "
"that could not be accessed!");
if (!canAccess) {
NS_RELEASE(*aStorage);
return NS_ERROR_DOM_SECURITY_ERR;
}
}
nsCOMPtr<nsPIDOMStorage> piStorage = do_QueryInterface(*aStorage);
if (piStorage) {
nsCOMPtr<nsIPrincipal> storagePrincipal = piStorage->Principal();
// The origin string used to map items in the hash table is
// an implicit security check. That check is double-confirmed
// by checking the principal a storage was demanded for
// really is the principal for which that storage was originally
// created. Originally, the check was hidden in the CanAccess
// method but it's implementation has changed.
bool equals;
nsresult rv = aPrincipal->EqualsIgnoringDomain(storagePrincipal, &equals);
NS_ASSERTION(NS_SUCCEEDED(rv) && equals,
"GetSessionStorageForPrincipal got a storage "
"that could not be accessed!");
if (NS_FAILED(rv) || !equals) {
NS_RELEASE(*aStorage);
return NS_ERROR_DOM_SECURITY_ERR;
}
}
#if defined(PR_LOGGING) && defined(DEBUG)
PR_LOG(gDocShellLog, PR_LOG_DEBUG,
("nsDocShell[%p]: returns existing sessionStorage %p",
this, *aStorage));
PR_LOG(gDocShellLog, PR_LOG_DEBUG,
("nsDocShell[%p]: returns existing sessionStorage %p",
this, *aStorage));
#endif
}
@ -2499,16 +2482,16 @@ nsDocShell::AddSessionStorage(nsIPrincipal* aPrincipal,
if (topItem) {
nsCOMPtr<nsIDocShell> topDocShell = do_QueryInterface(topItem);
if (topDocShell == this) {
nsCAutoString currentDomain;
rv = GetPrincipalDomain(aPrincipal, currentDomain);
nsXPIDLCString origin;
rv = aPrincipal->GetOrigin(getter_Copies(origin));
if (NS_FAILED(rv))
return rv;
if (currentDomain.IsEmpty())
if (origin.IsEmpty())
return NS_ERROR_FAILURE;
// Do not replace an existing session storage.
if (mStorages.GetWeak(currentDomain))
if (mStorages.GetWeak(origin))
return NS_ERROR_NOT_AVAILABLE;
#if defined(PR_LOGGING) && defined(DEBUG)
@ -2516,7 +2499,7 @@ nsDocShell::AddSessionStorage(nsIPrincipal* aPrincipal,
("nsDocShell[%p]: was added a sessionStorage %p",
this, aStorage));
#endif
if (!mStorages.Put(currentDomain, aStorage))
if (!mStorages.Put(origin, aStorage))
return NS_ERROR_OUT_OF_MEMORY;
}
else {

View File

@ -1543,6 +1543,8 @@ static nsDOMClassInfoData sClassInfoData[] = {
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(WebGLExtensionStandardDerivatives, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(WebGLExtensionTextureFilterAnisotropic, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(WebGLExtensionLoseContext, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
@ -4204,6 +4206,10 @@ nsDOMClassInfo::Init()
DOM_CLASSINFO_MAP_BEGIN(WebGLExtensionStandardDerivatives, nsIWebGLExtensionStandardDerivatives)
DOM_CLASSINFO_MAP_ENTRY(nsIWebGLExtensionStandardDerivatives)
DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN(WebGLExtensionTextureFilterAnisotropic, nsIWebGLExtensionTextureFilterAnisotropic)
DOM_CLASSINFO_MAP_ENTRY(nsIWebGLExtensionTextureFilterAnisotropic)
DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN(WebGLExtensionLoseContext, nsIWebGLExtensionLoseContext)
DOM_CLASSINFO_MAP_ENTRY(nsIWebGLExtensionLoseContext)

View File

@ -486,6 +486,7 @@ DOMCI_CLASS(WebGLShaderPrecisionFormat)
DOMCI_CLASS(WebGLActiveInfo)
DOMCI_CLASS(WebGLExtension)
DOMCI_CLASS(WebGLExtensionStandardDerivatives)
DOMCI_CLASS(WebGLExtensionTextureFilterAnisotropic)
DOMCI_CLASS(WebGLExtensionLoseContext)
DOMCI_CLASS(PaintRequest)

View File

@ -4,36 +4,160 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "BluetoothAdapter.h"
#include "nsDOMClassInfo.h"
#include "nsDOMEvent.h"
#include "nsThreadUtils.h"
#include "nsXPCOMCIDInternal.h"
#include "mozilla/LazyIdleThread.h"
#include "BluetoothAdapter.h"
#if defined(MOZ_WIDGET_GONK)
#include <bluedroid/bluetooth.h>
#endif
#define POWERED_EVENT_NAME NS_LITERAL_STRING("powered")
BEGIN_BLUETOOTH_NAMESPACE
class ToggleBtResultTask : public nsRunnable
{
public:
ToggleBtResultTask(bool result, nsRefPtr<BluetoothAdapter>& adapterPtr)
: mResult(result)
{
MOZ_ASSERT(!NS_IsMainThread()); // This should be running on the worker thread
mAdapterPtr.swap(adapterPtr);
}
NS_IMETHOD Run() {
MOZ_ASSERT(NS_IsMainThread()); // This method is supposed to run on the main thread!
mAdapterPtr->FirePowered();
return NS_OK;
}
private:
bool mResult;
nsRefPtr<BluetoothAdapter> mAdapterPtr;
};
class ToggleBtTask : public nsRunnable
{
public:
ToggleBtTask(bool onOff, BluetoothAdapter* adapterPtr)
: mOnOff(onOff),
mAdapterPtr(adapterPtr)
{
MOZ_ASSERT(NS_IsMainThread()); // The constructor should be running on the main thread.
}
NS_IMETHOD Run() {
bool result;
MOZ_ASSERT(!NS_IsMainThread()); // This should be running on the worker thread.
//Toggle BT here
#if defined(MOZ_WIDGET_GONK)
if (mOnOff) {
result = bt_enable();
} else {
result = bt_disable();
}
#else
result = true;
#endif
// Create a result thread and pass it to Main Thread,
nsCOMPtr<nsIRunnable> resultRunnable = new ToggleBtResultTask(result, mAdapterPtr);
NS_DispatchToMainThread(resultRunnable);
return NS_OK;
}
private:
nsRefPtr<BluetoothAdapter> mAdapterPtr;
bool mOnOff;
};
END_BLUETOOTH_NAMESPACE
DOMCI_DATA(BluetoothAdapter, mozilla::dom::bluetooth::BluetoothAdapter)
USING_BLUETOOTH_NAMESPACE
NS_IMPL_CYCLE_COLLECTION_CLASS(BluetoothAdapter)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(BluetoothAdapter,
nsDOMEventTargetHelper)
NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(powered)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(BluetoothAdapter,
nsDOMEventTargetHelper)
NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(powered)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(BluetoothAdapter)
NS_INTERFACE_MAP_ENTRY(nsIDOMBluetoothAdapter)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(BluetoothAdapter)
NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
NS_IMPL_ADDREF_INHERITED(BluetoothAdapter, nsDOMEventTargetHelper)
NS_IMPL_RELEASE_INHERITED(BluetoothAdapter, nsDOMEventTargetHelper)
BluetoothAdapter::BluetoothAdapter() : mPower(false)
{
}
NS_INTERFACE_MAP_BEGIN(BluetoothAdapter)
NS_INTERFACE_MAP_ENTRY(nsIDOMBluetoothAdapter)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(BluetoothAdapter)
NS_INTERFACE_MAP_END
NS_IMPL_ADDREF(BluetoothAdapter)
NS_IMPL_RELEASE(BluetoothAdapter)
DOMCI_DATA(BluetoothAdapter, BluetoothAdapter)
NS_IMETHODIMP
BluetoothAdapter::GetPower(bool* aPower)
{
#if defined(MOZ_WIDGET_GONK)
*aPower = bt_is_enabled();
#else
*aPower = mPower;
#endif
return NS_OK;
}
NS_IMETHODIMP
BluetoothAdapter::SetPower(bool aPower)
{
mPower = aPower;
if (mPower != aPower) {
mPower = aPower;
ToggleBluetoothAsync();
}
return NS_OK;
}
void
BluetoothAdapter::ToggleBluetoothAsync()
{
if (!mToggleBtThread) {
mToggleBtThread = new LazyIdleThread(15000);
}
nsCOMPtr<nsIRunnable> r = new ToggleBtTask(mPower, this);
mToggleBtThread->Dispatch(r, 0);
}
nsresult
BluetoothAdapter::FirePowered()
{
nsRefPtr<nsDOMEvent> event = new nsDOMEvent(nsnull, nsnull);
nsresult rv = event->InitEvent(POWERED_EVENT_NAME, false, false);
NS_ENSURE_SUCCESS(rv, rv);
bool dummy;
rv = DispatchEvent(event, &dummy);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
NS_IMPL_EVENT_HANDLER(BluetoothAdapter, powered)

View File

@ -8,20 +8,35 @@
#define mozilla_dom_bluetooth_bluetoothadapter_h__
#include "BluetoothCommon.h"
#include "nsDOMEventTargetHelper.h"
#include "nsIDOMBluetoothAdapter.h"
BEGIN_BLUETOOTH_NAMESPACE
class BluetoothAdapter : public nsIDOMBluetoothAdapter
,public nsDOMEventTargetHelper
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIDOMBLUETOOTHADAPTER
NS_FORWARD_NSIDOMEVENTTARGET(nsDOMEventTargetHelper::)
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(BluetoothAdapter,
nsDOMEventTargetHelper)
BluetoothAdapter();
nsresult FirePowered();
protected:
bool mPower;
NS_DECL_EVENT_HANDLER(powered)
private:
nsCOMPtr<nsIEventTarget> mToggleBtThread;
void ToggleBluetoothAsync();
};
END_BLUETOOTH_NAMESPACE

View File

@ -4,10 +4,14 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsISupports.idl"
#include "nsIDOMEventTarget.idl"
[scriptable, builtinclass, uuid(29689a22-45ff-4ccf-b552-5364ce3a3642)]
interface nsIDOMBluetoothAdapter : nsISupports
interface nsIDOMEventListener;
[scriptable, builtinclass, uuid(3dbaa9f4-5c93-11e1-8592-ff9bfcc3ab4b)]
interface nsIDOMBluetoothAdapter : nsIDOMEventTarget
{
attribute boolean power;
attribute nsIDOMEventListener onpowered;
};

View File

@ -168,6 +168,13 @@ interface nsIWebGLExtensionLoseContext : nsIWebGLExtension
void restoreContext();
};
[scriptable, uuid(73bfb64d-94bd-4a7a-9eab-6b6d32e57aa0)]
interface nsIWebGLExtensionTextureFilterAnisotropic : nsIWebGLExtension
{
const WebGLenum TEXTURE_MAX_ANISOTROPY = 0x84FE;
const WebGLenum MAX_TEXTURE_MAX_ANISOTROPY = 0x84FF;
};
[scriptable, builtinclass, uuid(f000afac-11b3-4c06-a35f-8db411f1cf54)]
interface nsIDOMWebGLRenderingContext : nsISupports
{

View File

@ -52,7 +52,7 @@ interface nsIDOMUserDataHandler;
* http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html
*/
[scriptable, uuid(ce82fb71-60f2-4c38-be31-de5f2f90dada)]
[scriptable, uuid(5e9bcec9-5928-4f77-8a9c-424ef01c20e1)]
interface nsIDOMNode : nsISupports
{
const unsigned short ELEMENT_NODE = 1;
@ -94,7 +94,8 @@ interface nsIDOMNode : nsISupports
nsIDOMNode appendChild(in nsIDOMNode newChild)
raises(DOMException);
boolean hasChildNodes();
nsIDOMNode cloneNode(in boolean deep);
// Modified in DOM Level 4:
[optional_argc] nsIDOMNode cloneNode([optional] in boolean deep);
// Modified in DOM Level 2:
void normalize();
// Introduced in DOM Level 2:

View File

@ -353,16 +353,6 @@ nsNPAPIPlugin::RunPluginOOP(const nsPluginTag *aPluginTag)
}
#endif
#ifdef XP_WIN
OSVERSIONINFO osVerInfo = {0};
osVerInfo.dwOSVersionInfoSize = sizeof(osVerInfo);
GetVersionEx(&osVerInfo);
// Always disabled on 2K or less. (bug 536303)
if (osVerInfo.dwMajorVersion < 5 ||
(osVerInfo.dwMajorVersion == 5 && osVerInfo.dwMinorVersion == 0))
return false;
#endif
nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
if (!prefs) {
return false;

View File

@ -57,7 +57,6 @@
#include "nsString.h"
#include "nsILocalFile.h"
#include "nsUnicharUtils.h"
#include "nsSetDllDirectory.h"
using namespace mozilla;
@ -303,7 +302,7 @@ nsresult nsPluginFile::LoadPlugin(PRLibrary **outLibrary)
}
if (protectCurrentDirectory) {
mozilla::NS_SetDllDirectory(NULL);
SetDllDirectory(NULL);
}
nsresult rv = plugin->Load(outLibrary);
@ -311,7 +310,7 @@ nsresult nsPluginFile::LoadPlugin(PRLibrary **outLibrary)
*outLibrary = NULL;
if (protectCurrentDirectory) {
mozilla::NS_SetDllDirectory(L"");
SetDllDirectory(L"");
}
if (restoreOrigDir) {

View File

@ -147,7 +147,7 @@ PluginProcessChild::Init()
}
if (protectCurrentDirectory) {
SanitizeEnvironmentVariables();
NS_SetDllDirectory(L"");
SetDllDirectory(L"");
}
#else

View File

@ -1848,8 +1848,7 @@ nsDOMStorage2::InitAsSessionStorage(nsIPrincipal *aPrincipal, const nsSubstring
if (!mStorage)
return NS_ERROR_OUT_OF_MEMORY;
// Leave security checks only for domain (nsDOMStorage implementation)
mStorage->mSecurityChecker = mStorage;
mStorage->mSecurityChecker = this;
mPrincipal = aPrincipal;
mDocumentURI = aDocumentURI;
@ -1949,7 +1948,7 @@ nsDOMStorage2::CanAccess(nsIPrincipal *aPrincipal)
// Allow more powerful principals (e.g. system) to access the storage
bool subsumes;
nsresult rv = aPrincipal->Subsumes(mPrincipal, &subsumes);
nsresult rv = aPrincipal->SubsumesIgnoringDomain(mPrincipal, &subsumes);
if (NS_FAILED(rv))
return false;

View File

@ -16,7 +16,7 @@ function startTest()
sessionStorage;
}
catch (e) {
is(e.result, 2152923145,
is(e.result, Components.results.NS_ERROR_NOT_AVAILABLE,
"Testing that we get the expected exception.");
exceptionCaught = true;
}

View File

@ -98,7 +98,7 @@ NS_IMETHODIMP SplitElementTxn::DoTransaction(void)
if (!mExistingRightNode || !mEditor) { return NS_ERROR_NOT_INITIALIZED; }
// create a new node
nsresult result = mExistingRightNode->CloneNode(false, getter_AddRefs(mNewLeftNode));
nsresult result = mExistingRightNode->CloneNode(false, 1, getter_AddRefs(mNewLeftNode));
NS_ASSERTION(((NS_SUCCEEDED(result)) && (mNewLeftNode)), "could not create element.");
NS_ENSURE_SUCCESS(result, result);
NS_ENSURE_TRUE(mNewLeftNode, NS_ERROR_NULL_POINTER);

View File

@ -2970,7 +2970,7 @@ nsWebBrowserPersist::GetNodeToFixup(nsIDOMNode *aNodeIn, nsIDOMNode **aNodeOut)
{
if (!(mPersistFlags & PERSIST_FLAGS_FIXUP_ORIGINAL_DOM))
{
nsresult rv = aNodeIn->CloneNode(false, aNodeOut);
nsresult rv = aNodeIn->CloneNode(false, 1, aNodeOut);
NS_ENSURE_SUCCESS(rv, rv);
}
else

View File

@ -107,33 +107,14 @@ static const char *MapErrorCode(int rc)
//-----------------------------------------------------------------------------
static HINSTANCE sspi_lib;
static PSecurityFunctionTableW sspi;
static nsresult
InitSSPI()
{
PSecurityFunctionTableW (*initFun)(void);
LOG((" InitSSPI\n"));
sspi_lib = LoadLibraryW(L"secur32.dll");
if (!sspi_lib) {
sspi_lib = LoadLibraryW(L"security.dll");
if (!sspi_lib) {
LOG(("SSPI library not found"));
return NS_ERROR_UNEXPECTED;
}
}
initFun = (PSecurityFunctionTableW (*)(void))
GetProcAddress(sspi_lib, "InitSecurityInterfaceW");
if (!initFun) {
LOG(("InitSecurityInterfaceW not found"));
return NS_ERROR_UNEXPECTED;
}
sspi = initFun();
sspi = InitSecurityInterfaceW();
if (!sspi) {
LOG(("InitSecurityInterfaceW failed"));
return NS_ERROR_UNEXPECTED;

View File

@ -96,6 +96,7 @@ static const char *sExtensionNames[] = {
"GL_ARB_texture_float",
"GL_EXT_unpack_subimage",
"GL_OES_standard_derivatives",
"GL_EXT_texture_filter_anisotropic",
"GL_EXT_framebuffer_blit",
"GL_ANGLE_framebuffer_blit",
"GL_EXT_framebuffer_multisample",

View File

@ -1408,6 +1408,7 @@ public:
ARB_texture_float,
EXT_unpack_subimage,
OES_standard_derivatives,
EXT_texture_filter_anisotropic,
EXT_framebuffer_blit,
ANGLE_framebuffer_blit,
EXT_framebuffer_multisample,

View File

@ -81,18 +81,6 @@ GetCairoAntialiasOption(gfxFont::AntialiasOption anAntialiasOption)
#define FE_FONTSMOOTHINGCLEARTYPE 2
#endif
static bool
HasClearType()
{
OSVERSIONINFO versionInfo;
versionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
return (GetVersionEx(&versionInfo) &&
(versionInfo.dwMajorVersion > 5 ||
(versionInfo.dwMajorVersion == 5 &&
versionInfo.dwMinorVersion >= 1))); // XP or newer
}
static bool
UsingClearType()
{
@ -100,10 +88,6 @@ UsingClearType()
if (!SystemParametersInfo(SPI_GETFONTSMOOTHING, 0, &fontSmoothing, 0) ||
!fontSmoothing)
{
return false;
}
if (!HasClearType()) {
return false;
}

View File

@ -65,6 +65,7 @@
#include "mozilla/Telemetry.h"
#include <usp10.h>
#include <t2embapi.h>
using namespace mozilla;
@ -102,50 +103,6 @@ BuildKeyNameFromFontName(nsAString &aName)
// Implementation of gfxPlatformFontList for Win32 GDI,
// using GDI font enumeration APIs to get the list of fonts
// from t2embapi.h, included in Platform SDK 6.1 but not 6.0
#ifndef __t2embapi__
#define TTLOAD_PRIVATE 0x00000001
#define LICENSE_PREVIEWPRINT 0x0004
#define E_NONE 0x0000L
typedef unsigned long( WINAPIV *READEMBEDPROC ) ( void*, void*, const unsigned long );
typedef struct
{
unsigned short usStructSize; // size in bytes of structure client should set to sizeof(TTLOADINFO)
unsigned short usRefStrSize; // size in wide characters of pusRefStr including NULL terminator
unsigned short *pusRefStr; // reference or actual string.
}TTLOADINFO;
LONG WINAPI TTLoadEmbeddedFont
(
HANDLE* phFontReference, // on completion, contains handle to identify embedded font installed
// on system
ULONG ulFlags, // flags specifying the request
ULONG* pulPrivStatus, // on completion, contains the embedding status
ULONG ulPrivs, // allows for the reduction of licensing privileges
ULONG* pulStatus, // on completion, may contain status flags for request
READEMBEDPROC lpfnReadFromStream, // callback function for doc/disk reads
LPVOID lpvReadStream, // the input stream tokin
LPWSTR szWinFamilyName, // the new 16 bit windows family name can be NULL
LPSTR szMacFamilyName, // the new 8 bit mac family name can be NULL
TTLOADINFO* pTTLoadInfo // optional security
);
#endif // __t2embapi__
typedef LONG( WINAPI *TTLoadEmbeddedFontProc ) (HANDLE* phFontReference, ULONG ulFlags, ULONG* pulPrivStatus, ULONG ulPrivs, ULONG* pulStatus,
READEMBEDPROC lpfnReadFromStream, LPVOID lpvReadStream, LPWSTR szWinFamilyName,
LPSTR szMacFamilyName, TTLOADINFO* pTTLoadInfo);
typedef LONG( WINAPI *TTDeleteEmbeddedFontProc ) (HANDLE hFontReference, ULONG ulFlags, ULONG* pulStatus);
static TTLoadEmbeddedFontProc TTLoadEmbeddedFontPtr = nsnull;
static TTDeleteEmbeddedFontProc TTDeleteEmbeddedFontPtr = nsnull;
class WinUserFontData : public gfxUserFontData {
public:
WinUserFontData(HANDLE aFontRef, bool aIsEmbedded)
@ -157,7 +114,7 @@ public:
if (mIsEmbedded) {
ULONG pulStatus;
LONG err;
err = TTDeleteEmbeddedFontPtr(mFontRef, 0, &pulStatus);
err = TTDeleteEmbeddedFont(mFontRef, 0, &pulStatus);
#if DEBUG
if (err != E_NONE) {
char buf[256];
@ -606,8 +563,6 @@ GDIFontFamily::FindStyleVariations()
gfxGDIFontList::gfxGDIFontList()
{
mFontSubstitutes.Init(50);
InitializeFontEmbeddingProcs();
}
static void
@ -794,15 +749,6 @@ gfxGDIFontList::LookupLocalFont(const gfxProxyFontEntry *aProxyEntry,
return fe;
}
void gfxGDIFontList::InitializeFontEmbeddingProcs()
{
HMODULE fontlib = LoadLibraryW(L"t2embed.dll");
if (!fontlib)
return;
TTLoadEmbeddedFontPtr = (TTLoadEmbeddedFontProc) GetProcAddress(fontlib, "TTLoadEmbeddedFont");
TTDeleteEmbeddedFontPtr = (TTDeleteEmbeddedFontProc) GetProcAddress(fontlib, "TTDeleteEmbeddedFont");
}
// used to control stream read by Windows TTLoadEmbeddedFont API
class EOTFontStreamReader {
@ -906,10 +852,6 @@ gfxGDIFontList::MakePlatformFont(const gfxProxyFontEntry *aProxyEntry,
};
FontDataDeleter autoDelete(aFontData);
// if calls aren't available, bail
if (!TTLoadEmbeddedFontPtr || !TTDeleteEmbeddedFontPtr)
return nsnull;
bool hasVertical;
bool isCFF = gfxFontUtils::IsCffFont(aFontData, hasVertical);
@ -948,11 +890,11 @@ gfxGDIFontList::MakePlatformFont(const gfxProxyFontEntry *aProxyEntry,
EOTFontStreamReader eotReader(aFontData, aLength, buffer, eotlen,
&overlayNameData);
ret = TTLoadEmbeddedFontPtr(&fontRef, TTLOAD_PRIVATE, &privStatus,
LICENSE_PREVIEWPRINT, &pulStatus,
EOTFontStreamReader::ReadEOTStream,
&eotReader,
(PRUnichar*)(fontName.get()), 0, 0);
ret = TTLoadEmbeddedFont(&fontRef, TTLOAD_PRIVATE, &privStatus,
LICENSE_PREVIEWPRINT, &pulStatus,
EOTFontStreamReader::ReadEOTStream,
&eotReader,
(PRUnichar*)(fontName.get()), 0, 0);
if (ret != E_NONE) {
fontRef = nsnull;
char buf[256];

View File

@ -225,7 +225,6 @@ public:
// based on http://msdn.microsoft.com/en-us/library/ms724834(VS.85).aspx
enum {
kWindowsUnknown = 0,
kWindows2000 = 0x50000,
kWindowsXP = 0x50001,
kWindowsServer2003 = 0x50002,
kWindowsVista = 0x60000,

View File

@ -158,7 +158,7 @@ EnableBatteryNotifications()
DEVICE_NOTIFY_WINDOW_HANDLE);
} else
{
// for Windows 2000 and Windwos XP. If we remove Windows XP support,
// for Windows XP. If we remove Windows XP support,
// we should remove timer-based power notification
sUpdateTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
if (sUpdateTimer) {

View File

@ -74,7 +74,7 @@ main(int argc, char* argv[])
// the details.
if (proctype != GeckoProcessType_Plugin) {
mozilla::SanitizeEnvironmentVariables();
mozilla::NS_SetDllDirectory(L"");
SetDllDirectory(L"");
}
#endif

View File

@ -3427,25 +3427,6 @@ AC_CHECK_FUNCS([fchmod flockfile getc_unlocked _getc_nolock getpagesize \
lchown localtime_r lstat64 memmove random rint sbrk snprintf \
stat64 statvfs statvfs64 strerror strtok_r truncate64])
dnl check for clock_gettime(), the CLOCK_MONOTONIC clock, and -lrt
_SAVE_LDFLAGS=$LDFLAGS
LDFLAGS="$LDFLAGS -lrt"
AC_CACHE_CHECK(for clock_gettime(CLOCK_MONOTONIC) and -lrt,
ac_cv_have_clock_monotonic,
[AC_TRY_LINK([#include <time.h>],
[ struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts); ],
ac_cv_have_clock_monotonic=yes,
ac_cv_have_clock_monotonic=no)])
LDFLAGS=$_SAVE_LDFLAGS
if test "$ac_cv_have_clock_monotonic" = "yes"; then
HAVE_CLOCK_MONOTONIC=1
REALTIME_LIBS=-lrt
AC_DEFINE(HAVE_CLOCK_MONOTONIC)
AC_SUBST(HAVE_CLOCK_MONOTONIC)
AC_SUBST(REALTIME_LIBS)
fi
dnl Windows functions, for mingw.
AC_TRY_LINK([#include <windows.h>],
[SYSTEMTIME st;FILETIME ft;SystemTimeToFileTime(&st,&ft);],

View File

@ -18,7 +18,7 @@ script 10.1.5-4.js
script 10.1.8-2.js
script 10.1.8-3.js
script 10.2.1.js
skip-if(!xulRuntime.shell) script 10.2.2-1.js # bug - NS_ERROR_DOM_NOT_SUPPORTED_ERR Line 91
skip-if(!xulRuntime.shell) script 10.2.2-2.js # bug - NS_ERROR_DOM_NOT_SUPPORTED_ERR Line 177
skip-if(Android) script 10.2.2-1.js # bug - nsIDOMWindow.crypto throws NS_ERROR_NOT_IMPLEMENTED on Android
skip-if(Android) script 10.2.2-2.js # bug - nsIDOMWindow.crypto throws NS_ERROR_NOT_IMPLEMENTED on Android
script 10.2.3-1.js
script 10.2.3-2.js

View File

@ -7,7 +7,7 @@ script dowhile-005.js
script dowhile-006.js
script dowhile-007.js
script forin-001.js
fails-if(!xulRuntime.shell) script forin-002.js # bug - NS_ERROR_DOM_NOT_SUPPORTED_ERR line 112
skip-if(Android) script forin-002.js # bug - nsIDOMWindow.crypto throws NS_ERROR_NOT_IMPLEMENTED on Android
script if-001.js
script label-001.js
script label-002.js

View File

@ -3,7 +3,7 @@ script 11.1.4.js
script array-001.js
random script regress-101964.js # bogus perf test (bug 467263)
script regress-107138.js
fails-if(!xulRuntime.shell) script regress-108440.js # bug - NS_ERROR_DOM_NOT_SUPPORTED_ERR line 74
skip-if(Android) script regress-108440.js # bug - nsIDOMWindow.crypto throws NS_ERROR_NOT_IMPLEMENTED on Android
script regress-154338.js
skip-if(xulRuntime.XPCOMABI.match(/x86_64/)||Android) script regress-157652.js # No test results
script regress-178722.js

View File

@ -3,15 +3,15 @@ script regress-312385-01.js
script regress-352392.js
script regress-385393-08.js
script regress-414098.js
fails-if(!xulRuntime.shell) script regress-455464-01.js # bug - NS_ERROR_DOM_NOT_SUPPORTED_ERR line 1
fails-if(!xulRuntime.shell) script regress-455464-02.js # bug - NS_ERROR_DOM_NOT_SUPPORTED_ERR line 49
fails-if(!xulRuntime.shell) script regress-455464-03.js # bug - NS_ERROR_DOM_NOT_SUPPORTED_ERR line 1
fails-if(!xulRuntime.shell&&!isDebugBuild) skip-if((!xulRuntime.shell&&isDebugBuild)||Android) script regress-455464-04.js # bug xxx - hangs reftests in debug, ### bug xxx - NS_ERROR_DOM_NOT_SUPPORTED_ERR in opt
skip-if(Android) script regress-455464-01.js # bug - nsIDOMWindow.crypto throws NS_ERROR_NOT_IMPLEMENTED on Android
skip-if(Android) script regress-455464-02.js # bug - nsIDOMWindow.crypto throws NS_ERROR_NOT_IMPLEMENTED on Android
skip-if(Android) script regress-455464-03.js # bug - nsIDOMWindow.crypto throws NS_ERROR_NOT_IMPLEMENTED on Android
skip-if(Android) script regress-455464-04.js # bug - nsIDOMWindow.crypto throws NS_ERROR_NOT_IMPLEMENTED on Android
skip-if(!xulRuntime.shell||Android) slow script regress-456826.js # bug 504632
script regress-457521.js
script regress-465443.js
script regress-470310.js
script regress-472508.js
fails-if(!xulRuntime.shell) script regress-475144.js # NS_ERROR_DOM_NOT_SUPPORTED_ERR
skip-if(Android) script regress-475144.js # bug - nsIDOMWindow.crypto throws NS_ERROR_NOT_IMPLEMENTED on Android
script regress-479567.js
script regress-565521.js

View File

@ -51,8 +51,8 @@ script regress-392308.js
script regress-396326.js
script regress-429266.js
script regress-453955.js
fails-if(!xulRuntime.shell) script regress-455982-01.js # NS_ERROR_DOM_NOT_SUPPORTED_ERR
fails-if(!xulRuntime.shell) script regress-455982-02.js # NS_ERROR_DOM_NOT_SUPPORTED_ERR
skip-if(Android) script regress-455982-01.js # bug - nsIDOMWindow.crypto throws NS_ERROR_NOT_IMPLEMENTED on Android
skip-if(Android) script regress-455982-02.js # bug - nsIDOMWindow.crypto throws NS_ERROR_NOT_IMPLEMENTED on Android
skip-if(!xulRuntime.shell||xulRuntime.shell&&xulRuntime.XPCOMABI.match(/x86_64/)) slow script regress-458679.js
script regress-469234.js
script regress-469405-01.js

View File

@ -20,7 +20,7 @@ script regress-422269.js
skip script regress-445818.js
skip script regress-446169-01.js
skip script regress-446169-02.js
fails-if(!xulRuntime.shell) script regress-452476.js # NS_ERROR_DOM_NOT_SUPPORTED_ERR
skip-if(Android) script regress-452476.js # bug - nsIDOMWindow.crypto throws NS_ERROR_NOT_IMPLEMENTED on Android
script regress-452913.js
script regress-454744.js
script regress-455973.js
@ -34,7 +34,7 @@ script regress-473040.js
skip script regress-475971.js
skip-if(!xulRuntime.shell) slow script regress-476414-01.js
skip-if(!xulRuntime.shell) slow script regress-476414-02.js
fails-if(!xulRuntime.shell) script regress-476427.js # NS_ERROR_DOM_NOT_SUPPORTED_ERR
skip-if(Android) script regress-476427.js # bug - nsIDOMWindow.crypto throws NS_ERROR_NOT_IMPLEMENTED on Android
script regress-476653.js
skip-if(Android) script regress-476869.js
script regress-476871-02.js

View File

@ -500,6 +500,7 @@ irregularFilenames = {
'nsIWebGLUniformLocation': 'nsIDOMWebGLRenderingContext',
'nsIWebGLExtension': 'nsIDOMWebGLRenderingContext',
'nsIWebGLExtensionStandardDerivatives' : 'nsIDOMWebGLRenderingContext',
'nsIWebGLExtensionTextureFilterAnisotropic' : 'nsIDOMWebGLRenderingContext',
'nsIWebGLExtensionLoseContext' : 'nsIDOMWebGLRenderingContext',
'nsIIndexedDatabaseUsageCallback': 'nsIIndexedDatabaseManager',

View File

@ -644,6 +644,7 @@ static inline mozilla::css::Side operator++(mozilla::css::Side& side, int) {
#define NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE NS_FONT_DECORATION_UNDERLINE
#define NS_STYLE_TEXT_DECORATION_LINE_OVERLINE NS_FONT_DECORATION_OVERLINE
#define NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH NS_FONT_DECORATION_LINE_THROUGH
#define NS_STYLE_TEXT_DECORATION_LINE_BLINK 0x08
#define NS_STYLE_TEXT_DECORATION_LINE_PREF_ANCHORS 0x10
// OVERRIDE_ALL does not occur in stylesheets; it only comes from HTML
// attribute mapping (and thus appears in computed data)

View File

@ -3296,9 +3296,7 @@ nsFrameSelection::DeleteFromDocument()
{
nsresult res;
// If we're already collapsed, then set ourselves to include the
// last item BEFORE the current range, rather than the range itself,
// before we do the delete.
// If we're already collapsed, then we do nothing (bug 719503).
bool isCollapsed;
PRInt8 index = GetIndexFromSelectionType(nsISelectionController::SELECTION_NORMAL);
if (!mDomSelections[index])
@ -3307,17 +3305,7 @@ nsFrameSelection::DeleteFromDocument()
mDomSelections[index]->GetIsCollapsed( &isCollapsed);
if (isCollapsed)
{
// If the offset is positive, then it's easy:
if (mDomSelections[index]->GetFocusOffset() > 0)
{
mDomSelections[index]->Extend(mDomSelections[index]->GetFocusNode(), mDomSelections[index]->GetFocusOffset() - 1);
}
else
{
// Otherwise it's harder, have to find the previous node
printf("Sorry, don't know how to delete across frame boundaries yet\n");
return NS_ERROR_NOT_IMPLEMENTED;
}
return NS_OK;
}
// Get an iterator

View File

@ -127,6 +127,7 @@ _TEST_FILES = \
$(srcdir)/../../reftests/backgrounds/fuchsia-32x32.png \
test_selection_splitText-normalize.html \
test_bug524925.html \
test_bug719503.html \
$(NULL)
_CHROME_FILES = \

View File

@ -0,0 +1,20 @@
<!doctype html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=719503
-->
<title>Test for Bug 719503</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" href="/tests/SimpleTest/test.css">
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=719503">Mozilla Bug 719503</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
<script>
try {
getSelection().collapse(document.head, 0);
getSelection().deleteFromDocument();
} catch(e) {
ok(false, "Exception thrown");
}
ok(true, "Passed, no exception");
</script>

View File

@ -54,7 +54,8 @@ namespace css {
// check that we can fit all the CSS properties into a PRUint8
// for the mOrder array - if not, might need to use PRUint16!
PR_STATIC_ASSERT(eCSSProperty_COUNT_no_shorthands - 1 <= PR_UINT8_MAX);
MOZ_STATIC_ASSERT(eCSSProperty_COUNT_no_shorthands - 1 <= PR_UINT8_MAX,
"CSS longhand property numbers no longer fit in a PRUint8");
Declaration::Declaration()
: mImmutable(false)
@ -439,23 +440,23 @@ Declaration::GetValue(nsCSSProperty aProperty, nsAString& aValue) const
aValue.Append(PRUnichar(' '));
position->mValue.AppendToString(eCSSProperty_background_position,
aValue);
NS_ABORT_IF_FALSE(clip->mValue.GetUnit() == eCSSUnit_Enumerated &&
origin->mValue.GetUnit() == eCSSUnit_Enumerated,
"should not be inherit/initial within list and "
"should have returned early for real inherit/initial");
"should not have inherit/initial within list");
if (clip->mValue.GetIntValue() != NS_STYLE_BG_CLIP_BORDER ||
origin->mValue.GetIntValue() != NS_STYLE_BG_ORIGIN_PADDING) {
PR_STATIC_ASSERT(NS_STYLE_BG_CLIP_BORDER ==
NS_STYLE_BG_ORIGIN_BORDER);
PR_STATIC_ASSERT(NS_STYLE_BG_CLIP_PADDING ==
NS_STYLE_BG_ORIGIN_PADDING);
PR_STATIC_ASSERT(NS_STYLE_BG_CLIP_CONTENT ==
NS_STYLE_BG_ORIGIN_CONTENT);
// The shorthand only has a single clip/origin value which
// sets both properties. So if they're different (and
// non-default), we can't represent the state using the
// shorthand.
// The shorthand only has a single clip/origin value which sets
// both properties. So if they're different (and non-default),
// we can't represent the state using the shorthand.
MOZ_STATIC_ASSERT(NS_STYLE_BG_CLIP_BORDER ==
NS_STYLE_BG_ORIGIN_BORDER &&
NS_STYLE_BG_CLIP_PADDING ==
NS_STYLE_BG_ORIGIN_PADDING &&
NS_STYLE_BG_CLIP_CONTENT ==
NS_STYLE_BG_ORIGIN_CONTENT,
"bg-clip and bg-origin style constants must agree");
if (clip->mValue != origin->mValue) {
aValue.Truncate();
return;

View File

@ -344,8 +344,8 @@ nsCSSSelector::nsCSSSelector(void)
mPseudoType(nsCSSPseudoElements::ePseudo_NotPseudoElement)
{
MOZ_COUNT_CTOR(nsCSSSelector);
// Make sure mPseudoType can hold all nsCSSPseudoElements::Type values
PR_STATIC_ASSERT(nsCSSPseudoElements::ePseudo_MAX < PR_INT16_MAX);
MOZ_STATIC_ASSERT(nsCSSPseudoElements::ePseudo_MAX < PR_INT16_MAX,
"nsCSSPseudoElements::Type values overflow mPseudoType");
}
nsCSSSelector*

View File

@ -571,8 +571,10 @@ public:
static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; }
static PLDHashNumber HashKey(KeyTypePointer aKey) {
PR_STATIC_ASSERT(sizeof(PLDHashNumber) == sizeof(PRUint32));
PR_STATIC_ASSERT(PLDHashNumber(-1) > PLDHashNumber(0));
MOZ_STATIC_ASSERT(sizeof(PLDHashNumber) == sizeof(PRUint32),
"this hash function assumes PLDHashNumber is PRUint32");
MOZ_STATIC_ASSERT(PLDHashNumber(-1) > PLDHashNumber(0),
"this hash function assumes PLDHashNumber is PRUint32");
float key = *aKey;
NS_ABORT_IF_FALSE(0.0f <= key && key <= 1.0f, "out of range");
return PLDHashNumber(key * PR_UINT32_MAX);

View File

@ -161,8 +161,10 @@ private:
};
/* Make sure the CDBValueStorage elements are aligned appropriately. */
PR_STATIC_ASSERT(sizeof(nsCSSCompressedDataBlock) == 8);
PR_STATIC_ASSERT(NS_ALIGNMENT_OF(CDBValueStorage) <= 8);
MOZ_STATIC_ASSERT(sizeof(nsCSSCompressedDataBlock) == 8,
"nsCSSCompressedDataBlock's size has changed");
MOZ_STATIC_ASSERT(NS_ALIGNMENT_OF(CDBValueStorage) <= 8,
"CDBValueStorage needs too much alignment");
class nsCSSExpandedDataBlock {
friend class nsCSSCompressedDataBlock;

View File

@ -6009,12 +6009,14 @@ CSSParserImpl::ParseBackgroundItem(CSSParserImpl::BackgroundParseState& aState)
NS_NOTREACHED("should be able to parse");
return false;
}
PR_STATIC_ASSERT(NS_STYLE_BG_CLIP_BORDER ==
NS_STYLE_BG_ORIGIN_BORDER);
PR_STATIC_ASSERT(NS_STYLE_BG_CLIP_PADDING ==
NS_STYLE_BG_ORIGIN_PADDING);
PR_STATIC_ASSERT(NS_STYLE_BG_CLIP_CONTENT ==
NS_STYLE_BG_ORIGIN_CONTENT);
MOZ_STATIC_ASSERT(NS_STYLE_BG_CLIP_BORDER ==
NS_STYLE_BG_ORIGIN_BORDER &&
NS_STYLE_BG_CLIP_PADDING ==
NS_STYLE_BG_ORIGIN_PADDING &&
NS_STYLE_BG_CLIP_CONTENT ==
NS_STYLE_BG_ORIGIN_CONTENT,
"bg-clip and bg-origin style constants must agree");
aState.mClip->mValue = aState.mOrigin->mValue;
} else {
if (haveColor)
@ -8503,22 +8505,20 @@ bool
CSSParserImpl::ParseTextDecoration()
{
enum {
eDecorationNone = 0x00,
eDecorationUnderline = 0x01,
eDecorationOverline = 0x02,
eDecorationLineThrough = 0x04,
eDecorationBlink = 0x08,
eDecorationPrefAnchors = 0x10
eDecorationNone = NS_STYLE_TEXT_DECORATION_LINE_NONE,
eDecorationUnderline = NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE,
eDecorationOverline = NS_STYLE_TEXT_DECORATION_LINE_OVERLINE,
eDecorationLineThrough = NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH,
eDecorationBlink = NS_STYLE_TEXT_DECORATION_LINE_BLINK,
eDecorationPrefAnchors = NS_STYLE_TEXT_DECORATION_LINE_PREF_ANCHORS
};
PR_STATIC_ASSERT(eDecorationUnderline ==
NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE);
PR_STATIC_ASSERT(eDecorationOverline ==
NS_STYLE_TEXT_DECORATION_LINE_OVERLINE);
PR_STATIC_ASSERT(eDecorationLineThrough ==
NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH);
PR_STATIC_ASSERT(eDecorationPrefAnchors ==
NS_STYLE_TEXT_DECORATION_LINE_PREF_ANCHORS);
MOZ_STATIC_ASSERT((eDecorationNone ^ eDecorationUnderline ^
eDecorationOverline ^ eDecorationLineThrough ^
eDecorationBlink ^ eDecorationPrefAnchors) ==
(eDecorationNone | eDecorationUnderline |
eDecorationOverline | eDecorationLineThrough |
eDecorationBlink | eDecorationPrefAnchors),
"text decoration constants need to be bitmasks");
static const PRInt32 kTextDecorationKTable[] = {
eCSSKeyword_none, eDecorationNone,

View File

@ -55,7 +55,6 @@
#include "nsString.h"
#include "nsReadableUtils.h"
#include "nsStaticNameTable.h"
#include "prlog.h" // for PR_STATIC_ASSERT
using namespace mozilla;
@ -604,9 +603,10 @@ const PRInt32 nsCSSProps::kBackgroundInlinePolicyKTable[] = {
eCSSKeyword_UNKNOWN,-1
};
PR_STATIC_ASSERT(NS_STYLE_BG_CLIP_BORDER == NS_STYLE_BG_ORIGIN_BORDER);
PR_STATIC_ASSERT(NS_STYLE_BG_CLIP_PADDING == NS_STYLE_BG_ORIGIN_PADDING);
PR_STATIC_ASSERT(NS_STYLE_BG_CLIP_CONTENT == NS_STYLE_BG_ORIGIN_CONTENT);
MOZ_STATIC_ASSERT(NS_STYLE_BG_CLIP_BORDER == NS_STYLE_BG_ORIGIN_BORDER &&
NS_STYLE_BG_CLIP_PADDING == NS_STYLE_BG_ORIGIN_PADDING &&
NS_STYLE_BG_CLIP_CONTENT == NS_STYLE_BG_ORIGIN_CONTENT,
"bg-clip and bg-origin style constants must agree");
const PRInt32 nsCSSProps::kBackgroundOriginKTable[] = {
eCSSKeyword_border_box, NS_STYLE_BG_ORIGIN_BORDER,
eCSSKeyword_padding_box, NS_STYLE_BG_ORIGIN_PADDING,
@ -1703,10 +1703,9 @@ static const nsCSSProperty gBorderBottomSubpropTable[] = {
eCSSProperty_UNKNOWN
};
PR_STATIC_ASSERT(NS_SIDE_TOP == 0);
PR_STATIC_ASSERT(NS_SIDE_RIGHT == 1);
PR_STATIC_ASSERT(NS_SIDE_BOTTOM == 2);
PR_STATIC_ASSERT(NS_SIDE_LEFT == 3);
MOZ_STATIC_ASSERT(NS_SIDE_TOP == 0 && NS_SIDE_RIGHT == 1 &&
NS_SIDE_BOTTOM == 2 && NS_SIDE_LEFT == 3,
"box side constants not top/right/bottom/left == 0/1/2/3");
static const nsCSSProperty gBorderColorSubpropTable[] = {
// Code relies on these being in top-right-bottom-left order.
// Code relies on these matching the NS_SIDE_* constants.

View File

@ -105,8 +105,9 @@
// See CSSParserImpl::ParseSingleValueProperty
#define CSS_PROPERTY_VALUE_PARSER_FUNCTION (1<<12)
PR_STATIC_ASSERT((CSS_PROPERTY_PARSE_PROPERTY_MASK &
CSS_PROPERTY_VALUE_PARSER_FUNCTION) == 0);
MOZ_STATIC_ASSERT((CSS_PROPERTY_PARSE_PROPERTY_MASK &
CSS_PROPERTY_VALUE_PARSER_FUNCTION) == 0,
"didn't leave enough room for the parse property constants");
#define CSS_PROPERTY_VALUE_RESTRICTION_MASK (3<<13)
// The parser (in particular, CSSParserImpl::ParseSingleValueProperty)

View File

@ -1571,8 +1571,10 @@ static const nsEventStates sPseudoClassStates[] = {
nsEventStates(),
nsEventStates()
};
PR_STATIC_ASSERT(NS_ARRAY_LENGTH(sPseudoClassStates) ==
nsCSSPseudoClasses::ePseudoClass_NotPseudoClass + 1);
MOZ_STATIC_ASSERT(NS_ARRAY_LENGTH(sPseudoClassStates) ==
nsCSSPseudoClasses::ePseudoClass_NotPseudoClass + 1,
"ePseudoClass_NotPseudoClass is no longer at the end of"
"sPseudoClassStates");
// |aDependence| has two functions:
// * when non-null, it indicates that we're processing a negation,

View File

@ -118,7 +118,8 @@ static const PRUint8 gLexTable[] = {
SI, SI, SI, SI, SI, SI, SI, SI, SI, SI, SI, SI, SI, SI, SI, SI,
};
PR_STATIC_ASSERT(NS_ARRAY_LENGTH(gLexTable) == 256);
MOZ_STATIC_ASSERT(NS_ARRAY_LENGTH(gLexTable) == 256,
"gLexTable expected to cover all 2^8 possible PRUint8s");
#undef W
#undef S

View File

@ -861,7 +861,8 @@ nsCSSValue::AppendToString(nsCSSProperty aProperty, nsAString& aResult) const
}
}
else if (eCSSProperty_unicode_bidi == aProperty) {
PR_STATIC_ASSERT(NS_STYLE_UNICODE_BIDI_NORMAL == 0);
MOZ_STATIC_ASSERT(NS_STYLE_UNICODE_BIDI_NORMAL == 0,
"unicode-bidi style constants not as expected");
PRInt32 intValue = GetIntValue();
if (NS_STYLE_UNICODE_BIDI_NORMAL == intValue) {
AppendASCIItoUTF16(nsCSSProps::LookupPropertyValue(aProperty, intValue),
@ -1410,8 +1411,9 @@ nsCSSRect_heap::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const
return n;
}
PR_STATIC_ASSERT(NS_SIDE_TOP == 0 && NS_SIDE_RIGHT == 1 &&
NS_SIDE_BOTTOM == 2 && NS_SIDE_LEFT == 3);
MOZ_STATIC_ASSERT(NS_SIDE_TOP == 0 && NS_SIDE_RIGHT == 1 &&
NS_SIDE_BOTTOM == 2 && NS_SIDE_LEFT == 3,
"box side constants not top/right/bottom/left == 0/1/2/3");
/* static */ const nsCSSRect::side_type nsCSSRect::sides[4] = {
&nsCSSRect::mTop,
@ -1774,8 +1776,9 @@ nsCSSCornerSizes::Reset()
}
}
PR_STATIC_ASSERT(NS_CORNER_TOP_LEFT == 0 && NS_CORNER_TOP_RIGHT == 1 && \
NS_CORNER_BOTTOM_RIGHT == 2 && NS_CORNER_BOTTOM_LEFT == 3);
MOZ_STATIC_ASSERT(NS_CORNER_TOP_LEFT == 0 && NS_CORNER_TOP_RIGHT == 1 &&
NS_CORNER_BOTTOM_RIGHT == 2 && NS_CORNER_BOTTOM_LEFT == 3,
"box corner constants not tl/tr/br/bl == 0/1/2/3");
/* static */ const nsCSSCornerSizes::corner_type
nsCSSCornerSizes::corners[4] = {

View File

@ -2726,7 +2726,8 @@ nsComputedDOMStyle::DoGetDirection()
return val;
}
PR_STATIC_ASSERT(NS_STYLE_UNICODE_BIDI_NORMAL == 0);
MOZ_STATIC_ASSERT(NS_STYLE_UNICODE_BIDI_NORMAL == 0,
"unicode-bidi style constants not as expected");
nsIDOMCSSValue*
nsComputedDOMStyle::DoGetUnicodeBidi()
@ -3414,7 +3415,9 @@ nsComputedDOMStyle::GetAbsoluteOffset(mozilla::css::Side aSide)
return val;
}
PR_STATIC_ASSERT((NS_SIDE_TOP == 0) && (NS_SIDE_RIGHT == 1) && (NS_SIDE_BOTTOM == 2) && (NS_SIDE_LEFT == 3));
MOZ_STATIC_ASSERT(NS_SIDE_TOP == 0 && NS_SIDE_RIGHT == 1 &&
NS_SIDE_BOTTOM == 2 && NS_SIDE_LEFT == 3,
"box side constants not as expected for NS_OPPOSITE_SIDE");
#define NS_OPPOSITE_SIDE(s_) mozilla::css::Side(((s_) + 2) & 3)
nsIDOMCSSValue*

View File

@ -46,9 +46,12 @@ nsRuleData::GetPoisonOffset()
// Fill in mValueOffsets such that mValueStorage + mValueOffsets[i]
// will yield the frame poison value for all uninitialized value
// offsets.
PR_STATIC_ASSERT(sizeof(PRUword) == sizeof(size_t));
PR_STATIC_ASSERT(PRUword(-1) > PRUword(0));
PR_STATIC_ASSERT(size_t(-1) > size_t(0));
MOZ_STATIC_ASSERT(sizeof(PRUword) == sizeof(size_t),
"expect PRUword and size_t to be the same size");
MOZ_STATIC_ASSERT(PRUword(-1) > PRUword(0),
"expect PRUword to be unsigned");
MOZ_STATIC_ASSERT(size_t(-1) > size_t(0),
"expect size_t to be unsigned");
PRUword framePoisonValue = nsPresArena::GetPoisonValue();
return size_t(framePoisonValue - PRUword(mValueStorage)) /
sizeof(nsCSSValue);

View File

@ -2681,7 +2681,7 @@ nsRuleNode::SetFont(nsPresContext* aPresContext, nsStyleContext* aContext,
aFont->mLanguage);
// -moz-system-font: enum (never inherit!)
PR_STATIC_ASSERT(
MOZ_STATIC_ASSERT(
NS_STYLE_FONT_CAPTION == LookAndFeel::eFont_Caption &&
NS_STYLE_FONT_ICON == LookAndFeel::eFont_Icon &&
NS_STYLE_FONT_MENU == LookAndFeel::eFont_Menu &&
@ -2697,7 +2697,8 @@ nsRuleNode::SetFont(nsPresContext* aPresContext, nsStyleContext* aContext,
NS_STYLE_FONT_BUTTON == LookAndFeel::eFont_Button &&
NS_STYLE_FONT_PULL_DOWN_MENU == LookAndFeel::eFont_PullDownMenu &&
NS_STYLE_FONT_LIST == LookAndFeel::eFont_List &&
NS_STYLE_FONT_FIELD == LookAndFeel::eFont_Field);
NS_STYLE_FONT_FIELD == LookAndFeel::eFont_Field,
"LookAndFeel.h system-font constants out of sync with nsStyleConsts.h");
// Fall back to defaultVariableFont.
nsFont systemFont = *defaultVariableFont;
@ -4920,10 +4921,11 @@ struct BackgroundItemComputer<nsCSSValuePairList, nsStyleBackground::Size>
size.*(axis->type) = nsStyleBackground::Size::eAuto;
}
else if (eCSSUnit_Enumerated == specified.GetUnit()) {
PR_STATIC_ASSERT(nsStyleBackground::Size::eContain ==
NS_STYLE_BG_SIZE_CONTAIN);
PR_STATIC_ASSERT(nsStyleBackground::Size::eCover ==
NS_STYLE_BG_SIZE_COVER);
MOZ_STATIC_ASSERT(nsStyleBackground::Size::eContain ==
NS_STYLE_BG_SIZE_CONTAIN &&
nsStyleBackground::Size::eCover ==
NS_STYLE_BG_SIZE_COVER,
"background size constants out of sync");
NS_ABORT_IF_FALSE(specified.GetIntValue() == NS_STYLE_BG_SIZE_CONTAIN ||
specified.GetIntValue() == NS_STYLE_BG_SIZE_COVER,
"invalid enumerated value for size coordinate");

View File

@ -2793,8 +2793,9 @@ nsStyleAnimation::ExtractComputedValue(nsCSSProperty aProperty,
case eCSSProperty_font_stretch: {
PRInt16 stretch =
static_cast<const nsStyleFont*>(styleStruct)->mFont.stretch;
PR_STATIC_ASSERT(NS_STYLE_FONT_STRETCH_ULTRA_CONDENSED == -4);
PR_STATIC_ASSERT(NS_STYLE_FONT_STRETCH_ULTRA_EXPANDED == 4);
MOZ_STATIC_ASSERT(NS_STYLE_FONT_STRETCH_ULTRA_CONDENSED == -4 &&
NS_STYLE_FONT_STRETCH_ULTRA_EXPANDED == 4,
"font stretch constants not as expected");
if (stretch < NS_STYLE_FONT_STRETCH_ULTRA_CONDENSED ||
stretch > NS_STYLE_FONT_STRETCH_ULTRA_EXPANDED) {
return false;
@ -3017,13 +3018,13 @@ nsStyleAnimation::ExtractComputedValue(nsCSSProperty aProperty,
case eStyleAnimType_Sides_Right:
case eStyleAnimType_Sides_Bottom:
case eStyleAnimType_Sides_Left: {
PR_STATIC_ASSERT(0 == NS_SIDE_TOP);
PR_STATIC_ASSERT(eStyleAnimType_Sides_Right - eStyleAnimType_Sides_Top
== NS_SIDE_RIGHT);
PR_STATIC_ASSERT(eStyleAnimType_Sides_Bottom - eStyleAnimType_Sides_Top
== NS_SIDE_BOTTOM);
PR_STATIC_ASSERT(eStyleAnimType_Sides_Left - eStyleAnimType_Sides_Top
== NS_SIDE_LEFT);
MOZ_STATIC_ASSERT(
NS_SIDE_TOP == eStyleAnimType_Sides_Top -eStyleAnimType_Sides_Top &&
NS_SIDE_RIGHT == eStyleAnimType_Sides_Right -eStyleAnimType_Sides_Top &&
NS_SIDE_BOTTOM == eStyleAnimType_Sides_Bottom-eStyleAnimType_Sides_Top &&
NS_SIDE_LEFT == eStyleAnimType_Sides_Left -eStyleAnimType_Sides_Top,
"box side constants out of sync with animation side constants");
const nsStyleCoord &coord = static_cast<const nsStyleSides*>(
StyleDataAtOffset(styleStruct, ssOffset))->
Get(mozilla::css::Side(animType - eStyleAnimType_Sides_Top));
@ -3033,16 +3034,17 @@ nsStyleAnimation::ExtractComputedValue(nsCSSProperty aProperty,
case eStyleAnimType_Corner_TopRight:
case eStyleAnimType_Corner_BottomRight:
case eStyleAnimType_Corner_BottomLeft: {
PR_STATIC_ASSERT(0 == NS_CORNER_TOP_LEFT);
PR_STATIC_ASSERT(eStyleAnimType_Corner_TopRight -
eStyleAnimType_Corner_TopLeft
== NS_CORNER_TOP_RIGHT);
PR_STATIC_ASSERT(eStyleAnimType_Corner_BottomRight -
eStyleAnimType_Corner_TopLeft
== NS_CORNER_BOTTOM_RIGHT);
PR_STATIC_ASSERT(eStyleAnimType_Corner_BottomLeft -
eStyleAnimType_Corner_TopLeft
== NS_CORNER_BOTTOM_LEFT);
MOZ_STATIC_ASSERT(
NS_CORNER_TOP_LEFT == eStyleAnimType_Corner_TopLeft -
eStyleAnimType_Corner_TopLeft &&
NS_CORNER_TOP_RIGHT == eStyleAnimType_Corner_TopRight -
eStyleAnimType_Corner_TopLeft &&
NS_CORNER_BOTTOM_RIGHT == eStyleAnimType_Corner_BottomRight -
eStyleAnimType_Corner_TopLeft &&
NS_CORNER_BOTTOM_LEFT == eStyleAnimType_Corner_BottomLeft -
eStyleAnimType_Corner_TopLeft,
"box corner constants out of sync with animation corner constants");
const nsStyleCorners *corners = static_cast<const nsStyleCorners*>(
StyleDataAtOffset(styleStruct, ssOffset));
PRUint8 fullCorner = animType - eStyleAnimType_Corner_TopLeft;

View File

@ -75,8 +75,11 @@ nsStyleContext::nsStyleContext(nsStyleContext* aParent,
mBits(((PRUint32)aPseudoType) << NS_STYLE_CONTEXT_TYPE_SHIFT),
mRefCnt(0)
{
PR_STATIC_ASSERT((PR_UINT32_MAX >> NS_STYLE_CONTEXT_TYPE_SHIFT) >=
nsCSSPseudoElements::ePseudo_MAX);
// This check has to be done "backward", because if it were written the
// more natural way it wouldn't fail even when it needed to.
MOZ_STATIC_ASSERT((PR_UINT32_MAX >> NS_STYLE_CONTEXT_TYPE_SHIFT) >=
nsCSSPseudoElements::ePseudo_MAX,
"pseudo element bits no longer fit in a PRUint32");
mNextSibling = this;
mPrevSibling = this;

View File

@ -280,7 +280,8 @@ void nsStyleCorners::Reset()
// Validation of NS_SIDE_IS_VERTICAL and NS_HALF_CORNER_IS_X.
#define CASE(side, result) \
PR_STATIC_ASSERT(NS_SIDE_IS_VERTICAL(side) == result)
MOZ_STATIC_ASSERT(NS_SIDE_IS_VERTICAL(side) == result, \
"NS_SIDE_IS_VERTICAL is wrong")
CASE(NS_SIDE_TOP, false);
CASE(NS_SIDE_RIGHT, true);
CASE(NS_SIDE_BOTTOM, false);
@ -288,7 +289,8 @@ CASE(NS_SIDE_LEFT, true);
#undef CASE
#define CASE(corner, result) \
PR_STATIC_ASSERT(NS_HALF_CORNER_IS_X(corner) == result)
MOZ_STATIC_ASSERT(NS_HALF_CORNER_IS_X(corner) == result, \
"NS_HALF_CORNER_IS_X is wrong")
CASE(NS_CORNER_TOP_LEFT_X, true);
CASE(NS_CORNER_TOP_LEFT_Y, false);
CASE(NS_CORNER_TOP_RIGHT_X, true);
@ -301,7 +303,8 @@ CASE(NS_CORNER_BOTTOM_LEFT_Y, false);
// Validation of NS_HALF_TO_FULL_CORNER.
#define CASE(corner, result) \
PR_STATIC_ASSERT(NS_HALF_TO_FULL_CORNER(corner) == result)
MOZ_STATIC_ASSERT(NS_HALF_TO_FULL_CORNER(corner) == result, \
"NS_HALF_TO_FULL_CORNER is wrong")
CASE(NS_CORNER_TOP_LEFT_X, NS_CORNER_TOP_LEFT);
CASE(NS_CORNER_TOP_LEFT_Y, NS_CORNER_TOP_LEFT);
CASE(NS_CORNER_TOP_RIGHT_X, NS_CORNER_TOP_RIGHT);
@ -314,7 +317,8 @@ CASE(NS_CORNER_BOTTOM_LEFT_Y, NS_CORNER_BOTTOM_LEFT);
// Validation of NS_FULL_TO_HALF_CORNER.
#define CASE(corner, vert, result) \
PR_STATIC_ASSERT(NS_FULL_TO_HALF_CORNER(corner, vert) == result)
MOZ_STATIC_ASSERT(NS_FULL_TO_HALF_CORNER(corner, vert) == result, \
"NS_FULL_TO_HALF_CORNER is wrong")
CASE(NS_CORNER_TOP_LEFT, false, NS_CORNER_TOP_LEFT_X);
CASE(NS_CORNER_TOP_LEFT, true, NS_CORNER_TOP_LEFT_Y);
CASE(NS_CORNER_TOP_RIGHT, false, NS_CORNER_TOP_RIGHT_X);
@ -327,7 +331,8 @@ CASE(NS_CORNER_BOTTOM_LEFT, true, NS_CORNER_BOTTOM_LEFT_Y);
// Validation of NS_SIDE_TO_{FULL,HALF}_CORNER.
#define CASE(side, second, result) \
PR_STATIC_ASSERT(NS_SIDE_TO_FULL_CORNER(side, second) == result)
MOZ_STATIC_ASSERT(NS_SIDE_TO_FULL_CORNER(side, second) == result, \
"NS_SIDE_TO_FULL_CORNER is wrong")
CASE(NS_SIDE_TOP, false, NS_CORNER_TOP_LEFT);
CASE(NS_SIDE_TOP, true, NS_CORNER_TOP_RIGHT);
@ -342,7 +347,8 @@ CASE(NS_SIDE_LEFT, true, NS_CORNER_TOP_LEFT);
#undef CASE
#define CASE(side, second, parallel, result) \
PR_STATIC_ASSERT(NS_SIDE_TO_HALF_CORNER(side, second, parallel) == result)
MOZ_STATIC_ASSERT(NS_SIDE_TO_HALF_CORNER(side, second, parallel) == result, \
"NS_SIDE_TO_HALF_CORNER is wrong")
CASE(NS_SIDE_TOP, false, true, NS_CORNER_TOP_LEFT_X);
CASE(NS_SIDE_TOP, false, false, NS_CORNER_TOP_LEFT_Y);
CASE(NS_SIDE_TOP, true, true, NS_CORNER_TOP_RIGHT_X);

View File

@ -69,9 +69,9 @@
#include "imgIContainer.h"
#include "prlog.h"
// Make sure we have enough bits in NS_STYLE_INHERIT_MASK.
PR_STATIC_ASSERT((((1 << nsStyleStructID_Length) - 1) &
~(NS_STYLE_INHERIT_MASK)) == 0);
MOZ_STATIC_ASSERT((((1 << nsStyleStructID_Length) - 1) &
~(NS_STYLE_INHERIT_MASK)) == 0,
"Not enough bits in NS_STYLE_INHERIT_MASK");
inline bool IsFixedUnit(const nsStyleCoord& aCoord, bool aEnumOK)
{
@ -2039,11 +2039,12 @@ void nsTimingFunction::AssignFromKeyword(PRInt32 aTimingFunctionType)
break;
}
PR_STATIC_ASSERT(NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE == 0);
PR_STATIC_ASSERT(NS_STYLE_TRANSITION_TIMING_FUNCTION_LINEAR == 1);
PR_STATIC_ASSERT(NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE_IN == 2);
PR_STATIC_ASSERT(NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE_OUT == 3);
PR_STATIC_ASSERT(NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE_IN_OUT == 4);
MOZ_STATIC_ASSERT(NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE == 0 &&
NS_STYLE_TRANSITION_TIMING_FUNCTION_LINEAR == 1 &&
NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE_IN == 2 &&
NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE_OUT == 3 &&
NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE_IN_OUT == 4,
"transition timing function constants not as expected");
static const float timingFunctionValues[5][4] = {
{ 0.25, 0.10, 0.25, 1.00 }, // ease

View File

@ -43,6 +43,7 @@
#ifndef mozilla_Assertions_h_
#define mozilla_Assertions_h_
#include "mozilla/Attributes.h"
#include "mozilla/Types.h"
/*
@ -222,6 +223,21 @@ MOZ_Assert(const char* s, const char* file, int ln);
# define MOZ_ASSERT_IF(cond, expr) ((void)0)
#endif
/* MOZ_NOT_REACHED_MARKER() expands (in compilers which support it) to an
* expression which states that it is undefined behavior for the compiler to
* reach this point. Most code should probably use the higher level
* MOZ_NOT_REACHED (which expands to this when appropriate).
*/
#if defined(__clang__)
# define MOZ_NOT_REACHED_MARKER() __builtin_unreachable()
#elif defined(__GNUC__)
# if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
# define MOZ_NOT_REACHED_MARKER() __builtin_unreachable()
# endif
#elif defined(_MSC_VER)
# define MOZ_NOT_REACHED_MARKER() __assume(0)
#endif
/*
* MOZ_NOT_REACHED(reason) indicates that the given point can't be reached
* during execution: simply reaching that point in execution is a bug. It takes
@ -239,10 +255,39 @@ MOZ_Assert(const char* s, const char* file, int ln);
* MOZ_NOT_REACHED("boolean literal that's not true or false?");
* }
*/
#ifdef DEBUG
# define MOZ_NOT_REACHED(reason) MOZ_Assert(reason, __FILE__, __LINE__)
#if defined(MOZ_NOT_REACHED_MARKER)
# if defined(DEBUG)
# define MOZ_NOT_REACHED(reason) do { \
MOZ_Assert(reason, __FILE__, __LINE__); \
MOZ_NOT_REACHED_MARKER(); \
} while (0)
# else
# define MOZ_NOT_REACHED(reason) MOZ_NOT_REACHED_MARKER()
# endif
#else
# define MOZ_NOT_REACHED(reason) ((void)0)
# if defined(__GNUC__)
/*
* On older versions of gcc we need to call a noreturn function to mark the
* code as unreachable. Since what we want is an unreachable version of
* MOZ_Assert, we use an asm label
* (http://gcc.gnu.org/onlinedocs/gcc-4.6.2/gcc/Asm-Labels.html) to create
* a new declaration to the same symbol. MOZ_ASSERT_NR should only be
* used via this macro, as it is a very specific hack to older versions of
* gcc.
*/
# define MOZ_GETASMPREFIX2(X) #X
# define MOZ_GETASMPREFIX(X) MOZ_GETASMPREFIX2(X)
# define MOZ_ASMPREFIX MOZ_GETASMPREFIX(__USER_LABEL_PREFIX__)
extern MOZ_NORETURN MFBT_API(void)
MOZ_ASSERT_NR(const char* s, const char* file, int ln) \
asm (MOZ_ASMPREFIX "MOZ_Assert");
# define MOZ_NOT_REACHED(reason) MOZ_ASSERT_NR(reason, __FILE__, __LINE__)
# elif defined(DEBUG)
# define MOZ_NOT_REACHED(reason) MOZ_Assert(reason, __FILE__, __LINE__)
# else
# define MOZ_NOT_REACHED(reason) ((void)0)
# endif
#endif
/*

View File

@ -662,9 +662,6 @@ pref("urlclassifier.gethashtables", "goog-phish-shavar,goog-malware-shavar");
// the database.
pref("urlclassifier.confirm-age", 2700);
// Maximum size of the sqlite3 cache during an update, in bytes
pref("urlclassifier.updatecachemax", 4194304);
// URL for checking the reason for a malware warning.
pref("browser.safebrowsing.malware.reportURL", "http://safebrowsing.clients.google.com/safebrowsing/diagnostic?client=%NAME%&hl=%LOCALE%&site=");
#endif

View File

@ -493,6 +493,14 @@ public class AboutHomeContent extends ScrollView {
String iconUrl = jsonobj.getString("iconURL");
String pageUrl = getPageUrlFromIconUrl(iconUrl);
final String homepageUrl = jsonobj.getString("homepageURL");
row.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if (mUriLoadCallback != null)
mUriLoadCallback.callback(homepageUrl);
}
});
Favicons favicons = GeckoApp.mAppContext.mFavicons;
favicons.loadFavicon(pageUrl, iconUrl,
new Favicons.OnFaviconLoadedListener() {

View File

@ -163,17 +163,27 @@ public class AwesomeBar extends Activity implements GeckoEventListener {
mText.setOnKeyPreImeListener(new AwesomeBarEditText.OnKeyPreImeListener() {
public boolean onKeyPreIme(View v, int keyCode, KeyEvent event) {
InputMethodManager imm =
(InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
// We only want to process one event per tap
if (event.getAction() != KeyEvent.ACTION_DOWN)
return false;
if (keyCode == KeyEvent.KEYCODE_ENTER && event.getAction() == KeyEvent.ACTION_DOWN) {
if (keyCode == KeyEvent.KEYCODE_ENTER) {
openUserEnteredAndFinish(mText.getText().toString());
return true;
}
// If input method is in fullscreen mode, we want to dismiss
// it instead of closing awesomebar straight away.
if (!imm.isFullscreenMode() && keyCode == KeyEvent.KEYCODE_BACK) {
InputMethodManager imm =
(InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
if (keyCode == KeyEvent.KEYCODE_BACK && !imm.isFullscreenMode()) {
// Let mAwesomeTabs try to handle the back press, since we may be in a
// bookmarks sub-folder.
if (mAwesomeTabs.onBackPressed())
return true;
// If mAwesomeTabs.onBackPressed() returned false, we didn't move up
// a folder level, so just exit the activity.
cancelAndFinish();
return true;
}
@ -409,23 +419,7 @@ public class AwesomeBar extends Activity implements GeckoEventListener {
Object selectedItem = null;
String title = "";
if (list == findViewById(R.id.all_pages_list)) {
if (!(menuInfo instanceof AdapterView.AdapterContextMenuInfo)) {
Log.e(LOGTAG, "menuInfo is not AdapterContextMenuInfo");
return;
}
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
selectedItem = list.getItemAtPosition(info.position);
if (!(selectedItem instanceof Cursor)) {
Log.e(LOGTAG, "item at " + info.position + " is not a Cursor");
return;
}
Cursor cursor = (Cursor) selectedItem;
title = cursor.getString(cursor.getColumnIndexOrThrow(URLColumns.TITLE));
} else {
if (list == findViewById(R.id.history_list)) {
if (!(menuInfo instanceof ExpandableListView.ExpandableListContextMenuInfo)) {
Log.e(LOGTAG, "menuInfo is not ExpandableListContextMenuInfo");
return;
@ -442,15 +436,31 @@ public class AwesomeBar extends Activity implements GeckoEventListener {
ExpandableListView exList = (ExpandableListView) list;
selectedItem = exList.getExpandableListAdapter().getChild(groupPosition, childPosition);
if (exList == findViewById(R.id.bookmarks_list)) {
// The bookmarks list is backed by a SimpleCursorTreeAdapter
Cursor cursor = (Cursor) selectedItem;
title = cursor.getString(cursor.getColumnIndexOrThrow(URLColumns.TITLE));
} else {
// The history list is backed by a SimpleExpandableListAdapter
@SuppressWarnings("rawtypes")
Map map = (Map) selectedItem;
title = (String) map.get(URLColumns.TITLE);
// The history list is backed by a SimpleExpandableListAdapter
@SuppressWarnings("rawtypes")
Map map = (Map) selectedItem;
title = (String) map.get(URLColumns.TITLE);
} else {
if (!(menuInfo instanceof AdapterView.AdapterContextMenuInfo)) {
Log.e(LOGTAG, "menuInfo is not AdapterContextMenuInfo");
return;
}
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
selectedItem = list.getItemAtPosition(info.position);
if (!(selectedItem instanceof Cursor)) {
Log.e(LOGTAG, "item at " + info.position + " is not a Cursor");
return;
}
Cursor cursor = (Cursor) selectedItem;
title = cursor.getString(cursor.getColumnIndexOrThrow(URLColumns.TITLE));
// Don't show the context menu for folders
if (list == findViewById(R.id.bookmarks_list) &&
cursor.getInt(cursor.getColumnIndexOrThrow(Bookmarks.IS_FOLDER)) == 1) {
selectedItem = null;
}
}

View File

@ -20,6 +20,7 @@
*
* Contributor(s):
* Lucas Rocha <lucasr@mozilla.com>
* Margaret Leibovic <margaret.leibovic@gmail.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@ -40,9 +41,7 @@ package org.mozilla.gecko;
import android.content.ContentResolver;
import android.content.Context;
import android.content.res.Resources;
import android.database.ContentObserver;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
@ -65,14 +64,12 @@ import android.widget.FilterQueryProvider;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.SimpleCursorTreeAdapter;
import android.widget.SimpleExpandableListAdapter;
import android.widget.TabHost;
import android.widget.TextView;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
@ -83,9 +80,9 @@ import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.mozilla.gecko.db.BrowserContract.Bookmarks;
import org.mozilla.gecko.db.BrowserDB;
import org.mozilla.gecko.db.BrowserDB.URLColumns;
import org.mozilla.gecko.sync.repositories.android.BrowserContract.Bookmarks;
public class AwesomeBarTabs extends TabHost {
private static final String LOGTAG = "GeckoAwesomeBarTabs";
@ -102,7 +99,6 @@ public class AwesomeBarTabs extends TabHost {
private View.OnTouchListener mListTouchListener;
private JSONArray mSearchEngines;
private ContentResolver mContentResolver;
private ContentObserver mContentObserver;
private AwesomeBarCursorAdapter mAllPagesCursorAdapter;
private BookmarksListAdapter mBookmarksAdapter;
@ -152,8 +148,7 @@ public class AwesomeBarTabs extends TabHost {
}
}
private class AwesomeCursorViewBinder implements SimpleCursorAdapter.ViewBinder,
SimpleCursorTreeAdapter.ViewBinder {
private class AwesomeCursorViewBinder implements SimpleCursorAdapter.ViewBinder {
private boolean updateFavicon(View view, Cursor cursor, int faviconIndex) {
byte[] b = cursor.getBlob(faviconIndex);
ImageView favicon = (ImageView) view;
@ -183,12 +178,6 @@ public class AwesomeBarTabs extends TabHost {
}
public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
// If we're updating a folder header in the bookmarks UI,
// the apadter updates the title for us automatically.
int isFolderIndex = cursor.getColumnIndex(Bookmarks.IS_FOLDER);
if (isFolderIndex >= 0 && cursor.getInt(isFolderIndex) == 1)
return false;
int faviconIndex = cursor.getColumnIndexOrThrow(URLColumns.FAVICON);
if (columnIndex == faviconIndex) {
return updateFavicon(view, cursor, faviconIndex);
@ -204,131 +193,178 @@ public class AwesomeBarTabs extends TabHost {
}
}
private class RefreshChildrenCursorTask extends AsyncTask<String, Void, Cursor> {
private int mGroupPosition;
private class BookmarksListAdapter extends SimpleCursorAdapter {
private static final int VIEW_TYPE_ITEM = 0;
private static final int VIEW_TYPE_FOLDER = 1;
private static final int VIEW_TYPE_COUNT = 2;
public RefreshChildrenCursorTask(int groupPosition) {
mGroupPosition = groupPosition;
private LayoutInflater mInflater;
private LinkedList<Pair<Integer, String>> mParentStack;
private RefreshBookmarkCursorTask mRefreshTask = null;
private TextView mBookmarksTitleView;
public BookmarksListAdapter(Context context, int layout, Cursor c, String[] from, int[] to) {
super(context, layout, c, from, to);
mInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
// mParentStack holds folder id/title pairs that allow us to navigate
// back up the folder heirarchy
mParentStack = new LinkedList<Pair<Integer, String>>();
// Add the root folder to the stack
Pair<Integer, String> rootFolder = new Pair<Integer, String>(Bookmarks.FIXED_ROOT_ID, "");
mParentStack.push(rootFolder);
}
public void refreshCurrentFolder() {
// Cancel any pre-existing async refresh tasks
if (mRefreshTask != null)
mRefreshTask.cancel(false);
Pair<Integer, String> folderPair = mParentStack.getFirst();
mRefreshTask = new RefreshBookmarkCursorTask(folderPair.first, folderPair.second);
mRefreshTask.execute();
}
// Returns false if there is no parent folder to move to
public boolean moveToParentFolder() {
// If we're already at the root, we can't move to a parent folder
if (mParentStack.size() == 1)
return false;
mParentStack.pop();
refreshCurrentFolder();
return true;
}
public void moveToChildFolder(int folderId, String folderTitle) {
Pair<Integer, String> folderPair = new Pair<Integer, String>(folderId, folderTitle);
mParentStack.push(folderPair);
refreshCurrentFolder();
}
public int getItemViewType(int position) {
Cursor c = getCursor();
if (c.moveToPosition(position) &&
c.getInt(c.getColumnIndexOrThrow(Bookmarks.IS_FOLDER)) == 1)
return VIEW_TYPE_FOLDER;
// Default to retuning normal item type
return VIEW_TYPE_ITEM;
}
@Override
public int getViewTypeCount() {
return VIEW_TYPE_COUNT;
}
public String getFolderTitle(int position) {
Cursor c = getCursor();
if (!c.moveToPosition(position))
return "";
return c.getString(c.getColumnIndexOrThrow(Bookmarks.TITLE));
}
@Override
protected Cursor doInBackground(String... params) {
String guid = params[0];
if (guid != null && guid.equals(Bookmarks.MOBILE_FOLDER_GUID))
return BrowserDB.getMobileBookmarks(mContentResolver);
public View getView(int position, View convertView, ViewGroup parent) {
int viewType = getItemViewType(position);
// If we don't have the mobile bookmarks folder, we must have
// the desktop bookmarks folder
return BrowserDB.getDesktopBookmarks(mContentResolver);
if (viewType == VIEW_TYPE_ITEM)
return super.getView(position, convertView, parent);
if (convertView == null)
convertView = mInflater.inflate(R.layout.awesomebar_folder_row, null);
TextView titleView = (TextView) convertView.findViewById(R.id.title);
titleView.setText(getFolderTitle(position));
return convertView;
}
@Override
protected void onPostExecute(Cursor childrenCursor) {
mBookmarksAdapter.setChildrenCursor(mGroupPosition, childrenCursor);
public void setBookmarksTitleView(TextView titleView) {
mBookmarksTitleView = titleView;
}
private class RefreshBookmarkCursorTask extends AsyncTask<Void, Void, Cursor> {
private int mFolderId;
private String mFolderTitle;
public RefreshBookmarkCursorTask(int folderId, String folderTitle) {
mFolderId = folderId;
mFolderTitle = folderTitle;
}
protected Cursor doInBackground(Void... params) {
return BrowserDB.getBookmarksInFolder(mContentResolver, mFolderId);
}
protected void onPostExecute(Cursor cursor) {
mRefreshTask = null;
mBookmarksAdapter.changeCursor(cursor);
// Hide the header text if we're at the root folder
if (mFolderId == Bookmarks.FIXED_ROOT_ID) {
mBookmarksTitleView.setVisibility(View.GONE);
} else {
mBookmarksTitleView.setText(mFolderTitle);
mBookmarksTitleView.setVisibility(View.VISIBLE);
}
}
}
}
public class BookmarksListAdapter extends SimpleCursorTreeAdapter {
public BookmarksListAdapter(Context context, Cursor cursor,
int groupLayout, String[] groupFrom, int[] groupTo,
int childLayout, String[] childFrom, int[] childTo) {
super(context, cursor, groupLayout, groupFrom, groupTo, childLayout, childFrom, childTo);
}
// This method checks to see if we're in a bookmark sub-folder. If we are,
// it will go up a level and return true. Otherwise it will return false.
public boolean onBackPressed() {
// If we're not in the bookmarks tab, we have nothing to do
if (!getCurrentTabTag().equals(BOOKMARKS_TAB))
return false;
@Override
protected Cursor getChildrenCursor(Cursor groupCursor) {
String guid = groupCursor.getString(groupCursor.getColumnIndexOrThrow(Bookmarks.GUID));
// We need to do this in a AsyncTask because we're on the main thread
new RefreshChildrenCursorTask(groupCursor.getPosition()).execute(guid);
// Return an empty Cursor to avoid possible NPE
return new MatrixCursor(new String [] { Bookmarks._ID,
Bookmarks.URL,
Bookmarks.TITLE,
Bookmarks.FAVICON });
}
return mBookmarksAdapter.moveToParentFolder();
}
private class BookmarksQueryTask extends AsyncTask<Void, Void, Cursor> {
protected Cursor doInBackground(Void... arg0) {
// Make our own cursor to group mobile bookmarks and desktop bookmarks.
// This data is used in BookmarksListAdapter and AwesomeCursorViewBinder.
MatrixCursor c = new MatrixCursor(new String[] { Bookmarks._ID,
Bookmarks.IS_FOLDER,
Bookmarks.GUID,
URLColumns.TITLE }, 2);
Resources resources = mContext.getResources();
c.addRow(new Object[] { 0, 1, Bookmarks.MOBILE_FOLDER_GUID,
resources.getString(R.string.bookmarks_folder_mobile)} );
c.addRow(new Object[] { 1, 1, null,
resources.getString(R.string.bookmarks_folder_desktop)} );
return c;
return BrowserDB.getBookmarksInFolder(mContentResolver, Bookmarks.FIXED_ROOT_ID);
}
protected void onPostExecute(Cursor cursor) {
// Load the list using a custom adapter so we can create the bitmaps
mBookmarksAdapter = new BookmarksListAdapter(
mContext,
cursor,
R.layout.awesomebar_header_row,
new String[] { URLColumns.TITLE },
new int[] { R.id.title },
R.layout.awesomebar_row,
cursor,
new String[] { URLColumns.TITLE,
URLColumns.URL,
URLColumns.FAVICON },
new int[] { R.id.title, R.id.url, R.id.favicon }
);
try {
// use reflection to disable auto-requery
Class<?> cls = Class.forName("android.widget.CursorTreeAdapter");
Field field = cls.getDeclaredField("mAutoRequery");
field.setAccessible(true);
field.set(mBookmarksAdapter, false);
// register an asynchronous custom observer to replace the synchronous auto-requery
mContentObserver = new ContentObserver(GeckoAppShell.getHandler()) {
public void onChange(boolean selfChange) {
// The group cursor doesn't ever need to change because it just holds the
// mobile/desktop folders, but we do need to update the children cursors.
Cursor groupCursor = mBookmarksAdapter.getCursor();
groupCursor.moveToPosition(-1);
while (groupCursor.moveToNext()) {
String guid = groupCursor.getString(groupCursor.getColumnIndexOrThrow(Bookmarks.GUID));
// We need to do this in a AsyncTask because we're on the main thread
new RefreshChildrenCursorTask(groupCursor.getPosition()).execute(guid);
}
}
};
BrowserDB.registerBookmarkObserver(mContentResolver, mContentObserver);
} catch (Exception e) {
Log.e(LOGTAG, "could not disable auto-requery for BookmarksListAdapter");
}
mBookmarksAdapter.setViewBinder(new AwesomeCursorViewBinder());
final ExpandableListView bookmarksList = (ExpandableListView) findViewById(R.id.bookmarks_list);
// This listener only applies to child items, not group header items.
bookmarksList.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
public boolean onChildClick(ExpandableListView parent, View view,
int groupPosition, int childPosition, long id) {
handleBookmarkItemClick(groupPosition, childPosition);
return true;
ListView bookmarksList = (ListView) findViewById(R.id.bookmarks_list);
bookmarksList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
handleBookmarkItemClick(position);
}
});
bookmarksList.setAdapter(mBookmarksAdapter);
// We need to add the header before we set the adapter
LayoutInflater inflater =
(LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View headerView = inflater.inflate(R.layout.awesomebar_folder_header_row, null);
// Expand the "Mobile Bookmarks" section
bookmarksList.expandGroup(0);
// Expand the "Desktop Bookmarks" section
// TODO: Once we update the UI to include a better "expand" affordance,
// we can collapse this at first if we want.
bookmarksList.expandGroup(1);
// Hide the header title view to begin with
TextView titleView = (TextView) headerView.findViewById(R.id.title);
titleView.setVisibility(View.GONE);
mBookmarksAdapter.setBookmarksTitleView(titleView);
bookmarksList.addHeaderView(headerView, null, true);
bookmarksList.setAdapter(mBookmarksAdapter);
}
}
@ -635,7 +671,6 @@ public class AwesomeBarTabs extends TabHost {
mInflated = false;
mSearchEngines = new JSONArray();
mContentResolver = context.getContentResolver();
mContentObserver = null;
}
@Override
@ -796,10 +831,29 @@ public class AwesomeBarTabs extends TabHost {
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
private void handleBookmarkItemClick(int groupPosition, int childPosition) {
Cursor cursor = mBookmarksAdapter.getChild(groupPosition, childPosition);
String url = cursor.getString(cursor.getColumnIndexOrThrow(URLColumns.URL));
private void handleBookmarkItemClick(int position) {
// If we tap on the header view, go up a level
if (position == 0) {
mBookmarksAdapter.moveToParentFolder();
return;
}
Cursor cursor = mBookmarksAdapter.getCursor();
// The header view takes up a spot in the list
cursor.moveToPosition(position - 1);
int isFolder = cursor.getInt(cursor.getColumnIndexOrThrow(Bookmarks.IS_FOLDER));
if (isFolder == 1) {
// If we're clicking on a folder, update mBookmarksAdapter to move to that folder
int folderId = cursor.getInt(cursor.getColumnIndexOrThrow(Bookmarks._ID));
String folderTitle = mBookmarksAdapter.getFolderTitle(position - 1);
mBookmarksAdapter.moveToChildFolder(folderId, folderTitle);
return;
}
// Otherwise, just open the URL
String url = cursor.getString(cursor.getColumnIndexOrThrow(URLColumns.URL));
if (mUrlOpenListener != null)
mUrlOpenListener.onUrlOpen(url);
}
@ -845,9 +899,6 @@ public class AwesomeBarTabs extends TabHost {
if (bookmarksCursor != null)
bookmarksCursor.close();
}
if (mContentObserver != null)
BrowserDB.unregisterBookmarkObserver(mContentResolver, mContentObserver);
}
public void filter(String searchTerm) {
@ -868,10 +919,10 @@ public class AwesomeBarTabs extends TabHost {
mAllPagesCursorAdapter.filter(searchTerm);
}
public void setSearchEngines(JSONArray engines) {
mSearchEngines = engines;
public void setSearchEngines(final JSONArray engines) {
GeckoAppShell.getMainHandler().post(new Runnable() {
public void run() {
mSearchEngines = engines;
mAllPagesCursorAdapter.notifyDataSetChanged();
}
});

View File

@ -399,7 +399,10 @@ public class GeckoAppShell
GeckoAppShell.putenv("EXTERNAL_STORAGE=" + f.getPath());
File cacheFile = getCacheDir();
GeckoAppShell.putenv("MOZ_LINKER_CACHE=" + cacheFile.getPath());
String linkerCache = System.getenv("MOZ_LINKER_CACHE");
if (System.getenv("MOZ_LINKER_CACHE") == null) {
GeckoAppShell.putenv("MOZ_LINKER_CACHE=" + cacheFile.getPath());
}
File pluginDataDir = GeckoApp.mAppContext.getDir("plugins", 0);
GeckoAppShell.putenv("ANDROID_PLUGIN_DATADIR=" + pluginDataDir.getPath());

View File

@ -221,6 +221,8 @@ RES_LAYOUT = \
$(SYNC_RES_LAYOUT) \
res/layout/autocomplete_list_item.xml \
res/layout/awesomebar.xml \
res/layout/awesomebar_folder_row.xml \
res/layout/awesomebar_folder_header_row.xml \
res/layout/awesomebar_header_row.xml \
res/layout/awesomebar_row.xml \
res/layout/awesomebar_search.xml \
@ -289,6 +291,7 @@ RES_DRAWABLE_NODPI = \
RES_DRAWABLE_BASE = \
res/drawable/favicon.png \
res/drawable/folder.png \
res/drawable/abouthome_icon.png \
res/drawable/abouthome_logo.png \
res/drawable/abouthome_separator.9.png \
@ -335,6 +338,7 @@ RES_DRAWABLE_LDPI = \
RES_DRAWABLE_HDPI = \
res/drawable-hdpi/favicon.png \
res/drawable-hdpi/folder.png \
res/drawable-hdpi/home_bg.png \
res/drawable-hdpi/home_star.png \
res/drawable-hdpi/abouthome_icon.png \
@ -399,6 +403,7 @@ RES_DRAWABLE_HDPI_V11 = \
RES_DRAWABLE_XHDPI_V11 = \
res/drawable-xhdpi-v11/favicon.png \
res/drawable-xhdpi-v11/folder.png \
res/drawable-xhdpi-v11/abouthome_icon.png \
res/drawable-xhdpi-v11/abouthome_logo.png \
res/drawable-xhdpi-v11/abouthome_separator.9.png \

View File

@ -188,12 +188,7 @@ public class AndroidBrowserDB implements BrowserDB.BrowserDBIface {
Browser.clearHistory(cr);
}
public Cursor getMobileBookmarks(ContentResolver cr) {
Cursor c = cr.query(null, null, null, null, null);
return new AndroidDBCursor(c);
}
public Cursor getDesktopBookmarks(ContentResolver cr) {
public Cursor getBookmarksInFolder(ContentResolver cr, long folderId) {
Cursor c = cr.query(null, null, null, null, null);
return new AndroidDBCursor(c);
}

View File

@ -77,9 +77,7 @@ public class BrowserDB {
public void clearHistory(ContentResolver cr);
public Cursor getMobileBookmarks(ContentResolver cr);
public Cursor getDesktopBookmarks(ContentResolver cr);
public Cursor getBookmarksInFolder(ContentResolver cr, long folderId);
public boolean isBookmark(ContentResolver cr, String uri);
@ -146,12 +144,8 @@ public class BrowserDB {
sDb.clearHistory(cr);
}
public static Cursor getMobileBookmarks(ContentResolver cr) {
return sDb.getMobileBookmarks(cr);
}
public static Cursor getDesktopBookmarks(ContentResolver cr) {
return sDb.getDesktopBookmarks(cr);
public static Cursor getBookmarksInFolder(ContentResolver cr, long folderId) {
return sDb.getBookmarksInFolder(cr, folderId);
}
public static String getUrlForKeyword(ContentResolver cr, String keyword) {

View File

@ -21,6 +21,7 @@
* Contributor(s):
* Lucas Rocha <lucasr@mozilla.com>
* Richard Newman <rnewman@mozilla.com>
* Margaret Leibovic <margaret.leibovic@gmail.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@ -52,7 +53,6 @@ import android.content.ContentValues;
import android.database.ContentObserver;
import android.database.Cursor;
import android.database.CursorWrapper;
import android.database.MatrixCursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
@ -79,6 +79,7 @@ public class LocalBrowserDB implements BrowserDB.BrowserDBIface {
private final String mProfile;
private long mMobileFolderId;
private long mTagsFolderId;
private final Uri mBookmarksUriWithProfile;
private final Uri mParentsUriWithProfile;
@ -86,9 +87,18 @@ public class LocalBrowserDB implements BrowserDB.BrowserDBIface {
private final Uri mImagesUriWithProfile;
private final Uri mDeletedHistoryUriWithProfile;
private static final String[] DEFAULT_BOOKMARK_COLUMNS =
new String[] { Bookmarks._ID,
Bookmarks.URL,
Bookmarks.TITLE,
Bookmarks.IS_FOLDER,
Bookmarks.PARENT,
Bookmarks.FAVICON };
public LocalBrowserDB(String profile) {
mProfile = profile;
mMobileFolderId = -1;
mTagsFolderId = -1;
mBookmarksUriWithProfile = appendProfile(Bookmarks.CONTENT_URI);
mParentsUriWithProfile = appendProfile(Bookmarks.PARENTS_CONTENT_URI);
@ -296,26 +306,18 @@ public class LocalBrowserDB implements BrowserDB.BrowserDBIface {
cr.delete(mHistoryUriWithProfile, null, null);
}
public Cursor getMobileBookmarks(ContentResolver cr) {
return getBookmarks(cr, true);
}
public Cursor getDesktopBookmarks(ContentResolver cr) {
return getBookmarks(cr, false);
}
private Cursor getBookmarks(ContentResolver cr, boolean mobileBookmarks) {
String parentSelection = mobileBookmarks ? " = ?" : " != ?";
long mobileFolderId = getMobileBookmarksFolderId(cr);
// This method filters out the root folder and the tags folder, since we
// don't want to see those in the UI
public Cursor getBookmarksInFolder(ContentResolver cr, long folderId) {
Cursor c = cr.query(mBookmarksUriWithProfile,
new String[] { Bookmarks._ID,
Bookmarks.URL,
Bookmarks.TITLE,
Bookmarks.FAVICON },
Bookmarks.IS_FOLDER + " = 0 AND " +
Bookmarks.PARENT + parentSelection,
new String[] { String.valueOf(mobileFolderId) },
Bookmarks.DATE_MODIFIED + " DESC");
DEFAULT_BOOKMARK_COLUMNS,
Bookmarks.PARENT + " = ? AND " +
Bookmarks._ID + " <> ? AND " +
Bookmarks._ID + " <> ?",
new String[] { String.valueOf(folderId),
String.valueOf(Bookmarks.FIXED_ROOT_ID),
String.valueOf(getTagsBookmarksFolderId(cr))},
null);
return new LocalDBCursor(c);
}
@ -355,23 +357,37 @@ public class LocalBrowserDB implements BrowserDB.BrowserDBIface {
if (mMobileFolderId >= 0)
return mMobileFolderId;
mMobileFolderId = getFolderIdFromGuid(cr, Bookmarks.MOBILE_FOLDER_GUID);
return mMobileFolderId;
}
private long getTagsBookmarksFolderId(ContentResolver cr) {
if (mTagsFolderId >= 0)
return mTagsFolderId;
mTagsFolderId = getFolderIdFromGuid(cr, Bookmarks.TAGS_FOLDER_GUID);
return mTagsFolderId;
}
private long getFolderIdFromGuid(ContentResolver cr, String guid) {
long folderId = -1;
Cursor c = null;
try {
c = cr.query(mBookmarksUriWithProfile,
new String[] { Bookmarks._ID },
Bookmarks.GUID + " = ?",
new String[] { Bookmarks.MOBILE_FOLDER_GUID },
new String[] { guid },
null);
if (c.moveToFirst())
mMobileFolderId = c.getLong(c.getColumnIndexOrThrow(Bookmarks._ID));
folderId = c.getLong(c.getColumnIndexOrThrow(Bookmarks._ID));
} finally {
if (c != null)
c.close();
}
return mMobileFolderId;
return folderId;
}
/**

Some files were not shown because too many files have changed in this diff Show More