mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-17 22:32:51 +00:00
Merge last win pgo-green changeset from m-i to m-c.
This commit is contained in:
commit
e7b436563b
@ -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
|
||||
|
@ -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=");
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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[
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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
87
build/mobile/droid.py
Normal 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
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
|
39
configure.in
39
configure.in
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -555,6 +555,7 @@ _TEST_FILES2 = \
|
||||
file_bug717511_2.html \
|
||||
file_bug717511_2.html^headers^ \
|
||||
test_bug726364.html \
|
||||
test_bug698381.html \
|
||||
$(NULL)
|
||||
|
||||
_CHROME_FILES = \
|
||||
|
56
content/base/test/test_bug698381.html
Normal file
56
content/base/test/test_bug698381.html
Normal 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>
|
@ -71,6 +71,7 @@ CPPSRCS += \
|
||||
WebGLContextReporter.cpp \
|
||||
WebGLContextValidate.cpp \
|
||||
WebGLExtensionStandardDerivatives.cpp \
|
||||
WebGLExtensionTextureFilterAnisotropic.cpp \
|
||||
WebGLExtensionLoseContext.cpp \
|
||||
$(NULL)
|
||||
|
||||
|
@ -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");
|
||||
|
||||
|
@ -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
|
||||
};
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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()
|
||||
{
|
||||
|
||||
}
|
@ -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_
|
||||
|
@ -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
|
||||
|
@ -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>
|
174
content/canvas/test/webgl/ext-texture-filter-anisotropic.patch
Normal file
174
content/canvas/test/webgl/ext-texture-filter-anisotropic.patch
Normal 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>
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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");
|
||||
|
@ -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 {
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -147,7 +147,7 @@ PluginProcessChild::Init()
|
||||
}
|
||||
if (protectCurrentDirectory) {
|
||||
SanitizeEnvironmentVariables();
|
||||
NS_SetDllDirectory(L"");
|
||||
SetDllDirectory(L"");
|
||||
}
|
||||
|
||||
#else
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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",
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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];
|
||||
|
@ -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,
|
||||
|
@ -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) {
|
||||
|
@ -74,7 +74,7 @@ main(int argc, char* argv[])
|
||||
// the details.
|
||||
if (proctype != GeckoProcessType_Plugin) {
|
||||
mozilla::SanitizeEnvironmentVariables();
|
||||
mozilla::NS_SetDllDirectory(L"");
|
||||
SetDllDirectory(L"");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -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);],
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -500,6 +500,7 @@ irregularFilenames = {
|
||||
'nsIWebGLUniformLocation': 'nsIDOMWebGLRenderingContext',
|
||||
'nsIWebGLExtension': 'nsIDOMWebGLRenderingContext',
|
||||
'nsIWebGLExtensionStandardDerivatives' : 'nsIDOMWebGLRenderingContext',
|
||||
'nsIWebGLExtensionTextureFilterAnisotropic' : 'nsIDOMWebGLRenderingContext',
|
||||
'nsIWebGLExtensionLoseContext' : 'nsIDOMWebGLRenderingContext',
|
||||
|
||||
'nsIIndexedDatabaseUsageCallback': 'nsIIndexedDatabaseManager',
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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 = \
|
||||
|
20
layout/generic/test/test_bug719503.html
Normal file
20
layout/generic/test/test_bug719503.html
Normal 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>
|
@ -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;
|
||||
|
@ -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*
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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.
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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] = {
|
||||
|
@ -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*
|
||||
|
@ -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);
|
||||
|
@ -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");
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
/*
|
||||
|
@ -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
|
||||
|
@ -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() {
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
});
|
||||
|
@ -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());
|
||||
|
@ -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 \
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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
Loading…
x
Reference in New Issue
Block a user